From 19399ca73f1427cc10115c874c8a61f2c9724589 Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Tue, 26 May 2026 13:54:17 +0200 Subject: [PATCH] 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 --- README.md | 118 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 6f97796..c147abb 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ server/ storage_helpers.py— load / save JSON store, midnight rotation helpers we_connect.py — WeConnect login and vehicle selection log_config.py — logging setup +credentials/ — JSON config files (gitignored) requirements.txt ``` @@ -25,67 +26,89 @@ requirements.txt pip install weconnect PyQt5 pyqtgraph ``` +Or use the installer which also sets up a systemd user service: + +```bash +./install.sh +``` + ## Collector (`collect.py`) Connects to WeConnect, polls selected domains at a configurable interval, and -appends records to a JSON file. Simultaneously runs a TCP push server so -clients receive every new snapshot the moment it is collected. +appends records to a rotating JSON log. Simultaneously runs a TCP push server +so clients receive every new snapshot the moment it is collected. ### Quick start ```bash -# Credentials via environment variables, all defaults -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 +python collect.py -c credentials/my_car.json ``` -### 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 { - "username": "me@example.com", - "password": "secret", - "vin": "WVWZZZE1ZMP000000", - "domains": ["charging", "measurements", "readiness"] + "credentials": { + "username": "me@example.com", + "password": "secret" + }, + "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` -environment variables take precedence. +| Key | Default | Description | +|-----|---------|-------------| +| `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 -| Flag | Default | Description | -|------|---------|-------------| -| `-c FILE` | — | JSON credentials file | -| `-u / -p` | `WC_USER` / `WC_PASS` | Username / password | -| `--vin` | first vehicle | Target VIN | -| `-d DOMAINS` | `charging,measurements,readiness` | Comma-separated domains or `all` | -| `-i SECONDS` | `300` | Collection interval | -| `-o FILE` | `logs/YYYY_MM_DD_HH_MM_SS_.json` | Output file | -| `--max-records N` | unlimited | Keep only last N records | -| `--host` | `0.0.0.0` | Push server bind address | -| `--port` | `9999` | Push server TCP port | -| `-v` | — | Verbose / debug logging | -| `--list-domains` | — | Print available domains and exit | +Only a handful of flags remain; all vehicle/server settings are in the credentials file. + +| Flag | Description | +|------|-------------| +| `-c FILE` | Credentials / settings file (required) | +| `-u / -p` | Override username / password (also `WC_USER` / `WC_PASS`) | +| `-d DOMAINS` | Override domains (comma-separated or `all`) | +| `--max-records N` | Keep only the last N records per file | +| `-v` | Verbose / debug logging | +| `--list-domains` | Print available domains and exit | **Available domains:** `charging`, `climatisation`, `measurements`, `readiness`, `parking`, `access` ### Log rotation -When using the default `logs/` directory the collector automatically starts a -new file after midnight UTC, keeping all previous files intact. On startup the -full day's records are pre-loaded from disk so newly connected clients receive -the complete history. +A new file is started automatically after midnight UTC; previous files are kept +intact. On startup and on each new client connection the collector sends the +last 24 hours of records, so clients always receive a full rolling window +regardless of when midnight falls. ### Output format -Each file is a JSON object: +Log files are named `YYYY_MM_DD_HH_MM_SS_.json` and contain: ```json { @@ -95,7 +118,7 @@ Each file is a JSON object: "ts": "2025-05-25T10:00:00+00:00", "charging": { "batteryStatus": { - "currentSOC": { "value": 80, "unit": "%" }, + "currentSOC": { "value": 80, "unit": "%" }, "cruisingRangeElectric": { "value": 310, "unit": "km" } } } @@ -108,26 +131,26 @@ Physical values are always `{"value": …, "unit": …}` objects. ## 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. -All messages are **newline-delimited JSON** (one record per line, `\n` -terminated). +All messages are **newline-delimited JSON** (one record per line, `\n` terminated). ## GUI client (`gui_client.py`) ```bash 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 -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 @@ -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: +* **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). * **Colored chips (`name ×`)** — click to remove a trace. * 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 -the next launch once matching signals arrive. - -Signal labels use short human-readable names (e.g. *SOC*, *range*, -*outside temp*) defined in `_TRACE_LABELS` near the top of `gui_client.py`. +the next launch. ## CLI test client (`client.py`) ```bash -python client.py python client.py --host 192.168.1.10 --port 9999 ```