Skip to content

[#100/#102] Expose phase information to dashboard + strategies, optional assignment of batteries to phases - #139

Open
nickles-lee wants to merge 7 commits into
gitcodebob:mainfrom
nickles-lee:102-phase-assignments-for-batteries
Open

[#100/#102] Expose phase information to dashboard + strategies, optional assignment of batteries to phases#139
nickles-lee wants to merge 7 commits into
gitcodebob:mainfrom
nickles-lee:102-phase-assignments-for-batteries

Conversation

@nickles-lee

@nickles-lee nickles-lee commented Jun 3, 2026

Copy link
Copy Markdown

Summary

  • Added optional manual battery-to-phase assignment for Marstek M1-M6:

    • Unassigned
    • L1
    • L2
    • L3
  • Added dashboard support:

    • Overview battery headings now show assigned phase, e.g. Marstek M1 - Phase 1
    • Added Battery Phase Interaction overview for live L1/L2/L3 battery power
    • Phase selectors live only on the Config/Advanced tab
    • Added shared Max phase power setting for future/custom phase-aware strategies (defaults to 5500W / 25A @ 220V nominal)
  • Added Home Assistant helpers/sensors:

    • input_select.marstek_m1_phase through input_select.marstek_m6_phase
    • input_number.house_battery_control_max_phase_power
    • sensor.house_battery_l1_power
    • sensor.house_battery_l2_power
    • sensor.house_battery_l3_power
  • Added optional install-specific per-phase grid power aliases in house_battery_control_config.yaml:

    • sensor.p1_meter_l1_power
    • sensor.p1_meter_l2_power
    • sensor.p1_meter_l3_power
  • Updated Node-RED flows to expose:

    • battery.phase
    • msg.grid_power_limit_phase
    • nullable msg.grid_power_phase.L1/L2/L3
  • Adds a .gitignore for .DS_Store, for any contributors running MacOS

Closes #100
Closes #102

Notes:

The new phase data is exposed for dashboards, future logic, and adventurous custom strategy authors. Built-in strategies do not yet use per-phase limits or perform phase-aware balancing. Doc updates + more extensive testing will be needed before it's safe to actually use this information.

Testing:

  • Deployed to my HomeAssistant install & validated that flows behave as expected
  • YAML parse passed
  • Node-RED JSON validation passed with jq
  • pwsh -File contribute/check.ps1 passed with ALL CHECKS PASSED

Screenshots:

Home Page - Shows phase info in headers + adds a "total battery phase interaction" block:

image

Home Page - Batteries with unassigned phase have old headers:
image

Config Page - Adds setting for "max power per phase" (currently not included in any strategies) + phase assignments

image

Timeline

  • Between work & family commitments, it's tough to find an hour or two every now and then to progress the PR & it may sit idle for a while (or will require co-authors to jump in)

@SuperTus

SuperTus commented Jun 3, 2026

Copy link
Copy Markdown

Thank you so much!
I greatly appreciate your work and invested time and I hope the phase based balancing and phase overload protection functionality will someday be realized. A small improvement proposal; the transition in the EU from 220V to 230V started in 1989 and was completed in 2004. The default max phase power could be safely raised to 25A x 230V = 5750W.
Is this important, well no, but I regularly max out (and beyond) all 3 phases when my car and ESS batteries are charging simultaneously because price valleys usually only last a few hours, so every amp/watt counts 😀.

@nickles-lee

Copy link
Copy Markdown
Author

The default max phase power could be safely raised to 25A x 230V = 5750W.

IMO, we might want the default set to 5500W to allow for some amount of safety margin for the average user, and people comfortable with running at exactly the rated limit (or having short periods above the current rating of their fuse) can always adjust as needed.

More correctly:

  • Overall power limits are likely a concern for Belgian users that don't want to pay a higher CAPTAR rate.
  • Per-phase current limits are probably more of a universal concern for NL/BE/DE users, but it's yet another entity to expose + pass through + support, and we'd have to sprinkle in unit conversions to a ton of strategies

My personal phase-monitoring dashboard is oriented more towards current, since that's what the fuse is rated on. IIRC, it's also what Zaptec uses for their charger throttling as well.

image

@nickles-lee

nickles-lee commented Jun 3, 2026

Copy link
Copy Markdown
Author

Emoji straw-poll for anyone with opinions:

🚀 - let's add in current-monitor entities + plan to include the unit-conversions in the implemented strategies
🎉 - Let's stick to using the simpler power-based entities + calculation

I'm fine going with either approach, but I'm not keen on adding complexity without others wanting it.

@SuperTus

SuperTus commented Jun 3, 2026

Copy link
Copy Markdown

Controlling based on current is certainly the intention, although I prefer this to be the calculated current, based on actual voltage and power of each phase, since the p1 meter does not provide decimals for the amperes per phase. I would like to participate in your poll but do not sufficiently understand what you mean by both options. It is my fault, so don't take it personally.

@nickles-lee

Copy link
Copy Markdown
Author

I did some additional reading:

  • DSMR meters report wattage in 1W increments & amperage in whole (1A) increments.
  • P1 readers like the Homewizard generally will present amperage as a derived power / voltage value, rather than what the meter exposes

If we did eventually support amperage-based phase protection, it's therefore probably best to stick to power entity inputs, additionally collect voltage entity inputs, and then add a "max phase current" setting.

@Wimpie-ccc

Copy link
Copy Markdown

Thanks for implementing this!!

Ideally, I would also like a "max phase current" setting. The main circuit breaker trips on to much current, not power.

Voltage fluctuates a lot here, I see 235V to 245V (and more) regulary while PV is injecting current.

@nickles-lee

nickles-lee commented Jun 9, 2026

Copy link
Copy Markdown
Author

TODO: AC Power should be used for the phase-aggregates in the dashboard, rather than battery power.

@nickles-lee

Copy link
Copy Markdown
Author

Defer to another PR, at another time: Also consider exposing the P1 power readings so that it's possible to see at a glance how loaded each phase is AND what the batteries are doing.

@nickles-lee

Copy link
Copy Markdown
Author

Ready for review / merge

nickles-lee added 2 commits August 14, 2026 16:48
main re-exported both `01 start-flow.json` and `all-flows-in-one-file.json`
from Node-RED with entirely new node IDs (only 3 of 620 base IDs survive in
the combined file), so the textual conflicts were not meaningful. Both flow
files were resolved by taking main's export as the new baseline and
re-applying this branch's changes against the remapped IDs:

  - 6 new nodes: Phase template, Phase, Max phase power,
    Normalize phase limit, Phase grid power, Normalize phase power
  - "Mapping": normalize + emit battery.phase
  - "Loop end": clean up msg.battery_phase / msg.template
  - "Energy max" -> Phase template (phase lookup ahead of Mapping)
  - "Export limit" -> Max phase power (phase chain ahead of Battery Strategy)
  - group "Peak shave settings": +4 members, widened to 1642

Verified main made no semantic change to any node this branch touches, so
the remap is the whole conflict.

house_battery_control.yaml: kept the new phase-assignment binary sensor and
accepted main's removal of the dynamic-v1 "Is below threshold cheapest
period tariff" sensor (nothing references it anymore).

.gitignore: union of both sides, de-duplicated .DS_Store.

contribute/check.ps1 passes.
"Phase template" and "Phase" carried g="Loop" (the battery information loop)
but were never listed in that group's nodes[], and sat outside its bounds.
Node-RED drives the runtime from the wires, so this was editor-only: the
nodes did not move or collapse with the group.

Add both to the group and widen it from 1612 to 1942, keeping the group's
existing 96px right padding. The parent "Get batteries information" group
grows 1678 -> 2008 so it still contains the nested group with its original
margin; no other group on the tab is overlapped.

Applied to both 01 start-flow.json and all-flows-in-one-file.json.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants