diff --git a/goodwe_controller/CHANGELOG.md b/goodwe_controller/CHANGELOG.md index 814e159..b62cb91 100644 --- a/goodwe_controller/CHANGELOG.md +++ b/goodwe_controller/CHANGELOG.md @@ -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 diff --git a/goodwe_controller/DECISIONS/SAFETY-125-grid-charge-under-the-month-peak.md b/goodwe_controller/DECISIONS/SAFETY-125-grid-charge-under-the-month-peak.md index 1457c0b..7ec515d 100644 --- a/goodwe_controller/DECISIONS/SAFETY-125-grid-charge-under-the-month-peak.md +++ b/goodwe_controller/DECISIONS/SAFETY-125-grid-charge-under-the-month-peak.md @@ -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. diff --git a/goodwe_controller/DOCS.md b/goodwe_controller/DOCS.md index c35b20e..3c23bdb 100644 --- a/goodwe_controller/DOCS.md +++ b/goodwe_controller/DOCS.md @@ -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. | diff --git a/goodwe_controller/app/homeview.py b/goodwe_controller/app/homeview.py index d0c5c7c..c416a0e 100644 --- a/goodwe_controller/app/homeview.py +++ b/goodwe_controller/app/homeview.py @@ -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)), diff --git a/goodwe_controller/app/messages.py b/goodwe_controller/app/messages.py index 09fdeec..9ae3607 100644 --- a/goodwe_controller/app/messages.py +++ b/goodwe_controller/app/messages.py @@ -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)) diff --git a/goodwe_controller/app/ui_text/nl.json b/goodwe_controller/app/ui_text/nl.json index 191c2f9..b92abea 100644 --- a/goodwe_controller/app/ui_text/nl.json +++ b/goodwe_controller/app/ui_text/nl.json @@ -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."}, diff --git a/goodwe_controller/test_safety125.py b/goodwe_controller/test_safety125.py index 063dd80..bedb326 100644 --- a/goodwe_controller/test_safety125.py +++ b/goodwe_controller/test_safety125.py @@ -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(