feat: weight power distribution by battery capacity (kWh)#1194
feat: weight power distribution by battery capacity (kWh)#1194Nicolas-nwb wants to merge 1 commit intoZendure:masterfrom
Conversation
The power distribution formula uses `pwr_max * SOC` to calculate each device's share. This ignores total energy capacity, causing unfair distribution when mixing batteries of different sizes (e.g. SolarFlow 2400AC with 17 kWh vs Hyper 2000 with 4 kWh). Multiply the weight by `max(d.kWh, 1.0)` so that larger batteries receive proportionally more charge/discharge power. Backward compatible: - Same-capacity batteries: kWh factor cancels out, no behavior change - Single battery: weight ratio is always 100%, no change - kWh not yet known (0.0): fallback to 1.0, original behavior preserved - Physical power limits (pwr_max) still enforced via min()/max() caps Addresses Zendure#806, Zendure#1084
|
I did not test this is real life, but the goal of the current software, is that all batteries are discharged at more or less the same electriclevel. Is that not the case? Would in your case not 1 device to all the work? I am just trying to understand, I do not have the same configuration as you... |
|
Hi FireSon, thanks for taking the time to review this PR! This is my first contribution to the project, so I appreciate the feedback. You're right that the current software tries to discharge all batteries at the same SOC level. The issue is that with batteries of very different capacities, equal SOC does not mean equal energy contribution. Here's a concrete example from my setup:
Both are at 70% SOC, but the 2400AC holds 4.25x more energy. Without the kWh factor, the weight formula With the kWh factor, the 17 kWh battery naturally receives more power, which means both batteries actually reach the same SOC at the same time. The kWh weighting doesn't fight the SOC balancing goal; it makes it work correctly for mixed-capacity setups. To address your concern about one device doing all the work: no, because the SOC term is still in the formula. As a battery discharges and its SOC drops, its weight decreases, so the other batteries progressively take over. Both batteries still participate and absorb peaks together: if there's a large charge or discharge spike, the power is split across all active batteries proportionally to their capacity, which also reduces stress on individual devices. For setups where all batteries have the same capacity, the kWh factor cancels out (same multiplier on both sides), so it changes absolutely nothing. Possible improvement: the current formula uses total |
|
I just checked the actual implementation and created a EXCEL-Sheet for this. But in my opinion, the capacity is implizit already included. All batteries are empty at nearly the same time. So I don't think there is a need for changing that. (I did not include the checking on optimal_power, which will change only slightly the result). |
|
Hi @harrymayr Thanks, Your math is correct: without minSoc, all batteries do reach 0% at roughly the same time. However, in practice, batteries stop discharging when they hit
Discharge_Distribution_with_minSoc.xlsx At 13:00, both Hypers cross below 10% and go The theoretical convergence to 0% is real, but With the kWh factor, the SF carries more of the load (proportional to its 17 kWh vs 4 kWh), so all batteries cross 10% within ~40 minutes of each other instead of 1h40. The house stays closer to 3500W for longer. You can try it yourself: I attached your spreadsheet with just the two extra columns added. Change B6 to any minSoc value and see the impact. For setups where all batteries have the same capacity, the kWh factor cancels out (same multiplier on both sides), so it changes absolutely nothing. Possible improvement: the current formula uses total |
|
Both EXCEL files are not "correct". I added now the limiting at the discharge_limits and the starting of devices according to the optimal_power. |
|
You're right, at lower demand where one device can handle it alone, the kWh factor doesn't change anything. The benefit only shows up when multiple devices discharge together at higher demand, which is my use case. And for setups where all batteries have the same capacity, the kWh multiplier is identical on both sides, so it cancels out completely: zero behavioral change. That said, I think mixed-capacity setups will become more and more common as the project grows. I started with a Hyper 2000 myself and later added a SolarFlow 2400AC. It's a natural upgrade path, and this change would make the transition smoother for anyone doing the same. I'm happy to keep this on my fork if you'd rather not merge it. Either way, thanks for taking the time to analyze it in detail. I came here to improve power distribution and ended up leveling up my Excel skills too! |


Problem
When mixing batteries of different capacities (e.g. SolarFlow 2400AC with 17 kWh and Hyper 2000 with 4 kWh), the power distribution is unfair. The current weight formula
pwr_max * SOCignores total energy capacity, so a 17 kWh battery only receives ~56% of discharge power despite holding ~73% of the total stored energy.This has been reported in #806 and #1084.
Solution
Multiply the distribution weight by
max(d.kWh, 1.0)so that larger batteries receive proportionally more charge/discharge power.New formula:
weight = pwr_max × SOC × max(kWh, 1.0)6 lines changed in
manager.py:powerChanged()— weight accumulation for charge and dischargepower_charge()— per-device power calculation and weight decrementpower_discharge()— per-device power calculation and weight decrementBackward compatibility
max(0.0, 1.0) = 1.0→ original behaviormin(pwr, d.pwr_max)/max(pwr, d.pwr_max)capsTest results
Tested on a real setup with 3 batteries (SolarFlow 2400AC 17 kWh + 2× Hyper 2000 4 kWh):
The larger battery now carries the bulk of the discharge, which is the expected behavior given its much higher stored energy. Peak power limits (2400W / 1200W) are still respected.