README: update for credentials-file config and recent GUI changes
- Credentials file is now the single source for vin, interval_s, host, port, log_dir; document new format with nested credentials block - CLI reference trimmed to the remaining flags only - Push server section: 24 h rolling window instead of same-day history - GUI section: connection persistence, clear-on-reconnect, per-plot time window spinner, x-axis fit when data < window size Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ server/
|
|||||||
storage_helpers.py— load / save JSON store, midnight rotation helpers
|
storage_helpers.py— load / save JSON store, midnight rotation helpers
|
||||||
we_connect.py — WeConnect login and vehicle selection
|
we_connect.py — WeConnect login and vehicle selection
|
||||||
log_config.py — logging setup
|
log_config.py — logging setup
|
||||||
|
credentials/ — JSON config files (gitignored)
|
||||||
requirements.txt
|
requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -25,67 +26,89 @@ requirements.txt
|
|||||||
pip install weconnect PyQt5 pyqtgraph
|
pip install weconnect PyQt5 pyqtgraph
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or use the installer which also sets up a systemd user service:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./install.sh
|
||||||
|
```
|
||||||
|
|
||||||
## Collector (`collect.py`)
|
## Collector (`collect.py`)
|
||||||
|
|
||||||
Connects to WeConnect, polls selected domains at a configurable interval, and
|
Connects to WeConnect, polls selected domains at a configurable interval, and
|
||||||
appends records to a JSON file. Simultaneously runs a TCP push server so
|
appends records to a rotating JSON log. Simultaneously runs a TCP push server
|
||||||
clients receive every new snapshot the moment it is collected.
|
so clients receive every new snapshot the moment it is collected.
|
||||||
|
|
||||||
### Quick start
|
### Quick start
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Credentials via environment variables, all defaults
|
python collect.py -c credentials/my_car.json
|
||||||
export WC_USER=me@example.com
|
|
||||||
export WC_PASS=secret
|
|
||||||
python collect.py
|
|
||||||
|
|
||||||
# Credentials from a JSON file, 10-minute interval
|
|
||||||
python collect.py -c credentials/my_car.json -i 600
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Credentials file (`-c FILE`)
|
Username and password can also be supplied via environment variables
|
||||||
|
(override the credentials file):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export WC_USER=me@example.com
|
||||||
|
export WC_PASS=secret
|
||||||
|
python collect.py -c credentials/my_car.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Credentials file
|
||||||
|
|
||||||
|
All connection and collection settings live in a single JSON file:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"username": "me@example.com",
|
"credentials": {
|
||||||
"password": "secret",
|
"username": "me@example.com",
|
||||||
"vin": "WVWZZZE1ZMP000000",
|
"password": "secret"
|
||||||
"domains": ["charging", "measurements", "readiness"]
|
},
|
||||||
|
"vin": "WVWZZZE1ZMP000000",
|
||||||
|
"domains": ["charging", "measurements", "readiness"],
|
||||||
|
"interval_s": 300,
|
||||||
|
"host": "0.0.0.0",
|
||||||
|
"port": 9999,
|
||||||
|
"log_dir": "./logs"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
All keys are optional; explicit CLI flags and `WC_USER` / `WC_PASS`
|
| Key | Default | Description |
|
||||||
environment variables take precedence.
|
|-----|---------|-------------|
|
||||||
|
| `credentials.username` | — | WeConnect / MyVolkswagen email |
|
||||||
|
| `credentials.password` | — | WeConnect password |
|
||||||
|
| `vin` | first vehicle | Target VIN |
|
||||||
|
| `domains` | `["charging","measurements","readiness"]` | Domains to collect (list or `"all"`) |
|
||||||
|
| `interval_s` | `300` | Collection interval in seconds |
|
||||||
|
| `host` | `"0.0.0.0"` | Push server bind address |
|
||||||
|
| `port` | `9999` | Push server TCP port |
|
||||||
|
| `log_dir` | `"./logs"` | Directory for rotating JSON log files |
|
||||||
|
|
||||||
### CLI reference
|
### CLI reference
|
||||||
|
|
||||||
| Flag | Default | Description |
|
Only a handful of flags remain; all vehicle/server settings are in the credentials file.
|
||||||
|------|---------|-------------|
|
|
||||||
| `-c FILE` | — | JSON credentials file |
|
| Flag | Description |
|
||||||
| `-u / -p` | `WC_USER` / `WC_PASS` | Username / password |
|
|------|-------------|
|
||||||
| `--vin` | first vehicle | Target VIN |
|
| `-c FILE` | Credentials / settings file (required) |
|
||||||
| `-d DOMAINS` | `charging,measurements,readiness` | Comma-separated domains or `all` |
|
| `-u / -p` | Override username / password (also `WC_USER` / `WC_PASS`) |
|
||||||
| `-i SECONDS` | `300` | Collection interval |
|
| `-d DOMAINS` | Override domains (comma-separated or `all`) |
|
||||||
| `-o FILE` | `logs/YYYY_MM_DD_HH_MM_SS_<VIN>.json` | Output file |
|
| `--max-records N` | Keep only the last N records per file |
|
||||||
| `--max-records N` | unlimited | Keep only last N records |
|
| `-v` | Verbose / debug logging |
|
||||||
| `--host` | `0.0.0.0` | Push server bind address |
|
| `--list-domains` | Print available domains and exit |
|
||||||
| `--port` | `9999` | Push server TCP port |
|
|
||||||
| `-v` | — | Verbose / debug logging |
|
|
||||||
| `--list-domains` | — | Print available domains and exit |
|
|
||||||
|
|
||||||
**Available domains:** `charging`, `climatisation`, `measurements`,
|
**Available domains:** `charging`, `climatisation`, `measurements`,
|
||||||
`readiness`, `parking`, `access`
|
`readiness`, `parking`, `access`
|
||||||
|
|
||||||
### Log rotation
|
### Log rotation
|
||||||
|
|
||||||
When using the default `logs/` directory the collector automatically starts a
|
A new file is started automatically after midnight UTC; previous files are kept
|
||||||
new file after midnight UTC, keeping all previous files intact. On startup the
|
intact. On startup and on each new client connection the collector sends the
|
||||||
full day's records are pre-loaded from disk so newly connected clients receive
|
last 24 hours of records, so clients always receive a full rolling window
|
||||||
the complete history.
|
regardless of when midnight falls.
|
||||||
|
|
||||||
### Output format
|
### Output format
|
||||||
|
|
||||||
Each file is a JSON object:
|
Log files are named `YYYY_MM_DD_HH_MM_SS_<VIN>.json` and contain:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -95,7 +118,7 @@ Each file is a JSON object:
|
|||||||
"ts": "2025-05-25T10:00:00+00:00",
|
"ts": "2025-05-25T10:00:00+00:00",
|
||||||
"charging": {
|
"charging": {
|
||||||
"batteryStatus": {
|
"batteryStatus": {
|
||||||
"currentSOC": { "value": 80, "unit": "%" },
|
"currentSOC": { "value": 80, "unit": "%" },
|
||||||
"cruisingRangeElectric": { "value": 310, "unit": "km" }
|
"cruisingRangeElectric": { "value": 310, "unit": "km" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -108,26 +131,26 @@ Physical values are always `{"value": …, "unit": …}` objects.
|
|||||||
|
|
||||||
## Push server protocol
|
## Push server protocol
|
||||||
|
|
||||||
The server listens on `--host`:`--port` (default `0.0.0.0:9999`).
|
The server listens on the `host`:`port` from the credentials file (default `0.0.0.0:9999`).
|
||||||
|
|
||||||
* On connect: sends all records from the current day, sorted by timestamp.
|
* On connect: sends all records from the last 24 hours, sorted by timestamp.
|
||||||
* On each new poll: sends the new snapshot immediately.
|
* On each new poll: sends the new snapshot immediately.
|
||||||
|
|
||||||
All messages are **newline-delimited JSON** (one record per line, `\n`
|
All messages are **newline-delimited JSON** (one record per line, `\n` terminated).
|
||||||
terminated).
|
|
||||||
|
|
||||||
## GUI client (`gui_client.py`)
|
## GUI client (`gui_client.py`)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python gui_client.py
|
python gui_client.py
|
||||||
python gui_client.py --host 192.168.1.10 --port 9999
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Dark theme matching nmea_client. Three tabs:
|
Dark theme. Three tabs:
|
||||||
|
|
||||||
### Connector tab
|
### Connector tab
|
||||||
|
|
||||||
Host / port fields, Connect / Disconnect button, and connection status.
|
Enter host and port, then click **Connect**. Settings are saved automatically
|
||||||
|
and restored on the next launch. All plot data is cleared on each
|
||||||
|
connect so fresh server history is never mixed with stale local data.
|
||||||
|
|
||||||
### Dashboard tab
|
### Dashboard tab
|
||||||
|
|
||||||
@@ -138,21 +161,20 @@ showing value and unit. Expand state is preserved across updates.
|
|||||||
|
|
||||||
8 plots (4 × 2) in a scrollable grid. Each plot has its own control bar:
|
8 plots (4 × 2) in a scrollable grid. Each plot has its own control bar:
|
||||||
|
|
||||||
|
* **Time window spinner** — show the last 1–24 hours (per plot).
|
||||||
* **Dropdown + `+`** — select a signal and add it as a trace (max 4 per plot).
|
* **Dropdown + `+`** — select a signal and add it as a trace (max 4 per plot).
|
||||||
* **Colored chips (`name ×`)** — click to remove a trace.
|
* **Colored chips (`name ×`)** — click to remove a trace.
|
||||||
* Zoom / pan with mouse; crosshair cursor tracks mouse position.
|
* Zoom / pan with mouse; crosshair cursor tracks mouse position.
|
||||||
|
* When available data is less than the selected window, the x-axis adjusts
|
||||||
|
to the actual data extent — no empty gap on the left.
|
||||||
|
|
||||||
Trace selections are persisted to
|
Trace selections, time windows, and connection settings are persisted to
|
||||||
`~/.config/we_monitor/plot_settings.json` and restored automatically on
|
`~/.config/we_monitor/plot_settings.json` and restored automatically on
|
||||||
the next launch once matching signals arrive.
|
the next launch.
|
||||||
|
|
||||||
Signal labels use short human-readable names (e.g. *SOC*, *range*,
|
|
||||||
*outside temp*) defined in `_TRACE_LABELS` near the top of `gui_client.py`.
|
|
||||||
|
|
||||||
## CLI test client (`client.py`)
|
## CLI test client (`client.py`)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python client.py
|
|
||||||
python client.py --host 192.168.1.10 --port 9999
|
python client.py --host 192.168.1.10 --port 9999
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user