3.0 KiB
3.0 KiB
Berger LFP BLE Flow
This is the app flow used to obtain battery information such as discharge current, SOC, voltage, temperatures, cell voltages, MOS state, and estimated charge/discharge time.
Evidence
- App package:
com.jbd.berger - Version:
1.0.3 - Main bundle:
assets/apps/__UNI__F61076D/www/app-service.js - Source-map style log labels embedded in bundle:
utils/BLE.tsApp.vue- dashboard/control/parameter pages
Connection Sequence
uni.openBluetoothAdapter()uni.startBluetoothDevicesDiscovery()with service filterff00uni.onBluetoothDeviceFound()records devices and RSSIuni.createBLEConnection()with 10 second timeoutuni.getBLEDeviceServices()uni.getBLEDeviceCharacteristics()uni.notifyBLECharacteristicValueChange()onff01uni.onBLECharacteristicValueChange()buffers incoming bytesuni.writeBLECharacteristicValue()sends command chunks toff02withwriteType: "writeNoResponse"
The app chunks outgoing buffers into 20-byte pieces before writing.
Services And Characteristics
- Service:
0000ff00-0000-1000-8000-00805f9b34fb - Notify/read:
0000ff01-0000-1000-8000-00805f9b34fb - Write:
0000ff02-0000-1000-8000-00805f9b34fb
Pairing / Bonding
- Needs Android bond before normal telemetry: likely no.
- Evidence: the app uses uni-app BLE APIs for connection, service discovery, notifications, and writes. I did not find a normal-path bond request in the app bundle.
- Caveat: a peripheral firmware could still enforce encryption independently, but the app flow itself does not show pairing as a telemetry prerequisite.
Getting Live Values
The app sends:
DD A5 03 00 FF FD 77
The response uses:
DD 03 <status> <length> <payload> <checksum> 77
Important payload fields for command 0x03:
| Payload bytes | Formula | Unit | Field |
|---|---|---|---|
0..1 |
big-endian / 100 | V | pack voltage |
2..3 |
signed big-endian / 100 | A | current |
4..5 |
big-endian / 100 | Ah | remaining capacity |
6..7 |
big-endian / 100 | Ah | nominal capacity |
8..9 |
raw | cycles | cycle count |
10..11 |
JBD bitfield | date | production date |
12..13 |
nonzero bitmap | boolean | balancing |
16..17 |
nonzero bitmap | boolean | protection |
18 |
decimal digits | version | software version |
19 |
raw | % | SOC |
20 |
1 = charge, 2 = discharge, 3 = both |
boolean | MOS state |
22 |
raw count | count | temperature sensor count |
23.. |
(raw - 2731) / 10 |
deg C | temperatures |
Production date bitfield:
day = value & 0x1F
month = (value >> 5) & 0x0F
year = 2000 + (value >> 9)
Estimated time is computed locally:
if current_A > 0:
time_to_full = (nominal_Ah - remaining_Ah) / current_A
if current_A < 0:
time_to_empty = remaining_Ah / abs(current_A)
Cell Voltages
The app sends:
DD A5 04 00 FF FC 77
The response command 0x04 payload is a sequence of big-endian 16-bit cell
voltages scaled by 0.001 V.