Concepts¶
How a schedule entry works, end to end. Read this first; the other pages go into each part.
How to read the scheduler pages
These pages describe what the code does in this release. Each behaviour has a hidden marker in the page source with the code location and whether a unit test covers it. Untested behaviour is described from the code, not from a test run. The Scheduler test plan lists every behaviour with its test status.
The model¶
An entry is one row on the Schedule tab. It has six parts, always in this order:
flowchart LR
T["1 · Trigger<br>when is the entry active?"] --> C["2 · Conditions<br>may it act now?<br>(gate + hold-for)"]
C --> A["3 · Action<br>what to send"]
A --> G["4 · Target<br>which gateway(s)"]
G --> X["5 · Exit<br>when does the run end?<br>(exit conditions, window end,<br>time limit, target SoC, Stop)"]
X --> O["6 · Outcome<br>Activity Log, dispatch<br>record, notifications"]
| Part | Question it answers | Fields in the form | Page |
|---|---|---|---|
| Trigger | When is the entry active? | Trigger Type, its time fields, Duration (min) | Triggers |
| Conditions | May it act now? | Entry conditions, Duration (HH:MM:SS) hold-for | Conditions |
| Action | What does it send? | Action, Power / Reserve % / Mode, HA Actions | Actions |
| Target | Which gateway or gateways? | Target, Gateway / Service | Targets |
| Exit | When does a run end, and what then? | Exit conditions, On exit / release | Exit and release |
| Outcome | What happened? | — (Activity Log, Logs, notifications) | Outcomes and audit |
Two more settings decide what happens when entries meet: Priority and If already controlled. See Priorities and conflicts.
Three ways to start¶
The owner's words "by time, by event, by sensor" map onto the trigger types like this:
| You want | Use | Example |
|---|---|---|
| By time | A window (Recurring or One-off) or a fire-based trigger (Daily, Weekly, Every N minutes, Monthly, Cron) | Charge 16:00–17:00 on weekdays |
| By event | A time trigger plus an entry condition on the thing that changes: a Home Assistant entity, the grid connection, the operating mode, a tariff window | Hold the battery while switch.ev_charger is on, 17:00–23:00 |
| By sensor | Always evaluate, or a short repeating trigger, with entry conditions on a sensor | Charge when the spot price is below 5 c/kWh |
There is no separate event trigger. An "event" is a condition that becomes true while the entry's trigger is active. The engine notices it on the next 15-second tick.
The tick¶
The engine runs on the bridge, not in the browser. Every 15 seconds it evaluates every enabled entry.
| Step | What happens |
|---|---|
| 1 | Load the enabled entries, highest priority first, then oldest first. |
| 2 | Build one sensor snapshot per gateway from its last poll (no Modbus read). |
| 3 | For each target, work out the gateways it covers. |
| 4 | Per gateway: pick the one battery entry that may act, and reconcile the gateway to it. Entries with No battery action run on their own lane. |
| 5 | Write every decision to the Activity Log. |
Saving, deleting, enabling or disabling an entry reloads the engine and runs a tick at once, so a change can act within a second rather than at the next tick.
Turning the Schedule module off does not stop schedules
Settings → Admin → Feature Modules → Schedule hides the tab and blocks the schedule API, but the engine starts with the bridge either way and keeps running the enabled entries it loaded. To stop schedules, disable the entries.
Window, activation and run¶
Three words recur:
| Word | Meaning |
|---|---|
| Window | The time the trigger makes the entry active. For a window trigger it is the start → end you type. For a fire-based trigger it is fire time → fire time + Duration (min). Always has one endless window. |
| Activation | One pass through a window. Fire-time HA actions run once per activation. |
| Run | A battery command the entry sent and still owns on one gateway. A run ends at the first exit (see Exit and release). After a run ends inside its window, the entry does not fire again until the window closes and opens again. |
What the engine remembers¶
The engine keeps its state in memory: which entry owns each gateway, which windows are done, hold-for timers, retry timers. A bridge restart forgets all of it. See Restarts and the clock.
Legacy and v2 entries¶
Entries saved before the trigger and condition fields existed are legacy entries. The code treats an entry as v2 when it has a trigger type or any entry or exit condition. The difference matters in one place: only v2 entries honour On exit / release; a plain window entry with no conditions always does a plain release.
Glossary¶
| Term | Meaning |
|---|---|
| Entry | One schedule row. Also called a schedule or an automation. |
| Gate | The entry conditions. |
| Hold-for (dwell) | Duration (HH:MM:SS) under the entry conditions: how long the gate must stay true before the entry fires. |
| Exit conditions | Checked while a force command from this entry runs; the first time they are true the run ends. |
| Owner | The entry that sent the command a gateway is running. |
| Manual control | A force command the scheduler did not send on this target (Controls tab, Home Assistant, MQTT, API, Run now, or another target's entry). |
| Release | Clearing the setpoint so the gateway returns to its own mode. |
| Fan-out | One entry acting on several gateways (Site or Service target). Each gateway is handled on its own. |