prop/config/config.exs
Graham McIntire 8ea0c3b94a
Ingest Canadian radiosondes via UWYO + plans for RDPS/HRDPS
IEM's RAOB endpoint stopped keeping Canadian stations current — most
stalled around Sep 2024 — which leaves a gap in refractivity/ducting
calibration over all the CW*/CY* stations already in weather_stations.
MSC's own tephi CSV is fixed-width and rendering-focused; the WMO TEMP
bulletins would need a full decoder. University of Wyoming serves the
same stations in a clean space-delimited format, is current, and
accepts the 3-letter station code (drop the leading C from Canadian
ICAO). Its output shape matches IemClient.parse_raob_json/1 exactly,
so it drops straight into Weather.upsert_sounding/2.

- New UwyoSoundingClient with URL builder, Req-based fetch_sounding,
  and a fixed-width parse_sounding_html that extracts PRES/HGHT/TEMP/
  DWPT/DRCT/SKNT from the <PRE> block and DateTime from the <H2> header.
- New CanadianSoundingFetchWorker: Oban batch worker that finds all
  sounding stations whose code starts with C, picks the most recently
  publishable 00Z or 12Z slot (90 min publish delay), calls UWYO per
  station, and upserts with SoundingParams-derived refractivity/
  ducting fields.
- Oban cron at 01:30Z and 13:30Z (dev + prod) to drive the worker.
- Req.Test plug wiring in config/test.exs.
- Captured Goose Bay fixture as test/support/fixtures/uwyo_sounding_yyr.html.

Also drops two implementation plans under docs/plans/:
- 2026-04-13-rdps-vertical-profiles.md: ~2 day plan for RDPS 10 km
  Canadian ducting outside HRRR's Lambert footprint.
- 2026-04-13-hrdps-canadian-prop-grid.md: ~5 day plan for the full
  HRDPS 2.5 km Canadian prop grid. Explicitly recommends doing RDPS
  first.

TDD throughout, 19 new tests, 1318/1318 passing, credo strict clean.
2026-04-13 09:14:34 -05:00

124 lines
3.7 KiB
Elixir

# This file is responsible for configuring your application
# and its dependencies with the aid of the Config module.
#
# This configuration file is loaded before any dependency and
# is restricted to this project.
# General application configuration
import Config
alias Microwaveprop.Workers.CanadianSoundingFetchWorker
# Configure esbuild (the version is required)
config :esbuild,
version: "0.27.4",
microwaveprop: [
args:
~w(js/app.ts --bundle --target=es2022 --outdir=../priv/static/assets/js --external:/fonts/* --external:/images/* --alias:@=.),
cd: Path.expand("../assets", __DIR__),
env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]}
]
config :live_table,
app: :microwaveprop,
repo: Microwaveprop.Repo,
pubsub: Microwaveprop.PubSub,
defaults: %{
custom_footer: {MicrowavepropWeb.LiveTableFooter, :render}
}
# Configure Elixir's Logger
config :logger, :default_formatter,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id, :remote_ip]
# Configure the mailer
#
# By default it uses the "Local" adapter which stores the emails
# locally. You can see the emails in your browser, at "/dev/mailbox".
#
# For production it's recommended to configure a different adapter
# at the `config/runtime.exs`.
config :microwaveprop, Microwaveprop.Mailer, adapter: Swoosh.Adapters.Local
# Configure the endpoint
config :microwaveprop, MicrowavepropWeb.Endpoint,
url: [host: "localhost"],
adapter: Bandit.PhoenixAdapter,
render_errors: [
formats: [html: MicrowavepropWeb.ErrorHTML, json: MicrowavepropWeb.ErrorJSON],
layout: false
],
pubsub_server: Microwaveprop.PubSub,
live_view: [signing_salt: "Gdq36xze"]
config :microwaveprop, Oban,
engine: Oban.Pro.Engines.Smart,
repo: Microwaveprop.Repo,
queues: [
solar: 1,
weather: 20,
enqueue: 1,
hrrr: 5,
terrain: 4,
commercial: 2,
iemre: 10,
propagation: 1,
admin: 1,
nexrad: 2
],
plugins: [
{Oban.Plugins.Pruner, max_age: 3600 * 24},
{Oban.Plugins.Lifeline, rescue_after: to_timeout(minute: 30)},
{Oban.Plugins.Cron,
crontab: [
{"0 8 * * *", Microwaveprop.Workers.SolarIndexWorker},
{"*/5 * * * *", Microwaveprop.Commercial.PollWorker},
{"5 */3 * * *", Microwaveprop.Workers.PropagationGridWorker},
{"*/2 * * * *", Microwaveprop.Workers.MrmsFetchWorker},
{"*/10 * * * *", Microwaveprop.Workers.AsosAdjustmentWorker},
{"*/15 * * * *", Microwaveprop.Workers.PropagationPruneWorker},
# UWYO publishes the 00Z/12Z Canadian radiosondes ~90 minutes after launch
{"30 1 * * *", CanadianSoundingFetchWorker},
{"30 13 * * *", CanadianSoundingFetchWorker}
]}
]
config :microwaveprop, :scopes,
user: [
default: true,
module: Microwaveprop.Accounts.Scope,
assign_key: :current_scope,
access_path: [:user, :id],
schema_key: :user_id,
schema_type: :binary_id,
schema_table: :users,
test_data_fixture: Microwaveprop.AccountsFixtures,
test_setup_helper: :register_and_log_in_user
]
config :microwaveprop,
ecto_repos: [Microwaveprop.Repo],
generators: [timestamp_type: :utc_datetime, binary_id: true]
# Use EXLA as default Nx backend for accelerated tensor operations
config :nx, :default_backend, EXLA.Backend
# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason
# Configure tailwind (the version is required)
config :tailwind,
version: "4.2.2",
microwaveprop: [
args: ~w(
--input=assets/css/app.css
--output=priv/static/assets/css/app.css
),
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
cd: Path.expand("..", __DIR__)
]
import_config "#{config_env()}.exs"