Every HA notification the add-on raises now has a title of at most 5 everyday words and a one-sentence body; a red alarm may use three so no action is lost. The texts live in app/messages.py, the rule in STYLE.md, and the detail that moved out in DOCS.md "Notifications", which each body links to. No notification_id, trigger or cadence changed. test_messages.py enforces the rule on every notification, fails any notification worded outside app/messages.py, and ratchets the kinds not yet rewritten (rows, banners, refusals, logs, options) through a shrinking allowlist of 200. Six tests re-pinned from prose to meaning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LyR88rXETvwhTgx6yHE39p
208 lines
29 KiB
Plaintext
208 lines
29 KiB
Plaintext
# UX-08 ratchet (test_messages.py part 3). Each line is a user-facing string that
|
|
# does not follow STYLE.md yet: "<kind> <sha1-12 of its text> # where :: start".
|
|
# These are waiting for phase 2b (row, banner), 2c (refusal, option-name,
|
|
# option-desc) and 2d (log). Delete the line when you rewrite the string, because
|
|
# a stale line fails the test. Never add a line for a new string: write the new
|
|
# string to STYLE.md instead.
|
|
|
|
banner c185022e391f # main.py banned: SAFETY-25; option key: peak_soc_floor; capitals: THE PEAK GUARD ONLY :: '{…} - and peak_soc_floor bounds THE PEAK GUARD ONLY (SAFETY-25, see be'
|
|
banner 4a246fc26def # main.py over 12 words (14); capitals: CIRCULATING POWER :: 'CIRCULATING POWER — the inverters were pushing against each other. Sit'
|
|
banner 750ccd4f2126 # main.py over 12 words (14) :: "FAILSAFE — the site's total command opposed the meter. Every inverter "
|
|
banner 637f334f130a # main.py over 12 words (26) :: 'FAILSAFE — the command opposed the meter. Inverter held at 0 W. / FAIL'
|
|
banner 0a3d2d9c4232 # main.py capitals: NOT READY :: "NOT READY — {bad[0].get('banner') or bad[0]['text']}"
|
|
banner dbcc227a9589 # main.py over 12 words (26); capitals: NOT DELIVERING :: 'NOT DELIVERING — {_nd} is standing at a share it is not producing. The'
|
|
log a5e99679fd80 # main.py banned: SAFETY-02, latch :: 'SAFETY-02: the per-inverter store migration did not verify (%s). The l'
|
|
log 128b18b32d86 # main.py over 25 words (41); banned: LATCHED, SAFETY-44, latched :: 'SAFETY-44: this store carries a LATCHED sign-disagreement failsafe und'
|
|
log f60446541ae5 # main.py over 25 words (83); banned: LATCH, LATCHED, SAFETY-02, latch; capitals: LATCH GUARD :: 'SAFETY-02 LATCH GUARD: this store carries a LATCHED sign-disagreement '
|
|
log 04d06bf223c8 # main.py over 25 words (73); banned: REGISTER, SAFETY-37, SAFETY-57, register; capitals: WHICH IS NOT BY ITSELF :: 'SAFETY-37: %s battery-power reading did not move under a command that '
|
|
log aec01642bd07 # main.py banned: SAFETY-57 :: 'SAFETY-57: %s'
|
|
log aebbca17acb3 # main.py over 25 words (52); banned: allocator :: 'write_setpoint() was asked to put %+.0f W on every one of %d inverters'
|
|
log b74c3018461e # main.py over 25 words (30); banned: SAFETY-28, allocator :: 'SAFETY-28 REFUSED a write of %+.0f W to %s: %s. Commanding 0 W instead'
|
|
log cefffafa8b27 # main.py over 25 words (31) :: 'the write of %+.0f W to %s (%s) did not complete in %.0f s and was aba'
|
|
log 1001c6250b85 # main.py over 25 words (29); banned: SAFETY-02 :: 'SAFETY-02 TRIPPED on %s - %s. Commanding 0 W on that inverter and hold'
|
|
log 8252ef5eefad # main.py over 25 words (48); banned: SAFETY-30 :: 'SAFETY-30 TRIPPED at the SITE - %s. That is the SUM of every standing '
|
|
log 8a65cf945e00 # main.py over 25 words (32); banned: SAFETY-31 :: 'SAFETY-31 TRIPPED - %s. Commanding 0 W on every inverter and holding i'
|
|
log 5d2beed2f1a2 # main.py over 25 words (65); banned: HW-01, SAFETY-42; capitals: NOTHING IS COMMANDED DIFFERENTLY :: 'SAFETY-42 TRIPPED on %s - %s. NOTHING IS COMMANDED DIFFERENTLY: this g'
|
|
log d50b775b9cd4 # main.py banned: ARBITER; capitals: ARBITER SCOPE :: 'ARBITER SCOPE: %s'
|
|
log 749c2c6fe81d # main.py over 25 words (26); banned: SAFETY-10, heartbeat; capitals: SHADOW MODE IS ON :: 'SAFETY-10 SHADOW MODE IS ON. The full decision path runs and NOTHING i'
|
|
log 4d271dfc6f1c # main.py banned: SAFETY-10 :: 'SAFETY-10 shadow mode is OFF. This controller is commanding the batter'
|
|
log 730387e0da2b # main.py banned: SAFETY-03 :: 'SAFETY-03 - %s Engagements so far: %d.'
|
|
log 3bf899e99297 # main.py over 25 words (56); banned: SAFETY-03, clamp, clamped, integrator; capitals: STILL RUNNING :: 'SAFETY-03 - %s Silently clipping this is how a winding integrator reac'
|
|
log 78cb6bd09633 # main.py over 25 words (48); banned: SAFETY-07; capitals: STILL RUNNING :: 'SAFETY-07 - %s. The guard is asking for everything the inverter has an'
|
|
log cc735997adc7 # main.py over 25 words (44); banned: SAFETY-24; capitals: STILL RUNNING :: 'SAFETY-24 - %s. The controller is STILL RUNNING and charging is still '
|
|
log ebcb428a70d0 # main.py over 25 words (70); banned: SAFETY-18, arbiter, watchdog; capitals: CHECK THE METER :: 'SAFETY-18 - %s. The grid-following loop is regulating against a number'
|
|
log 38018b887495 # main.py over 25 words (43) :: 'tariff refresh degraded (%s); KEEPING the plan resolved at %s, %.0f s '
|
|
log 0eab1ec96fe8 # main.py capitals: CONTROL LOOP DIED :: 'CONTROL LOOP DIED (%s) - commanding 0 W and exiting with status %d'
|
|
log db529f2c419d # main.py over 25 words (40); banned: SAFETY-02 :: 'SAFETY-02 was TRIPPED on %s before this restart and stays tripped: %s.'
|
|
log c5aadd5c8bf9 # main.py over 25 words (45); banned: SAFETY-42; capitals: NOTHING IS BEING COMMANDED DIFFERENTLY :: 'SAFETY-42 was TRIPPED on %s before this restart and stays tripped: %s.'
|
|
log d72bbdb7e595 # main.py over 25 words (39); banned: SAFETY-30 :: 'SAFETY-30 (site) was TRIPPED before this restart and stays tripped: %s'
|
|
log 8b880e65a7c3 # main.py over 25 words (38); banned: SAFETY-31 :: 'SAFETY-31 was TRIPPED before this restart and stays tripped: %s. Every'
|
|
log 23f58b7f305c # p1.py:1264 over 25 words (30) :: 'meter_poll_s %.1f leaves no room under meter_max_age_s %.1f: one misse'
|
|
log 88a7251e842b # p1.py:470 banned: telegram :: 'P1 telegram rejected: %s'
|
|
log 0dd83d6dfaf4 # price.py over 25 words (30) :: 'the feed published no price for %d of %d instants (index %s); those in'
|
|
log bcfd7062e28e # price.py over 25 words (79); banned: §8 :: 'price_feed_url is set, so %s is requesting %s exactly as given and is '
|
|
log b57bc6de4a6b # price.py over 25 words (47); banned: validate.py :: 'price_taxes_profile cannot be used (%s: %s), so this fetch has NO tax '
|
|
log d5595aaaacc4 # price_history.py banned: §8 :: 'price history at %s is %s - starting from empty. §8.3 carry-forward ha'
|
|
log dbed0b8e35ea # static_tariff.py banned: validate.py :: 'static_profile is unusable (%s); no cheap window. This should have bee'
|
|
log 8fbe9f5407ea # static_tariff.py over 25 words (28); banned: §1, §6 :: '§11.4: %s, and no static_profile is configured to fall back to. The pl'
|
|
log 4ce29e043d89 # static_tariff.py banned: §1 :: '§11.4: %s - falling back to the static profile, plan marked PROVISIONA'
|
|
log a3c7c9719ed2 # store.py capitals: LOST STATE :: 'per-inverter store migration LOST STATE and has not been marked done: '
|
|
log 5b537a77052b # validate.py over 25 words (41); banned: arbiter, saturation :: 'integrator_max_w %.0f W is above max_w %.0f W. Not refused - the arbit'
|
|
log 12ae40f9d289 # validate.py over 25 words (73); banned: arbiter, clamp, clamps :: 'maintenance_discharge_w %.0f W is above max_w%s %.0f W. Not refused - '
|
|
log c6dc799502cf # validate.py over 25 words (32) :: '%s carries negative levies %s EUR/kWh. That is accepted, but a tax com'
|
|
log 1688a7478ceb # validate.py over 25 words (36) :: 'price_formula is filled in but price_provider is %r, so the coefficien'
|
|
log f37f9fce4433 # validate.py over 25 words (96) :: '%s has no "card" block, so its coefficients are UNGRADED: nothing reco'
|
|
log 396fbdd009c2 # validate.py over 25 words (52); banned: §1 :: "price_provider is %r but static_profile is empty. §11.4's degradation "
|
|
log 37bba6ed37e3 # validate.py capitals: REFUSING TO START :: 'REFUSING TO START: the add-on configuration is not usable.'
|
|
option-desc b927826d01f0 # en.yaml over 30 words (112); capitals: LEAVING IT OFF DOES NOT TURN THE PRICE FEED OFF :: 'Charge in the cheapest published hour and discharge in the dearest, bu'
|
|
option-desc b98c42e34df7 # en.yaml over 30 words (34) :: 'The reserve price trading may not spend. Deliberately not the same key'
|
|
option-desc 84e054da385b # en.yaml over 30 words (39) :: 'Off by default. Leave it off until the site has been commissioned: wit'
|
|
option-desc 0f55d3b37afa # en.yaml over 30 words (38); banned: 0x0518, register, watchdog :: "The sensor that reports this inverter's own battery power, positive wh"
|
|
option-desc 307afdd74f84 # en.yaml over 30 words (98); banned: 0x0560, Register; capitals: GW5000S-BP :: "MEASURED, not chosen: the percent at which the pack's OWN battery mana"
|
|
option-desc 4da37ff6250d # en.yaml over 30 words (66); banned: SAFETY-31; capitals: TWO OR MORE INVERTERS ONLY :: 'TWO OR MORE INVERTERS ONLY. DERIVED (SAFETY-31): 75 s is fifteen contr'
|
|
option-desc db464169ed66 # en.yaml over 30 words (144); banned: SAFETY-31; capitals: TWO OR MORE INVERTERS ONLY :: 'TWO OR MORE INVERTERS ONLY; with one inverter the quantity is identica'
|
|
option-desc df9735452fa1 # en.yaml over 30 words (88); banned: OPT-08; capitals: THIS ONE IS NOT DERIVED FROM :: 'What one full round trip costs per kWh: wear on the pack plus conversi'
|
|
option-desc 8147a82a437e # en.yaml over 30 words (51) :: 'A deadline on the gap between cycles, reset by every cycle. On a healt'
|
|
option-desc cb66f230ef63 # en.yaml over 30 words (45); banned: register :: 'Errors smaller than this are ignored. ⚠️ The deadband is a one-way rat'
|
|
option-desc 4167af90cfc2 # en.yaml over 30 words (288); banned: SAFETY-42, delivery_window.py, saturation; capitals: TWO OR MORE INVERTERS ONLY :: 'TWO OR MORE INVERTERS ONLY; with one inverter this check cannot fire a'
|
|
option-desc 3c0898cc1149 # en.yaml over 30 words (63) :: 'What you are paid for feeding a kWh back into the grid, all in. One nu'
|
|
option-desc 05560996cb2e # en.yaml capitals: MEASURED ON REAL HARDWARE :: 'How much of the remaining error the loop corrects each cycle. MEASURED'
|
|
option-desc f225d7a8f3a5 # en.yaml over 30 words (32); banned: watchdog :: 'How often the setpoint is rewritten even when it has not changed. It m'
|
|
option-desc ef70d16a93bd # en.yaml over 30 words (98); banned: clamp, saturation :: 'Caps how much stale error can be waiting to unwind when the sign flips'
|
|
option-desc bde7357af38d # en.yaml over 30 words (107); capitals: EMPTY DOES NOT MEAN :: 'Leave this empty unless the site really has more than one inverter. EM'
|
|
option-desc 217c5ae9599c # en.yaml over 30 words (66); banned: 0x0560, register :: "The percent at which THIS pack's own battery management system cuts ou"
|
|
option-desc 746a0f9ae506 # en.yaml over 30 words (143) :: "THIS pack's usable capacity in kilowatt-hours, from its datasheet or i"
|
|
option-desc cb6ad204f59d # en.yaml over 30 words (52) :: 'The supervised ceiling on what may be written to THIS inverter; the si'
|
|
option-desc 46142bcc1ab1 # en.yaml over 30 words (36); banned: heartbeat, latch :: 'A short identifier for this inverter, for example inverter-a. It gives'
|
|
option-desc d787e9f2454d # en.yaml over 30 words (63); banned: arbiter; capitals: MUST STAY AT OR BELOW :: '⚠️ MUST STAY AT OR BELOW the inverter rating, and the add-on refuses t'
|
|
option-desc a90fced63631 # en.yaml over 30 words (52); banned: CLAMPED :: 'How fast the cycle drains the pack; the surplus is exported. Above the'
|
|
option-desc ab58c8fae4fb # en.yaml over 30 words (57); capitals: THIS IS NOT THE PEAK GUARD :: 'The depth the monthly recalibration deliberately goes to, once a month'
|
|
option-desc 73f51bdd3d6e # en.yaml over 30 words (83); capitals: THIS IS YOUR NUMBER :: 'THIS IS YOUR NUMBER, not a derived one: the hard ceiling on what may e'
|
|
option-desc dd9023e6c812 # en.yaml over 30 words (45); capitals: POSITIVE MUST MEAN DRAWING FROM THE GRID :: "The net grid power sensor, used when the meter source is 'off'. POSITI"
|
|
option-desc aa5b929f3c22 # en.yaml over 30 words (114); banned: SAFETY-18, latch; capitals: NOT CHOSEN :: 'MEASURED, NOT CHOSEN (SAFETY-18). How long the meter may keep answerin'
|
|
option-desc 1b3038c5c9e5 # en.yaml over 30 words (46) :: 'Beyond this the grid figure counts as missing. On its own it does not '
|
|
option-desc bbf26329f056 # en.yaml over 30 words (48); banned: telegram, telegrams :: 'Must match your connection. A telegram whose phase count disagrees is '
|
|
option-desc 92da72e54e77 # en.yaml over 30 words (52) :: "For meter source homewizard_local only. 5 s is the meter's own update "
|
|
option-desc 24f329136309 # en.yaml over 30 words (84) :: "'off' keeps the single Home Assistant entity below, which is what an e"
|
|
option-desc 47e5fa0dba52 # en.yaml banned: register :: 'The UNSIGNED injection register, the counterpart of the import registe'
|
|
option-desc 9b8f5ea6c656 # en.yaml banned: 192.168.2.250 :: "For meter source homewizard_local only: the meter's own address on you"
|
|
option-desc d5d3e30ac4d2 # en.yaml over 30 words (37); banned: register :: 'The UNSIGNED consumption register. Do not point this at a signed templ'
|
|
option-desc 0b05d89400ba # en.yaml over 30 words (39) :: 'For meter source ha_signed only. ONE signed sensor: positive is drawn '
|
|
option-desc e74a5db257e1 # en.yaml over 30 words (46) :: 'For meter source ha_signed only. Optional, in L1..L3 order, each signe'
|
|
option-desc 3f07a88a61fd # en.yaml over 30 words (34); capitals: THIS IS YOUR NUMBER :: 'THIS IS YOUR NUMBER: the quarter-hour average demand the peak guard tr'
|
|
option-desc 6ec195081ef9 # en.yaml over 30 words (112); banned: SAFETY-24; capitals: IT BOUNDS THE PEAK GUARD ONLY :: 'DERIVED, not picked (SAFETY-24): the reference pack holds 13.8 kWh usa'
|
|
option-desc 228fdc168458 # en.yaml over 30 words (270); capitals: INJECTION IS EXEMPT FROM VAT :: 'Optional, and only if your supplier pays you a price that moves with t'
|
|
option-desc 98987808a7f0 # en.yaml over 30 words (98); capitals: WHAT YOU TYPE IS SENT EXACTLY AS WRITTEN :: "Leave empty to use the chosen source's own feed. Only a host that sour"
|
|
option-desc 26f17751b2f7 # en.yaml over 30 words (234); capitals: IN THE UNITS THE CARD PRINTS :: "For price source custom_formula only: your own contract's two coeffici"
|
|
option-desc 011841a82d7d # en.yaml over 30 words (34) :: "Your supplier's margin. The add-on adds it ONLY when the chosen price "
|
|
option-desc d34ef16ba99a # en.yaml over 30 words (63) :: 'The older way of getting a price, kept because retiring it would take '
|
|
option-desc c70929091e71 # en.yaml over 30 words (252); capitals: SWITCHING THIS ON IS WHAT STARTS THE PRICE FETCH :: "Where day-ahead or real-time prices come from. 'off' is what ships, an"
|
|
option-desc a62e17ccf445 # en.yaml over 30 words (230); banned: TARIFF-18; capitals: THIS NUMBER IS NOT :: 'Everything on your bill that is not the energy itself - distribution, '
|
|
option-desc 56d56f58c43e # en.yaml over 30 words (206); capitals: THE NUMBERS HERE ARE THE LEVIES ALONE :: 'Leave this empty unless your network tariff really does charge a diffe'
|
|
option-desc 313bdd035b0b # en.yaml over 30 words (193); capitals: MEASUREMENT ONLY :: 'Optional, and MEASUREMENT ONLY - it changes no control behaviour whats'
|
|
option-desc 4172d9920d65 # en.yaml over 30 words (128); capitals: MEASUREMENT ONLY :: 'Optional, and MEASUREMENT ONLY - it changes no control behaviour whats'
|
|
option-desc 09ceba2c6afb # en.yaml over 30 words (70); banned: clamp; capitals: MEASUREMENT ONLY :: 'Optional, MEASUREMENT ONLY. Some sensors - typically a kWh meter or a '
|
|
option-desc 42a7eaac6ff1 # en.yaml banned: saturated :: 'How many consecutive saturated cycles before the loop stops winding up'
|
|
option-desc 12b0dffec9dd # en.yaml over 30 words (42) :: 'The gap between what was commanded and what the inverter delivers that'
|
|
option-desc 91fd58c08a59 # en.yaml over 30 words (54) :: 'The ESPHome number entity this add-on writes the power setpoint to, no'
|
|
option-desc 01e1af709cd5 # en.yaml over 30 words (201); banned: arbiter, clamps, heartbeat, latch :: 'Runs the whole decision path — strategies, arbiter, clamps and guards '
|
|
option-desc 96b077d4e2e9 # en.yaml over 30 words (72); banned: SAFETY-02; capitals: NOT CHOSEN :: 'MEASURED, NOT CHOSEN (SAFETY-02). How long the setpoint and the meter '
|
|
option-desc addf5c495ae8 # en.yaml over 30 words (90); banned: SAFETY-02, watchdog; capitals: NOT CHOSEN :: 'MEASURED, NOT CHOSEN (SAFETY-02). Both the setpoint being emitted and '
|
|
option-desc 0a66ac772b27 # en.yaml over 30 words (117); banned: SAFETY-30; capitals: TWO OR MORE INVERTERS ONLY :: 'TWO OR MORE INVERTERS ONLY. DERIVED FROM 1890 CLOSED-LOOP TEST RUNS (S'
|
|
option-desc c0deabb69ab6 # en.yaml over 30 words (60); banned: SAFETY-30; capitals: TWO OR MORE INVERTERS ONLY :: 'TWO OR MORE INVERTERS ONLY. The same 300 W as the single-inverter thre'
|
|
option-desc 7d7272743277 # en.yaml over 30 words (123); banned: SAFETY-39; capitals: MEANS FOLLOW THE INVERTER RATING :: 'How far the setpoint may move in one control cycle. ⚠️ 0 MEANS FOLLOW '
|
|
option-desc 436efca21a7d # en.yaml over 30 words (31) :: "The sensor that reports the pack's state of charge in percent. Use the"
|
|
option-desc 9ac8a3b21a1e # en.yaml over 30 words (43) :: 'How long the inputs may be missing before the add-on commands 0 W. Wit'
|
|
option-desc 86cbfd6a5693 # en.yaml over 30 words (130); capitals: RECOMMENDED EVEN ON :: 'Your fixed or day/night contract, written as a single line of JSON. RE'
|
|
option-desc 996dffbf563d # en.yaml over 30 words (74); banned: register :: 'What the meter should sit at when nothing is happening; negative means'
|
|
option-desc faf346256008 # en.yaml over 30 words (52); banned: SAFETY-30; capitals: TWO OR MORE INVERTERS ONLY :: 'TWO OR MORE INVERTERS ONLY. DERIVED FROM 1890 CLOSED-LOOP TEST RUNS (S'
|
|
option-desc 5323134f3131 # en.yaml over 30 words (95); banned: SAFETY-30, saturation; capitals: TWO OR MORE INVERTERS ONLY :: 'TWO OR MORE INVERTERS ONLY; with one inverter this setting does nothin'
|
|
option-name ca3a62bb8260 # en.yaml over 6 words (7) :: 'Circulating-power hold (s) — derived, do not change'
|
|
option-name edee163fdc2b # en.yaml over 6 words (7) :: 'Circulating-power threshold (W) — measured, do not change'
|
|
option-name 99b3beeab621 # en.yaml over 6 words (7) :: 'Cost of one full charge/discharge cycle (EUR/kWh)'
|
|
option-name cccd8a42f51a # en.yaml over 6 words (8) :: 'Not-delivering report after (s) — derived, do not change'
|
|
option-name 989891e2ce23 # en.yaml over 6 words (10); banned: Integrator :: 'Integrator bound (W, 0 means the same as the rating)'
|
|
option-name 42c6b595320c # en.yaml over 6 words (9) :: 'Inverter list (leave empty if you have one inverter)'
|
|
option-name 230e6dc9d872 # en.yaml over 6 words (7) :: 'Hour of day a due cycle starts'
|
|
option-name 18e1de907c54 # en.yaml over 6 words (8) :: 'Frozen-meter alarm after (s) — measured, do not change'
|
|
option-name 9071c4cfa460 # en.yaml over 6 words (7) :: 'A reading counts as stale after (s)'
|
|
option-name e3d06ed93e2e # en.yaml banned: register :: 'Export register entity (W)'
|
|
option-name a0f59ea5de36 # en.yaml banned: register :: 'Import register entity (W)'
|
|
option-name ed757924f40f # en.yaml over 6 words (7) :: 'Per-phase signed net entities (L1, L2, L3)'
|
|
option-name 52d03808da01 # en.yaml over 6 words (8) :: 'Your own INJECTION formula (one line of JSON)'
|
|
option-name bf22f2121af4 # en.yaml over 6 words (8) :: 'Your own tariff formula (one line of JSON)'
|
|
option-name 5593992fcf5b # en.yaml over 6 words (7) :: 'How far ahead to fetch prices (hours)'
|
|
option-name d9fee5514a4b # en.yaml over 6 words (11) :: 'Levies and VAT by time of day (one line of JSON)'
|
|
option-name 7d8d691905e0 # en.yaml over 6 words (7) :: 'PV production entities, one per inverter (W)'
|
|
option-name eac7ee084aaa # en.yaml banned: Saturated :: 'Saturated cycles before freezing (count)'
|
|
option-name 5c6bbc5cab40 # en.yaml banned: Saturation :: 'Saturation threshold (W)'
|
|
option-name 99a1ec154d36 # en.yaml over 6 words (7) :: 'Shadow mode — run every decision, command nothing'
|
|
option-name 82fcd0faa687 # en.yaml over 6 words (8); banned: watchdog :: 'Sign watchdog hold (s) — measured, do not change'
|
|
option-name 8fc34172dc01 # en.yaml over 6 words (8); banned: watchdog :: 'Sign watchdog threshold (W) — measured, do not change'
|
|
option-name 8516934704f5 # en.yaml over 6 words (8) :: 'Site-wide sign hold (s) — derived, do not change'
|
|
option-name 2b8278ab2b16 # en.yaml over 6 words (8) :: 'Site-wide sign threshold (W) — measured, do not change'
|
|
option-name bd52e795ea97 # en.yaml over 6 words (8) :: 'Command 0 W after inputs missing for (s)'
|
|
option-name 9e33febf4481 # en.yaml over 6 words (8) :: 'Fixed or day/night tariff (one line of JSON)'
|
|
option-name 40e1e3ba3841 # en.yaml over 6 words (8) :: 'Per-inverter sign hold (s) — derived, do not change'
|
|
option-name 4ba7087578dc # en.yaml over 6 words (8) :: 'Per-inverter sign threshold (W) — derived, do not change'
|
|
refusal 87620efa0704 # p1.py:1176 banned: telegram :: 'p1_phase_net_entities has {len(phase_net)} entities but meter_phases i'
|
|
refusal 5d1b8147792b # p1.py:1186 banned: 192.168.2.250 :: "meter_source {SOURCE_HOMEWIZARD} needs p1_host (the meter's own addres"
|
|
refusal 701db346696d # validate.py over 30 words (85); banned: SAFETY-30, watchdog :: 'unit_sign_disagree_w is {unit_sign_w} W but max_w{unit_where} is {weak'
|
|
refusal 710b4d89a9d7 # validate.py over 30 words (88); banned: ARBITER, arbiter; capitals: THE CEILING WINS :: 'maintenance_charge_w is {charge_w} W but max_w{maint_where} is {maint_'
|
|
refusal 16d40434116b # validate.py over 30 words (193); banned: NOTES.md, §5; capitals: THE PLANT WINS :: 'slew_w is {slew_w} W against a site rail of {rail} W, so the loop cros'
|
|
refusal 613375fb6b5f # validate.py over 30 words (107); banned: SAFETY-07; capitals: THE BMS WINS :: "peak_soc_floor is {soc_floor} % but the pack's own cut-out (bms_soc_fl"
|
|
refusal ba21c5ba8c0d # validate.py over 30 words (224); banned: TARIFF-07, §1; capitals: IT HAS NEVER FETCHED :: 'price_provider is {pid}, which WAS a shipped plugin and has been WITHD'
|
|
refusal de8df32186b6 # validate.py over 30 words (46); banned: §1 :: 'price_provider is {pid}, which is not a shipped plugin. The ids that e'
|
|
refusal 0ee7c15eafef # validate.py over 30 words (103); banned: arbitrage.py, main.py, static_tariff.py; capitals: THE HOME ASSISTANT ENTITIES WIN :: "price_provider is {pid} AND {' and '.join(ha_price)} {'is' if len(ha_p"
|
|
refusal c4149a762c39 # validate.py over 30 words (62); banned: main.py; capitals: THE HOME ASSISTANT ENTITIES WIN :: "static_profile is set AND {' and '.join(ha_price)} {'is' if len(ha_pri"
|
|
refusal 6af34466bbc2 # validate.py over 30 words (83); capitals: THE TABLE WINS :: '{TAXES_PROFILE_OPTION} is set AND price_taxes_eur_kwh is {scalar} rath'
|
|
refusal 8f69bdbbf3fc # validate.py over 30 words (55) :: '{TAXES_PROFILE_OPTION} carries {steep} EUR/kWh. Belgian levies and dis'
|
|
refusal 96a090d2ad97 # validate.py over 30 words (72); banned: DOCS.md, §1 :: "price_provider is 'custom_formula' but price_formula is empty, so the "
|
|
refusal db9d0d53c4f1 # validate.py over 30 words (45); banned: §1 :: "cycle_cost_threshold_eur is {opts.get('cycle_cost_threshold_eur')} and"
|
|
refusal 58ccb3bbd560 # validate.py over 30 words (63); banned: §1; capitals: NO PRICES AT ALL :: "arbitrage_enabled is on but price_provider is 'off' and static_profile"
|
|
refusal 780592c897fb # validate.py over 30 words (85); banned: arbitrage.py, telegram, §9 :: "arbitrage_enabled is on but meter_source is 'off', so there is no P1 t"
|
|
refusal 4f80c091ca95 # validate.py over 30 words (69) :: 'arbitrage_soc_floor is {floor} % and arbitrage_soc_ceiling is {ceiling'
|
|
refusal 0c089bb2f200 # validate.py over 30 words (57); banned: §1 :: "price_provider is 'manual_csv' but price_csv_path is empty, so the off"
|
|
refusal 152dfec79224 # validate.py over 30 words (48); banned: SAFETY-02, heartbeat, latch :: '{where} has no name. Every inverter needs one: the Store namespaces th'
|
|
refusal eb14af760f5c # validate.py over 30 words (51); banned: SAFETY-02, heartbeat, latch :: '{where} and {seen[name]} are both called {name}. The Store keys every '
|
|
refusal 36f53c989b4a # validate.py over 30 words (55) :: '{who} has no setpoint_entity, so this add-on cannot command it. It wou'
|
|
refusal c98c6ab66e9f # validate.py over 30 words (56) :: "{who} has no usable max_w (got {entry.get('max_w')}). It is the superv"
|
|
refusal 5ca16a4d0a1e # validate.py over 30 words (71) :: '{who} has capacity_kwh {raw}, which is not a usable number of kilowatt'
|
|
refusal 63a864d2e0a3 # validate.py over 30 words (73) :: "capacity_kwh is stated on {', '.join(stated)} and left empty on {', '."
|
|
refusal 8d82500ecb1d # validate.py over 30 words (64) :: 'setpoint_entity is set to {flat_sp} AND an inverters list of {len(entr'
|
|
refusal 3d778e0ab5e1 # validate.py over 30 words (36); capitals: THE DEVICE WINS :: '{name}: max_w is {cap} W but {entity} accepts at most {float(dev_max)}'
|
|
refusal ecd0883f5649 # validate.py over 30 words (36); capitals: THE DEVICE WINS :: '{name}: max_w is {cap} W, so this controller may command {-cap} W, but'
|
|
refusal eff7efac51f8 # validate.py over 30 words (56); banned: heartbeat :: 'setpoint_entity is not set, so this add-on has no actuator: every writ'
|
|
refusal b126f1a88b77 # validate.py over 30 words (76); banned: §1 :: '{len(who)} configured writers can reach the one actuator {actuator}: {'
|
|
refusal 07a88756c864 # validate.py over 30 words (48); banned: arbiter :: 'max_w is {max_w} W and must be positive - it is a magnitude, not a sig'
|
|
refusal c4a1d0371e31 # validate.py over 30 words (42); capitals: THE DEVICE WINS :: "max_w is {max_w} W but {opts.get('setpoint_entity') or 'the setpoint d"
|
|
refusal a15624d1aa10 # validate.py over 30 words (33); capitals: THE DEVICE WINS :: 'max_w is {max_w} W, so this controller may command {-max_w} W, but {op'
|
|
refusal 26d0602c32d7 # validate.py over 30 words (79); capitals: THE FIRMWARE WINS :: 'meter_max_age_s is {max_age_s} s but the ESP32 firmware vetoes any P1 '
|
|
refusal 2ade09aaa579 # validate.py over 30 words (73); banned: SAFETY-02, arbiter, watchdog :: 'sign_disagree_w is {sign_w} W but max_w{where} is {weakest} W, so the '
|
|
row c24ab8bd9cb3 # main.py over 15 words (18); banned: heartbeat, layer 1; capitals: NO PASS FOR :: 'control loop: NO PASS FOR {_pass_age} s (layer 1 zeroes the inverter a'
|
|
row c771d4bc1e0a # main.py over 15 words (17); banned: telegrams :: "P1 meter ({o.get('meter_source')}): {self.p1.net_w} W, {age} s old, {s"
|
|
row f6195fee8575 # main.py over 15 words (33); capitals: METER MAY BE FROZEN :: 'METER MAY BE FROZEN - {…}. The loop is STILL FOLLOWING it and is still'
|
|
row db05be7cd99c # main.py over 15 words (16); option key: meter_source; capitals: NOT COVERED :: "freeze detector: NOT COVERED on meter_source {o.get('meter_source')} -"
|
|
row 9a21960bbbe8 # main.py capitals: NOT COVERED :: 'freeze detector: NOT COVERED - {…}'
|
|
row c38b746a6585 # main.py banned: SATURATED; capitals: PEAK GUARD SATURATED :: 'PEAK GUARD SATURATED - {…}'
|
|
row dd0629834473 # main.py over 15 words (36); banned: SAFETY-25; option key: peak_soc_floor; capitals: THE PEAK GUARD ONLY :: '{…}. NOTE: peak_soc_floor bounds THE PEAK GUARD ONLY - it is not a pac'
|
|
row 4132e246e675 # main.py over 15 words (26); banned: telegrams; option key: meter_source; capitals: NOT COVERED :: "peak guard: NOT COVERED on meter_source {o.get('meter_source')} - the "
|
|
row 7b34b16d8bb2 # main.py over 15 words (61) :: '{label}: no usable value this cycle from {entity} - and this row canno'
|
|
row 04e0381f16c2 # main.py banned: CLAMP; capitals: OUTPUT CLAMP ENGAGED :: 'OUTPUT CLAMP ENGAGED - {…} Engagements: {self.clamp_wd.engagements}.'
|
|
row 9f8b8adcbc6c # main.py banned: INTEGRATOR; capitals: LOOP AT INTEGRATOR BOUND :: 'LOOP AT INTEGRATOR BOUND - {…} Engagements: {self.clamp_wd.engagements'
|
|
row f00cc9688eca # main.py over 15 words (20); banned: clamp :: 'output clamp: not engaged now, but it has engaged {self.clamp_wd.engag'
|
|
row a44333431331 # main.py over 15 words (31); capitals: SIGN-DISAGREEMENT FAILSAFEX :: 'SIGN-DISAGREEMENT FAILSAFE{tag} - {…}. The inverter is held at 0 W. Fi'
|
|
row 3ef4e60f2328 # main.py over 15 words (17) :: 'sign watchdog{tag}: armed{vs} (trips after {inv.sign_wd.cfg.hold_s} s '
|
|
row 9f879b339282 # main.py over 15 words (50); banned: integrator; capitals: SITE SIGN-DISAGREEMENT FAILSAFE :: 'SITE SIGN-DISAGREEMENT FAILSAFE - {…}. EVERY inverter is held at 0 W. '
|
|
row 96e93e34bdbf # main.py over 15 words (24); banned: watchdog :: 'site sign watchdog: armed against the sum of the commands (trips after'
|
|
row 9ee8d293fea5 # main.py over 15 words (38); capitals: CIRCULATING POWER :: 'CIRCULATING POWER - {…}. EVERY inverter is held at 0 W. The meter cann'
|
|
row 55eb950acd5f # main.py over 15 words (17); banned: watchdog :: 'circulation watchdog: armed (trips after {self.circ_wd.cfg.hold_s} s o'
|
|
row 1817192a7f1c # main.py over 15 words (42); capitals: NOT DELIVERINGX :: 'NOT DELIVERING{tag} - {…}. Nothing has been commanded differently and '
|
|
row 685c1416364b # main.py over 15 words (26) :: 'delivery watchdog{tag}: armed (reports after {inv.delivery_wd.cfg.hold'
|
|
row d3cd52827dd0 # main.py over 15 words (29); banned: watchdog :: 'delivery watchdog: n/a at one inverter - a unit short of its share is '
|
|
row d6981c8d7b56 # main.py banned: latched :: 'no e-stop fitted: if this host dies the battery stays latched at its l'
|
|
row 685c8f02c97a # main.py capitals: NO SITE TOTAL :: 'PV production: NO SITE TOTAL - {…}. Reporting: {…}'
|
|
row abef339bf192 # main.py over 15 words (25); option key: pv_entities :: 'PV production: `pv_entities` is set, so `pv_entity` is IGNORED - the {'
|
|
row 514511bd0a93 # main.py over 15 words (32); option key: pv_invert_entities :: 'PV production: {ent} reads {watt} W - far below zero, so its sign is p'
|
|
row 328abd6171ce # main.py over 15 words (22); option key: pv_invert_entities :: 'PV production: `pv_invert_entities` names {ent}, which is not a PV ent'
|