defmodule Microwaveprop.Workers.WeatherFetchWorker do @moduledoc false use Oban.Worker, queue: :weather, max_attempts: 5 alias Microwaveprop.Repo alias Microwaveprop.Weather alias Microwaveprop.Weather.IemClient alias Microwaveprop.Weather.SoundingParams alias Microwaveprop.Weather.Station @impl Oban.Worker def perform(%Oban.Job{args: %{"fetch_type" => "asos"} = args}) do %{ "station_id" => station_id, "station_code" => station_code, "start_dt" => start_dt_str, "end_dt" => end_dt_str } = args {:ok, start_dt, _} = DateTime.from_iso8601(start_dt_str) {:ok, end_dt, _} = DateTime.from_iso8601(end_dt_str) case Repo.get(Station, station_id) do nil -> :ok station -> if Weather.has_surface_observations?(station.id, start_dt, end_dt) do :ok else case IemClient.fetch_asos(station_code, start_dt, end_dt) do {:ok, rows} -> Enum.each(rows, fn row -> if row.observed_at, do: Weather.upsert_surface_observation(station, row) end) :ok {:error, reason} -> {:error, reason} end end end end def perform(%Oban.Job{args: %{"fetch_type" => "raob"} = args}) do %{ "station_id" => station_id, "station_code" => station_code, "sounding_time" => sounding_time_str } = args {:ok, sounding_time, _} = DateTime.from_iso8601(sounding_time_str) case Repo.get(Station, station_id) do nil -> :ok station -> if Weather.has_sounding?(station.id, sounding_time) do :ok else case IemClient.fetch_raob(station_code, sounding_time) do {:ok, [parsed | _]} -> params = SoundingParams.derive(parsed.profile) sounding_attrs = if params do %{ observed_at: parsed.observed_at, profile: parsed.profile, level_count: params.level_count, surface_pressure_mb: params.surface_pressure_mb, surface_temp_c: params.surface_temp_c, surface_dewpoint_c: params.surface_dewpoint_c, surface_refractivity: params.surface_refractivity, min_refractivity_gradient: params.min_refractivity_gradient, boundary_layer_depth_m: params.boundary_layer_depth_m, precipitable_water_mm: params.precipitable_water_mm, k_index: params.k_index, lifted_index: params.lifted_index, ducting_detected: params.ducting_detected, duct_characteristics: params.duct_characteristics } else %{ observed_at: parsed.observed_at, profile: parsed.profile, level_count: length(parsed.profile) } end Weather.upsert_sounding(station, sounding_attrs) :ok {:ok, []} -> :ok {:error, reason} -> {:error, reason} end end end end end