aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-18 14:55:41 +0200
committerDanilo M. <danix@danix.xyz>2026-10-18 14:55:41 +0200
commit7b496ef7fde61ada939e9c20af9af33b76f2fd2a (patch)
treea144f0646ca5555d47ad8f0f59d35e9f895854b9
parent1e8203d8b0e1a75d8dbfa643dd29a0276c89abac (diff)
downloadconky-theme-udt-7b496ef7fde61ada939e9c20af9af33b76f2fd2a.tar.gz
conky-theme-udt-7b496ef7fde61ada939e9c20af9af33b76f2fd2a.zip
docs: the Open-Meteo weather cards and their Conky-Mirage origin
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
-rw-r--r--DESIGN.md4
-rw-r--r--README.md65
2 files changed, 35 insertions, 34 deletions
diff --git a/DESIGN.md b/DESIGN.md
index 604e7cb..80276cb 100644
--- a/DESIGN.md
+++ b/DESIGN.md
@@ -18,7 +18,7 @@ bottom:
numbers. A row's value takes the `threshold` colour when it is a measured
quantity, and stays in `value` when it is not (a fan RPM, a total).
- **Variable band.** One element may absorb the height left over, chosen per
- card: the daylight arc in `weather`. Or the type itself fills the cell.
+ card: the daylight arc in `sky`, the curve in `hourly`. Or the type itself fills the cell.
Failure states keep the chrome and draw a notice in it ("no calendar data", `--`
for a missing sensor). An empty cell is indistinguishable from a crashed
@@ -67,7 +67,7 @@ One language for every measured quantity, so state is read rather than decoded:
## Glyphs
Nerd Font glyphs stand in for labels where an icon reads faster than a word:
-weather puts the condition glyph in its header, and every card title
+`now` puts the condition glyph in its header, and every card title
carries one in `highlight` before its label (the codepoints live in
`card.ICON`). A wrong-but-present codepoint draws a plausible neighbour rather
than failing, so render a new glyph and look at it before trusting it.
diff --git a/README.md b/README.md
index c5b261b..fa2451b 100644
--- a/README.md
+++ b/README.md
@@ -29,37 +29,41 @@ config. Both are deliberately left as your choice rather than done for you.
## Weather
-The weather card needs an [OpenWeatherMap](https://openweathermap.org/api) API
-key. Copy the example and fill it in:
+Five cards cover the weather: `now` (current conditions), `hourly` (the next
+24 hours), `week` (seven days), `details` (wind, humidity, UV, air quality) and
+`sky` (sun, moon and the daylight arc). The forecast cards are adapted from
+[Conky-Mirage](https://github.com/alexsson-xexpanderx/Conky-themes/tree/master/Conky-Mirage)
+by alexsson-xexpanderx, redrawn in this dashboard's palette, glyphs and fonts.
+
+Data comes from [Open-Meteo](https://open-meteo.com), which needs no key. Set
+the location:
cp weather.env.example ~/.config/udt/weather.env
chmod 600 ~/.config/udt/weather.env
-That path is outside the repo because it holds a key, and anything committed is
-potentially public. `weather.env` is gitignored here as a second line of
-defence.
-
-**A new key returns `401 Invalid API key` for anywhere from a few minutes to a
-few hours after you create it.** That is the API activating it, not a mistake in
-the file. Until it works, and whenever the cache is missing, the card draws its
-own chrome with `no weather data` and the thing to fix, rather than vanishing.
+The file is sourced by bash, so a value with spaces needs quotes, as in
+`CITY="Example City"`. That path is outside the repo because a location is
+personal data, and anything committed is potentially public. `weather.env` is
+gitignored here as a second line of defence. `CITY` is geocoded once through
+Open-Meteo and the result cached in `~/.cache/udt/weather-loc`; changing `CITY`
+or `COUNTRY` re-geocodes on the next fetch.
-Fetching is scheduled by conky itself: `conky.text` carries a single
+Fetching is scheduled by conky itself: `conky.text` carries
`${texeci 900 ~/.config/conky/bin/weather-fetch.sh}`, so the cache refreshes
every 15 minutes while the dashboard runs and never while it does not. The
-widget only ever reads `~/.cache/udt/weather.json`; it makes no network call and
-cannot block the draw.
+cards only ever read `~/.cache/udt/weather.txt`; they make no network call and
+cannot block the draw. Until the first fetch lands, each card draws its own
+chrome with `no weather data` rather than vanishing. A leftover
+`~/.cache/udt/weather.json` from the old OpenWeatherMap version is no longer
+read and can be deleted.
To check the fetch by hand:
./bin/weather-fetch.sh; echo "exit: $?"
It prints nothing and exits 0 on success. On failure it says why on stderr and
-leaves any existing cache alone, so a transient error never replaces good data
-with an error body.
-
-Location and units live in `weather.env` too (`CITY`, `COUNTRY`, `UNITS`), not
-in the source, so no real location appears in committed files.
+leaves any existing cache alone. A failed air-quality call is not a failure:
+the AQI row reads `--` and everything else updates.
## System widgets
@@ -160,7 +164,7 @@ dropping photos that are no longer in it. It needs
`immich.env.example`. The key wants `memory.read` and `asset.view`; with
`asset.read` too, the card shows the place, and without it the row reads `--`.
-The key sits in a plain file, like the weather key, because the fetch runs
+The key sits in a plain file because the fetch runs
unattended from conky: reading it from a GPG-backed store would raise a
pinentry whenever the agent's cache has expired.
@@ -181,7 +185,7 @@ table works on differently shaped monitors.
local layout = {
{ widget = 'clock', col = 1, row = 1, w = 1, h = 1 },
- { widget = 'weather', col = 1, row = 2, w = 1, h = 1 },
+ { widget = 'now', col = 1, row = 2, w = 1, h = 1 },
}
Reordering widgets is an edit to that table and nothing else: a widget is handed
@@ -237,17 +241,16 @@ the largest base size at which every row still fits the width, and the widget
takes the smaller of that and its height budget. Larger cell, larger type; a row
that would collide pulls the size back down. The breaktimer and
immich cards do this. A card that cannot afford the measuring pass can still key off width with
-a clamp, `math.max(lo, math.min(hi, inner.w * k))`; the clock and weather
-cards do.
+a clamp, `math.max(lo, math.min(hi, inner.w * k))`; the clock does.
**Decide where the slack goes, and let one element absorb it.** The clock pins
its date block to the bottom and gives the numerals everything above. The
-weather card stacks from the top and lets the arc take the remainder. Either is
+sky card stacks its rows from the top and pins the arc to the bottom. Either is
fine; what fails is leaving the slack wherever it lands.
An element that cannot shrink below some size should drop out rather than
-overlap. The weather arc does this: below 70px it is not drawn at all, because a
-curve crossing the stat rows is worse than no curve. Check a widget at several
+overlap. The sky arc does this: below 50px it is not drawn at all, because a
+curve crossing the rows is worse than no curve. Check a widget at several
spans before believing it is fluid, which the offscreen renderer above makes
cheap.
@@ -337,7 +340,7 @@ for bold.
**Fonts are per-widget when a widget wants one.** `lib/card.lua` holds the
shared `FONT_*` families, but `card.font()` takes any family string, so a
widget passes its own. The clock uses `FONT_CLOCK` (Oswald, OFL-1.1, under
-`~/.fonts/o/Oswald`) for squared numerals while the weather card keeps
+`~/.fonts/o/Oswald`) for squared numerals while the other cards keep
`FONT_HEAVY`. Check a new family with `fc-match` first: fontconfig silently
substitutes a default for a name it does not know, which looks exactly like the
font "not applying".
@@ -352,11 +355,9 @@ on the 2-second draw cadence, entirely unrelated to the 15-minute fetch, so a
fetch killed mid-write would otherwise hand the parser half a response. Rename
is only atomic within a filesystem, so the temp file sits in the same directory.
-**A bad OWM key returns 401 and an unknown city returns 404**, so `curl -f`
-catches both. The fetch script also checks `.cod` is 200 before replacing the
-cache, which covers the remaining case of a 200 whose body is not usable
-weather. The polybar script this was ported from needed that check as its only
-defence, because it ran curl without `-f`.
+**A 200 is not proof of a forecast.** `curl -f` rejects HTTP errors, and the
+fetch script also checks the flattened cache has a current temperature before
+replacing the old one, so an unusable body never reaches the cards.
**Nothing in `lib/weather.lua` raises.** Every function returns nil, or a
sentinel, on input it cannot use, and that is verified against every function
@@ -365,7 +366,7 @@ the parser's input is a file written by a network fetch, and a raise here is a
blank dashboard rather than a message.
**Type keyed on one dimension alone leaves the card broken or sparse.** The
-weather text once shrank to a whisper beside the clock when its cell got shorter
+old weather card's text once shrank to a whisper beside the clock when its cell got shorter
because the size keyed on height; a card keyed only on width leaves a tall cell
half empty. Fill the cell instead: `card.fit_unit()` measures the rows and
returns the largest size that fits the width, the widget takes the smaller of