Normalize Cell Voltages and Compute Spread
Turn a per-cell battery voltage array into min, max, average and the cell imbalance in millivolts, converting millivolt readings to volts automatically.
Who it’s for
Anyone monitoring a multi-cell battery pack - a LiFePO4 or Li-ion storage bank, an EV or e-bike pack, a telecom or solar backup string - whose device (or BMS) reports the individual cell voltages. It turns that raw per-cell array into the four numbers a pack dashboard and its alarms actually use, and it fixes the unit problem (millivolts vs volts) once, on the server, so every widget, chart and rule downstream sees the same correct value.
What it does
Reads one telemetry key holding the per-cell voltages as a JSON array (for example
[3.520, 3.600, 3.550, 3.472]), fixes the units, and writes the lowest, highest and average
cell voltage plus the spread between them:
The spread is the point. A pack can read a healthy total voltage and a confident 100 percent while one
cell quietly drifts out of line. The pack-level number cannot show it, but the spread can, and a
widening spread over time is the earliest sign of a failing pack. Because cellSpreadMv is now a
real telemetry key, an alarm rule can fire on it, a chart can trend it, and a card can display it.
It also normalises units: if the cell readings arrive in millivolts (any value above 100), they are
converted to volts before anything is computed, so cellSpreadMv is correct whether the device sends
3.472 or 3472.
How to set up
- On the device (or asset) that carries the pack, add this calculated field.
- Check the
cellsargument: its Time series key defaults tocellVoltages. Change it if your device publishes the array under a different key. - Post or wait for a telemetry update. The four output keys appear on the entity and update on every new reading.
- Use them: bind
cellMinV/cellMaxV/cellAvgVto a pack widget, trendcellSpreadMvon a time-series or range chart, and raise an alarm whencellSpreadMvcrosses your imbalance threshold.
Suggested imbalance thresholds, derived from the cell’s full voltage (not a single guessed number): advisory at 3 percent of full capped at 120 mV, serious at 5 percent capped at 200 mV. For LiFePO4 that is about 110 / 183 mV, and for Li-ion / NCM, 120 / 200 mV.
How to customize
- To read the array from a different key - change the Time series key on the
cellsargument. - To change what counts as a millivolt reading - open the script and change the
100. Raise it only if you monitor modules above 100 V reported in volts. - To rename the outputs - open the script and rename the
result.*keys.
See also
Trend cellSpreadMv on a Range chart or Time series chart with the two thresholds above to
watch the imbalance over time.
If your BMS reports only the minimum and maximum cell voltage rather than the whole per-cell array, that is the other template - this one reads the array and also gives you the pack average, that one reads the two extremes:
Compute Cell Spread from Min and MaxShare Your Calculated Field with the Community
Built a useful data transformation? Export it as a JSON from ThingsBoard and publish it to the IoT Hub. Share it with thousands of ThingsBoard developers worldwide.