Support active control for combined-mode (phase D) batteries#537
Conversation
…pection Phase "D" is combined / whole-home mode (newer Marstek firmware), a valid operating phase — but the CT002 emulator's inspection gate lumped it in with the unassigned "0"/empty diagnostic markers. As a result a combined-mode battery never fired the consumer event, so its Home Assistant discovery never published: the per-battery Distribution Weight, Manual/Auto Target, Active and Min DC Output entities were simply absent, and the battery was never actively steered. Reclassify inspection as "0"/empty/unknown only (A/B/C/D are all valid, steered phases) on both the Python stack and its ESPHome C++ mirror: - A combined battery now fires the event listener → HA discovery + per-battery entities appear, and active control computes a per-consumer target for it. - Its net instructed power is the reported output plus the *whole* target (a combined battery reads the summed grid field 7), not a single phase slot. - Its instructed net power aggregates into the ABC cross-talk bucket like an A/B/C battery, and the ABC count is reported as 1 under active control so it applies its individual target as-is instead of dividing by N. The count=1 override is scoped to a phase-"D" requester so phase-A/B/C responses stay byte-identical. Updates the protocol doc and adds/updates protocol tests; the Python↔ESPHome byte-for-byte parity suite passes. Fixes #536 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V7hfUMC69s8KXiDdRMmi2D
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
WalkthroughCombined/whole-home mode (phase D) is now treated as an actively-steered mode instead of inspection-only across the Python and ESPHome C++ CT002 emulator implementations. Instructed power for phase-D consumers is now the sum of all three phase values, ABC bucket aggregation is active-control aware, and response fields, protocol docs, changelog, and tests are updated accordingly. ChangesCombined/whole-home phase D active control
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 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 Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V7hfUMC69s8KXiDdRMmi2D
Steering evaluation (base vs head)Overall: 0 improved, 0 regressed, 15 unchanged across 15 metrics — mean 0% (unchanged). Priority: priority-weighted 0% (unchanged) — ✅ 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 26.0→26.0s, overshoot 396.6→396.6W, RMS 20.4→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 — |
Summary
Extends active control to combined-mode (phase "D") batteries, which represent newer Marstek firmware running in whole-home mode without per-phase assignment. Previously, phase-D batteries were incorrectly treated as inspection-mode reporters and served only the relay path; now they are recognized as valid, actively-steered operating phases alongside A/B/C.
Key Changes
reported_power + sum(values)rather thanreported_power + values[phase_idx]src/astrameter/ct002/ct002.pyandesphome/components/ct002/ct002.cppImplementation Details
The key insight is that a combined-mode battery reads field 7 (the summed grid power across all phases) and divides it by the ABC count to determine its share. Under active control, we now deliver a per-consumer target in that summed field with count=1, so each battery applies its full target. In relay mode, the real count is forwarded so each battery takes its 1/N share of the aggregate.
The ABC count logic includes a guard scoped to phase-"D" requesters to avoid spuriously setting count=1 on per-phase responses (where the battery ignores it anyway).
Fixes issue #459 (missing Home Assistant entities for combined-mode batteries).
https://claude.ai/code/session_01V7hfUMC69s8KXiDdRMmi2D
Summary by CodeRabbit
New Features
Bug Fixes
Tests