First step toward physics-based HF / sporadic-E scoring. Polls GIRO's DIDBase tabular endpoint every 10 minutes for two US ionosondes (Millstone Hill MHJ45, Alpena AL945), parses the plain-text response into observation rows, and upserts into a new ionosonde_observations table keyed on (station_code, valid_time). This gets foEs (E-layer sporadic critical frequency) into the database as a direct measurement — the key input for predicting 144 MHz Es openings via ITU-R P.534-6. foF2 + MUFD are the F2-layer inputs for HF MUF predictions. Not yet wired into scoring. Boulder/Wallops/Austin/Idaho/Point Arguello are in the GIRO catalog but were silent when probed — add them back if/when they come online. Next steps: SWPC JSON (Kp, F10.7, sunspot), GOES X-ray flux, D-RAP text, and the P.534-6 Es scoring factor that uses foEs at midpoint for the 144/440 band configs.
49 lines
1.7 KiB
Elixir
49 lines
1.7 KiB
Elixir
defmodule Microwaveprop.Workers.IonosphereFetchWorkerTest do
|
||
use Microwaveprop.DataCase, async: false
|
||
use Oban.Testing, repo: Microwaveprop.Repo
|
||
|
||
alias Microwaveprop.Ionosphere
|
||
alias Microwaveprop.Ionosphere.GiroClient
|
||
alias Microwaveprop.Ionosphere.Observation
|
||
alias Microwaveprop.Workers.IonosphereFetchWorker
|
||
|
||
@sample File.read!("test/fixtures/giro/mhj45_sample.txt")
|
||
|
||
describe "perform/1" do
|
||
test "pulls each configured station and upserts the parsed rows" do
|
||
Req.Test.stub(GiroClient, fn conn ->
|
||
assert conn.method == "GET"
|
||
params = Plug.Conn.fetch_query_params(conn).query_params
|
||
assert params["ursiCode"] in ~w(MHJ45 AL945)
|
||
|
||
Plug.Conn.resp(conn, 200, @sample)
|
||
end)
|
||
|
||
assert :ok = perform_job(IonosphereFetchWorker, %{})
|
||
|
||
# 25 observations per station × 2 stations = 50 rows (fixture has 25
|
||
# data lines; upserts go to each station code separately).
|
||
assert Repo.aggregate(Observation, :count, :id) == 50
|
||
assert Ionosphere.latest_observation("MHJ45")
|
||
assert Ionosphere.latest_observation("AL945")
|
||
end
|
||
|
||
test "survives a station's fetch error and still ingests the others" do
|
||
Req.Test.stub(GiroClient, fn conn ->
|
||
params = Plug.Conn.fetch_query_params(conn).query_params
|
||
|
||
if params["ursiCode"] == "MHJ45" do
|
||
Plug.Conn.resp(conn, 500, "boom")
|
||
else
|
||
Plug.Conn.resp(conn, 200, @sample)
|
||
end
|
||
end)
|
||
|
||
assert :ok = perform_job(IonosphereFetchWorker, %{})
|
||
|
||
# MHJ45 failed, AL945 ingested.
|
||
assert Ionosphere.latest_observation("MHJ45") == nil
|
||
assert Ionosphere.latest_observation("AL945")
|
||
end
|
||
end
|
||
end
|