DOC-1: operator docs name the real P1 entity and a roster that starts #119

Merged
admin merged 1 commits from doc-1-operator-docs into release/1.0 2026-09-24 23:42:14 +02:00
Owner

DOC-1. Operator docs told installers to do the wrong thing.

1. Wrong safety entity. The P1 age entity the ESP32 watchdog subscribes to is sensor.goodwe_p1_sample_age, not sensor.p1_sample_age_s. HA builds it from the device name GoodWe (app/mqtt.py DEVICE) plus the entity name P1 sample age, and it matches the id recorded from the live install in tools/rehearsal/announced-reference.txt. Fixed in DOCS.md (heading and 4 mentions) and config.yaml:227. DOCS.md now says not to rename the device or the entity, rather than "the entity id".

2. Roster example wouldn't start. The DOCS.md inverters: example and table now include the required bms_soc_floor (and the table has capacity_kwh). The "three keys required" wording is corrected in DOCS.md and in the config.yaml schema comment.

3. Field guide. build_guide.py now says v0.1.0 is outdated (DOCS.md wins), and its slew_w row says 0 = follow the rail, with faster values refused (SAFETY-39). field-guide.html was regenerated, and the HTML build reproduces byte for byte at base. The PDF was not rebuilt: there is no Chrome on this host and CHROME is a Windows path. FIELD-GUIDE.md and README flag it as outdated. DOCS.md:7 now points to the PDF, and README's non-existent "FIELD-GUIDE.md §10" is now "field guide Step 7b".

New check test_docs.py:

  • The DOCS.md roster example, pasted over config.yaml's shipped options, is accepted by validate_startup_config(). It also has to carry every non-? per-entry schema key and no unknown keys.
  • A precondition confirms it is the roster being graded: without the roster, the example is refused.
  • The documented watchdog entity heading equals the id built from mqtt.DEVICE + the p1_age row, which is also checked against the recorded live id.
  • p1_sample_age_s appears in no shipped doc (DOCS.md, config.yaml, README.md, FIELD-GUIDE.md, build_guide.py, field-guide.html).

Mutations (each red, on a purged copy): drop bms_soc_floor from the example → 1b + 1d red; drop one capacity_kwh → 1d red; DOCS.md from a45ed06 → 1b/1d/2c/2d red; rename the device in mqtt.py → 2b/2c red; wrong id added to README → 2d red; config.yaml from a45ed06 → 2d red.

Suite: 32/32 PASS in goodwe-addon-checks:1 with checks.yml's exact command, on a purged tree mounted :ro.

Not touched: CHANGELOG.md and DECISIONS/TEL-07 still say p1_sample_age_s (history, out of scope).

🤖 Generated with Claude Code

https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU

DOC-1. Operator docs told installers to do the wrong thing. **1. Wrong safety entity.** The P1 age entity the ESP32 watchdog subscribes to is `sensor.goodwe_p1_sample_age`, not `sensor.p1_sample_age_s`. HA builds it from the device name `GoodWe` (`app/mqtt.py` `DEVICE`) plus the entity name `P1 sample age`, and it matches the id recorded from the live install in `tools/rehearsal/announced-reference.txt`. Fixed in DOCS.md (heading and 4 mentions) and config.yaml:227. DOCS.md now says not to rename the device or the entity, rather than "the entity id". **2. Roster example wouldn't start.** The DOCS.md `inverters:` example and table now include the required `bms_soc_floor` (and the table has `capacity_kwh`). The "three keys required" wording is corrected in DOCS.md and in the config.yaml schema comment. **3. Field guide.** `build_guide.py` now says v0.1.0 is **outdated** (DOCS.md wins), and its `slew_w` row says 0 = follow the rail, with faster values refused (SAFETY-39). `field-guide.html` was regenerated, and the HTML build reproduces byte for byte at base. **The PDF was not rebuilt:** there is no Chrome on this host and `CHROME` is a Windows path. FIELD-GUIDE.md and README flag it as outdated. DOCS.md:7 now points to the PDF, and README's non-existent "FIELD-GUIDE.md §10" is now "field guide Step 7b". **New check `test_docs.py`:** - The DOCS.md roster example, pasted over config.yaml's shipped options, is **accepted by `validate_startup_config()`**. It also has to carry every non-`?` per-entry schema key and no unknown keys. - A precondition confirms it is the roster being graded: without the roster, the example is refused. - The documented watchdog entity heading equals the id built from `mqtt.DEVICE` + the `p1_age` row, which is also checked against the recorded live id. - `p1_sample_age_s` appears in no shipped doc (DOCS.md, config.yaml, README.md, FIELD-GUIDE.md, build_guide.py, field-guide.html). **Mutations (each red, on a purged copy):** drop `bms_soc_floor` from the example → 1b + 1d red; drop one `capacity_kwh` → 1d red; DOCS.md from a45ed06 → 1b/1d/2c/2d red; rename the device in mqtt.py → 2b/2c red; wrong id added to README → 2d red; config.yaml from a45ed06 → 2d red. **Suite:** 32/32 PASS in `goodwe-addon-checks:1` with checks.yml's exact command, on a purged tree mounted `:ro`. Not touched: CHANGELOG.md and DECISIONS/TEL-07 still say `p1_sample_age_s` (history, out of scope). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU
admin added 1 commit 2026-09-24 23:33:29 +02:00
- DOCS.md / config.yaml: the watchdog's P1 age entity is
  sensor.goodwe_p1_sample_age (device "GoodWe" + "P1 sample age", as
  app/mqtt.py announces and the live install recorded), not
  sensor.p1_sample_age_s.
