aboutsummaryrefslogtreecommitdiff
path: root/working/weather-kit-integration/README.org
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-19 15:44:24 -0500
committerCraig Jennings <c@cjennings.net>2026-07-19 15:44:24 -0500
commit96bc42fafff425cf7690ad417cc6d4d4a757547b (patch)
tree84bbb487e44d27bad51d7daef82d4a2e2336f59c /working/weather-kit-integration/README.org
parente0383618dfef4cf5dae331422c206cde308eb9dc (diff)
downloadarchsetup-96bc42fafff425cf7690ad417cc6d4d4a757547b.tar.gz
archsetup-96bc42fafff425cf7690ad417cc6d4d4a757547b.zip
docs: file interface design references
Record the reconciled weather work and future component direction.\nFile the clock and retro-interface reference materials for later design work.
Diffstat (limited to 'working/weather-kit-integration/README.org')
-rw-r--r--working/weather-kit-integration/README.org119
1 files changed, 119 insertions, 0 deletions
diff --git a/working/weather-kit-integration/README.org b/working/weather-kit-integration/README.org
new file mode 100644
index 0000000..d04899f
--- /dev/null
+++ b/working/weather-kit-integration/README.org
@@ -0,0 +1,119 @@
+#+TITLE: Weather kit — for the Dupre kit / waybar / Wayland UX
+#+AUTHOR: Craig Jennings
+#+DATE: 2026-07-18
+
+Built to completion elsewhere and handed to archsetup, which owns the Dupre kit,
+waybar, and the Wayland UI/UX and will maintain it from here. This note is the
+integration guide: what's in the package, the data contract, and how each
+surface consumes it.
+
+* What's in the package
+
+| File | Purpose |
+|----------------------+-------------------------------------------------------------------------|
+| =weather= | The fetcher. Python 3, stdlib only. Hits Open-Meteo, normalises, caches. |
+| =weather-glyphs.svg= | The custom condition glyph set (9 symbols, currentColor). |
+| =weather-chip.html= | Reference renderer: the chosen chip, wired to the contract. Port target.|
+| =README.org= | This file. |
+
+* The design decisions it encodes (settled over the 2026-07-18 session)
+
+- *Source: Open-Meteo, =model=best_match=.* No API key, no signup, non-commercial
+ free tier (10k calls/day; a 15-min poll is ~96/day). =best_match= auto-selects
+ the most accurate regional model — NOAA blend in the US, ECMWF/ICON abroad — so
+ the same binary is right on ratio in New Orleans and on velox travelling. For a
+ bar chip there's no perceptible accuracy gap vs the NWS API, and NWS is US-only,
+ so Open-Meteo is the single source. (NWS stays a possible *additive* feature
+ later, only for official US severe-weather alerts.)
+- *One fetcher, one cache, thin renderers.* Every surface shells out to =weather=
+ and renders the JSON. Nobody re-implements the API call or the cache. A shared
+ cache means several widgets polling still hit the API at most once per TTL and
+ all show the identical reading.
+- *Windy is a condition, not a compass reading.* Below the threshold the chip
+ shows the direction vane + speed; at/above it, the gust glyph + speed. Same
+ width either way. Threshold default *15 mph* (Beaufort 4 — where wind stops
+ being ambient). It's a =--windy-threshold= flag, derived at output from
+ =wind_mph=, so changing it takes effect without a cache bust.
+- *Custom glyphs, not Nerd Font.* Seven conditions + a gust mark + a vane, drawn
+ to sit in the instrument aesthetic. =currentColor=, so each surface recolours.
+
+* The contract (=weather --json=)
+
+#+begin_src json
+{
+ "temp_f": 82, "feels_f": 92,
+ "condition": "clear", // clear | partly | cloud | fog | rain | snow | storm
+ "wmo_code": 0,
+ "windy": false, // wind_mph >= threshold
+ "wind_mph": 6, "wind_dir": "WNW", "wind_deg": 293,
+ "location": "New Orleans",
+ "observed": "2026-07-18T01:00", "stale": false
+}
+#+end_src
+
+=condition= is the coupling to the glyphs. Mapping (also in =weather-chip.html=):
+=clear->wx-sun=, =partly->wx-partly=, =cloud->wx-cloud=, =fog->wx-fog=,
+=rain->wx-rain=, =snow->wx-snow=, =storm->wx-storm=; plus =wx-wind= (shown when
+=windy=) and =wx-vane= (shown otherwise, rotated by =wind_deg=). A consumer never
+sees the WMO number unless it wants =wmo_code=.
+
+=stale: true= means the network fetch failed and this is the last good reading —
+render it dimmed, never blank the bar.
+
+* WMO weather-code -> condition (what the fetcher collapses)
+
+| WMO code(s) | condition |
+|--------------------------------------+-----------|
+| 0 | clear |
+| 1, 2 | partly |
+| 3 | cloud |
+| 45, 48 | fog |
+| 51-57, 61-67, 80-82 | rain |
+| 71-77, 85-86 | snow |
+| 95, 96, 99 | storm |
+| (anything unmapped) | cloud |
+
+* Install
+
+Drop =weather= on =PATH= the way the other fleet CLIs travel (=agent-page=, etc.):
+into the rulesets/dotfiles bin so =make install= / stow links it to
+=~/.local/bin/weather= on every machine. It's dependency-free, so nothing else to
+provision.
+
+No coordinates are baked in (nothing personal ships in the repo). Each machine
+sets its own location, resolved in order:
+
+1. =--lat/--lon= flags.
+2. =$WEATHER_LAT= / =$WEATHER_LON= (and optional =$WEATHER_NAME=).
+3. =~/.config/weather/config.json= — ={"lat":29.97,"lon":-90.09,"name":"New Orleans"}=.
+ Add ="use_geo": true= (or pass =--geo=) to prefer =whereami= — the right call
+ on velox, which travels.
+
+* How each surface consumes it
+
+- *waybar* — a custom module:
+ #+begin_src jsonc
+ "custom/weather": { "exec": "weather --format waybar", "return-type": "json",
+ "interval": 900, "on-click": "..." }
+ #+end_src
+ =--format waybar= emits ={text, alt, class, tooltip}=; the stylesheet picks the
+ icon by =alt=/=class= (=.clear=, =.windy=, =.stale=, ...).
+- *Dupre kit / =svg.el=* — =(json-parse-string (shell-command-to-string "weather --json"))=,
+ then render the chip. =weather-chip.html='s =renderChip(reading)= is the exact
+ logic to port: glyph, temp, wind slot (gust vs vane by =windy=).
+- *clock-panel (Python)* — =json.loads(subprocess.run(["weather","--json"],...).stdout)=.
+ No HTTP in clock-panel at all.
+
+* Notes / open choices for the maintainer
+
+- Poll cadence lives with the consumer (waybar =interval=), not the tool; the tool
+ just honours its own cache TTL (=--ttl=, default 900s).
+- =weather-glyphs.svg= is the canonical glyph source. =weather-chip.html= inlines a
+ copy for a standalone demo — if the glyphs change, update both (or have the kit
+ build inline from the =.svg=).
+- The chip currently shows the wind slot always. If it ever reads busy on a packed
+ bar, hiding the slot below the threshold (show only when windy) is a one-line
+ change — the data's already there.
+- A "windy later today" hint would want the hourly endpoint (=hourly=wind_speed_10m=)
+ and a small max-over-next-N-hours; the fetcher is structured to add that as a
+ second field without touching consumers.