feat(rain): nowcast enhancements + tests (amounts, capitals, snow/ice, !snow, probability, changeover)#195
Merged
Conversation
730b97c to
c721f60
Compare
… 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.
c721f60 to
ffa5595
Compare
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
(est 0.2 in)on!rain/!nowcastand the proactive push; sums Open-Meteo per-bucket precip over the episode.snowfall(cm), not liquid-equivalent; freezing rain taggedin ice.!rain france→ Paris, France), via a self-containedmodules/region_capitals.py(no new dependency).join_location()collapses "Spain, Spain" and city-states.!snowalias + neutral!nowcast— each looks for its own precip family across the window, otherwise falls back with a cross-type line ("No snow, but rain …").help rain/help snowdescribe the right mode.precipitation_probability, shows(…, 70%), and gates the proactive incoming alert at>= rain_nowcast_min_probability(default 50) to cut false alarms.Tests
test_rain_command_e2e.py— drivesRainCommand.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— drivesWeather_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.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_unitNotes
ruff+mypyclean (against the pinned ruff 0.15.15). Deployed and running in production for several days.