Case study
BM2 Battery Monitor: reconstructing an encrypted BLE voltage protocol
Reimplements the Bluetooth Low Energy protocol of the BM2 (Battery Monitor 2) car battery monitor for independent voltage readings. A Python client built on Bleak decrypts the monitor's AES-encrypted notifications to read the current voltage and request the stored voltage history, an ESPHome template exposes the voltage from an ESP32, and example apps view and dump readings or forward them over MQTT. The author's write-up reports that the key and packet layout were recovered from the vendor app; results are author- and contributor-reported.
- Targets
- Protocol
- Category
- Independent reconstruction cases
- Relationship
- Independent reconstruction project
- Sources reviewed
- Stars
- 87
- Last commit
- 2026-10-13
- Language
- Python
- License (GitHub)
- MIT
GitHub data as of 2026-11-09
Requirements & limits
- The bm2 0.1.0 package requires Python 3.8+. The client reads current voltage and history; history timestamps are inferred at two-minute intervals, while the ESPHome template reads current voltage only.
- Supply a BM2 monitor and its Bluetooth address. The client and ESPHome template include the AES-128-CBC key recovered from the vendor app.
- The Python client uses Bleak ~0.14.2 and PyCryptodome; its reconnect path calls Linux bluetoothctl. MQTT adds paho-mqtt ~1.6.1. The ESPHome template targets a nodemcu-32s ESP32 with Arduino, mbedtls and Wi-Fi, MQTT and MAC secrets.
- The repository has a mypy check but no tests or CI. The history fix reports testing on Linux Mint 22.3 with a PowerHouse BM2 N2099A; coverage of other BM2 models is unspecified.
- Code is MIT under LICENSE.txt; the device and vendor app retain their rights.
Cite
BibTeX
@misc{bm2-battery-monitor-ble-case,
title = {{BM2 Battery Monitor: reconstructing an encrypted BLE voltage protocol}},
howpublished = {\url{https://github.com/KrystianD/bm2-battery-monitor}},
url = {https://github.com/KrystianD/bm2-battery-monitor},
urldate = {2026-10-20},
note = {Awesome REA entry: \url{https://awesomerea.org/resources/bm2-battery-monitor-ble-case/}}
}Plain text
BM2 Battery Monitor: reconstructing an encrypted BLE voltage protocol. https://github.com/KrystianD/bm2-battery-monitor (accessed 2026-10-20). Awesome REA entry: https://awesomerea.org/resources/bm2-battery-monitor-ble-case/
Useful? Star Awesome REA on GitHub2.4k
About this entry
The description was reviewed against primary sources.
Primary sources
- README.md GitHub · KrystianD/bm2-battery-monitor · Revision 494a39c
- .docs/reverse_engineering.md GitHub · KrystianD/bm2-battery-monitor · Revision 494a39c
- bm2_python/src/bm2/client.py GitHub · KrystianD/bm2-battery-monitor · Revision 494a39c
- bm2_python/src/bm2/encryption.py GitHub · KrystianD/bm2-battery-monitor · Revision 494a39c
- bm2_esphome/bm2.yaml GitHub · KrystianD/bm2-battery-monitor · Revision 494a39c
- bm2_esphome/main.yaml GitHub · KrystianD/bm2-battery-monitor · Revision 494a39c
- bm2_python/requirements.txt GitHub · KrystianD/bm2-battery-monitor · Revision 494a39c
- pyproject.toml GitHub · KrystianD/bm2-battery-monitor · Revision 494a39c
- LICENSE.txt GitHub · KrystianD/bm2-battery-monitor · Revision 494a39c
- https://github.com/KrystianD/bm2-battery-monitor/pull/28
More in Protocols
- Smart ring protocol: documenting the Oura Ring BLE protocol and event format · Case study
- openrsync: an ISC implementation of rsync protocol 27 · Case study
- Thermal Master P3: a browser client for the vendor USB protocol · Case study
- SNX-VPN: reconstructing Check Point browser login for SNX · Case study
- OpenDS: reconstructing an FRC Driver Station client · Case study
- CO/Tech power plugs: reproducing captured radio commands · Case study