Auto-fetch solar index data on contact page when missing
- SolarIndexWorker accepts date arg for specific date fetch - Contact show page enqueues solar fetch when data missing - PubSub broadcast on solar data arrival, live-updates page - Spinner shown while fetching
This commit is contained in:
parent
9fe53b4e7b
commit
0e089e8493
2 changed files with 50 additions and 3 deletions
|
|
@ -1,11 +1,34 @@
|
||||||
defmodule Microwaveprop.Workers.SolarIndexWorker do
|
defmodule Microwaveprop.Workers.SolarIndexWorker do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
use Oban.Worker, queue: :solar, max_attempts: 3
|
use Oban.Worker, queue: :solar, max_attempts: 3, unique: [period: 3600]
|
||||||
|
|
||||||
alias Microwaveprop.Weather
|
alias Microwaveprop.Weather
|
||||||
alias Microwaveprop.Weather.SolarClient
|
alias Microwaveprop.Weather.SolarClient
|
||||||
|
|
||||||
@impl Oban.Worker
|
@impl Oban.Worker
|
||||||
|
def perform(%Oban.Job{args: %{"date" => date_str}}) do
|
||||||
|
{:ok, target_date} = Date.from_iso8601(date_str)
|
||||||
|
|
||||||
|
case SolarClient.fetch_solar_indices() do
|
||||||
|
{:ok, all_records} ->
|
||||||
|
matched = Enum.filter(all_records, fn r -> r.date == target_date end)
|
||||||
|
Enum.each(matched, &Weather.upsert_solar_index/1)
|
||||||
|
|
||||||
|
if matched != [] do
|
||||||
|
Phoenix.PubSub.broadcast(
|
||||||
|
Microwaveprop.PubSub,
|
||||||
|
"contact_enrichment:solar",
|
||||||
|
{:solar_ready, date_str}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
:ok
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
{:error, reason}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def perform(%Oban.Job{}) do
|
def perform(%Oban.Job{}) do
|
||||||
since_date = Date.add(Date.utc_today(), -7)
|
since_date = Date.add(Date.utc_today(), -7)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
||||||
alias Microwaveprop.Weather.HrrrClient
|
alias Microwaveprop.Weather.HrrrClient
|
||||||
alias Microwaveprop.Workers.ContactWeatherEnqueueWorker
|
alias Microwaveprop.Workers.ContactWeatherEnqueueWorker
|
||||||
alias Microwaveprop.Workers.HrrrFetchWorker
|
alias Microwaveprop.Workers.HrrrFetchWorker
|
||||||
|
alias Microwaveprop.Workers.SolarIndexWorker
|
||||||
alias Microwaveprop.Workers.TerrainProfileWorker
|
alias Microwaveprop.Workers.TerrainProfileWorker
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
@ -26,10 +27,11 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
||||||
Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:#{contact.id}")
|
Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:#{contact.id}")
|
||||||
Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:hrrr")
|
Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:hrrr")
|
||||||
Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:weather")
|
Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:weather")
|
||||||
|
Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:solar")
|
||||||
end
|
end
|
||||||
|
|
||||||
weather = load_weather(contact)
|
weather = load_weather(contact)
|
||||||
solar = load_solar(contact)
|
solar = maybe_enqueue_solar(contact)
|
||||||
hrrr_path = Weather.hrrr_profiles_for_path(contact)
|
hrrr_path = Weather.hrrr_profiles_for_path(contact)
|
||||||
hrrr = List.first(hrrr_path)
|
hrrr = List.first(hrrr_path)
|
||||||
{hrrr, contact, hrrr_jobs_ahead} = maybe_enqueue_hrrr(hrrr, contact)
|
{hrrr, contact, hrrr_jobs_ahead} = maybe_enqueue_hrrr(hrrr, contact)
|
||||||
|
|
@ -182,6 +184,11 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
||||||
)}
|
)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_info({:solar_ready, _date}, socket) do
|
||||||
|
solar = load_solar(socket.assigns.contact)
|
||||||
|
{:noreply, assign(socket, solar: solar)}
|
||||||
|
end
|
||||||
|
|
||||||
defp maybe_enqueue_weather(weather, contact) do
|
defp maybe_enqueue_weather(weather, contact) do
|
||||||
has_data = weather.surface_observations != [] or weather.soundings != []
|
has_data = weather.surface_observations != [] or weather.soundings != []
|
||||||
|
|
||||||
|
|
@ -353,6 +360,18 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
||||||
|> Weather.get_solar_index()
|
|> Weather.get_solar_index()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp maybe_enqueue_solar(contact) do
|
||||||
|
solar = load_solar(contact)
|
||||||
|
|
||||||
|
if solar do
|
||||||
|
solar
|
||||||
|
else
|
||||||
|
date = DateTime.to_date(contact.qso_timestamp)
|
||||||
|
Oban.insert(SolarIndexWorker.new(%{"date" => Date.to_iso8601(date)}))
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
|
|
@ -665,7 +684,12 @@ defmodule MicrowavepropWeb.ContactLive.Show do
|
||||||
<div><span class="font-semibold">Kp:</span> {format_kp(@solar.kp_values)}</div>
|
<div><span class="font-semibold">Kp:</span> {format_kp(@solar.kp_values)}</div>
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
<p class="text-sm text-base-content/50 italic">No solar data available for this date.</p>
|
<div class="text-sm text-base-content/50 italic">
|
||||||
|
<span class="flex items-center gap-2">
|
||||||
|
<span class="loading loading-spinner loading-sm"></span>
|
||||||
|
Fetching solar index data...
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div class="divider" />
|
<div class="divider" />
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue