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:
2026-05-26 13:54:17 +02:00
co-authored by Claude Sonnet 4.6
parent bedf5ed646
commit 19399ca73f
+70 -48
View File
@@ -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 124 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
``` ```