diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-17 08:53:43 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-17 08:53:43 +0200 |
| commit | a249039f2de33d8cc8126d6dd62fbc1004193536 (patch) | |
| tree | e2f5d93c3dcc91d3513174548143826da369c73c | |
| parent | 6832a816f9965e273c104f7641c662d6d5d57ced (diff) | |
| download | conky-theme-udt-a249039f2de33d8cc8126d6dd62fbc1004193536.tar.gz conky-theme-udt-a249039f2de33d8cc8126d6dd62fbc1004193536.zip | |
feat: add wind conversion, Beaufort and compass tables
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
| -rw-r--r-- | lib/weather.lua | 41 | ||||
| -rw-r--r-- | test/test_weather.lua | 50 |
2 files changed, 91 insertions, 0 deletions
diff --git a/lib/weather.lua b/lib/weather.lua index 0b4b1b7..6e2741a 100644 --- a/lib/weather.lua +++ b/lib/weather.lua @@ -63,4 +63,45 @@ function M.icon(id, now, sunrise, sunset) return M.ICON.unknown end +-- OWM's metric units report wind in m/s. The card shows km/h. +function M.kmh(ms) + if type(ms) ~= 'number' then return nil end + return ms * 3.6 +end + +-- Beaufort force from km/h. Upper bounds carried over from the polybar +-- script; a value equal to a bound stays in the lower force. +local BEAUFORT = { 1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117 } + +function M.beaufort(kmh) + if type(kmh) ~= 'number' then return nil end + for force, bound in ipairs(BEAUFORT) do + if kmh <= bound then return force - 1 end + end + return 12 +end + +-- Eight compass points. The half-step offset is what makes north straddle +-- zero: without it, 350 degrees would land in NW and 10 in NE, leaving north +-- with only half its arc. +local POINTS = { 'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW' } + +function M.compass(deg) + if type(deg) ~= 'number' then return nil end + local i = math.floor(((deg % 360) + 22.5) / 45) % 8 + return POINTS[i + 1] +end + +-- Arrow glyphs, in the same order as POINTS but rotated half a turn: OWM +-- reports the direction the wind comes FROM, and an arrow reads as the +-- direction it goes TO. +local ARROWS = { '\u{2193}', '\u{2199}', '\u{2190}', '\u{2196}', + '\u{2191}', '\u{2197}', '\u{2192}', '\u{2198}' } + +function M.arrow(deg) + if type(deg) ~= 'number' then return '' end + local i = math.floor(((deg % 360) + 22.5) / 45) % 8 + return ARROWS[i + 1] +end + return M diff --git a/test/test_weather.lua b/test/test_weather.lua index f61fa22..e18aa15 100644 --- a/test/test_weather.lua +++ b/test/test_weather.lua @@ -77,4 +77,54 @@ assert(weather.icon(800, DAY, nil, nil) == weather.ICON.clear_day, -- the plan's Step 5, and it is how a wrong-but-present codepoint was caught -- before this file existed. +-- === Wind ================================================================= +-- OWM metric gives m/s; the card shows km/h. The conversion is where a wrong +-- factor would look plausible but read 3.6x off. +assert(weather.kmh(10) == 36, '10 m/s is 36 km/h') +assert(weather.kmh(0) == 0, 'calm') +assert(weather.kmh(nil) == nil, 'missing wind speed stays missing') + +-- Beaufort thresholds, in km/h, from the polybar script. Each assertion sits +-- on a boundary and just past it, which is where an inclusive/exclusive +-- mistake hides. +assert(weather.beaufort(0) == 0, 'calm is force 0') +assert(weather.beaufort(1) == 0, '1 km/h is still force 0') +assert(weather.beaufort(2) == 1, 'just over 1 is force 1') +assert(weather.beaufort(5) == 1, '5 is still force 1') +assert(weather.beaufort(6) == 2, 'just over 5 is force 2') +assert(weather.beaufort(11) == 2, '11 is still force 2') +assert(weather.beaufort(12) == 3, 'just over 11 is force 3') +assert(weather.beaufort(19) == 3, '19 is still force 3') +assert(weather.beaufort(28) == 4, '28 is force 4') +assert(weather.beaufort(38) == 5, '38 is force 5') +assert(weather.beaufort(49) == 6, '49 is force 6') +assert(weather.beaufort(61) == 7, '61 is force 7') +assert(weather.beaufort(74) == 8, '74 is force 8') +assert(weather.beaufort(88) == 9, '88 is force 9') +assert(weather.beaufort(102) == 10, '102 is force 10') +assert(weather.beaufort(117) == 11, '117 is force 11') +assert(weather.beaufort(118) == 12, 'over 117 is hurricane force') + +-- Compass: eight points, each spanning 45 degrees, offset by half a step so +-- north straddles 0 rather than starting at it. The wraparound is the case +-- that a naive floor(deg/45) gets wrong. +assert(weather.compass(0) == 'N', '0 is north') +assert(weather.compass(360) == 'N', '360 wraps to north') +assert(weather.compass(11) == 'N', 'just under the NE boundary') +assert(weather.compass(349) == 'N', 'just over the NW boundary wraps to north') +assert(weather.compass(45) == 'NE', '45 is northeast') +assert(weather.compass(90) == 'E', '90 is east') +assert(weather.compass(135) == 'SE', '135 is southeast') +assert(weather.compass(180) == 'S', '180 is south') +assert(weather.compass(225) == 'SW', '225 is southwest') +assert(weather.compass(270) == 'W', '270 is west') +assert(weather.compass(315) == 'NW', '315 is northwest') +assert(weather.compass(nil) == nil, 'missing direction stays missing') + +-- The arrow points where the wind is going, and OWM reports where it comes +-- from, so a north wind draws a downward arrow. +assert(weather.arrow(0) == '\u{2193}', 'a north wind blows southward') +assert(weather.arrow(180) == '\u{2191}', 'a south wind blows northward') +assert(weather.arrow(nil) == '', 'no direction draws nothing') + print('test_weather: all assertions passed') |
