The PAGER Alert That Arrived After the Sirens

这篇内容暂时只有 English 版本,以下是原文。

Last spring I was running a small ShakeAlert-style relay for a volunteer group in northern California. The stack was a Raspberry Pi 4 with a USB GPS dongle, a Python listener against the USGS GeoJSON feed, and a 4G modem on a prepaid SIM. The feed was the standard all_hour.geojson plus a separate WebSocket to a regional EEW broker. The failure wasn’t in the code. The LTE link took 41 seconds to reattach after a brief tower handoff, and the M4.9 event’s PAGER-style alert landed on the Pi after the local sirens had already finished sounding.

My fix was to stop treating the modem as reliable transport and treat it as a hint. The relay now listens on three paths in parallel: the 4G modem, a LoRa receiver on 915 MHz, and a cheap FM RDS receiver tuned to a regional station. The LoRa path is the one I actually trust for the first 10 seconds; the internet path is for detail, not latency. The core loop is short:

# dedupe by event id, forward first alert only
seen = set()
for msg in merge_streams(ws, lora, rds):
    eid = msg['properties']['eventId']
    if eid in seen:
        continue
    seen.add(eid)
    if msg['properties']['mag'] >= 4.0:
        relay.send(msg)

The tradeoff is real: merge_streams blocks on the slowest iterator unless you use asyncio.wait(FIRST_COMPLETED), and I initially wrote it the blocking way. That cost me a 7-second delay in a drill. I also learned that RDS is sparse and often carries only a county code, not magnitude, so I map codes to a coarse polygon and accept false positives. The LoRa path needs line of sight to a repeater I don’t control, so on windy days it drops.

What still fails: the Pi’s GPS dongle takes 90 seconds to get a fix after a cold boot, and without a fix I don’t trust the timestamp. I now timestamp on receipt and log the GPS fix age separately. If the age is over 5 minutes, the relay flags every message as time_uncertain and does not forward it to the public channel.

A concrete question for anyone running a similar relay: how do you handle clock drift when the only authoritative time source is the same link that delivers the alert? I’ve been using the Pi’s RTC plus a weekly NTP sync, but I’d like to hear what others do when the network is the thing that’s down.

0
赞同度 100% · 0 条评论 · 1 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。