aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-17 08:57:27 +0200
committerDanilo M. <danix@danix.xyz>2026-09-17 08:57:27 +0200
commit2b499067d07328e775547059212bf3737cfcfdd4 (patch)
tree4971a888f526373d2014a34a835f140a3ab4da60
parent17692349e6b6ce3f6083b5d565dda9f3ca7dba22 (diff)
downloadconky-theme-udt-2b499067d07328e775547059212bf3737cfcfdd4.tar.gz
conky-theme-udt-2b499067d07328e775547059212bf3737cfcfdd4.zip
feat: add sun position along the daylight arc
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
-rw-r--r--lib/weather.lua24
-rw-r--r--test/test_weather.lua26
2 files changed, 50 insertions, 0 deletions
diff --git a/lib/weather.lua b/lib/weather.lua
index ac1f4cf..f8c7517 100644
--- a/lib/weather.lua
+++ b/lib/weather.lua
@@ -113,4 +113,28 @@ function M.arrow(deg)
return ARROWS[i + 1]
end
+-- Fraction of daylight elapsed, clamped to 0..1.
+--
+-- OWM returns TODAY's sunrise and sunset, so before dawn this is negative and
+-- after dusk it is over 1. Clamping parks the dot at the corresponding end of
+-- the arc, which is the cheap correct-enough behaviour; multi-day astronomy
+-- buys nothing for a dot on a curve.
+function M.sun_t(now, sunrise, sunset)
+ if type(now) ~= 'number' or type(sunrise) ~= 'number'
+ or type(sunset) ~= 'number' then return nil end
+ local span = sunset - sunrise
+ if span <= 0 then return 0 end -- polar day/night or bad data: no division
+ local t = (now - sunrise) / span
+ if t < 0 then return 0 elseif t > 1 then return 1 end
+ return t
+end
+
+-- Whether the sun is up. Inclusive at both ends, matching the polybar script's
+-- comparison, so the instant of sunrise draws the day face.
+function M.is_day(now, sunrise, sunset)
+ if type(now) ~= 'number' or type(sunrise) ~= 'number'
+ or type(sunset) ~= 'number' then return true end
+ return now >= sunrise and now <= sunset
+end
+
return M
diff --git a/test/test_weather.lua b/test/test_weather.lua
index e18aa15..1d35748 100644
--- a/test/test_weather.lua
+++ b/test/test_weather.lua
@@ -127,4 +127,30 @@ 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')
+-- === Sun position =========================================================
+-- t is the fraction of daylight elapsed, and the widget uses it to place the
+-- dot along the arc. Sunrise 1000, sunset 2000, so midday is 1500.
+assert(weather.sun_t(1000, 1000, 2000) == 0, 'at sunrise t is 0')
+assert(weather.sun_t(1500, 1000, 2000) == 0.5, 'at midday t is half')
+assert(weather.sun_t(2000, 1000, 2000) == 1, 'at sunset t is 1')
+
+-- OWM reports today's sunrise and sunset, so between midnight and sunrise the
+-- numerator is negative. The clamp is the whole handling; without it the dot
+-- would be drawn off the left end of the arc.
+assert(weather.sun_t(500, 1000, 2000) == 0, 'before dawn clamps to 0')
+assert(weather.sun_t(9999, 1000, 2000) == 1, 'after dusk clamps to 1')
+
+-- Degenerate input must not divide by zero.
+assert(weather.sun_t(1500, 2000, 2000) == 0, 'zero-length day gives 0, not nan')
+assert(weather.sun_t(nil, 1000, 2000) == nil, 'missing now gives nil')
+assert(weather.sun_t(1500, nil, 2000) == nil, 'missing sunrise gives nil')
+
+-- is_day drives both the icon face and the dot's colour: a dot parked at the
+-- end of the arc must not read as a sun that is still up.
+assert(weather.is_day(1500, 1000, 2000) == true, 'midday is day')
+assert(weather.is_day(1000, 1000, 2000) == true, 'sunrise counts as day')
+assert(weather.is_day(2000, 1000, 2000) == true, 'sunset counts as day')
+assert(weather.is_day(500, 1000, 2000) == false, 'before dawn is night')
+assert(weather.is_day(2500, 1000, 2000) == false, 'after dusk is night')
+
print('test_weather: all assertions passed')