UX-09: Details link for current HA, "would" in shadow mode, plain terms
checks / unit (pull_request) Successful in 8m50s
infra-pin / fresh (pull_request) Successful in 2s

- Details link: /config/app/<slug>/documentation on HA 2026.2+ (the old
  /hassio/addon path is a 404 from 2026.5), /hassio/addon on 2026.1 and
  older. Slug from GET /addons/self/info, version from GET /info, hostname
  as fallback.
- Shadow mode: the over-rating alarm and row say what would have been sent,
  the peak alarm no longer says the battery is giving all it can.
- "controller" -> "the add-on" / "control". Settings named by their labels;
  four labels changed to match (Peak reserve, Battery level entity, Solar
  production ..., Reversed-sign solar entities).
- Shadow banner and inverter link notes moved to messages.py and checked.
- DOCS Notifications and Status page rewritten for home owners, with a
  "For installers" part each. Allowlist 168 -> 167.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LyR88rXETvwhTgx6yHE39p
This commit is contained in:
2026-09-27 04:10:39 +02:00
co-authored by Claude Opus 5.5
parent d57767fe38
commit 00e3ee9de8
16 changed files with 666 additions and 264 deletions
+190 -109
View File
@@ -2805,123 +2805,170 @@ it.
## Notifications
Each Home Assistant notification this add-on raises has a short title, one
sentence (a red alarm may use three), and a **Details** link to the add-on
documentation that names the section below. This section holds what the
notification leaves out. The wording rule is `STYLE.md` in the repository; the
texts live in `app/messages.py`. Every notification keeps a fixed
`notification_id`, so a repeat replaces the card instead of adding one.
The add-on tells you about a problem with a Home Assistant notification. Each
one has a short title, one to three sentences, and a **Details** link to this
page. The link opens the add-on's Documentation tab. Look for the section with
the same name as the notification title below. A repeat of the same problem
replaces the notification rather than adding a new one.
| Title | Severity | id |
|---|---|---|
| Battery is not keeping up | warning | `goodwe_integrator_bound` |
| Power request too high | alarm | `goodwe_output_clamp` |
| Load too high for battery | alarm | `goodwe_peak_saturated` |
| Battery stopped limiting the peak | alarm | `goodwe_peak_soc_floor` |
| Inverters working against each other | alarm | `goodwe_circulating_power` |
| *name* is not delivering | alarm | `goodwe_not_delivering_<name>` |
| Meter reading may be stuck | alarm | `goodwe_meter_frozen` |
In **shadow mode** the add-on makes every decision but sends nothing: every
inverter stays at 0 W. Notifications then say what the add-on *would* have
sent.
### Battery is not keeping up
The grid-following loop's integrator reached its anti-windup bound
(`integrator_max_w`): the controller has been asking for more than the battery
delivers for a while. This is SAFETY-40, and it is **not** a fault. No command
went over the rating and control keeps running. Short spells after a big load
or solar step are normal. If it keeps coming back, check that the battery
follows its commands. The bound and the command of that tick are in the add-on
log (WARNING, reason code `OUTPUT_CLAMP`). See *The winding-loop alarm* for the
full story.
The battery gives less power than the add-on asks for. This is normal for a
short time, for example just after a large load switches on or the sun comes
out. It is not a fault, and control keeps running. If it keeps coming back,
check that the battery is switched on, and that it is not empty (when it should
give power) or full (when it should charge).
### Power request too high
The controller computed a command above a limit, and the command was cut to that
limit before it was written. The notification names what was asked, what was
sent, and which limit cut it: the configured inverter rating (`max_w`), the
inverter's own limit (the setpoint device's range), or the inverter rating on
the loop side. Asked always comes first. This is a **software fault** (the old
wording was "BUG SIGNAL"). It is not the inverter failing to follow a legal
command, which is the saturation freeze and does not alarm. Control keeps
running. Report it with the add-on log, whose ERROR line carries the reason code
`OUTPUT_CLAMP` and the full figures. See *The winding-loop alarm*.
The add-on worked out a power request above what is allowed, and cut it back
before sending it. The notification shows what was asked and what was sent,
and which limit cut it: the “Inverter rating” setting, or the inverter's own
limit. In shadow mode it shows what *would* have been sent. Control keeps
running. This should never happen, so it is a software fault: please send the
notification and the add-on log to your installer.
### Load too high for battery
The capacity-peak guard (SAFETY-07) is asking for everything the inverter can
discharge, and the running 15-minute average is still projected over the peak
limit. That 15-minute period will set or raise the month's billed peak
(capaciteitstarief). The controller is not at fault: the house load is larger
than the inverter. Switching off load in the next few minutes is the only thing
that still changes the bill. The projection and the watts are in the add-on
log. See *The capacity-peak guard*.
Your home uses more power than the battery can supply, so this 15-minute
period will go over your peak limit and raise this month's peak. The battery
is already giving all it can. This is not a fault. Switch off large loads,
such as an oven, a car charger or a heat pump, for the next few minutes. In
shadow mode the battery gives nothing, so this can happen with a much smaller
load.
### Battery stopped limiting the peak
Two words in this notification are settings. The **peak reserve** is
*Peak guard will not discharge below (%)* (`peak_soc_floor`). The
**cut-out level** is *Battery cut-out level (%)* (`bms_soc_floor`), where the
battery's own system stops discharging.
The add-on stopped using the battery to keep your peak down, so this
15-minute period will go over your peak limit and raise this month's peak.
Switch off large loads for the next few minutes. The notification says why,
and what to do:
The peak guard wanted to discharge to hold the 15-minute peak, but it may not go
below the peak reserve (`peak_soc_floor`, SAFETY-24). It also stops when the
battery level cannot be read, or when an inverter's cut-out level is not set,
because the reserve is graded against it. So this 15-minute
period will go over the peak limit and set or raise the month's billed peak.
Charging from the grid stays blocked meanwhile. On a site with several inverters
the notification names the battery at its limit (SAFETY-32): each battery is
graded against its own cut-out level (`bms_soc_floor`), and raising the other
batteries' settings will not change this one.
- **The battery is at its peak reserve.** The “Peak reserve” setting keeps
that much charge back from peak limiting. Lower it if you accept a lower
battery level.
- **The battery level cannot be read.** Check the “Battery level entity”
setting and that sensor in Home Assistant.
- **A battery cut-out level is not known.** Fill in “Battery cut-out level”
for each inverter in the settings.
⚠️ **The reserve binds the peak guard only (SAFETY-25).** It is not a
whole-battery reserve. Ordinary self-consumption has no such floor and goes on
discharging below it, down to the battery's own cut-out level. See *What
`peak_soc_floor` does not protect*.
The peak reserve only applies to keeping the peak down. Normal home use can
still draw the battery below it, down to the battery cut-out level, where the
battery switches itself off.
### Inverters working against each other
Two inverters were pushing power into each other: one discharging while another
charged (SAFETY-31). **The meter cannot see this.** The two flows cancel at the
P1 meter, so the site reads idle while both batteries cycle through two
conversion stages. Every other guard reads that net figure, so none of them
fires. The add-on has **stopped control and commands 0 W on every inverter**.
If the grid reading does not move after that, one inverter is no longer
listening to the add-on; this has happened on this hardware, once for
6 h 25 min. Switch the inverters off at the isolator. The alarm is latched: a
Home Assistant or add-on restart does not clear it, and the card is raised
again every 5 min until you start control on the add-on page. The watts and the time
window are in the add-on log; the *Circulating* line on the status page shows the
live watts. See *The circulating-power alarm*.
With several inverters, one was charging its battery from another. Your meter
cannot see this, because the two flows cancel out, but it wastes energy. The
add-on has stopped control and set every inverter to 0 W. If the grid power
does not change after that, switch the inverters off at the isolator. A
restart does not clear this. Find out why, then start control on the add-on
page.
### An inverter is not delivering
One inverter has stood well short of its share of the site target for longer
than the hold time (SAFETY-42), while the others have not. No other check sees
this. A unit at 0 W is absent rather than pushing the wrong way, so the per-unit
sign check and the circulation check stay quiet. **Nothing is commanded
differently.** The guard only reports: commanding an inverter that has stopped
listening achieves nothing, and the only fallback the add-on has is
all-or-nothing. The other inverters keep regulating, and the site is short by up
to the missing unit's rating. Check, in this order:
With several inverters, one gives much less power than it is asked for, while
the others do. Nothing is changed: control keeps running, and the other
inverters carry on. Check, in this order:
1. Is the inverter answering on RS485 at all?
2. Is its battery colder or emptier than its configured cut-out level
(`bms_soc_floor`) says? If so, that setting does not describe this battery.
3. Is anything else writing to it?
1. Is the inverter on and connected?
2. Is its battery empty or cold? If it is emptier than its “Battery cut-out
level” says, that setting does not match this battery.
3. Is anything else controlling it?
The alarm is latched and survives restarts. Control is still running, so to
clear it, press *Start / stop control* twice (stop, then start) once you know
why. See *A unit that stops DELIVERING is a third fault again*.
A restart does not clear this. Once you know why, stop and then start control
on the add-on page.
### Meter reading may be stuck
The meter keeps answering, but its value has not changed for longer than the
hold time while the command stands at the power limit (SAFETY-18). The loop is
regulating against a number that has stopped moving. The age is still fresh, so
no other guard stops it. This is an alarm only: control keeps running and keeps
following the reading. Held for a whole 15-minute period, it can set the month's
billed peak. Check the meter; if it is stuck, stop control on the add-on page.
The limit and command figures are in the add-on log. See
*The frozen-meter alarm*.
The meter keeps answering, but its value has not changed for a long time while
the add-on asks the battery for full power. That usually means the meter
reading is stuck. Control keeps running and keeps following the reading, so a
stuck reading can raise this month's peak. Check the meter. If it is stuck,
stop control on the add-on page.
### For installers: notifications
This part is for installers. The texts live in `app/messages.py` and follow
`STYLE.md`. Every notification keeps a fixed `notification_id`, so a repeat
replaces the card. The full figures and reason codes are on the ERROR or
WARNING line of the add-on log.
| Title | Severity | id | Card |
|---|---|---|---|
| Battery is not keeping up | warning | `goodwe_integrator_bound` | SAFETY-40 |
| Power request too high | alarm | `goodwe_output_clamp` | SAFETY-03 |
| Load too high for battery | alarm | `goodwe_peak_saturated` | SAFETY-07 |
| Battery stopped limiting the peak | alarm | `goodwe_peak_soc_floor` | SAFETY-24/25/32 |
| Inverters working against each other | alarm | `goodwe_circulating_power` | SAFETY-31 |
| *name* is not delivering | alarm | `goodwe_not_delivering_<name>` | SAFETY-42 |
| Meter reading may be stuck | alarm | `goodwe_meter_frozen` | SAFETY-18 |
**The Details link.** Home Assistant 2026.2 and newer show add-on pages at
`/config/app/<slug>/documentation`; 2026.5 removed the old
`/hassio/addon/<slug>/documentation`, which 2026.1 and older still use. At
start the add-on reads its slug from `GET /addons/self/info` and the Home
Assistant version from `GET /info`, and builds the link for that version. If
the version cannot be read it uses the new path. If the slug cannot be read it
falls back to the container hostname, and outside an add-on the line names the
section without a link. The documentation tab adds no heading anchors, so the
link cannot jump to the section.
**Battery is not keeping up.** The grid-following loop's integrator reached its
anti-windup bound (`integrator_max_w`, SAFETY-40). No command went over the
rating. The log line is a WARNING with reason code `OUTPUT_CLAMP`. See *The
winding-loop alarm*.
**Power request too high.** A computed command above a limit was cut before it
was written (SAFETY-03). The limits are `max_w` (label “Inverter rating”), the
setpoint device's own range, or the rating on the loop side. Asked always comes
first. The old wording was "BUG SIGNAL". It is not the inverter failing to
follow a legal command, which is the saturation freeze and does not alarm. In
shadow mode the clamp still grades the decision (SAFETY-10), so the alarm can
fire while 0 W is on the wire, and the text says "would have sent". ERROR line,
reason code `OUTPUT_CLAMP`.
**Load too high for battery.** The capacity-peak guard (SAFETY-07) asks for
everything the inverter can discharge and the running 15-minute average is
still projected over the peak limit, so the month's billed peak
(capaciteitstarief) goes up. In shadow mode the guard's projection is made on a
plant that did not respond (SAFETY-47), and the text says so. See *The
capacity-peak guard*.
**Battery stopped limiting the peak.** The peak guard may not discharge below
`peak_soc_floor` (label “Peak reserve”, SAFETY-24). It also stops when the
state of charge is unread, or when an inverter's `bms_soc_floor` (label
“Battery cut-out level”) is missing, because the reserve is graded against it.
Charging from the grid stays blocked meanwhile. With several inverters the
notification names the battery at its limit (SAFETY-32), each graded against
its own cut-out level. ⚠️ **The reserve binds the peak guard only
(SAFETY-25).** Self-consumption has no such floor. See *What `peak_soc_floor`
does not protect*.
**Inverters working against each other.** SAFETY-31. The flows cancel at the
P1 meter, so every other guard, which reads that net figure, stays quiet. This
has happened on this hardware once for 6 h 25 min. The alarm is latched,
survives restarts, and is raised again every 5 min until control is started.
The watts and the time window are in the log; the *Circulating power check*
row shows the live watts. See *The circulating-power alarm*.
**An inverter is not delivering.** SAFETY-42. The unit stood well short of its
share of the site target for longer than `delivery_hold_s`. A unit at 0 W is
absent rather than pushing the wrong way, so the per-unit sign check and the
circulation check stay quiet. The guard only reports: commanding an inverter
that has stopped listening achieves nothing. Check first whether it answers on
RS485. The alarm is latched and survives restarts; stop then start clears it.
See *A unit that stops DELIVERING is a third fault again*.
**Meter reading may be stuck.** SAFETY-18. The value has not changed for
longer than `meter_freeze_s` while the command stands at the power limit, and
the age is still fresh, so no other guard stops it. Only `meter_source:
homewizard_local` can tell a silent meter from an unchanged value. The limit
and command figures are in the log. See *The frozen-meter alarm*.
## The Web UI
@@ -2938,27 +2985,61 @@ exactly the three buttons it always had.
## Status page
The banner at the top says in one line what matters most now. Below it, the
**Commissioning** list has one short row per check: ✓ green is fine, ! amber
needs a look, ✗ red needs action. The rows name settings in words, never a Home
Assistant entity id. The full figures of any alarm are in the add-on log, on the
ERROR or WARNING line of that alarm. The texts are in `app/messages.py`.
The add-on page shows a banner at the top and a **Commissioning** list below
it. The banner says in one line what matters most now. Each row of the list is
one check: ✓ green is fine, ! amber needs a look, ✗ red needs action. Rows name
settings by their label, never by a Home Assistant entity id.
In **shadow mode** the banner says so first, whatever else is going on: the
add-on makes every decision but the battery is not controlled, and every
inverter stays at 0 W. If the banner is red and says a safety stop stays on,
one of the red rows below is a stop that will still be there when shadow mode
ends. That row says how to clear it.
| Row starts with | What it tells you |
|---|---|
| Controller | When the controller last ran. Red when it has stalled: the control board then sets the inverter to 0 W. |
| Meter | The grid reading, its age, readings refused, and how long its value has not changed. |
| Stuck-meter check | Whether the frozen-meter alarm can run. It needs the HomeWizard local source (`homewizard_local`), an inverter rating, and a power range the inverter can reach. *The inverter's own limit* means the setpoint device's range sets the threshold, below `max_w`. |
| Meter reading may be stuck | The frozen-meter alarm is on. See *Meter reading may be stuck* under Notifications. |
| *month*: peak … | This month's peak, and how close it is to the soft limit. |
| Peak guard, Load too high, Battery at its peak reserve | What the capacity-peak guard is doing. *Peak guard: off* means `meter_source` is `off`, so there is no 15-minute average to guard. |
| Battery level, Battery power, Grid power | The reading of that sensor. *No usable reading* means the sensor is missing **or** its reading is held back as too old (a separate stale-reading row then says so). Check it in Developer Tools before replacing it. |
| Inverter control | The setpoint entity, and the power range the inverter accepts. |
| Power request too high, Battery is not keeping up | The two loop alarms, each with its own count since start. After an episode clears, the count stays, ending in *fine now*. See *The winding-loop alarm*. |
| Direction check, Site direction check | The sign checks (SAFETY-02/30). *Opposite for 12 of 60 seconds* counts toward a stop. When it trips, the inverter, or every inverter for the site check, is set to 0 W until you start control. |
| Circulating power check, Inverters worked against each other | SAFETY-31, only with several inverters. |
| Delivery check, *name* is not delivering | SAFETY-42, only with several inverters. |
| Solar production | The PV reading. Sources are numbered in the order of `pv_entities`. The *reversed-sign list* is `pv_invert_entities`. A strongly negative reading by day means that source's sign is reversed. |
| Control | When control last ran. Red when it has stopped running: the control board then sets the inverter to 0 W. |
| Meter | The grid reading, its age, how many readings were refused, and how long its value has not changed. |
| Stuck-meter check | Whether the add-on can warn you about a stuck meter. |
| Meter reading may be stuck | See *Meter reading may be stuck* under Notifications. |
| *month*: peak … | This month's peak, and how close it is to your peak limit. |
| Peak guard, Load too high for battery, Battery at its peak reserve | What the add-on does to keep your peak down. |
| 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 the power range it accepts. |
| *name*: … cannot be controlled, commands refused, “Setpoint entity” is not set | Whether each inverter still takes commands. |
| Power request too high, Battery is not keeping up | See those titles under Notifications. Each shows how often it happened since the add-on started, and *fine now* once it has cleared. In shadow mode the row says what *would* have been sent. |
| Direction check, Site direction check | Whether each inverter's power goes the way it is told. *Opposite for 12 of 60 seconds* counts toward a stop. When it stops, the inverter, or every inverter, is set to 0 W until you start control. |
| Circulating power check, Inverters worked against each other | Only with several inverters. See *Inverters working against each other*. |
| Delivery check, *name* is not delivering | Only with several inverters. See *An inverter is not delivering*. |
| Solar production | Your solar production. Sources are numbered in the order of “Solar production entities, per inverter”. A strongly negative reading by day means that entity reads the wrong way round: add it to “Reversed-sign solar entities”. |
### For installers: status page
The texts are in `app/messages.py`. The full figures of any alarm are on its
ERROR or WARNING line in the add-on log.
- **Stuck-meter check: off** needs `meter_source: homewizard_local` (label
“Where the meter reading comes from”), a `max_w` (“Inverter rating”) and a
power range the inverter can reach. *The inverter's own limit* means the
setpoint device's range sets the threshold, below `max_w`.
- **Peak guard: off** means `meter_source` is `off`, so there is no 15-minute
average to guard.
- **Battery level / Battery power / Grid power** are `soc_entity`,
`batt_entity` and `meter_entity`. *No usable reading* is SAFETY-56: missing
**or** held back as stale, and a separate stale-reading row then says which.
- **Inverter control** is the `setpoint_entity` and the range it accepts.
- ***name* cannot be controlled** (red): every write was rejected for
`LINK_STALE_S`, so the unit is dropped and the others carry its share
(DEV-02). ***name*: commands refused** (amber) is the same before that limit.
***name*: “Setpoint entity” is not set** (amber): a roster entry nobody can
write, so the site refuses to run at part strength and holds 0 W.
- **Direction check, Site direction check** are the sign checks (SAFETY-02/30).
**Circulating power check** is SAFETY-31, **Delivery check** SAFETY-42.
- **Solar production** reads `pv_entity` or `pv_entities` (TEL-11/12). The
*Reversed-sign solar entities* setting is `pv_invert_entities` (TEL-14).
- **Shadow mode** (SAFETY-10): the banner turns red when a latch is up
(circulating power, or a site or per-inverter sign trip), and that latch keeps
its own red row.
## Status entities