Release 0.19.2: SAFETY-125 grid charge stays under the month peak #217

Merged
admin merged 4 commits from hotfix-0.19.2 into master 2026-10-30 07:44:26 +01:00
7 changed files with 29 additions and 22 deletions
Showing only changes of commit 6eebd4882b - Show all commits
+1 -1
View File
@@ -18,7 +18,7 @@ Contents of this release, in merge order since 0.19.1 (`2932f3a`):
### Known issues
The list under `## 0.19.0` below still applies. The SAFETY-99 line there now
covers the guard's discharge only, not a grid charge.
covers the guard's discharge, and the maintenance charge with one inverter.
### If you are crossing from a version older than 0.10.0
@@ -5,5 +5,6 @@
A grid charge is sized by `peakguard.charge_room_w()`, the guard's headroom
with the seconds since a late meter reading counted at that reading (the
projection leaves them out, SAFETY-99, the bill does not), and the guard's own
floor is unchanged. Evidence (repro on 0.19.1, sweep, digests): the SAFETY-125
pull request.
floor is unchanged. Not at N=1: the maintenance charge there is not sized to
the room (SAFETY-84), so SAFETY-99 still applies to it. Evidence (repro on
0.19.1, sweep, digests): the SAFETY-125 pull request.
+1 -1
View File
@@ -3597,7 +3597,7 @@ for a new install*.
| Meter reading may be stuck | See *Meter reading may be stuck* under Notifications. |
| Month peak | This month's highest 15-minute average, when it happened, and how close it is to your peak limit. Amber from 80 %. |
| 15-minute periods measured this month | How many 15-minute periods the add-on has measured and saved this month. |
| Peak guard, Load too high for battery, Battery at its peak reserve | What the add-on does to keep your peak down. *Idle, heading for …* is where this 15-minute period is heading. *Waiting for meter readings* after a restart means the battery does not charge until the add-on can measure the period again. A red peak row is an alarm while control keeps running, so the banner shows its title without *Not ready*. |
| Peak guard, Load too high for battery, Battery at its peak reserve | What the add-on does to keep your peak down. *Idle, heading for …* is where this 15-minute period is heading. *At this rate … over …* means it would go over at the current rate. With *grid charge limited*, a charge from the grid is cut back so it does not. *Waiting for meter readings* after a restart means the battery does not charge until the add-on can measure the period again. A red peak row is an alarm while control keeps running, so the banner shows its title without *Not ready*. |
| Battery level, Battery power, Grid power | The reading of that entity. *No usable reading* means the entity is missing, or its reading is too old. Check it in Developer Tools before replacing it. |
| Inverter control | Whether the inverter can be controlled, and how much it can charge and give. |
| *name*: battery power reading stopped changing | The reading did not change while the add-on asked for a change. It may be stuck, or the battery may be refusing. The add-on sets the inverters to 0 W until it changes. |
+2
View File
@@ -1453,6 +1453,8 @@ def _samples() -> list:
("plan", line_period(1240, 3500, sh)),
("plan", line_period(None, 3500, sh)),
("plan", line_period(1240, 3500, sh, unmeasured=True)),
("plan", line_period(5814, 5413, sh)),
("plan", line_period(5814, 5413, sh, cut=True)),
("plan", control_text(True, sh)),
("plan", control_text(False, sh))]
out += [("plan", run_grid_why(0.1412)), ("plan", run_grid_amount(1.23)),
+13 -8
View File
@@ -1174,18 +1174,18 @@ def row_peak_guard_idle(projected_w, limit_w, month_peak: bool,
cut: bool = False) -> str:
"""The projection first and the limit second (SAFETY-38's ordered pair).
SAFETY-125: over the limit at this rate it says so, and `cut` that a
grid charge is cut back to the room left."""
grid charge is limited to the room left."""
if float(projected_w) > float(limit_w):
doing, doet = (("grid charge limited", "laden beperkt") if cut
else ("idle", "in rust"))
return Bi(f"Peak guard: {doing}, at this rate {watts(projected_w)}, "
f"over {watts(limit_w)}",
f"Piekbewaking: {doet}, aan dit tempo "
f"{watts(projected_w)}, boven {watts(limit_w)}")
limit = (f"this month's {watts(limit_w)} peak" if month_peak
else f"the {watts(limit_w)} peak limit")
grens = (f"de maandpiek van {watts(limit_w)}" if month_peak
else f"de piekgrens van {watts(limit_w)}")
if float(projected_w) > float(limit_w):
doing, doet = (("cutting the grid charge", "schroeft het laden van "
"het net terug") if cut else ("idle", "in rust"))
return Bi(f"Peak guard: {doing}, at this rate {watts(projected_w)}, "
f"over {limit}",
f"Piekbewaking: {doet}, aan dit tempo "
f"{watts(projected_w)}, boven {grens}")
return Bi(f"Peak guard: idle, heading for {watts(projected_w)}, under "
f"{limit}",
f"Piekbewaking: in rust, richting {watts(projected_w)}, onder "
@@ -1573,6 +1573,11 @@ def status_samples() -> list:
("row_periods_measured", GREEN, row_periods_measured("unreadable")),
("row_peak_guard_idle", GREEN, row_peak_guard_idle(1300, 2500, True)),
("row_peak_guard_idle", GREEN, row_peak_guard_idle(1300, 2500, False)),
("row_peak_guard_idle", GREEN, row_peak_guard_idle(5814, 5413, True)),
("row_peak_guard_idle", GREEN, row_peak_guard_idle(5814, 5413, True,
cut=True)),
("row_peak_guard_idle", GREEN, row_peak_guard_idle(3814, 3500, False,
cut=True)),
("row_peak_guard_quiet", GREEN, row_peak_guard_quiet()),
("row_peak_guard_unmeasured", AMBER, row_peak_guard_unmeasured()),
*(("row_peak_guard_blind", AMBER, row_peak_guard_blind(k))
+2 -2
View File
@@ -352,8 +352,8 @@
"period": "Dit kwartier gaat richting {kw}.",
"period_unmeasured": "Een deel van dit kwartier is niet gemeten.",
"period_over": "Aan dit tempo komt dit kwartier op {kw}.",
"charge_cut": "Het laden van het net wordt teruggeschroefd om onder {kw} te blijven.",
"charge_cut_would": "Het laden van het net zou teruggeschroefd worden om onder {kw} te blijven.",
"charge_cut": "Laadt minder van het net om onder {kw} te blijven.",
"charge_cut_would": "Zou minder van het net laden om onder {kw} te blijven.",
"prices": {"now": "Prijs nu {eur} per kWh, alles inbegrepen.", "today": "Vandaag: laagste {lo} om {lo_at}, hoogste {hi} om {hi_at}.", "none": "Geen prijzen voor vandaag."},
"tomorrow": {"known": "De prijzen van morgen zijn binnen.", "unknown": "De prijzen van morgen komen meestal na 13:00."},
"region": {"preset": "Heffingen en btw: {region}, cijfers van {year}.", "own": "Heffingen en btw: uw eigen bedrag."},
+7 -8
View File
@@ -355,9 +355,9 @@ for name, kw, aim, kw_text in (("month peak banked", dict(peak=PEAK),
f"{_u[3] if present(_u) else _u!s} / "
f"{_u[4] if present(_u) else _u!s}")
check(f"{name}: over the limit at this rate the guard row never says "
f"'under'; it says the grid charge is cut",
f"'under'; it says the grid charge is limited",
present(_o) and all(
"under" not in s[3] and "Peak guard: cutting the grid charge, "
"under" not in s[3] and "Peak guard: grid charge limited, "
"at this rate" in s[3] and " over " in s[3] for s in over))
check(f"{name}: ...and the month-peak line says the rate, and that the "
f"grid charge is cut back to stay under {kw_text}",
@@ -382,17 +382,16 @@ _cut = messages.row_peak_guard_idle(5814.0, 5413.0, month_peak=True,
_ok = messages.row_peak_guard_idle(5200.0, 5413.0, month_peak=True)
print(f" {_en}\n {_cut}\n {_ok}")
check("over, nothing cut: 'idle, at this rate ..., over ...'",
_en == "Peak guard: idle, at this rate 5 814 W, over this month's "
"5 413 W peak")
_en == "Peak guard: idle, at this rate 5 814 W, over 5 413 W")
check("over, a grid charge cut",
_cut == "Peak guard: cutting the grid charge, at this rate 5 814 W, "
"over this month's 5 413 W peak")
_cut == "Peak guard: grid charge limited, at this rate 5 814 W, "
"over 5 413 W")
check("under: the 0.19.1 sentence, unchanged",
_ok == "Peak guard: idle, heading for 5 200 W, under this month's "
"5 413 W peak")
check("the Dutch forms say the same",
_cut.nl == "Piekbewaking: schroeft het laden van het net terug, aan "
"dit tempo 5 814 W, boven de maandpiek van 5 413 W"
_cut.nl == "Piekbewaking: laden beperkt, aan dit tempo 5 814 W, "
"boven 5 413 W"
and _en.nl.startswith("Piekbewaking: in rust, aan dit tempo"))
check("the month-peak line in shadow mode says 'would'",
homeview.line_period(5814.0, 5413.0, True, cut=True).endswith(