Auto-convert kW/MW/mW power sensors to watts, reject non-power units - #573
Conversation
|
Warning Review limit reached
Next review available in: 16 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
WalkthroughChangesPower unit handling
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Possibly related PRs
Sequence Diagram(s)sequenceDiagram
participant ESPHomeSensor
participant CT002Component
participant HomeAssistant
ESPHomeSensor->>CT002Component: Report reading and declared unit
CT002Component->>CT002Component: Convert reading to watts
CT002Component->>HomeAssistant: Publish watt reading
sequenceDiagram
participant HomeAssistant
participant PowerEntity
participant PowerMeter
HomeAssistant->>PowerEntity: Send state and unit attributes
PowerEntity->>PowerEntity: Persist unit across partial updates
PowerEntity->>PowerMeter: Provide entity value
PowerMeter->>PowerMeter: Convert value to watts or raise ValueError
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XFuVf6AqbQSPdie9gwvtyZ
Steering evaluation (base vs head)Overall: 5 improved, 1 regressed, 9 unchanged across 15 metrics — mean +0.3% (worse). Priority: priority-weighted +0.6% (worse) — ✅ no do-no-harm guardrail regressions. Lower is better for every metric. See Metrics are the per-scenario mean of 5 seeds. Aggregate — mean across 32 scenarios
📊 Interactive grid-power charts (zoom / hover / toggle series) are in the self-contained What do these metrics mean?
Per-scenario tables (32 scenarios)full_battery_low_pace — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 29.1→29.1W
mixed_cadence/eff — settle 50.8→50.8s, overshoot 164.5→164.5W, RMS 21.9→21.9W
mixed_cadence/fair — settle 47.7→47.7s, overshoot 70.4→70.4W, RMS 12.9→12.9W
mixed_cadence_solar/eff — settle 52.5→52.5s, overshoot 384.7→384.7W, RMS 28.6→28.6W
mixed_cadence_solar/fair — settle 56.0→56.0s, overshoot 75.4→75.4W, RMS 23.7→23.7W
mixed_venus_b2500/eff — settle 81.2→81.2s, overshoot 221.9→221.9W, RMS 18.6→18.6W
mixed_venus_b2500/fair — settle 75.4→75.4s, overshoot 231.1→231.1W, RMS 22.3→22.3W
phase_imbalance — settle 53.4→53.4s, overshoot 145.2→145.2W, RMS 30.3→30.3W
single_venus_d_solar — settle 24.2→24.2s, overshoot 94.4→94.4W, RMS 15.9→15.9W
single_venus_d_steps — settle 26.3→26.3s, overshoot 90.3→90.3W, RMS 15.5→15.5W
single_venus_d_washer — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 61.0→61.0W
single_venus_drain — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 907.3→907.3W
single_venus_fill — settle 360.0→360.0s, overshoot 0.0→0.0W, RMS 953.6→953.6W
single_venus_noisy — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 94.3→94.3W
single_venus_pv — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 60.8→60.8W
single_venus_solar — settle 26.8→26.8s, overshoot 80.3→80.3W, RMS 17.8→17.8W
single_venus_solar_slow — settle 33.9→33.9s, overshoot 68.3→68.3W, RMS 22.8→22.8W
single_venus_steps — settle 26.0→26.0s, overshoot 88.0→88.0W, RMS 14.7→14.7W
single_venus_steps_slow — settle 40.5→40.5s, overshoot 98.5→98.5W, RMS 14.8→14.8W
single_venus_trace — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 278.9→278.9W
single_venus_washer — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 61.0→61.0W
two_venus/eff — settle 18.1→18.1s, overshoot 126.1→126.1W, RMS 14.0→14.0W
two_venus/fair — settle 18.4→18.4s, overshoot 116.7→116.7W, RMS 13.8→13.8W
two_venus_noisy/eff — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 94.3→94.3W
two_venus_noisy/fair — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 94.2→94.2W
two_venus_slow/fair — settle 41.8→41.8s, overshoot 174.5→174.5W, RMS 14.0→14.0W
two_venus_solar/eff — settle 28.7→26.0s, overshoot 252.7→396.6W, RMS 20.5→20.4W
two_venus_solar/fair — settle 25.9→25.9s, overshoot 151.4→151.4W, RMS 20.4→20.4W
two_venus_trace/eff — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 283.1→283.1W
two_venus_trace/fair — settle 0.0→0.0s, overshoot 0.0→0.0W, RMS 282.1→282.1W
venus_d_plus_c/eff — settle 20.1→20.1s, overshoot 128.9→128.9W, RMS 14.7→14.7W
venus_d_plus_c/fair — settle 21.6→21.6s, overshoot 121.0→121.0W, RMS 14.6→14.6W
📊 Open the interactive report — |
A grid-power source reporting kW was silently misread as W in both stacks (#39, #572): typical household magnitudes round to ~0 W on the wire, the batteries idle, and nothing hints at a unit mismatch. ESPHome ct002: - FINAL_VALIDATE_SCHEMA rejects power_sensor_lX references whose declared unit_of_measurement is not a power unit (°C, %, kWh, ...) with an explicit config-time error. - to_code passes a per-phase unit scale (kW→1000, MW→1e6, mW→0.001) to the firmware, applied where sensor callbacks fill the raw-value cache. - Sensors with no declared unit keep the historical assume-watts behavior, but the firmware now logs a one-shot warning after 10 consecutive nonzero sub-1 W readings — the signature of a kW feed misread as W. Python HomeAssistant powermeter: - Tracks each entity's unit_of_measurement from the subscribe_entities snapshot, attribute diffs, and the REST bootstrap. - Converts kW/MW/mW states to watts at read time; rejects non-power units with a clear ValueError instead of feeding wrong values downstream. Docs note that a manual ×1000 workaround must be removed on kW sensors, since the value would now be scaled twice. Closes #572 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XFuVf6AqbQSPdie9gwvtyZ
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XFuVf6AqbQSPdie9gwvtyZ
467259f to
5839280
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/astrameter/powermeter/homeassistant.py`:
- Around line 333-342: Update _update_entity_unit to distinguish complete
snapshots/REST payloads from partial “+” attribute diffs: clear the cached
_entity_units entry when a complete payload omits _ATTR_UNIT_OF_MEASUREMENT,
while preserving it for diffs that omit the key. Add a reconnect regression test
covering an initial kW unit followed by an unqualified state that uses the watts
default.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: a3253f6d-5f1a-4493-a1c7-77238fc474f0
📒 Files selected for processing (13)
CHANGELOG.mdCONTRIBUTING.mddocs/esphome-powermeters.mddocs/installation/esphome.mddocs/powermeters.mdesphome.example.yamlesphome/components/ct002/__init__.pyesphome/components/ct002/ct002.cppesphome/components/ct002/ct002.hsrc/astrameter/powermeter/homeassistant.pysrc/astrameter/powermeter/homeassistant_test.pytests/components/ct002/test.1phase.yamltests/components/ct002/test_codegen.py
A unit learned from an earlier snapshot survived _reset_for_reconnect and would keep scaling values after the entity stopped declaring one (e.g. reconfigured from kW to unitless). Full attribute payloads (snapshot/REST) now replace the recorded unit — clearing it back to the watts default when absent — while partial '+' diffs still only touch it when the key itself is present. Adds reconnect and full-snapshot regression tests. Addresses CodeRabbit review on #573. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XFuVf6AqbQSPdie9gwvtyZ
* Share one power-unit list between the meter and the sensor picker The unit auto-conversion added in #573 taught the Home Assistant powermeter to read W, kW, MW and mW. The dashboard's sensor picker kept its own copy of that list, still saying "W or kW" — so an MW or mW sensor was hidden from the guided form, and one already configured was reported as "Not found in Home Assistant right now." Both sides now read `astrameter.power_units`, a leaf module so the picker cannot pull in the powermeter package (whose `__init__` cycles back through the config loader). A `device_class: power` entity whose unit the meter refuses is still offered — a mislabelled template sensor is exactly the entity someone goes looking for — but it is marked "not a power unit" in the list, and choosing it says AstraMeter cannot read it instead of looking resolved. The multiplier field now warns that a kW sensor is converted on its own, since a leftover 1000 there scales the reading twice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CWw7pRCh73ZpbEMwc66TqA * Fall back to the entity id when a sensor has no friendly name HaEntity.name is optional, so an entity without one rendered "undefined reports kWh". The suggestion list already fell back; the row's help line now does too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CWw7pRCh73ZpbEMwc66TqA --------- Co-authored-by: tomquist <528585+tomquist@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Summary
Fixes silent misreading of kilowatt-scale power sensors as watts, which caused typical household readings to round to ~0 W and left batteries idle with no error. Both the ESPHome component and Home Assistant powermeter now:
Key Changes
ESPHome Component (
esphome/components/ct002/)POWER_UNIT_SCALESdict mapping power units to conversion factors_power_unit_scale()and_validate_power_unit()helpers to validate and extract unit scales from sensor configFINAL_VALIDATE_SCHEMAhook rejects non-power units at config validation time with clear error messagesto_code()callsset_power_unit_scale()for each phase when a unit is declaredset_power_unit_scale()setter, per-phaseunit_scale_andunit_declared_arrays, and a kW-suspicion heuristic (logs warning when undeclared sensor shows sub-1 W readings) as a runtime safety netHome Assistant Powermeter (
src/astrameter/powermeter/homeassistant.py)unit_of_measurementper entity in_entity_unitsdict_update_entity_unit()extracts and validates units from both initial snapshots and state diffs_get_entity_value()applies the unit scale at read time; rejects non-power units with a clear errorunit_of_measurementleaves the recorded unit untouched)Tests
Documentation & Examples
docs/powermeters.md,docs/installation/esphome.md,docs/esphome-powermeters.mdto document unit handlingesphome.example.yamland test YAML with unit examples and commentsCHANGELOG.mdwith user-facing summaryImplementation Details
Addresses issues #39 and #572.
https://claude.ai/code/session_01XFuVf6AqbQSPdie9gwvtyZ
Summary by CodeRabbit
New Features
kW,MW, andmWare automatically converted to watts.Bug Fixes
Documentation