Skip to content
Stand with Ukraine flag

Battery cell voltage monitor

  • Widget
  • 6 installs
  • v1.0.0
  • Aug 28, 2026
  • MIT license
  • v4.2+
Battery cell voltage monitor

Shows each cell’s voltage in a multi-cell battery pack, flags the weakest cell and the imbalance in millivolts, and warns while the pack total reads full.

Widget Type
  • Latest
Category
  • Cards & Info
Use Cases
  • Smart Energy
  • Predictive Maintenance
  • Solar Monitoring
  • Asset Tracking
  • Fleet Tracking

Who it’s for

Anyone watching a multi-cell battery pack — a LiFePO4 or Li-ion storage bank, an EV or e-bike pack, a solar or telecom backup string — asks which cell is dragging the pack down, and why a pack that reads full keeps delivering shorter runtimes. A pack total answers neither: it stays healthy right up until the weakest cell collapses. This card is where you look at the cells instead of the total.

What it does

A 16-cell LiFePO4 string reports a pack total of 56.36 V at an average of 3.523 V — both healthy, and a pack-level card would stop there. Drawn cell by cell, cell 4 sits at 3.472 V against cell 11 at 3.600 V: a spread of 128 mV, enough to turn the verdict chip amber while the pack total still reads full.

  • Every cell on a zoomed axis. The frame runs from the lowest cell to the highest plus a small margin, so a few millivolts of spread is visible instead of a row of identical bars. Small packs draw numbered tiles, and larger packs draw a bar row.
  • The weak cell by number. The lowest and highest cells are marked with their cell number, so a technician knows which link to put a meter on rather than only that something is off.
  • The spread in millivolts, beside the pack voltage and the average cell voltage.
  • The cell count the widget actually parsed. 16S for a sixteen-cell string. An array that arrives short draws as 15S instead of being charted as though it were the whole pack.
  • An imbalance verdict derived from the chemistry. Amber past the advisory threshold, red past the serious one — computed from the cell’s full voltage rather than one guessed millivolt figure, and both relax near the top of a charge where the curve naturally pushes cells apart.
  • Pack context when your BMS sends it. State of charge, current, power, temperature, capacity, cycle count and state of health, each appearing only when its key arrives.
  • Shows the pack as it stands right now: it does not chart the spread over time, and it does not balance cells or command the BMS.

Requirements

A device that reports the individual cell voltages — a BMS, a battery gateway, or anything that publishes them as one JSON array or as a key per cell. A pack total alone is not enough: the card draws cells, and the spread it measures does not exist at pack level. Server-side attributes work as well as telemetry, which matters on a hosted tenant where an attribute is the value an operator can write without a device token.

How to set up

Data keys

KeyRoleTypeDescription
cellVoltages (user-configured)Per-cell valuesTimeseries or AttributeA JSON array of numbers, for example [3.305, 3.306, 3.305, 3.298]. Volts and millivolts are both accepted and auto-detected. One key carries a pack of any length
one key per cell (user-configured)Per-cell valuesTimeseries or AttributeThe alternative shape. Each cell is bound as its own data key on the Data tab and read in bind order, with its own history and time period
packVoltage (user-configured)Pack summary rowTimeseries or AttributeThe pack total, in volts
soc current power temperature capacity cycles soh (user-configured)Stats stripTimeseries or AttributeOne key per entry in the context strip

Cell data source picks between the two shapes, and it is the first setting in the Data tab. The array is the default because one key means one timestamp: every cell in the pack is read at the same instant, and a spread computed across that snapshot is a real spread. Independent per-cell keys cannot promise that — each arrives on its own — but they are ordinary data keys, so each cell carries its own history, time period and unit. Choose the array for a BMS that publishes the pack in one message, and one key per cell for a device that reports its cells separately.

The per-cell key is the only one the card cannot do without — without it nothing renders. Every other key is optional: an unbound one hides its own row, or its own entry in the stats strip, and leaves no empty slot behind. A server-side attribute works as well as a telemetry key, which matters on a hosted tenant where an attribute is the one an operator can write without a device access token.

Data

SettingDefaultEffect
Cell data sourceOne JSON array key for the whole packThe array is one key with one timestamp, an atomic snapshot of the pack; one key per cell binds each cell as an ordinary data key, with its own history
Per-cell voltages key (JSON array)cellVoltagesThe single key that carries the whole pack. Hidden when the source is one key per cell
Cell voltage unitAuto-detectPins volts or millivolts rather than relying on the guess. One cell can override it in its own data-key settings
Bind optional telemetry keysOffReveals the pack-level key fields below. An installer who has only cell voltages never opens them
Show pack summary rowOnDraws the pack total and average, and reads Pack voltage key
Pack voltage keypackVoltageThe pack total feeding that row
Show the stats strip (SoC, current, cycles, etc.)OnDraws the context strip and reads the seven keys below it
State of charge key (%), Current key, Power key (W), Temperature key, Capacity key (Ah), Cycle count key, State of health key (%)soc, current, power, temperature, capacity, cycles, sohOne key per entry. Bind only what your device sends

