Check windows — wakes every 2 minutes within these times

☀️ Morning · BRI→PAD / SUR→WAT / NRB→WAT / SUR→CLJ / WAT→GLD / RDG→PAD / GLD→WAT

05:00 – 08:40
Checks trains departing 06:30–08:40

🌆 Afternoon · PAD→BRI / WAT→SUR / WAT→NRB / CLJ→SUR / GLD→WAT / PAD→RDG / WAT→GLD

14:00 – 18:00
Checks trains departing 14:30–18:00

All times Europe/London — BST (summer) and GMT (winter) handled automatically

What each check looks for

❌ Cancelled

API flag isCancelled = true
OR estimated departure = "Cancelled"
Always alert, no threshold

⏰ Delayed

If status = "Delayed" (no time yet) → always alert
If new time given:
≥ 8 mins late → alert
< 8 mins late → ignore
ℹ️Delay is measured against scheduled departure time — not arrival. A train delayed at the platform triggers the alert before you leave home.

📢 Station Alert

Free-text bulletin from National Rail
Filtered per route: Alex check for "BRI" or "PAD"; Chris& Fredrowntree& Joemkcarr& Marcus check for "London Waterloo" or "Surbiton"; Esha& Mani check for "London Waterloo" or "Norbiton"; Jenny check for "Clapham Junction" or "Surbiton"; Mrpandapopking& Stephen check for "GLD" or "London Waterloo"; Ricky Tanner check for "PAD" or "RDG"
Other lines/routes → ignored

Example scenarios — morning check at various times

✅ Scenario 1 — All clear, no alert sent
Check runs at 05:40 · Looking at upcoming SUR→WAT departures
ScheduledStatusAction
06:32On timeno action
06:47On timeno action
07:00On timeno action
07:15On timeno action
07:30On timeno action
08:00On timeno action
😴 Nothing to report. Goes back to sleep for 2 minutes.
🔕 Scenario 2 — Delay under 8 mins, ignored
Check runs at 06:10 · 07:00 train is running slightly late
ScheduledStatusAction
06:32On timeno action
06:47On timeno action
07:00Exp 07:05 (+5 mins)below 8 min threshold
07:15On timeno action
07:30On timeno action
😴 5 minute delay is below the 8 minute threshold — no alert sent. Back to sleep.
🚨 Scenario 3 — Significant delay, alert sent
Check runs at 06:20 · 07:00 train is running 19 minutes late
ScheduledStatusAction
06:32On timeno action
06:47On timeno action
07:00Exp 07:19 (+19 mins)🚨 ALERT
07:15On timeno action
07:30On timeno action
📧📱 Email + text sent. Remembers: { "07:00": "delayed" }
🔁 Scenario 4 — Same disruption 2 mins later, no repeat alert
Check runs at 06:22 · 07:00 train still delayed (same disruption as Scenario 3)
ScheduledStatusAction
06:32On timeno action
06:47On timeno action
07:00Exp 07:19 (+19 mins)already alerted
07:15On timeno action
😴 07:00 was already reported — not sending again.
🆕 Scenario 5 — New disruption appears, second alert sent
Check runs at 06:40 · 07:00 still delayed (known) + 07:15 now also cancelled (new)
ScheduledStatusAction
06:32On timeno action
06:47On timeno action
07:00Exp 07:19 (+19 mins)already alerted
07:15CANCELLEDNEW🚨 ALERT
07:30On timeno action
📧📱 Second alert sent for the cancellation only. Remembers: { "07:00": "delayed", "07:15": "cancelled" }
⏳ Scenario 6 — New train disrupted, but cooldown is active
Check runs at 07:20 · Alert was last sent at 06:40 (only 40 mins ago · cooldown = 120 mins)
ScheduledStatusAction
07:00Exp 07:19 (+19 mins)already alerted
07:15CANCELLEDalready alerted
07:30CANCELLEDNEW cooldown — 20 mins remaining
😴 No alert sent. Even though 07:30 is a new disruption, the 120-minute cooldown is still active.
🚨 Scenario 7 — Cooldown expired, new disruption fires
Check runs at 07:40 · Alert was last sent at 06:40 (120 mins ago — cooldown lifted)
ScheduledStatusAction
07:00Exp 07:19 (+19 mins)already alerted
07:15CANCELLEDalready alerted
07:30CANCELLEDNEW 🚨 ALERT
07:45CANCELLEDNEW 🚨 ALERT
📧📱 Alert sent covering both new cancellations. Cooldown resets for another 120 minutes.
🚨 Scenario 8 — Delay with no time given
Check runs at 07:10 · 07:30 train shows as "Delayed" with no time yet
ScheduledStatusAction
07:15On timeno action
07:30Delayed (no time given)🚨 ALERT
07:45On timeno action
08:00On timeno action
📧📱 Alert sent immediately — when no time is given we don't know how bad it is, so we always flag it.