A missing notification reads as "all good"
Good Morning Dashboard tells my household when to leave for the train. SEPTA's API has character. The parameter for how many results you
want is req3; the one that looks right, top, is silently ignored. Delay text is free-form ("On time", "5 min",
"Cancelled", "Suspended", or something else entirely), and the code never treats text it can't parse as on time.
The design rule I'm proudest of: a push that doesn't arrive looks exactly like a push saying everything's fine. So every upstream has a cache, stale data is served but flagged in the message, and if the check crashes outright, it still sends a "check failed" push. Silence is never the answer.
Transfers were the other fun part. When there's no direct train, it plans each leg separately and pairs them, picking the earliest connection you can still make once live delays are counted. If no connection works at the usual station, it tries the other Center City stations and says where to change instead.
The newest lesson came from a gap in that rule. The follow-up pushes stopped as soon as the first train left, which is exactly when the connection becomes the risky part. SEPTA's trip planner stops listing a train once it leaves your station, so now the follow-ups read its live delay from SEPTA's train positions instead and keep checking the connection until it leaves. Without GPS it can't know which train my partner actually makes it to, so the push also lists the next trains whose connection clearly works.
I also wanted it to be a polite API client. Home Assistant asks for an update every 30 seconds, so answers under a minute old are now reused, and nothing calls SEPTA outside commute hours. That took it from about 4,300 calls a weekday to about 1,500.