Server that scrapes bin collection dates from the Reigate & Banstead council website and exposes them over HTTP for an ESP32 client.
Build and start the container:
docker-compose up -d --buildStop it:
docker-compose downRebuild after code changes:
docker-compose up -d --buildNote: Synology NAS uses
docker-compose(hyphenated, v1). The newerdocker compose(space, v2 plugin) is not available on most Synology systems.
Environment variables in docker-compose.yml:
| Variable | Default | Description |
|---|---|---|
UPRN |
200001920678 |
Property identifier for the council lookup |
REFRESH_HOURS |
12 |
How often to re-scrape (hours) |
TZ |
Europe/London |
Timezone used for the /next rollover (see below) |
All responses are application/json. FastAPI also serves auto-generated interactive docs at /docs (Swagger UI) and /redoc.
| Method | Path | Description |
|---|---|---|
| GET | /next |
Next collection date and bin types (ESP32-optimised) |
| GET | /collections |
All upcoming collection dates |
| POST | /refresh |
Force an immediate re-scrape |
| GET | /health |
Health check |
Returns the next upcoming collection. Past noon local time (ROLLOVER_HOUR in TZ), today is treated as already collected and the response rolls over to the next collection. This avoids the indicator showing a stale "today" all afternoon and evening after the bins have been emptied.
200 OK
{"date": "2025-04-07", "bins": ["Rubbish", "Recycling"]}| Field | Type | Description |
|---|---|---|
date |
string | ISO date (YYYY-MM-DD) of the next collection |
bins |
string[] | Bin types collected on that date |
503 Service Unavailable — cache not yet populated, or no upcoming collections in cache:
{"date": null, "bins": []}Returns every upcoming collection currently cached.
200 OK — object keyed by ISO date, values are arrays of bin-type strings:
{
"2025-04-07": ["Rubbish", "Recycling"],
"2025-04-14": ["Garden", "Food"]
}503 Service Unavailable — cache not yet populated:
{}Forces an immediate re-scrape of the council site. Synchronous — typically takes 30-60 seconds while headless Chrome loads the page. Use sparingly; the background scheduler already refreshes every REFRESH_HOURS (default 12).
200 OK
{"status": "ok", "collections": 8}| Field | Type | Description |
|---|---|---|
status |
string | "ok" on success |
collections |
integer | Number of collection dates now cached |
Lightweight liveness probe. Does not hit the council site.
200 OK
{"status": "ok", "cached": true}| Field | Type | Description |
|---|---|---|
status |
string | Always "ok" while the server is running |
cached |
boolean | true once the cache has been populated at least once |