Perch fetches the forecast itself (met.no, located by the machine’s IP) about every 40 minutes, so a weather widget needs only the weather scope.
| Scope | Installs |
|---|---|
weather | perch.weather.read(), perch.weather.on_change, perch.weather.configure(options) |

perch.weather.read
perch.weather.read(): weather_state_t
The last forecast, or an empty table before the first fetch. Synchronous.
perch.weather.on_change
perch.weather.on_change: signal_t<weather_state_t>
Fires when a fetch completes and when the unit changes (the same data re-emitted in the other unit).
--!strict
perch.weather.on_change:connect(function(x: weather_state_t)
if not x.temp then return end
local week = {}
for i, day in ipairs(x.week) do
week[i] = { d = day.d, i = day.i, t = day.t, today = day.today }
end
wx:present({ temp = x.temp, cond = x.cond, icon = x.icon, city = x.city, hi = x.hi, lo = x.lo, week = week })
end)
perch.weather.configure
perch.weather.configure(options: weather_options_t): ()
{ unit = "fahrenheit" } selects Fahrenheit; any other value means Celsius. Changing the unit re-emits on_change at once. The builtin package’s settings page calls it; a third-party widget usually shows whatever unit the user already chose.
Types
export type weather_state_t = { city: string, temp: string, cond: string, icon: string, hi: string, lo: string, week: { weather_day_t } }
export type weather_day_t = { d: string, i: string, t: string, today: boolean }
export type weather_options_t = { unit: string? }
Temperatures are strings, already rounded and already in the configured unit, so they bind directly.
| Field | Meaning |
|---|---|
city | may be "" |
temp, hi, lo | the current temperature and today’s high and low |
cond | condition text, "Partly cloudy" |
icon | one of thunder, sleet, snow, rain, sun, moon, suncloud, mooncloud, fog, cloud |
week | up to 7 days starting today: d is "Sun" to "Sat", i an icon name, t the day’s high, today marks the first |