BMW BMW BMW Modbus RTU template

BMW BMW

The BMW battery storage system is a stationary energy storage unit built around BMW high-voltage battery packs, used in commercial and industrial installations managed via OpenEMS. This template connects over Modbus RTU and reads a comprehensive set of BMS registers: state of charge, state of health, DC link and internal voltage, pack current, per-cell voltage extremes in millivolts, cell and pack temperatures, insulation resistance, string topology, remaining charge and discharge energy, and full cycle count. The writable battery state command register allows the EMS to trigger state transitions. ModbusCloud makes this data continuously available for monitoring, alerting, and long-term performance analysis.

Protocol
Modbus RTU
Connection
RS485
Registers
36, read and write
Brand
BMW
Last updated

Registers (36)

35 read, 1 write

NameUnitAccessAddress (Hidden until you enter your email)Function (hidden)Type (hidden)
battery_state_commandWrite
battery_stateRead
max_operating_currentARead
min_operating_currentARead
charge_max_voltageVRead
discharge_min_voltageVRead
bp_discharge_bmsRead
bp_charge_bmsRead
max_dynamic_voltageVRead
min_dynamic_voltageVRead
connected_string_numbercountRead
installed_string_numbercountRead
battery_total_soc%Read
battery_soc%Read
remaining_charge_capacityRead
remaining_discharge_capacityRead
remaining_charge_energyWhRead
remaining_discharge_energyWhRead
nominal_energyWhRead
nominal_energy_totalRead
nominal_capacityRead
capacityWhRead
soh%Read
link_voltageVRead
internal_voltageVRead
currentARead
avg_battery_temperature°CRead
min_cell_temperature°CRead
max_cell_temperature°CRead
min_cell_voltagemVRead
max_cell_voltagemVRead
avg_cell_temperature°CRead
insulation_resistanceRead
discharge_max_current_high_resolutionARead
charge_max_current_high_resolutionARead
full_cycle_countcountRead

Loading registers…

Send your device list

If a device is not in the library yet, we build the template for free as soon as we have the register data.

Number of installations (optional)

Use cases

  • Track battery_total_soc and battery_soc together to detect imbalance across connected strings over time.
  • Monitor soh and full_cycle_count to schedule preventive maintenance before capacity degrades below site thresholds.
  • Alert on min_cell_voltage or max_cell_voltage extremes to catch cell drift before the BMS triggers a protective shutdown.
  • Compare connected_string_number against installed_string_number to verify all strings remain online after maintenance.
  • Log insulation_resistance readings over time to detect early-stage isolation faults in the high-voltage pack enclosure.

Installation

  1. Confirm the BMW battery system is configured for Modbus RTU communication and note its assigned RS485 slave address in the BMS or system controller settings.

  2. Wire the RS485 A and B lines from the battery system's Modbus port to the ModbusCloud Gateway serial terminals, observing polarity and fitting a 120-ohm termination resistor at each end of the bus.

  3. In the ModbusCloud portal, add the Gateway, create a new device, import the BMW battery template, and set the Modbus unit ID to match the slave address configured on the battery.

  4. Trigger a live poll on register 1016 (battery_total_soc) and register 1026 (soh) in the portal console to confirm values are being received correctly before enabling full dashboard collection.

Things to watch for

All registers return zero or an error. What should I check?

Verify the RS485 wiring polarity first: swapped A and B lines are the most common cause. Then confirm the Modbus slave address in the portal matches the address set on the BMW BMS. Check that the baud rate and parity settings on the Gateway match the battery's RS485 configuration, typically 9600 or 19200 baud, 8 data bits, no parity.

battery_total_soc and battery_soc read different values. Is that normal?

Yes, when multiple strings are installed but not all are connected, the two registers diverge. battery_total_soc (address 1016) aggregates all installed strings while battery_soc (address 1017) reflects the active string. Compare both against connected_string_number and installed_string_number to understand whether a string has been taken offline.

min_cell_voltage and max_cell_voltage show unexpected large numbers. Why?

Both registers use millivolt units, so a reading of 3500 represents 3.5 V per cell. Divide raw values by 1000 to convert to volts. If your dashboard shows raw integers without scaling, check that the unit field is set to mV and apply the correct factor in your chart configuration.

Is it safe to write to the battery_state_command register during normal operation?

Use write register 1400 with caution. Sending an unintended state transition command while the system is under load can cause the BMS to open contactors, interrupting active charge or discharge cycles and potentially triggering protective lockouts. Only issue commands when the system is at rest and always follow the BMW battery system's documented state machine sequence.

Want to see how it works?

Electrician working in an open distribution board