diff --git a/lib/microwaveprop_web/live/weather_ca_map_live.ex b/lib/microwaveprop_web/live/weather_ca_map_live.ex index 9b7fb85b..32368051 100644 --- a/lib/microwaveprop_web/live/weather_ca_map_live.ex +++ b/lib/microwaveprop_web/live/weather_ca_map_live.ex @@ -104,13 +104,13 @@ defmodule MicrowavepropWeb.WeatherCaMapLive do Enum.min_by(valid_times, fn vt -> abs(DateTime.diff(vt, now, :second)) end) end - # Drop valid_times older than one hour. HRDPS cycles run 4×/day and - # the chain seeder writes one row per hour, so the on-disk set can - # span many old hours; the user wants "now", not yesterday. - defp recent_valid_times(valid_times) do - cutoff = DateTime.add(DateTime.utc_now(), -3600, :second) - Enum.filter(valid_times, fn vt -> DateTime.compare(vt, cutoff) != :lt end) - end + # Don't filter by recency. HRDPS publishes 4×/day with a 3-4h + # publication latency and our chain step adds ~13 min on top, so the + # freshest valid_time on disk is routinely 4-6h old. /weather's 1h + # cutoff would leave /weather-ca empty most of the time. The sidebar + # shows the selected valid_time in big letters — users can see for + # themselves how stale the data is. + defp recent_valid_times(valid_times), do: valid_times defp build_path(socket, overrides \\ []) do layer = Keyword.get(overrides, :layer, socket.assigns.selected_layer) diff --git a/test/microwaveprop_web/live/weather_ca_map_live_test.exs b/test/microwaveprop_web/live/weather_ca_map_live_test.exs index 1a953bf0..748160b1 100644 --- a/test/microwaveprop_web/live/weather_ca_map_live_test.exs +++ b/test/microwaveprop_web/live/weather_ca_map_live_test.exs @@ -6,6 +6,7 @@ defmodule MicrowavepropWeb.WeatherCaMapLiveTest do alias Microwaveprop.Propagation.ProfilesFile alias Microwaveprop.Weather.GridCache + alias Microwaveprop.Weather.ScalarFile setup do GridCache.clear() @@ -54,4 +55,35 @@ defmodule MicrowavepropWeb.WeatherCaMapLiveTest do assert_patch(lv, "/weather-ca?layer=pwat&lat=55.0&lon=-100.0&zoom=4") end + + test "shows HRDPS valid_times even when several hours old (no 1h cutoff)", %{conn: conn} do + # HRDPS publishes 4x/day with ~3-4h latency, plus our chain step + # takes ~13 min. The 1-hour cutoff /weather uses would routinely + # leave /weather-ca empty between fresh chain steps. Hand-write a + # 4-hour-old HRDPS chunk and confirm it lands in the timeline. + now = + DateTime.utc_now() + |> DateTime.truncate(:second) + |> Map.put(:minute, 0) + |> Map.put(:second, 0) + + stale_t = DateTime.add(now, -4 * 3600, :second) + hrdps_dir = ScalarFile.dir_for_hrdps(stale_t) + File.mkdir_p!(hrdps_dir) + + payload = + Msgpax.pack!( + [%{"lat" => 53.0, "lon" => -60.0, "valid_time" => DateTime.to_iso8601(stale_t), "temperature" => 8.0}], + iodata: false + ) + + File.write!(Path.join(hrdps_dir, "10_-12.mp.gz"), :zlib.gzip(payload)) + + on_exit(fn -> File.rm_rf!(hrdps_dir) end) + + {:ok, _lv, html} = live(conn, ~p"/weather-ca") + + iso = DateTime.to_iso8601(stale_t) + assert html =~ iso, "4-hour-old HRDPS valid_time should appear in /weather-ca timeline" + end end