I’ve been working on a custom battery aggregation service for the Cerbo GX to solve the “split-personality” issue when running multiple independent BMS units. Instead of relying on SmartShunt estimates or a single battery’s data, this service creates a Virtual Battery on the DBus that the system uses for its primary logic.
The core philosophy is “Safety through the lowest common denominator.” While individual batteries remain visible in the overview, the aggregation passes a conservative, unified value to the system based on real-time bms data rather than a single shunt value.
The service (running via /service/bms-aggregator) polls all connected BMS units every 2 seconds. It calculates the system state using two primary functions:
Aggregated SOC: It tracks the lowest SOC across all units (e.g., if your bank is 93%, 84%, and 82%, the system operates at 82%). This ensures the inverter doesn’t over-discharge the weakest link.
Dynamic Charge Limiting (DCL): This is the “brain” of the service. It monitors the percentage spread between units and cell voltage deltas (>0.2V). It then dynamically scales the com.victronenergy.battery/280 charge limit to force balancing:
<5% Imbalance: 100% Current (150A nominal)
5-10% Imbalance: 85% Current (128A)
10-15% Imbalance: 66% Current (99A)
>15% or Spike Detected: Throttles to 33% (50A) and triggers a Red Alert.
By passing these values directly to the DBus, the system protects itself. If a cell spikes or a battery drifts, the aggregation automatically throttles the charger to give the internal balancers time to work. As the batteries equalize, the service “unlocks” more current until you’re back at full power.
It’s essentially a “set it and forget it” way to manage a complex battery bank without worrying about one unit hitting a high-voltage disconnect while the others are still hungry for a charge.
One of mine charges and discharges faster than the other two as well.
The config allows you to easily tune the setup. On default settings the system will only warn you if the batteries are more than 15% difference soc.
All thresholds are configurable and easily adapted per the config.
Tbh it’s brand new. It’s been running for about 48h and 2 half cycles. I have to see how my config works out in my insurance. However I assumed that the applied logic would be the most versatile for a wide range of systems.
The problem is that dbus will pass default information. So if the “cells” show out of range data, the cerbo itself triggers the alarm. I thought this would be better than allowing a larger gap to develop.
My cells have adaptive charge control so my end goal it to use that specific logic to slow a battery down to let the other charge more/longer.
in my experience - especially when charging - most important value is cell voltage the system has to reduce or cut off charging if one cell reaches the limit
Could your program do that? maybe send some screenshots?
The charger logic handles that already. I just have to present the charger with a base soc, temp etc. The controller and charge curve or ESS or hub4 handles the rest.
Do your batteries have any adaptive current limiting in place? Are the able to regulate themselves?
what do you mean by adaptive current limiting? The BMS could be either on or off - no way to regulate current individual - there is only the general current, provided by the MP2
I think the simplest solution for your system would be to set up logic to trigger the battery disconnect switch as soon as a battery reaches 100% soc. Leaving the others to finish charging and only reconnect for loads.
In your case, at least one battery will always be on your grid, either charging or discharging. If one is full, it should disconnect itself with a relay to let the other finish charging.
The diybms from stuart pittaway is an excellent implementation that easily does this, and afaik it can handle 127?? cells.
Its added safety.
If your batteries have the ability to disconnect if something goes wrong then there’s that extra security that they wont burn down your house. That is the core function of most victron products, safety automation.
The ibms, or battery safety controller add that functionality that cheap consumer bms boards don’t provide. Especially when charging at a few hundred amps, things can go wrong very fast. And for a long time the only protection core protection that the Tesla power-wall 1 or some of the early 18650 packs had was 1a fuses welded on the end of their cells to hinder thermal runaway. From there the concept grew that there had to be another way to stop aeroplanes from crashing when the tail burnt off because the generator charged the battery at minus 50c. One solution was to work with patented polymers that raised the price of a lipo pack by 700%. Or LTO cells came back into popularity as a result, not only for their crank power but they could be charged and discharged at minus 70c.
Or you can work with a simple disconnect. For houses, motor-homes and boats that was usually enough.
I bet your bms supports a disconnect switch, so for the price of @100 euros, you can get a high-end 300a relay. Then set up your bms to trigger the relay when the battery is full, reconnect if the other battery is under load, or reconnect when the second battery is full and not charging. You could even do it with two tiny arduinos.
Simple.
Is one protocol better than the other? People have been arguing about that for years, and sure its fine until the house burns down or someone gets killed because your battery didn’t have a disconnect.
In Germany, you are only allowed to have approved batteries on board; otherwise, your insurance coverage is voided, and along with it, your operating license. It is like transporting hazardous materials without authorization. If anything happens, you could end up spending a long time in prison, depending on the severity.
But okay, I’ve played the devil’s advocate for long enough now.