Skip to the content.

Battery State of Charge (SoC)

What services/battery_soc/ publishes and how it is configured. See device-services.md for where this service sits among the others, and knowledge/services/battery-soc-how-it-works.md for the coulomb-counting algorithm itself — the calibration math, the AC/DC efficiency handling and why it works the way it does.

services/battery_soc/ + libs/battery_soc_core/ · battery-soc.service · battery_soc_devices.json

The one service that polls nothing. It subscribes to power and voltage topics that the other bridges already publish, and computes the state of charge of one or two LiFePO4 banks by coulomb counting — with voltage recalibration at the ends of the curve, per-converter efficiency, and load compensation on the measured cell voltage.

It is a monitoring estimate, not a BMS.

Configuration

Inputs. Charger power, inverter power, and one voltage topic per bank — each as a topic plus an optional JSON key, because a Trucki stick publishes a bare number where a Shelly publishes an object. Optional DC-side power topics take over from the AC measurements while they are fresh (dc_max_age_s), and fall back automatically when they go stale.

Topology. parallel (both banks on one DC bus, one voltage) or series; bank_b_enabled: false for a single-bank installation. The entity list follows the topology — a series pack additionally gets per-bank SoC, the voltage difference between banks and an imbalance warning.

Calibration and efficiency. Cell count and capacity per bank; the open-circuit volts per cell that count as empty and full; how far those thresholds may soften at rest (calibration_tolerance_v_per_cell); how long a voltage must hold before calibration applies; charger AC→DC and inverter DC→AC efficiency; and the charge efficiency of the cells themselves.

Entities

All sensor and binary-sensor entities read from a single JSON state topic, outstation/<id>/state, via a value_template; the “Field” column below is the JSON key inside that payload. Most carry entity_category: diagnostic, noted where it applies — unlike the other services’ diagnostic sensors, none of these are disabled by default.

Always published:

Entity Field Unit Notes
SoC soc_combined_pct % combined; on a series pack this is the weaker bank
Net battery power net_power_w W positive = net charge
Inputs stale inputs_stale binary_sensor, problem, diagnostic
AC fallback active ac_fallback_active binary_sensor, problem, diagnostic
Time to full time_to_full_h h diagnostic
Time to empty time_to_empty_h h diagnostic

Per unit — once for pack, or once each for bank_a / bank_b on a series topology (<unit> below stands for that unit’s name):

Entity Field Unit Notes
Voltage <unit>_voltage_v V diagnostic
Current (estimated) <unit>_current_a A diagnostic
Remaining capacity <unit>_remaining_ah Ah diagnostic
Load-corrected cell voltage <unit>_corrected_v_per_cell V diagnostic
Last calibration last_calibration_<unit> timestamp diagnostic
Calibration threshold, empty <unit>_calibration_empty_v_per_cell V diagnostic
Calibration threshold, full <unit>_calibration_full_v_per_cell V diagnostic
Voltage-based SoC (uncertain) <unit>_voltage_soc_pct % diagnostic
Voltage/coulomb mismatch <unit>_voltage_soc_mismatch binary_sensor, problem, diagnostic
Calibration jump <unit>_last_calibration_residual_ah Ah diagnostic
Current at calibration <unit>_last_calibration_current_a A diagnostic

Series topology only:

Entity Field Unit Notes
SoC Bank A soc_a_pct %  
SoC Bank B soc_b_pct %  
Voltage difference A/B voltage_delta_v V diagnostic
Banks unbalanced imbalance_warning binary_sensor, problem, diagnostic

Control:

Entity Topic Range
Set SoC by hand (number) outstation/<id>/cmd/manual_soc — parallel/single-bank, or .../cmd/manual_soc/bank_a and .../bank_b on a series pack 0–100 %

This is the way back after an outage that lost the coulomb count.

Discovery is cleaned up as the topology changes: object IDs that do not belong to the current configuration are cleared with an empty retained payload rather than left behind as ghost entities.

Also available as a native Home Assistant integration

The same engine is also available as a native Home Assistant integration under integrations/homeassistant/, installable through HACS — the same core with a config flow instead of MQTT topics. See integration/ha-integration-hacs-release.md.