Files
river-monitor/README.md
2026-07-05 00:09:00 +01:00

3.1 KiB

River Levels Monitor

Polls the UK Environment Agency's flood-monitoring API 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

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.

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:

python3 ~/river-monitor/river_monitor.py

3. Polling periodically

Two options — pick whichever fits your setup:

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

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)

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:

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)."