Skip to content

feat(rain): nowcast enhancements + tests (amounts, capitals, snow/ice, !snow, probability, changeover)#195

Merged
agessaman merged 1 commit into
agessaman:devfrom
rlwilliamson-dev:feat/rain-enhancements
Jun 15, 2026
Merged

feat(rain): nowcast enhancements + tests (amounts, capitals, snow/ice, !snow, probability, changeover)#195
agessaman merged 1 commit into
agessaman:devfrom
rlwilliamson-dev:feat/rain-enhancements

Conversation

@rlwilliamson-dev

Copy link
Copy Markdown

Summary

Builds on the merged minute-level rain/snow nowcast (#193) with ten enhancements plus end-to-end, proactive, and live-smoke test coverage. Everything new is config-gated or additive — existing deployments are unchanged by default.

Enhancements

  • Amount estimate(est 0.2 in) on !rain/!nowcast and the proactive push; sums Open-Meteo per-bucket precip over the episode.
  • Real snow depth — snow shows accumulation via Open-Meteo snowfall (cm), not liquid-equivalent; freezing rain tagged in ice.
  • Region defaulting — a bare country / US state resolves to its capital with a heads-up (!rain franceParis, France), via a self-contained modules/region_capitals.py (no new dependency).
  • Location dedupejoin_location() collapses "Spain, Spain" and city-states.
  • !snow alias + neutral !nowcast — each looks for its own precip family across the window, otherwise falls back with a cross-type line ("No snow, but rain …").
  • Keyword-aware helphelp rain / help snow describe the right mode.
  • Probability — fetches 15-min precipitation_probability, shows (…, 70%), and gates the proactive incoming alert at >= rain_nowcast_min_probability (default 50) to cut false alarms.
  • Rain ↔ snow changeover — a single line when the window holds both families.
  • Borderline temperature tag — shown only in the 30–38 °F band, where precip type is in doubt.
  • Short-lived series cache — shared by the command and the proactive poll to avoid duplicate Open-Meteo fetches.

Tests

  • test_rain_command_e2e.py — drives RainCommand.execute() end to end and asserts the exact rendered reply across dry / incoming / raining, snow depth, cross-type mismatch, changeover, ice, temp tag, region capitals, config toggles, DM budget, and keyword-aware help.
  • test_rain_proactive_e2e.py — drives Weather_Service._check_rain_nowcast() for the probability gate, snow depth, rain-ending notice, and once-per-episode dedup.
  • test_rain_live_smoke.py — opt-in (RAIN_LIVE_SMOKE=1) live Open-Meteo check that the API still serves the fields we depend on; skipped in CI.
  • Shared scaffolding in tests/unit/_rain_harness.py. Rain suite: 93 passing, +2 opt-in live-smoke skipped.

Config (all optional; defaults preserve current behavior)

[Rain_Command]: show_amount, amount_unit, show_probability, show_temp, cache_seconds, zip_city_lookup
[Weather_Service]: rain_nowcast_min_probability, rain_nowcast_cache_seconds, rain_nowcast_show_amount, rain_nowcast_amount_unit

Notes

ruff + mypy clean (against the pinned ruff 0.15.15). Deployed and running in production for several days.

@rlwilliamson-dev rlwilliamson-dev force-pushed the feat/rain-enhancements branch from 730b97c to c721f60 Compare June 6, 2026 21:11
… probability, changeover) + tests

Builds on the merged rain/snow nowcast (agessaman#193): ten enhancements plus
end-to-end, proactive, and live-smoke test coverage. All new behavior is
config-gated or additive, so existing deployments are unaffected by default.

Enhancements
- Precip amount estimate "(est 0.2 in)" on the command and the proactive push;
  snow shown as real depth (Open-Meteo snowfall, cm); freezing rain tagged "in ice".
- Bare country / US state resolves to its capital with a heads-up
  (self-contained modules/region_capitals.py; no pycountry/us dependency).
- join_location() dedupes "Spain, Spain" / city-states.
- !snow alias + neutral !nowcast; each looks for its own precip family across
  the window, else falls back with a "No snow, but rain ..." cross-type line.
- Keyword-aware help (help rain / help snow).
- Precip probability shown "(..., 70%)"; the proactive incoming alert is gated
  to >= [Weather_Service] rain_nowcast_min_probability (default 50).
- Rain<->snow changeover line when the window holds both families.
- Borderline temperature tag (30-38F).
- Short-lived series cache shared by the command and the proactive poll.

Tests
- test_rain_command_e2e.py: drives RainCommand.execute() end to end and asserts
  the exact rendered reply across dry/incoming/raining, snow depth, cross-type
  mismatch, changeover, ice, temp tag, region capitals, config toggles, DM
  budget, and keyword-aware help.
- test_rain_proactive_e2e.py: drives Weather_Service._check_rain_nowcast() for
  the probability gate, snow depth, ending notice, and once-per-episode dedup.
- test_rain_live_smoke.py: opt-in (RAIN_LIVE_SMOKE=1) live Open-Meteo check for
  upstream schema drift; skipped in CI.
- Shared scaffolding in tests/unit/_rain_harness.py.

New config: [Rain_Command] show_amount/amount_unit/show_probability/show_temp/
cache_seconds/zip_city_lookup; [Weather_Service] rain_nowcast_min_probability/
rain_nowcast_cache_seconds/rain_nowcast_show_amount/rain_nowcast_amount_unit.
ruff + mypy clean.
@rlwilliamson-dev

Copy link
Copy Markdown
Author

Note: #196 (NWS gridpoint precip source) is now stacked on top of this PR. Merging this one first lets #196's diff collapse to just its own change, conflict-free — no rebase needed on either side.

@agessaman agessaman merged commit af6ef9f into agessaman:dev Jun 15, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants