Commit Graph
4 Commits
Author SHA1 Message Date
grabowski cf10f2e4c8 feat(dashboard): console phase 4 - 2024 replay, simulation, replaces the old page
CI / Format & lint (push) Successful in 26s
CI / Test suite (push) Successful in 1m15s
Docs / Validate documentation (push) Successful in 12s
The console is now the dashboard at / (src/static/dashboard.html); the old
page and console.html are gone.

- Replay of the October 2024 flood (flood-2024-all.json): the page's clock,
  verdict, list, markers, flood zones and panel follow the replay; the panel
  charts the season on fixed axes with the 2024 model's 24 h peak. Hourly
  while the model alerts or P.1 is above 3.50 m, faster through quiet days;
  pause and drag. Rain, basin stations and the 5-minute refresh are off
  during the replay (today's data).
- ?demo_level= and ?demo_rise= simulate P.1. A violet REPLAY / amber
  SIMULATION bar, the top bar's KPI and the P.1 panel say so; the mode is
  drawn from state.mode alone, so a refresh or language switch cannot
  relabel either as live.
- History: rows without discharge_percent are ThaiWater's copy of the gauge
  (night hours RID publishes late), with a different rating (P.1: 26 against
  RID's 54 m3/s); their discharge is not drawn for gauges with RID discharge.
  The discharge strip has headroom so its label stays clear of the line.
- Swap: the old page's title, description, Open Graph and JSON-LD tags; no
  noindex; tests/test_dashboard.py = console tests + the old checks that
  still apply (one P.1 level, SEO files) + a replay/simulation labelling test.
- Docs: README screenshot (docs/img/dashboard.jpg, replacing two unused
  images), CLAUDE.md, CONTRIBUTING.md, FLOOD_FORECASTING.md (where the model
  shows), DASHBOARD_REDESIGN.md (phase 4 done, mode rules).

Deploy needs a restart: the server reads dashboard.html at start.
2026-10-20 13:47:15 +07:00
grabowski ffd3030352 feat(dashboard): console phase 3 - history, forecast accuracy, data statistics
CI / Format & lint (push) Successful in 25s
CI / Test suite (push) Successful in 58s
Docs / Validate documentation (push) Successful in 11s
- History in the station panel (inline SVG): 3 d / 7 d / 30 d / 90 d / 1 y /
  all or a date range; level and discharge, the 24 h peaks as the model
  issued them, warning/danger bands, hover/touch values. Up to 7 d the chart
  ends in the current forecast. Above 2,500 readings it shows the daily mean
  with the daily low-high band, so a flood peak is not averaged away; gaps
  (RID's nightly pause) break the line instead of being bridged. Days are
  Bangkok days computed arithmetically: Intl per reading took a minute for
  "All" (67,000 rows), now 2 s.
- "How accurate is the forecast?" for P.1 (/api/forecast/skill), loaded when
  opened because a cold skill query takes up to 20 s.
- Data statistics (/api/stats) behind "2.7M readings since 2018" in the
  status bar.

fix(dashboard): "All time" history ended in October 2024. The history route
returns the oldest rows first and stops at 50,000 by default; P.1 has about
67,000 hours. Both dashboards now ask for limit=100000 (the route's maximum).
2026-10-19 17:12:39 +07:00
grabowski 71cc1b0ca7 feat(dashboard): console phase 2 - self-hosted basemap, basin stations, markers
CI / Format & lint (push) Successful in 24s
CI / Test suite (push) Successful in 1m9s
Docs / Validate documentation (push) Successful in 14s
- Basemap: src/static/basemap/ping-basin.pmtiles, a Protomaps extract of the
  Ping basin (zoom 0-12, 15 MB, OpenStreetMap data), drawn by
  protomaps-leaflet 5.1.0 (unpkg, SRI) in its light/dark style with labels in
  the page language. It replaces the dimmed OSM raster tiles, whose baked-in
  labels were the noisiest part of the screen; OSM stays as the fallback.
  The browser reads the file with range requests (ServeDir answers 206;
  dev_proxy.py now does too). The map stays within the basin.
- Basin stations: a second list next to the RID gauges and a map layer of
  diamonds, from /api/hii/waterlevel/latest (falling back to
  /sensors/thaiwater), coloured by ThaiWater's bank-height classes (over the
  bank = danger, 70-100 % = watch). Gauges RID already lists appear once.
  The panel shows level (m MSL), % of bank height, distance to and height of
  the bank top, gauge reading and agency; selection in the URL (#hii-<id>).
- custom-markers.json as pins from zoom 12, with the flood zone they are in.

Refresh instructions for the basemap in src/static/basemap/README.md.
2026-10-19 16:58:21 +07:00
grabowski 301a629b42 feat(dashboard): the console, phase 1 of the redesign (preview at /static/console.html)
CI / Format & lint (push) Successful in 24s
CI / Test suite (push) Successful in 1m31s
Docs / Validate documentation (push) Successful in 10s
The user chose direction B of the redesign: a full-screen operations console.
It is built next to the current dashboard, served by ServeDir at
/static/console.html (noindex, links back to /), and replaces dashboard.html
once it covers every feature (docs/DASHBOARD_REDESIGN.md, phase 4).

Phase 1:
- top bar: the Chiang Mai verdict (P.1 level + 24 h forecast, the current
  dashboard's rule), gauges reporting, highest 24 h flood chance, data age
  ("overnight pause" instead of "stale" during RID's nightly gap, as in the
  notifier), EN/TH, light/dark (dark default), Get alerts
- gauge list: one status rule for list, map and panel (normal, watch within
  0.5 m or >= 25 % chance, warning, danger, no data), margin to the warning
  level, 72 h sparkline, 6 h change; filter; sort by river order, closest to
  the warning level, rising; arrow keys
- map: Ping mainstem and tributaries, status markers with code + level,
  layers Rain 24 h (on by default only with heavy rain) and Flood zones
  (auto-shown while P.1 is at a stage), one legend
- station panel: level, change, discharge (last RID value when the newest
  hour is level-only), warning/danger levels with margins, capacity, level
  scale with now and 24 h peak, 72 h chart with the forecast peaks, forecast
  table with the model and issue time, the P.1 inundation stages, data links
- alerts drawer with the ntfy topics; selection in the URL (#P.84); refresh
  every 5 minutes
- Inter and Noto Sans Thai self-hosted (src/static/fonts, 75 KB, OFL), no
  emoji, Thai first, Bangkok time

tests/test_console.py: routed fetch paths, EN/TH parity, translated aria
labels, no emoji, fonts and licences, noindex. dev_proxy.py serves
src/static with real content types (it sent HTML as octet-stream).
2026-10-19 16:31:09 +07:00