TEL-05: read the meter, not Home Assistant's opinion of the meter
A fourth meter_source, `homewizard_local`, polling a HomeWizard P1's own local API (GET /api/v1/data) instead of watching an HA entity. The point is the age sensor. sensor.p1_sample_age_s is FW-01's watchdog input, and on every transport we had it measured "time since the value CHANGED", not "time since the meter REPORTED". Home Assistant offers nothing better: a repeated reading emits no state_changed, advances last_reported on neither serialiser, and state_reported cannot be subscribed to at all. Measured twice - 70 s of a frozen meter on the ENV-01 rig, and ten repeated readings against the live house. Our own capture of this house's meter goes 42.2 s and 97.0 s between changes, both past the default meter_max_age_s of 30, so the age sensor would have commanded 0 W on a perfectly healthy meter. Here every HTTP response is an arrival. The meter answered, now, with its current reading; whether the number moved is not consulted. Five identical readings are five arrivals. Reuses TEL-01's pipeline rather than restructuring it: same split_signed sign convention as ha_signed, same make_sample, same ingest stamping, meter_max_age_s, clock-recomputed age, plausibility bounds and the §20 unsigned-decode rejection. A failed or timed-out poll submits nothing, so it is a missing reading - never 0 W - and does not reset the age. meter_poll_s (default 5 s, the meter's own rate) is checked against meter_max_age_s once at startup, like the ha_signed entity ids. ⚠️ An arrival stamp cannot see a FROZEN meter, and no arrival detector can - one answering 200 OK with a stale number is arriving. The local API does expose what HA never had (the total_power_*_kwh registers stop advancing) and the transport tracks it as `unchanged_s`, but it is deliberately not folded into the age and not thresholded: this controller regulates grid toward ~0 W, and at a converged -10 W the export register needs six minutes to move by its 1 Wh resolution while the power figure legitimately repeats. Thresholding that would rebuild the false-trip limit cycle at the exact operating point we aim for. test_p1.py 179 -> 236 checks. Still defaults to off. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Du77usMj8XNKNFZGmUiWDa
This commit is contained in:
co-authored by
Claude Opus 5
parent
ad9c5772a4
commit
98109a9b91
@@ -45,10 +45,21 @@ options:
|
||||
# integration's entities over the HA WebSocket; mqtt_p1 reads the topic below;
|
||||
# ha_signed reads ONE signed HA entity (+ import / - export), which is what a
|
||||
# HomeWizard P1 publishes and what ha_dsmr cannot consume.
|
||||
# homewizard_local skips Home Assistant entirely and polls the meter's own
|
||||
# local API. ⚠️ It is the ONLY mode whose sensor.p1_sample_age_s measures when
|
||||
# the meter REPORTED rather than when the value last CHANGED - HA emits
|
||||
# nothing at all for a repeated reading - so it is the only mode a firmware
|
||||
# watchdog may threshold. See DOCS.md.
|
||||
meter_source: "off"
|
||||
meter_phases: 1
|
||||
meter_max_age_s: 30
|
||||
meter_mqtt_topic: ""
|
||||
# homewizard_local only. The meter's own address, `host` or `host:port`.
|
||||
p1_host: ""
|
||||
# homewizard_local only. Seconds between polls. Must be well under
|
||||
# meter_max_age_s - the age is never fresher than this interval - and there is
|
||||
# nothing to gain below the meter's own ~5.0 s update rate (NOTES.md:640).
|
||||
meter_poll_s: 5
|
||||
# The two UNSIGNED Belgian registers. The EMS derives net power from them
|
||||
# (import - export); do NOT point these at a signed template sensor.
|
||||
p1_import_entity: ""
|
||||
@@ -109,14 +120,16 @@ schema:
|
||||
batt_invert: bool
|
||||
setpoint_entity: str
|
||||
|
||||
meter_source: list(off|ha_dsmr|mqtt_p1|ha_signed)
|
||||
meter_source: list(off|ha_dsmr|mqtt_p1|ha_signed|homewizard_local)
|
||||
# ⚠️ 2 is accepted by this range but is not a real Belgian connection. A
|
||||
# telegram whose phase count disagrees is rejected at ingest and logged, so a
|
||||
# mis-set 2 shows up immediately as "0 telegrams accepted" rather than as a
|
||||
# quietly wrong number.
|
||||
meter_phases: int(1,3)
|
||||
meter_max_age_s: int(5,300)
|
||||
meter_poll_s: int(1,60)
|
||||
meter_mqtt_topic: str?
|
||||
p1_host: str?
|
||||
p1_import_entity: str?
|
||||
p1_export_entity: str?
|
||||
p1_phase_import_entities:
|
||||
|
||||
Reference in New Issue
Block a user