Adds haversine_km/4 to Radio context and backfill_distances/1 which calculates distance_km from pos1/pos2 for QSOs missing it. Called by QsoWeatherEnqueueWorker before enqueueing weather fetches.
79 lines
2 KiB
Elixir
79 lines
2 KiB
Elixir
defmodule Microwaveprop.Workers.QsoWeatherEnqueueWorker do
|
|
@moduledoc false
|
|
use Oban.Worker, queue: :enqueue, max_attempts: 3
|
|
|
|
alias Microwaveprop.Radio
|
|
alias Microwaveprop.Weather
|
|
alias Microwaveprop.Workers.WeatherFetchWorker
|
|
|
|
@asos_radius_km 150
|
|
@sounding_radius_km 300
|
|
|
|
@impl Oban.Worker
|
|
def perform(%Oban.Job{}) do
|
|
qsos = Radio.unprocessed_qsos()
|
|
|
|
if qsos != [] do
|
|
Radio.backfill_distances(qsos)
|
|
|
|
jobs = build_weather_jobs(qsos)
|
|
|
|
if jobs != [] do
|
|
Oban.insert_all(jobs)
|
|
end
|
|
|
|
qso_ids = Enum.map(qsos, & &1.id)
|
|
Radio.mark_weather_queued!(qso_ids)
|
|
end
|
|
|
|
:ok
|
|
end
|
|
|
|
def build_weather_jobs(qsos) do
|
|
qsos
|
|
|> Enum.flat_map(&jobs_for_qso/1)
|
|
|> Enum.uniq_by(fn changeset -> changeset.changes.args end)
|
|
end
|
|
|
|
defp jobs_for_qso(qso) do
|
|
lat = qso.pos1["lat"]
|
|
lon = qso.pos1["lon"] || qso.pos1["lng"]
|
|
|
|
asos_jobs = build_asos_jobs(lat, lon, qso.qso_timestamp)
|
|
raob_jobs = build_raob_jobs(lat, lon, qso.qso_timestamp)
|
|
|
|
asos_jobs ++ raob_jobs
|
|
end
|
|
|
|
defp build_asos_jobs(lat, lon, timestamp) do
|
|
start_dt = DateTime.add(timestamp, -2 * 3600, :second)
|
|
end_dt = DateTime.add(timestamp, 2 * 3600, :second)
|
|
|
|
lat
|
|
|> Weather.nearby_stations(lon, "asos", @asos_radius_km)
|
|
|> Enum.map(fn station ->
|
|
WeatherFetchWorker.new(%{
|
|
"fetch_type" => "asos",
|
|
"station_id" => station.id,
|
|
"station_code" => station.station_code,
|
|
"start_dt" => DateTime.to_iso8601(start_dt),
|
|
"end_dt" => DateTime.to_iso8601(end_dt)
|
|
})
|
|
end)
|
|
end
|
|
|
|
defp build_raob_jobs(lat, lon, timestamp) do
|
|
sounding_times = Weather.sounding_times_around(timestamp)
|
|
|
|
stations = Weather.nearby_stations(lat, lon, "sounding", @sounding_radius_km)
|
|
|
|
for station <- stations, sounding_time <- sounding_times do
|
|
WeatherFetchWorker.new(%{
|
|
"fetch_type" => "raob",
|
|
"station_id" => station.id,
|
|
"station_code" => station.station_code,
|
|
"sounding_time" => DateTime.to_iso8601(sounding_time)
|
|
})
|
|
end
|
|
end
|
|
end
|