Replies: 5 comments 6 replies
-
|
Maybe this is a related issue: I have a two batteries setup, where each battery has only output 1 connected to the inverter. Due to load distribution, one battery is full a lot earlier than the other - which then triggers the surplus feed-in. Since only Output 1 is connected to the inverter, only the power from input 1 will be passed through. The surplus feed-in also seems to be capped, so that the other battery (that still isn't full), has to provide a lot of the necessary load, while the other kind of idles. This leads to a big waste of energy (One Panel off completely, passthrough of the other panel capped). |
Beta Was this translation helpful? Give feedback.
-
|
You don't need a code change for this, AstraMeter already exposes a per-battery Distribution Weight entity (the A simple approach: map each battery's weight inversely to its SoC so the emptier battery takes the larger share of charging power (neutral alias: AstraMeter – SoC-weighted battery distribution
description: >
Bias AstraMeter's per-battery Distribution Weight by State of Charge so the
emptier battery takes the larger share. Neutral (1.0) at 50% SoC, ~2.0 when
empty, ~0 when full.
mode: restart
trigger:
- platform: state
entity_id:
- sensor.battery_1_soc
- sensor.battery_2_soc
action:
- service: number.set_value
target:
entity_id: number.battery_1_distribution_weight
data:
value: >
{% set s = states('sensor.battery_1_soc') | float(50) %}
{{ [[ (100 - s) / 50, 0] | max, 10] | min | round(1) }}
- service: number.set_value
target:
entity_id: number.battery_2_distribution_weight
data:
value: >
{% set s = states('sensor.battery_2_soc') | float(50) %}
{{ [[ (100 - s) / 50, 0] | max, 10] | min | round(1) }}Swap in your own SoC sensors and the actual One thing to keep in mind: a single weight applies to whatever the balancer is doing at that moment, so "emptier gets more" is ideal for charging (which is the feed-in case you ran into) but is the opposite of what you'd want while discharging. If you also want to bias discharge, you can extend the automation to flip the mapping based on whether the system is currently charging or discharging (e.g. branch on grid/target power sign). |
Beta Was this translation helpful? Give feedback.
-
|
Thanks. I will try. |
Beta Was this translation helpful? Give feedback.
-
|
Very cool project and many thanks! |
Beta Was this translation helpful? Give feedback.
-
|
Works perfect with an automation alias: AstraMeter - SoC-weighted battery distribution (output)
description: >-
Distributes discharge output via Distribution Weight based on deviation
from average SoC. g=2. Runs every 10min AND reactively on SoC change >=5%.
Weight floor 0.3 instead of 0 -> no battery is ever parked (both stay active); guard: only computes
when both SoC values are available (no writes during cloud flicker/unavailable).
triggers:
- trigger: time_pattern
minutes: /10
id: tick
- trigger: state
entity_id:
- sensor.hame_energy_hmj_2_123456789abc_host_battery_soc
- sensor.hame_energy_hmj_2_cba987654321_host_battery_soc
id: soc_jump
conditions:
- condition: numeric_state
entity_id:
- sensor.hame_energy_hmj_2_123456789abc_host_battery_soc
- sensor.hame_energy_hmj_2_cba987654321_host_battery_soc
above: -1
- condition: or
conditions:
- condition: trigger
id: tick
- condition: template
value_template: >-
{% set s3 =
states('sensor.hame_energy_hmj_2_123456789abc_host_battery_soc') |
float(50) %}{% set s4 =
states('sensor.hame_energy_hmj_2_cba987654321_host_battery_soc') |
float(50) %}{% set avg = (s3 + s4) / 2 %}{% set g = 2 %}{% set w3 =
states('number.astrameter_consumer_hmj_2_123456789abc_distribution_weight')
| float(1) %}{% set w4 =
states('number.astrameter_consumer_hmj_2_cba987654321_distribution_weight')
| float(1) %}{% set d3 = s3 - avg %}{% set dl3 = (w3 - 1) * 25 / g
%}{% set d4 = s4 - avg %}{% set dl4 = (w4 - 1) * 25 / g %}{{
(d3-dl3)|abs >= 5 or (d4-dl4)|abs >= 5 }}
actions:
- action: number.set_value
target:
entity_id: number.astrameter_consumer_hmj_2_123456789abc_distribution_weight
data:
value: >-
{% set s3 =
states('sensor.hame_energy_hmj_2_123456789abc_host_battery_soc') |
float(50) %}{% set s4 =
states('sensor.hame_energy_hmj_2_cba987654321_host_battery_soc') |
float(50) %}{% set avg = (s3 + s4) / 2 %}{% set g = 2 %}{{ [[1 + (s3 -
avg) * g / 25, 0.3] | max, 10] | min | round(1) }}
- action: number.set_value
target:
entity_id: number.astrameter_consumer_hmj_2_cba987654321_distribution_weight
data:
value: >-
{% set s3 =
states('sensor.hame_energy_hmj_2_123456789abc_host_battery_soc') |
float(50) %}{% set s4 =
states('sensor.hame_energy_hmj_2_cba987654321_host_battery_soc') |
float(50) %}{% set avg = (s3 + s4) / 2 %}{% set g = 2 %}{{ [[1 + (s4 -
avg) * g / 25, 0.3] | max, 10] | min | round(1) }}
mode: restart |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
-
When running multiple batteries in CT002/CT003 mode, AstraMeter currently distributes load based on fair-share balancing or efficiency optimization — but without any awareness of each battery's State of Charge (SOC), as far I know. This can lead to situations where a battery with very low SOC takes on the full load while a battery with high SOC stays idle.
Proposed Implementation
Add optional SOC entity configuration per battery MAC (e.g. via [CT002] section in config.ini)
Use SOC as a weighting factor in the existing fair-distribution algorithm
Fall back to current behavior if no SOC entities are configured
Beta Was this translation helpful? Give feedback.
All reactions