Initial commit: river level monitoring service
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
108
README.md
Normal file
108
README.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# 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)."*
|
||||
Reference in New Issue
Block a user