alerts

3ec6f92 · gmorell · 2026-04-09 02:51

10 files +79 -1

Files changed

modified apps/room_gtfs/lib/room_gtfs/gtfs_worker.ex
+57 −0
@@ -56,6 +56,16 @@ defmodule RoomGtfs.Worker do
56 56 |> GenServer.call({:query_realtime, trips, stop}, 30_000)
57 57 end
58 58
59 + def query_alerts(name, stop, route_ids) do
60 + try do
61 + "gtfs-rt#{name}"
62 + |> via_tuple()
63 + |> GenServer.call({:query_alerts, stop, route_ids}, 10_000)
64 + catch
65 + :exit, _ -> []
66 + end
67 + end
68 +
59 69 def get_current_vehicle_positions(name) do
60 70 "gtfs-rt#{name}"
61 71 |> via_tuple
@@ -285,6 +295,53 @@ defmodule RoomGtfs.Worker.RT do
285 295
286 296 defp via_tuple(name), do: {:via, Registry, {@registry, name}}
287 297
298 + def handle_call({:query_alerts, stop, route_ids}, _from, state) do
299 + now = System.os_time(:second)
300 +
301 + alerts = case state.rt_sa do
302 + nil -> []
303 + feed ->
304 + feed.entity
305 + |> Enum.filter(& &1.alert)
306 + |> Enum.map(& &1.alert)
307 + |> Enum.filter(fn alert ->
308 + active = case alert.active_period do
309 + [] -> true
310 + periods -> Enum.any?(periods, fn p ->
311 + (p.start == nil || p.start <= now) &&
312 + (Map.get(p, :end) == nil || Map.get(p, :end) >= now)
313 + end)
314 + end
315 + relevant = Enum.any?(alert.informed_entity, fn e ->
316 + (e.stop_id != nil && e.stop_id == stop) ||
317 + (e.route_id != nil && e.route_id in route_ids) ||
318 + (e.agency_id != nil && e.stop_id == nil && e.route_id == nil) ||
319 + (e.stop_id == nil && e.route_id == nil && e.trip == nil && e.agency_id == nil)
320 + end)
321 + active && relevant
322 + end)
323 + |> Enum.map(fn alert ->
324 + route_id = Enum.find_value(alert.informed_entity, fn e -> e.route_id end)
325 + %{
326 + effect: alert.effect |> to_string(),
327 + cause: alert.cause |> to_string(),
328 + header: get_translation(alert.header_text),
329 + description: get_translation(alert.description_text),
330 + route_id: route_id,
331 + }
332 + end)
333 + end
334 +
335 + {:reply, alerts, state}
336 + end
337 +
338 + defp get_translation(nil), do: nil
339 + defp get_translation(%{translation: []}), do: nil
340 + defp get_translation(%{translation: translations}) do
341 + t = Enum.find(translations, fn t -> t.language in ["en", "en-US", nil] end) || List.first(translations)
342 + t && t.text
343 + end
344 +
288 345 def handle_call(:stats, _from, state) do
289 346 {:reply, %{
290 347 rt_sa: feed_summary(state.rt_sa),
modified apps/room_sanctum/lib/room_sanctum/condensers/basic_mqtt.ex
+22 −1
@@ -197,9 +197,30 @@ defmodule RoomSanctum.Condenser.BasicMQTT do
197 197 @doc """
198 198 Condenses data and wraps it with query information
199 199 """
200 + def condense({id, :gtfs}, data, query) do
201 + condensed = condense_data({id, :gtfs}, data)
202 + route_ids = condensed |> Enum.map(& &1.route) |> Enum.uniq()
203 + alerts = RoomGtfs.Worker.query_alerts(id, query.stop, route_ids)
204 +
205 + condensed_with_alerts = condensed |> Enum.map(fn route ->
206 + route_alerts = Enum.filter(alerts, fn a ->
207 + a.route_id == nil || a.route_id == route.route
208 + end)
209 + case route_alerts do
210 + [] -> route
211 + _ -> Map.put(route, :alerts, route_alerts)
212 + end
213 + end)
214 +
215 + %{
216 + data: condensed_with_alerts,
217 + query: %{name: query.name, meta: query.meta || %{}}
218 + }
219 + end
220 +
200 221 def condense({id, type}, data, query) do
201 222 condensed_data = condense_data({id, type}, data)
202 −
223 +
203 224 %{
204 225 data: condensed_data,
205 226 query: %{

Parents: f5112b5