Battery

SettingDefaultEffect
Chemistry presetLi-ion / NCMDerives the imbalance thresholds and the balance-start voltage from the cell’s full voltage. Li-SOCl2, CR2032, Li-ion / NCM, LiFePO4, Alkaline, NiMH, Lead-acid 12 V or Custom
Imbalance advisory (mV)from the presetThe amber threshold. Shown under Custom only; every named chemistry derives it
Imbalance serious (mV)from the presetThe red threshold, the same way
Balance-start voltage (per cell)from the presetThe point above which both thresholds relax. Custom only, like the two above

Each preset carries the cell’s full voltage, and the thresholds are derived from it — three per cent of full for the advisory, five per cent for the serious one, each capped at 120 mV and 200 mV:

PresetFull voltageAdvisory / seriousBalance-start
Li-ion / NCM4.20 V120 / 200 mV4.00 V
LiFePO43.65 V110 / 182 mV3.45 V
Li-SOCl23.67 V110 / 184 mVnot applicable
CR20323.40 V102 / 170 mVnot applicable
Alkaline1.60 V48 / 80 mVnot applicable
NiMH1.45 V44 / 73 mVnot applicable
Lead-acid 12 V12.64 V120 / 200 mVnot applicable
Customyoursyoursyours, if the chemistry needs one

The cap is why a Li-ion cell and a 12 V lead-acid block end up on the same 120 / 200 mV, though their voltages differ by a factor of three.

How to customize

  • To widen or tighten the zoom around the cells — set Axis margin around cells (mV).
  • To keep numbered tiles on a larger pack — raise Show tiles up to this many cells. Six by default — above it the card draws a bar row.
  • To read the cells without a verdict — turn off Show verdict chip.
  • To be told when the reading has aged — set Stale after (minutes, 0 = off). The card dims and the chip reads Stale. It ships off, and the footer prints the age of the reading either way, as Last updated 13s ago or Last updated 2h 10m ago. On a card too narrow for three labels the words drop and the age stays.
  • To match the type to your dashboard — set Pack name font, Value font and Cell count and caption font. Each follows the dashboard until you set it.

Tips

  • Read the spread, not the total. The pack voltage and the state of charge are the two numbers a pack-level card already gives you, and they are the two that stay healthy longest. The spread moves first. Everything else on the card is there to tell you whether that spread means anything yet.

  • A tall bar is not a full cell. The axis frames the real minimum-to-maximum window plus a margin, which is why 128 mV across cells sitting near 3.5 V fills the height of the card. Read the bars against each other, not against the top of the frame. A zero-based axis would draw sixteen identical bars and show nothing, which is exactly why this card does not use one.

  • The extremes are numbered so you can act on them. Knowing a pack is 128 mV out tells you to raise a ticket. Knowing it is cell 4 tells the technician which link to put a meter on.

  • Check the cell count in the header. 16S is how many cells the widget parsed, not how many you own. A sixteen-cell pack drawing as 15S means the array arrived short or a key is mistyped.

  • A wide spread near full charge is less alarming than the same spread at rest. Cells push apart while the balancer works at the top of a charge, so the thresholds relax above the balance-start voltage. The same spread on a pack sitting at rest is the one to chase.

  • Half the chemistries carry no balance-start voltage, and that is deliberate. Relaxing the verdict near a full charge only makes sense where there is something to charge and where the curve turns steep at the top — the lithium chemistries a BMS actually balances. Li-SOCl2, CR2032 and alkaline cells are primary: they are never charged, so there is no top of charge to relax around. NiMH is charged, but termination is read from a voltage drop and from temperature rather than from a per-cell threshold. The lead-acid preset describes a whole 12 V block, which is equalised at block level rather than balanced cell by cell. For all of them the spread is taken at face value, at any point in the charge.

  • A backup string sits float-charged for months and reads full the whole time, while a cell losing capacity surfaces only under load — usually during the outage the bank exists for. Watch the spread while the pack is idle: it moves weeks before the total does.

  • Cell voltages tell you the pack’s internal health. They do not tell you whether the device carrying that pack is still reporting, how strong its link is, or when it was last heard from — and a silent gateway looks exactly like a healthy pack until somebody checks. Put the two side by side:

${item-link:d7931040-8f49-11f1-a1b4-f1800178e9a1}

For the spread over time, which is the earliest failure signal a pack gives, derive it as a calculated field and chart that — an alarm rule can then fire on it. When your BMS sends the raw per-cell array, one field on the hub normalizes it and computes the spread:

${item-link:da992630-932c-11f1-9a63-ef2cf49c242b}

When it already reports a minimum and a maximum, another takes those instead:

${item-link:3a4f4030-93fc-11f1-9a63-ef2cf49c242b}

Share Your Widget with the Community

Built a custom widget? Export it as a JSON from ThingsBoard and publish it to the IoT Hub through a simple 4-step wizard (Upload, Listing, Readme, Review & Submit). Share it with thousands of ThingsBoard developers worldwide and get featured in the catalog.