All checks were successful
Build & Deploy docs / build-deploy (push) Successful in 3m52s
Relu contre le moteur (main 61db6cf) : en temps réel la protection ne bride que les bornes, les autres charges sont délestées au cycle suivant ; cycle chaque minute ; repli à 90 s de silence du compteur, états sûrs. Ordre réel : mesure et marge de soutirage, échéances VE, réserve batterie, passe éco (demandes ponctuelles puis obligations étalées) avant la cascade confort ; recrédit, plancher, verrous et indisponibilité appliqués charge par charge ; une commande par charge. Retiré : « si l'installateur l'a autorisé » (aucune autorisation dédiée). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ry3vBrJT1tHdxAaXdCWi6L
108 lines
5.8 KiB
Markdown
108 lines
5.8 KiB
Markdown
# How the engine decides
|
|
|
|
<span class="badge community">COMMUNITY</span>
|
|
|
|
The box's energy engine drives your loads on its own: EV chargers, water heater,
|
|
SG-Ready heat pump, relays. It is free software (GPL-3.0) and it is the one that decides
|
|
in the **Community** edition. This page describes its logic for installers and
|
|
integrators; the following pages detail each feature.
|
|
|
|
## Two loops, two priorities
|
|
|
|
The engine keeps safety apart from allocation. They are two separate loops, running at
|
|
different rates and with different priorities.
|
|
|
|
- **Overload protection, on every measurement.** As soon as the measured balance
|
|
changes, the engine reads the current of each phase at the grid meter. If a phase
|
|
exceeds the configured limit, it **immediately** lowers the current of the EV chargers,
|
|
then releases it when the margin returns. The other loads (water heater, heat pump,
|
|
relays) are shed at the start of the next cycle ([load management](delestage.md)). This
|
|
protection overrides any allocation decision.
|
|
- **The allocation cycle, every minute.** It shares the available power between the
|
|
loads, on the one-minute measurement of the electrical balance, and runs again right
|
|
away when you change a setting. It is the only place where a strategy comes in: the
|
|
built-in rules, or an [optimizer](../optimiseur/index.md) if one is connected.
|
|
|
|
**If the grid meter goes silent** (more than 90 s without a reading), the engine suspends
|
|
allocation and puts the loads in a safe position: adjustable loads at 0 W, relays open,
|
|
heat pump in normal operation, chargers already charging brought down to minimum
|
|
current, no new load started. Overload protection stays active. Allocation resumes on the
|
|
cycle after the meter comes back.
|
|
|
|
## The rules, in order
|
|
|
|
On every cycle, the engine applies the same steps, in the same order.
|
|
|
|
1. **Measure.** The starting point is what the grid meter measures (export and import).
|
|
The engine also derives the **draw margin** from it: what the installation can still
|
|
take from the grid without exceeding the phase limit. No grid purchase, whatever its
|
|
reason, goes beyond it.
|
|
2. **Serve charging deadlines.** A vehicle that must be charged by a given time is served
|
|
from the grid, outside the surplus sharing.
|
|
3. **Protect the battery.** If a home battery is below its reserve threshold, the surplus
|
|
goes to it first: the controlled loads get none of it. Above the threshold, what it
|
|
absorbs counts as available surplus. Its discharge is never counted as surplus.
|
|
4. **Guaranteed needs ("eco" pass).** First the **one-off requests** made from the app
|
|
("heat now"): the load gets its full power, whatever its rank. Then the **daily
|
|
obligations**, for example a minimum amount of energy for the water heater before a
|
|
given time: the engine buys the missing energy from the grid, spread evenly until the
|
|
deadline, and switches to full power when only the time strictly needed is left. These
|
|
purchases stay within the draw margin.
|
|
5. **Share the surplus in cascade ("comfort" pass).** Loads are served in the
|
|
**priority** order you set (1 = served first). Each receives what is left of the
|
|
budget, within its bounds, and the budget is decreased accordingly. There is **one**
|
|
budget: without it, three managers would each see "2 kW of surplus" and draw 6. In
|
|
turn, for each load:
|
|
- what it already consumes is given back to it: a running load is not counted against
|
|
itself;
|
|
- below its minimum power, it stays off rather than running at half power, and the
|
|
budget moves on to the next one. An EV charger may still start with a small top-up
|
|
from the grid, within the configured tolerance;
|
|
- a load under **lock** (minimum on or off time, delay between two changes) keeps its
|
|
current power;
|
|
- an **unavailable** load keeps its current power, with no new setpoint; what it
|
|
consumes is still counted.
|
|
6. **One command per load.** The guaranteed need and the surplus share of the same load
|
|
are merged: each load receives a single setpoint, with its reason.
|
|
|
|
### The bounds of each load
|
|
|
|
Each load carries bounds entered by the installer, which **every** decision respects,
|
|
whatever the strategy:
|
|
|
|
- a power **floor** and **ceiling**. For an EV charger they are in current (times the
|
|
number of phases), and the ceiling is further capped by the phase limit;
|
|
- **anti-flapping locks**: minimum on and off time, delay between two changes. An EV
|
|
charger has its own (delay between on and off, delay between two current changes);
|
|
- for an SG-Ready heat pump: the state chosen from the estimated power of each state,
|
|
with hysteresis and a minimum hold time. The blocking state is never commanded by the
|
|
surplus.
|
|
|
|
## The reason for every decision
|
|
|
|
The engine makes no decision without stating why. Every decision carries a non-empty
|
|
**reason** (`decisionReason`): a stable code and its parameters, which the app displays
|
|
in your language — "insufficient surplus", "below minimum power", "charging deadline"…
|
|
The list of codes is published with the
|
|
[optimizer protocol](../optimiseur/protocole.md#reponse).
|
|
|
|
## The measurement, never the result of control
|
|
|
|
The surplus is computed on the **raw measurement** of the grid meter, as measured. Never
|
|
on a balance recomputed after control: the engine would be reading itself and would
|
|
oscillate.
|
|
|
|
## Without internet
|
|
|
|
Everything above runs on the box. Without internet, the engine controls, applies safety
|
|
and answers the app on your local network. Only the [PV forecast](prevision-pv.md)
|
|
stops. In the Community edition, neither the forecast nor the
|
|
[entered tariff](../tarifs.md) enters the decisions of the rules: both are displayed and
|
|
recorded, never used to decide.
|
|
|
|
## And an optimizer?
|
|
|
|
An optimizer can propose a plan over several hours, based on forecasts. It replaces the
|
|
allocation step, **never** the overload protection or the bounds. See the
|
|
[Optimizer](../optimiseur/index.md) section.
|