# River Levels Monitor Polls the UK Environment Agency's [flood-monitoring API](https://environment.data.gov.uk/flood-monitoring/doc/reference) for river level stations within a radius you choose, archives every reading to a local SQLite database, and generates a self-contained HTML dashboard. Data on the EA network itself typically updates every 15 minutes, so polling more often than that gains you nothing. ## 1. Install ```bash mkdir -p ~/river-monitor cp river_monitor.py ~/river-monitor/ pip install --user requests # only dependency ``` ## 2. First run Give it a UK postcode (or `--lat`/`--lon`) and a search radius in km. This location is saved to `~/river-data/config.json` so you don't need to repeat it on later runs. ```bash python3 ~/river-monitor/river_monitor.py --postcode "WS15 3RZ" --radius 15 ``` This creates: - `~/river-data/river_levels.db` — the SQLite archive (`stations` and `readings` tables) - `~/river-data/dashboard.html` — open this in a browser to see current levels and a small trend chart per station - `~/river-data/config.json` — remembered location/paths for future runs Subsequent runs need no arguments: ```bash python3 ~/river-monitor/river_monitor.py ``` ## 3. Polling periodically Two options — pick whichever fits your setup: ### Option A: systemd timer (recommended on Kubuntu) ```bash mkdir -p ~/.config/systemd/user cp river-monitor.service river-monitor.timer ~/.config/systemd/user/ systemctl --user daemon-reload systemctl --user enable --now river-monitor.timer # Check it's scheduled: systemctl --user list-timers river-monitor.timer # Check logs: journalctl --user -u river-monitor.service -f ``` ### Option B: cron ```bash crontab -e ``` Add: ``` */15 * * * * /usr/bin/python3 /home/YOURUSER/river-monitor/river_monitor.py >> /home/YOURUSER/river-data/poll.log 2>&1 ``` ### Option C: built-in loop (no scheduler needed) ```bash python3 ~/river-monitor/river_monitor.py --daemon --interval 900 ``` Runs in the foreground (or under `tmux`/`screen`), polling every 900 seconds until stopped. ## Data model **stations**: `station_id`, `label`, `river_name`, `lat`, `lon` **readings**: `station_id`, `measure_id`, `unit`, `qualifier`, `value`, `date_time` (from the EA), `fetched_at` (when you polled it). Unique on `(measure_id, date_time)` so re-polling before a new reading is published never creates duplicates — safe to poll as often as you like. Query it directly any time, e.g. levels for the last 24h: ```bash sqlite3 ~/river-data/river_levels.db \ "SELECT label, date_time, value, unit FROM readings JOIN stations USING(station_id) WHERE date_time > datetime('now','-1 day') ORDER BY date_time DESC;" ``` ## Notes - Only stations that measure river **level** (as opposed to rainfall or flow-only gauges) are included. Edit `parameter=level` in `fetch_level_stations()` if you also want rainfall/tide stations. - No API key is required — this is the EA's open data API. - Attribution (per the Open Government Licence): *"This uses Environment Agency flood and river level data from the real-time data API (Beta)."*