Skip to content

Programs schedules and curves

monikapurpl3 edited this page Aug 21, 2026 · 1 revision

Programs, schedules and curves

Automation that runs on the server. This is the part that separates a remote control from a thermostat: a schedule fires whether or not your phone is home, charged, or awake, and it keeps firing while nobody is looking.

Programs live in programs.json, a third store alongside config.json and devices.json, and are edited from the web panel, the Android app, or /api/programs directly.

The three kinds

Kind What it is When it acts
favourite A saved set of settings — mode, setpoint, fan, swing. Only when you apply it. Nothing automatic.
schedule A list of entries, each with days of the week, a time, and settings. On the matching minute, server-local.
curve A set of (time, temperature) points for one mode and fan speed. Continuously — the setpoint is interpolated between points.

Every program targets a list of unit_ids, so one schedule can drive the whole flat or a single room.

Curves, specifically

A curve is a day-shaped target rather than a list of events. Give it a handful of points — cooler overnight, warmer before you wake, cooler again in the afternoon heat — and the scheduler interpolates between them, cyclically over 24 hours, and snaps the result to the 0.5° the protocol allows.

It only sends a command when the rounded target actually changes, so a curve does not chatter at the unit every tick. Points are 16.030.0 °C; mode defaults to COOL and fan to auto (102).

How it fires

One asyncio task started with the app, ticking every AC_SCHED_TICK seconds (30 by default). Because there is exactly one uvicorn worker, there is exactly one scheduler — no duplicate firing, no leader election.

Both schedules and curves go through the same code path as the HTTP control route, so a scheduled change and a change you make by hand are indistinguishable from the unit's point of view — and from the SSE stream's, which is why a schedule firing shows up live in the panel.

Two consequences worth knowing:

  • Times are server-local. Set the server's timezone, or programs run on UTC. In containers that means TZ=Europe/Zagreb — all five images carry the timezone database precisely because getting this wrong is silent.
  • The beep stays off. Scheduled changes never chirp, which is the whole point of a 3 a.m. setpoint drop.

In the panel

Favourites apply with one press. Schedules are edited as a list of entries and do not have an Apply button — a schedule is not a thing you apply, it is a thing that runs, and the server rejects the attempt. Toggling a program's enabled switch sends the whole spec back with just that flag flipped.

From the API

GET, POST, PUT, DELETE under /api/programs, all requiring both credentials. The shapes:

  • favourite{operational_mode?, target_temperature?, fan_speed?, swing_mode?, power?}
  • schedule[{days:[0-6], time:"HH:MM", settings:{…}}, …]
  • curve{operational_mode, fan_speed, points:[{time:"HH:MM", temperature}, …]}

Full endpoint reference: REST API. Field values and bounds: Control schema.

Clone this wiki locally