Skip to content

Exit and release

How a run ends, and what the gateway does afterwards. Everything here is per gateway: for a Site or Service target each member gateway ends its own run.

What happens when two entries, or you and an entry, want the same gateway is on Priorities and conflicts. Run now, Stop and the Activity Log are on Outcomes and audit.

How a run ends

A force command started by an entry ends at the first of these:

End Logged as Fires again…
Window ends (window end, or fire time + Duration (min)) ok — "window exit — released to native" at the next window
Exit conditions become true exit_condition_met at the next window
Time limit reached (API params.duration_s) expired — "dispatch ended in-window" at the next window
Target SoC reached (API params.target_soc) expired at the next window
Released elsewhere: the Release button, the Controls tab, MQTT, another tool, the overshoot guard expired at the next window
Stop (■) on the entry stopped at the next window
Entry disabled or deleted ok — released when enabled again
Bridge shuts down control log only: release, reason shutdown after restart, if the window is still open

"At the next window" means the entry is marked done for the current window and does not fire again until its window closes and opens again. For an Always entry the window never closes; see Triggers → Always.

A window end may not release when another entry is active on the gateway

A run is released at its window end only when no other battery entry on the same target is active at that moment. If another one is (an Always entry, or an overlapping window), the code hands the gateway to it instead:

  • If that entry's entry conditions pass, its own action replaces the run.
  • If they fail, the old command keeps running with no time limit, after its own window has ended. It stops only when the other entry's gate passes, its exit conditions are met, or something else releases it.
  • The other entry's exit conditions are evaluated against the old run and can end it.
  • The first entry's exit-time HA actions do not run at its window end.

Until this is changed, avoid an Always battery entry on a gateway that has other battery entries, and give force entries a time limit through the API.

Exit conditions

Exit conditions block

Exit conditions:

  • are checked on every tick while this entry owns a running force command on that gateway, starting with the tick after the command was sent;

  • use the same sensors, operators, ALL/ANY and groups as entry conditions;

  • end the run as soon as they are true, release it with the On exit / release policy, log exit_condition_met, run the exit-time HA actions and mark the window done;

  • are not checked for Release, Reserve, Mode or HA-only entries, nor for Run now or a late fire (the scheduler does not own those).

The Activity Log detail for exit_condition_met lists the exit rows that were false at that moment, not the ones that ended the run. With an ANY block that is the rows that did not match; with an ALL block it just says "exit conditions met".

Typical exits: battery.soc_pct >= const.max_charge_soc for a charge, battery.soc_pct <= const.min_discharge_soc for a discharge, tariff.spot_price >= 8 for a price rule.

Release policy

On exit / release

Option (UI) API release_policy When the run ends
release → native release (default) The setpoint is cleared; the gateway goes back to whatever mode it is in.
release, log any mode change restore_prior_mode The same release. The bridge also compares the mode now with the mode when the run started and logs the result ("mode unchanged (TOU)" or "mode not restored: changed during dispatch (TOU → Self-Consumption), left as-is"). It never writes the old mode back.
(API only) set_operating_mode:<Mode> Release, then set that mode, for example set_operating_mode:TOU. Skipped when the mode is already in place or the gateway is known to ignore mode writes; the reason is logged.
  • The policy applies to every way a v2 run ends: window end, exit conditions and Stop. A plain window entry with no conditions always does a plain release (see Concepts).

  • A run that ends inside its window by itself (time limit, target SoC, released elsewhere) has already been released; no policy is applied.

  • The API accepts any text for release_policy. An unknown value releases plainly.

  • Entries created before the trigger fields existed were given restore_prior_mode by the database upgrade, so their Details panel shows it, but as plain window entries they release plainly.

What a release does on the gateway

The command handler clears the setpoint and the revert timer, reads WSetEna back, and records the dispatch as released, or release_unverified when WSetEna still reads 1. It also clears any staged target SoC.

Hold instead of release (API only)

The API field release takes release (default) or hold. With hold, when the window of a force command ends the bridge does not hand back: it switches to Force Standby (0 W) and keeps the gateway in remote-control mode, so its own TOU or Self-Consumption logic stays suppressed. The Activity Log says "window exit — holding native suppressed". The form has no control for this; it keeps whatever value the entry has.

A hold has no end of its own

The standby lasts until another entry takes the gateway, you press Stop on the entry, or you release the battery. Disabling or deleting the entry does not end it: the engine keeps the hold, with no time limit.

Bridge shutdown

On a graceful shutdown the engine stops first, then each gateway releases its active command (a fast release, no ramp-down). No released row is written to the Activity Log and exit-time HA actions do not run. See Restarts and the clock.