Make notifier radar actually animate, and split the flag that never meant what it said (#184) #185
No reviewers
Labels
No labels
area:ai
area:ci-cd
area:notifications
area:observability
area:public-pages
backlog
bug
duplicate
enhancement
help wanted
invalid
question
type:decision
type:feature
type:infra
type:maintenance
type:security
v1.0.1
v1.1.0
v1.2.0
v1.3.0
v2.0.0
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
rbrooks/WeatherBot!185
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/notifier-radar-animation"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #184. Targeted at v2.0.0-rc3. Based on
mainat the rc2 commit.Three bugs, one code path
animated=Truewas a no-op —_fetch_radaraccepted the flag and never read it, always returning a static PNG. The "animated radar" option has never animated.image/gif, attached to Discord asradar.gif, base64'd into Signal asdata:image/gif. PNG bytes wearing a GIF label.radar_animatedgated attachment, not animation — turning "animated radar" off silently removed the radar image entirely.Why it needed more than a content-type fix
NOAA cannot animate. Its MapServer exposes no
timeInfoand its capabilities areMap,Query,Data— it serves "now" only, with no historical frames to sweep. RainViewer can (~13 past frames at 10-min cadence) and was already a dependency — but used as a single fixed tile at z6, which is coarse and badly framed: a location sits wherever it falls in its tile, and St. Louis lands at fraction 0.93 across its own, hard against the edge.3x3, not 2x2: a location can sit near a tile corner, and only a 3x3 grid guarantees margin for a centred crop in every direction. The same stitcher backs the static fallback, so the off-centre framing defect is fixed for stills too — not just animations.
Measurements that shaped the design
Format has to travel with the bytes
Because an animated request can silently fall back to a still, no caller can infer the format from the
animatedargument it passed._fetch_radarnow returns aRadarImagecarrying the format actually produced, and every call site labels from it. The cache-hit path sniffs magic bytes rather than trusting the requested format — the disk backend doesn't persist content types, so an animated-key entry written during a RainViewer outage would otherwise be served mislabelled.Migration 0037
Adds
radar_enabled, backfilled from each row's ownradar_animated. That is the only value preserving existing behaviour — a constant default would have switched radar on for every channel that had deliberately opted out.server_defaultexists only soADD COLUMNsucceeds on a populated table, and is dropped after the backfill so the ORM default governs new rows.Verification
Independently re-run, not taken on trust:
ruff check app/ tests/— cleanradar_animated=Falserow must land onradar_enabled=False)Worth knowing
optimize=False— 6 identical frames becomen_frames=1. Consequence: on a genuinely clear day every frame composites identically and the "animation" is a single-frame GIF. Correctly labelled either way, and there is nothing to animate, so this is benign — but the multi-frame test deliberately varies tiles per frame so it tests the #184 regression rather than Pillow's dedup.radar_animation_framesandradar_animation_crop_pxare configurable to tune it down./radarand Matrix's!radarcommands, and in the dashboard/public radar endpoints, which hardcodedmedia_type="image/png"while capable of serving GIF bytes. Those endpoints remain deliberately un-composited (no basemap) per #182, since they render under a Leaflet tile layer.