- DOCS.md: the inverters: example and per-entry table carry the required
  bms_soc_floor (and capacity_kwh); config.yaml's schema comment says four
  required keys, not three.
- Field guide: marked v0.1.0/outdated; slew_w row no longer recommends the
  1000 W that SAFETY-39 now refuses. HTML regenerated; the PDF is NOT
  rebuilt (no Chrome here). README/DOCS pointers fixed.
- test_docs.py: the documented roster must pass app/validate.py and the
  schema's per-entry keys; the documented entity id must equal the id
  composed from app/mqtt.py; the wrong id may appear in no shipped doc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwRLw7eKYj2byVdwB6kbjU
Author
Owner

Review of DOC-1 (head 29ca9b5): approved and merging.

  • CI is this PR's own run. Run 832, job 1957 shows PRNUM 119 and BASEREF release/1.0. It merged base a45ed06 with head 29ca9b5, and all 32 test files ran and passed, including test_docs.py.
  • The entity id is right. DEVICE["name"] is "GoodWe" (mqtt.py:29) and the row name is "P1 sample age". HA slugifies them together to sensor.goodwe_p1_sample_age, and object_id (p1_sample_age_s) does not decide the id. I checked this against three other sources: tools/rehearsal/live-entities-recorded.txt:38, announced-reference.txt (id and unique_id goodwe_ctl_p1_age), and the stage-4 failsafe firmware, which subscribes with entity_id: sensor.goodwe_p1_sample_age.
  • The roster example validates and the checks catch errors. I ran test_docs.py in the goodwe-addon-checks:1 image and it passed. I then applied 5 mutations of my own, and each one turned it red:
    1. Removing bms_soc_floor from inverter-b fails 1b and 1d.
    2. Putting back the old heading fails 2c and 2d.
    3. Renaming the device to "GoodWe RS485 Controller" fails 2b and 2c.
    4. Setting bms_soc_floor: 150 fails 1d.
    5. Adding the wrong id to README fails 2d.
  • The change is docs only. Nothing changes under app/, and CHANGELOG and the version are untouched. The config.yaml diff is comments only. The anchors I checked in DOCS.md (#tariff-all-optional, the OPT-09 one, and the two-inverters one) all resolve. The README's "Step 7b" reference exists in the guide.

Non-blocking notes:

  • The test's 2b label says "the id recorded from the live install (announced-reference.txt)". That file's own header says it is not a live-registry dump: it records what the build announces. The live anchor is live-entities-recorded.txt. The check itself is still sound. Only the label overstates where the id came from.
  • The FIELD-GUIDE.md note about the CHROME Windows path is fine and useful. The verbosity is acceptable.

Known leftovers, not addressed here: the PDF is still v0.1.0 with slew_w: 1000. The wrong id is still in CHANGELOG.md and DECISIONS/TEL-07, kept as history. The comment at app/mqtt.py:68 still gives the device as "GoodWe RS485 Controller" where it should be "GoodWe".

**Review of DOC-1 (head 29ca9b5): approved and merging.** - **CI is this PR's own run.** Run 832, job 1957 shows PRNUM 119 and BASEREF release/1.0. It merged base a45ed06 with head 29ca9b5, and all 32 test files ran and passed, including `test_docs.py`. - **The entity id is right.** `DEVICE["name"]` is `"GoodWe"` (mqtt.py:29) and the row name is `"P1 sample age"`. HA slugifies them together to `sensor.goodwe_p1_sample_age`, and `object_id` (`p1_sample_age_s`) does not decide the id. I checked this against three other sources: `tools/rehearsal/live-entities-recorded.txt:38`, `announced-reference.txt` (id and unique_id `goodwe_ctl_p1_age`), and the stage-4 failsafe firmware, which subscribes with `entity_id: sensor.goodwe_p1_sample_age`. - **The roster example validates and the checks catch errors.** I ran `test_docs.py` in the `goodwe-addon-checks:1` image and it passed. I then applied 5 mutations of my own, and each one turned it red: 1. Removing `bms_soc_floor` from inverter-b fails 1b and 1d. 2. Putting back the old heading fails 2c and 2d. 3. Renaming the device to "GoodWe RS485 Controller" fails 2b and 2c. 4. Setting `bms_soc_floor: 150` fails 1d. 5. Adding the wrong id to README fails 2d. - **The change is docs only.** Nothing changes under `app/`, and CHANGELOG and the version are untouched. The config.yaml diff is comments only. The anchors I checked in DOCS.md (`#tariff-all-optional`, the OPT-09 one, and the two-inverters one) all resolve. The README's "Step 7b" reference exists in the guide. Non-blocking notes: - The test's 2b label says "the id recorded from the live install (announced-reference.txt)". That file's own header says it is **not** a live-registry dump: it records what the build announces. The live anchor is `live-entities-recorded.txt`. The check itself is still sound. Only the label overstates where the id came from. - The FIELD-GUIDE.md note about the `CHROME` Windows path is fine and useful. The verbosity is acceptable. Known leftovers, not addressed here: the PDF is still v0.1.0 with `slew_w: 1000`. The wrong id is still in CHANGELOG.md and DECISIONS/TEL-07, kept as history. The comment at `app/mqtt.py:68` still gives the device as "GoodWe RS485 Controller" where it should be "GoodWe".
admin merged commit fa3d237ce1 into release/1.0 2026-09-24 23:42:14 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: admin/goodwe-addon#119