把地震速报推到自己手机上:一次自建提醒的取舍
我用的是自己写的一个小脚本,跑在一台常开的树莓派上,拉的是公开的 GeoJSON 地震目录,参数是按分钟轮询。场景很具体:家里有老人,夜里不希望手机响,但白天希望 M4.5 以上、距离我所在城市 300 km 内的事件能在两三分钟内到手机。数据量不大,一次请求返回最近一小时几十条,处理不成问题。
做法分三步。先拉最近一小时窗口,再按 mag 和震中距过滤,最后去重后推送到 Bark。关键片段如下:
import math, requests
def haversine(lat1, lon1, lat2, lon2):
r = 6371.0
p1, p2 = math.radians(lat1), math.radians(lat2)
dp = p2 - p1
dl = math.radians(lon2 - lon1)
a = math.sin(dp/2)**2 + math.cos(p1)*math.cos(p2)*math.sin(dl/2)**2
return 2 * r * math.asin(math.sqrt(a))
url = "https://example.org/quake/hour.geojson"
seen = set()
for f in requests.get(url, timeout=10).json()["features"]:
p = f["properties"]
uid = p["id"]
if uid in seen:
continue
d = haversine(30.6, 104.0, f["geometry"]["coordinates"][1],
f["geometry"]["coordinates"][0])
if p["mag"] >= 4.5 and d <= 300:
requests.post("https://api.day.app/你的key/地震提醒",
json={"body": f"M{p['mag']} 距{d:.0f}km"}, timeout=10)
seen.add(uid)
这样做的理由不是追求“快”,而是控制噪音。全量推送会让人对提醒脱敏,真正需要反应的时候反而忽略。代价是可能漏掉边界事件,比如刚好 4.4 但震感明显的情况,所以我把阈值和距离做成可调,而不是写死。
会失效的地方我也踩过:目录有修订,同一事件 mag 可能上调,去重键要用稳定 id 而不是时间;轮询过密会被限流;树莓派断网后 seen 丢失会重复推送,需要持久化。还有一次时区处理错了,半夜推了一条,这个比漏报更烦。
你们自建提醒时,是把阈值固定在震级上,还是按“预计烈度/震中距”做动态判断?我目前还在用固定值,想听听别人的实际做法。
0
赞同度 100% · 0 条评论 · 1 阅读
0 条评论
还没有评论,写下第一条。