syssi / esphome-jbd-bms

ESPHome component to monitor and control a Xiaoxiang Battery Management System (JBD-BMS) via UART-TTL or BLE
Apache License 2.0
102 stars 28 forks source link

Add auth flow of a new bluetooth module (SOF: `0xFF 0xAA`) #94

Open HansWegman opened 2 weeks ago

HansWegman commented 2 weeks ago

Hello, thanks for your great work, unfortunately I cannot get to to work with my unit SP04S034L4S200A.

I have included the log and the home assistant ESPHome configuration and hope to get some pointers to fix this.

It might be relevant that I have accidentally set a bluetooth password on the device. I did try to remove it by changing it to 000000 but not sure whether that helped.

Log underneath:

INFO ESPHome 2024.8.0
INFO Reading configuration /config/esphome/test.yaml...
INFO Updating https://github.com/syssi/esphome-jbd-bms.git@main
INFO Generating C++ source...
INFO Compiling app...
Processing battery-connect (board: esp32dev; framework: espidf; platform: platformio/espressif32@5.4.0)
--------------------------------------------------------------------------------
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
 - framework-espidf @ 3.40407.240606 (4.4.7) 
 - tool-cmake @ 3.16.4 
 - tool-ninja @ 1.7.1 
 - toolchain-esp32ulp @ 2.35.0-20220830 
 - toolchain-xtensa-esp32 @ 8.4.0+2021r2-patch5
Reading CMake configuration...
Dependency Graph
|-- noise-c @ 0.1.6
Compiling .pioenvs/battery-connect/src/main.o
Linking .pioenvs/battery-connect/firmware.elf
RAM:   [==        ]  16.6% (used 54540 bytes from 327680 bytes)
Flash: [=======   ]  74.1% (used 1358833 bytes from 1835008 bytes)
Building .pioenvs/battery-connect/firmware.bin
Creating esp32 image...
Successfully created esp32 image.
esp32_create_combined_bin([".pioenvs/battery-connect/firmware.bin"], [".pioenvs/battery-connect/firmware.elf"])
Wrote 0x15d5a0 bytes to file /data/build/battery-connect/.pioenvs/battery-connect/firmware.factory.bin, ready to flash to offset 0x0
esp32_copy_ota_bin([".pioenvs/battery-connect/firmware.bin"], [".pioenvs/battery-connect/firmware.elf"])
========================= [SUCCESS] Took 28.67 seconds =========================
INFO Successfully compiled program.
INFO Connecting to 192.168.1.141
INFO Uploading /data/build/battery-connect/.pioenvs/battery-connect/firmware.bin (1365408 bytes)
Uploading: [============================================================] 100% Done...

INFO Upload took 12.38 seconds, waiting for result...
INFO OTA successful
INFO Successfully uploaded program.
INFO Starting log output from 192.168.1.141 using esphome API
INFO Successfully connected to battery-connect @ 192.168.1.141 in 19.321s
INFO Successful handshake with battery-connect @ 192.168.1.141 in 0.123s
[17:20:52][I][app:100]: ESPHome version 2024.8.0 compiled on Aug 25 2024, 17:19:53
[17:20:52][I][app:102]: Project syssi.esphome-jbd-bms version 1.4.0
[17:20:52][C][wifi:600]: WiFi:
[17:20:52][C][wifi:428]:   Local MAC: D0:EF:76:58:CC:80
[17:20:52][C][wifi:433]:   SSID: 'Wegnet'[redacted]
[17:20:52][C][wifi:436]:   IP Address: 192.168.1.141
[17:20:52][C][wifi:440]:   BSSID: 74:83:C2:2A:FD:EA[redacted]
[17:20:52][C][wifi:441]:   Hostname: 'battery-connect'
[17:20:52][C][wifi:443]:   Signal strength: -62 dB ▂▄▆█
[17:20:52][C][wifi:447]:   Channel: 11
[17:20:52][C][wifi:448]:   Subnet: 255.255.255.0
[17:20:52][C][wifi:449]:   Gateway: 192.168.1.1
[17:20:52][C][wifi:450]:   DNS1: 0.0.0.0
[17:20:52][C][wifi:451]:   DNS2: 0.0.0.0
[17:20:52][C][logger:185]: Logger:
[17:20:52][C][logger:186]:   Level: DEBUG
[17:20:52][C][logger:188]:   Log Baud Rate: 115200
[17:20:52][C][logger:189]:   Hardware UART: UART0
[17:20:52][C][jbd_bms_ble:379]: JbdBmsBle:
[17:20:52][C][jbd_bms_ble:381]: Balancing 'battery-connect balancing'
[17:20:52][C][jbd_bms_ble:382]: Charging 'battery-connect charging'
[17:20:52][C][jbd_bms_ble:383]: Discharging 'battery-connect discharging'
[17:20:52][C][jbd_bms_ble:385]: Total voltage 'battery-connect total voltage'
[17:20:52][C][jbd_bms_ble:385]:   Device Class: 'voltage'
[17:20:52][C][jbd_bms_ble:385]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:385]:   Unit of Measurement: 'V'
[17:20:52][C][jbd_bms_ble:385]:   Accuracy Decimals: 2
[17:20:52][C][jbd_bms_ble:386]: Battery strings 'battery-connect battery strings'
[17:20:52][C][jbd_bms_ble:386]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:386]:   Unit of Measurement: ''
[17:20:52][C][jbd_bms_ble:386]:   Accuracy Decimals: 0
[17:20:52][C][jbd_bms_ble:386]:   Icon: 'mdi:car-battery'
[17:20:52][C][jbd_bms_ble:387]: Software version 'battery-connect software version'
[17:20:52][C][jbd_bms_ble:387]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:387]:   Unit of Measurement: ''
[17:20:52][C][jbd_bms_ble:387]:   Accuracy Decimals: 1
[17:20:52][C][jbd_bms_ble:387]:   Icon: 'mdi:numeric'
[17:20:52][C][jbd_bms_ble:388]: Current 'battery-connect current'
[17:20:52][C][jbd_bms_ble:388]:   Device Class: 'current'
[17:20:52][C][jbd_bms_ble:388]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:388]:   Unit of Measurement: 'A'
[17:20:52][C][jbd_bms_ble:388]:   Accuracy Decimals: 1
[17:20:52][C][jbd_bms_ble:388]:   Icon: 'mdi:current-dc'
[17:20:52][C][jbd_bms_ble:389]: Power 'battery-connect power'
[17:20:52][C][jbd_bms_ble:389]:   Device Class: 'power'
[17:20:52][C][jbd_bms_ble:389]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:389]:   Unit of Measurement: 'W'
[17:20:52][C][jbd_bms_ble:389]:   Accuracy Decimals: 1
[17:20:52][C][jbd_bms_ble:390]: Charging Power 'battery-connect charging power'
[17:20:52][C][jbd_bms_ble:390]:   Device Class: 'power'
[17:20:52][C][jbd_bms_ble:390]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:390]:   Unit of Measurement: 'W'
[17:20:52][C][jbd_bms_ble:390]:   Accuracy Decimals: 2
[17:20:52][C][jbd_bms_ble:391]: Discharging Power 'battery-connect discharging power'
[17:20:52][C][jbd_bms_ble:391]:   Device Class: 'power'
[17:20:52][C][jbd_bms_ble:391]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:391]:   Unit of Measurement: 'W'
[17:20:52][C][jbd_bms_ble:391]:   Accuracy Decimals: 2
[17:20:52][C][jbd_bms_ble:392]: State of charge 'battery-connect state of charge'
[17:20:52][C][jbd_bms_ble:392]:   Device Class: 'battery'
[17:20:52][C][jbd_bms_ble:392]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:392]:   Unit of Measurement: '%'
[17:20:52][C][jbd_bms_ble:392]:   Accuracy Decimals: 0
[17:20:52][C][jbd_bms_ble:393]: Operation status bitmask 'battery-connect operation status bitmask'
[17:20:52][C][jbd_bms_ble:393]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:393]:   Unit of Measurement: ''
[17:20:52][C][jbd_bms_ble:393]:   Accuracy Decimals: 0
[17:20:52][C][jbd_bms_ble:393]:   Icon: 'mdi:heart-pulse'
[17:20:52][C][jbd_bms_ble:394]: Errors bitmask 'battery-connect errors bitmask'
[17:20:52][C][jbd_bms_ble:394]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:394]:   Unit of Measurement: ''
[17:20:52][C][jbd_bms_ble:394]:   Accuracy Decimals: 0
[17:20:52][C][jbd_bms_ble:394]:   Icon: 'mdi:alert-circle-outline'
[17:20:52][C][jbd_bms_ble:395]: Nominal capacity 'battery-connect nominal capacity'
[17:20:52][C][jbd_bms_ble:395]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:395]:   Unit of Measurement: 'Ah'
[17:20:52][C][jbd_bms_ble:395]:   Accuracy Decimals: 2
[17:20:52][C][jbd_bms_ble:395]:   Icon: 'mdi:battery-50'
[17:20:52][C][jbd_bms_ble:396]: Charging cycles 'battery-connect charging cycles'
[17:20:52][C][jbd_bms_ble:396]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:396]:   Unit of Measurement: ''
[17:20:52][C][jbd_bms_ble:396]:   Accuracy Decimals: 0
[17:20:52][C][jbd_bms_ble:396]:   Icon: 'mdi:battery-sync'
[17:20:52][C][jbd_bms_ble:397]: Balancer status bitmask 'battery-connect balancer status bitmask'
[17:20:52][C][jbd_bms_ble:397]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:397]:   Unit of Measurement: ''
[17:20:52][C][jbd_bms_ble:397]:   Accuracy Decimals: 0
[17:20:52][C][jbd_bms_ble:397]:   Icon: 'mdi:seesaw'
[17:20:52][C][jbd_bms_ble:398]: Capacity remaining 'battery-connect capacity remaining'
[17:20:52][C][jbd_bms_ble:398]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:398]:   Unit of Measurement: 'Ah'
[17:20:52][C][jbd_bms_ble:398]:   Accuracy Decimals: 2
[17:20:52][C][jbd_bms_ble:398]:   Icon: 'mdi:battery-50'
[17:20:52][C][jbd_bms_ble:399]: Average cell voltage sensor 'battery-connect average cell voltage'
[17:20:52][C][jbd_bms_ble:399]:   Device Class: 'voltage'
[17:20:52][C][jbd_bms_ble:399]:   State Class: 'measurement'
[17:20:52][C][jbd_bms_ble:399]:   Unit of Measurement: 'V'
[17:20:52][C][jbd_bms_ble:399]:   Accuracy Decimals: 4
[17:20:52][C][jbd_bms_ble:400]: Delta cell voltage sensor 'battery-connect delta cell voltage'
[17:20:53][C][jbd_bms_ble:400]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:400]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:400]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:400]:   Accuracy Decimals: 4
[17:20:53][C][jbd_bms_ble:401]: Maximum cell voltage 'battery-connect max cell voltage'
[17:20:53][C][jbd_bms_ble:401]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:401]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:401]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:401]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:401]:   Icon: 'mdi:battery-plus-outline'
[17:20:53][C][jbd_bms_ble:402]: Min voltage cell 'battery-connect min voltage cell'
[17:20:53][C][jbd_bms_ble:402]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:402]:   Unit of Measurement: ''
[17:20:53][C][jbd_bms_ble:402]:   Accuracy Decimals: 0
[17:20:53][C][jbd_bms_ble:402]:   Icon: 'mdi:battery-minus-outline'
[17:20:53][C][jbd_bms_ble:403]: Max voltage cell 'battery-connect max voltage cell'
[17:20:53][C][jbd_bms_ble:403]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:403]:   Unit of Measurement: ''
[17:20:53][C][jbd_bms_ble:403]:   Accuracy Decimals: 0
[17:20:53][C][jbd_bms_ble:403]:   Icon: 'mdi:battery-plus-outline'
[17:20:53][C][jbd_bms_ble:404]: Minimum cell voltage 'battery-connect min cell voltage'
[17:20:53][C][jbd_bms_ble:404]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:404]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:404]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:404]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:404]:   Icon: 'mdi:battery-minus-outline'
[17:20:53][C][jbd_bms_ble:406]: Temperature 1 'battery-connect temperature 1'
[17:20:53][C][jbd_bms_ble:406]:   Device Class: 'temperature'
[17:20:53][C][jbd_bms_ble:406]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:406]:   Unit of Measurement: '°C'
[17:20:53][C][jbd_bms_ble:406]:   Accuracy Decimals: 1
[17:20:53][C][jbd_bms_ble:407]: Temperature 2 'battery-connect temperature 2'
[17:20:53][C][jbd_bms_ble:407]:   Device Class: 'temperature'
[17:20:53][C][jbd_bms_ble:407]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:407]:   Unit of Measurement: '°C'
[17:20:53][C][jbd_bms_ble:407]:   Accuracy Decimals: 1
[17:20:53][C][jbd_bms_ble:408]: Temperature 3 'battery-connect temperature 3'
[17:20:53][C][jbd_bms_ble:408]:   Device Class: 'temperature'
[17:20:53][C][jbd_bms_ble:408]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:408]:   Unit of Measurement: '°C'
[17:20:53][C][jbd_bms_ble:408]:   Accuracy Decimals: 1
[17:20:53][C][jbd_bms_ble:409]: Temperature 4 'battery-connect temperature 4'
[17:20:53][C][jbd_bms_ble:409]:   Device Class: 'temperature'
[17:20:53][C][jbd_bms_ble:409]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:409]:   Unit of Measurement: '°C'
[17:20:53][C][jbd_bms_ble:409]:   Accuracy Decimals: 1
[17:20:53][C][jbd_bms_ble:410]: Temperature 5 'battery-connect temperature 5'
[17:20:53][C][jbd_bms_ble:410]:   Device Class: 'temperature'
[17:20:53][C][jbd_bms_ble:410]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:410]:   Unit of Measurement: '°C'
[17:20:53][C][jbd_bms_ble:410]:   Accuracy Decimals: 1
[17:20:53][C][jbd_bms_ble:411]: Temperature 6 'battery-connect temperature 6'
[17:20:53][C][jbd_bms_ble:411]:   Device Class: 'temperature'
[17:20:53][C][jbd_bms_ble:411]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:411]:   Unit of Measurement: '°C'
[17:20:53][C][jbd_bms_ble:411]:   Accuracy Decimals: 1
[17:20:53][C][jbd_bms_ble:412]: Cell Voltage 1 'battery-connect cell voltage 1'
[17:20:53][C][jbd_bms_ble:412]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:412]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:412]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:412]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:413]: Cell Voltage 2 'battery-connect cell voltage 2'
[17:20:53][C][jbd_bms_ble:413]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:413]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:413]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:413]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:414]: Cell Voltage 3 'battery-connect cell voltage 3'
[17:20:53][C][jbd_bms_ble:414]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:414]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:414]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:414]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:415]: Cell Voltage 4 'battery-connect cell voltage 4'
[17:20:53][C][jbd_bms_ble:415]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:415]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:415]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:415]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:416]: Cell Voltage 5 'battery-connect cell voltage 5'
[17:20:53][C][jbd_bms_ble:416]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:416]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:416]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:416]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:417]: Cell Voltage 6 'battery-connect cell voltage 6'
[17:20:53][C][jbd_bms_ble:417]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:417]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:417]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:417]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:418]: Cell Voltage 7 'battery-connect cell voltage 7'
[17:20:53][C][jbd_bms_ble:418]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:418]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:418]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:418]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:419]: Cell Voltage 8 'battery-connect cell voltage 8'
[17:20:53][C][jbd_bms_ble:419]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:419]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:419]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:419]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:420]: Cell Voltage 9 'battery-connect cell voltage 9'
[17:20:53][C][jbd_bms_ble:420]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:420]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:420]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:420]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:421]: Cell Voltage 10 'battery-connect cell voltage 10'
[17:20:53][C][jbd_bms_ble:421]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:421]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:421]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:421]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:422]: Cell Voltage 11 'battery-connect cell voltage 11'
[17:20:53][C][jbd_bms_ble:422]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:422]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:422]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:422]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:423]: Cell Voltage 12 'battery-connect cell voltage 12'
[17:20:53][C][jbd_bms_ble:423]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:423]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:423]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:423]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:424]: Cell Voltage 13 'battery-connect cell voltage 13'
[17:20:53][C][jbd_bms_ble:424]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:424]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:424]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:424]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:425]: Cell Voltage 14 'battery-connect cell voltage 14'
[17:20:53][C][jbd_bms_ble:425]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:425]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:425]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:425]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:426]: Cell Voltage 15 'battery-connect cell voltage 15'
[17:20:53][C][jbd_bms_ble:426]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:426]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:426]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:426]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:427]: Cell Voltage 16 'battery-connect cell voltage 16'
[17:20:53][C][jbd_bms_ble:427]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:427]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:427]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:427]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:428]: Cell Voltage 17 'battery-connect cell voltage 17'
[17:20:53][C][jbd_bms_ble:428]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:428]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:428]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:428]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:429]: Cell Voltage 18 'battery-connect cell voltage 18'
[17:20:53][C][jbd_bms_ble:429]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:429]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:429]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:429]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:430]: Cell Voltage 19 'battery-connect cell voltage 19'
[17:20:53][C][jbd_bms_ble:430]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:430]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:430]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:430]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:431]: Cell Voltage 20 'battery-connect cell voltage 20'
[17:20:53][C][jbd_bms_ble:431]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:431]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:431]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:431]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:432]: Cell Voltage 21 'battery-connect cell voltage 21'
[17:20:53][C][jbd_bms_ble:432]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:432]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:432]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:432]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:433]: Cell Voltage 22 'battery-connect cell voltage 22'
[17:20:53][C][jbd_bms_ble:433]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:433]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:433]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:433]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:434]: Cell Voltage 23 'battery-connect cell voltage 23'
[17:20:53][C][jbd_bms_ble:434]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:434]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:434]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:434]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:435]: Cell Voltage 24 'battery-connect cell voltage 24'
[17:20:53][C][jbd_bms_ble:435]:   Device Class: 'voltage'
[17:20:53][C][jbd_bms_ble:435]:   State Class: 'measurement'
[17:20:53][C][jbd_bms_ble:435]:   Unit of Measurement: 'V'
[17:20:53][C][jbd_bms_ble:435]:   Accuracy Decimals: 3
[17:20:53][C][jbd_bms_ble:436]: Cell Voltage 25 'battery-connect cell voltage 25'
[17:20:53][C][jbd_bms_ble:436]:   Device Class: 'voltage'
[17:20:54][C][jbd_bms_ble:436]:   State Class: 'measurement'
[17:20:54][C][jbd_bms_ble:436]:   Unit of Measurement: 'V'
[17:20:54][C][jbd_bms_ble:436]:   Accuracy Decimals: 3
[17:20:54][C][jbd_bms_ble:437]: Cell Voltage 26 'battery-connect cell voltage 26'
[17:20:54][C][jbd_bms_ble:437]:   Device Class: 'voltage'
[17:20:54][C][jbd_bms_ble:437]:   State Class: 'measurement'
[17:20:54][C][jbd_bms_ble:437]:   Unit of Measurement: 'V'
[17:20:54][C][jbd_bms_ble:437]:   Accuracy Decimals: 3
[17:20:54][C][jbd_bms_ble:438]: Cell Voltage 27 'battery-connect cell voltage 27'
[17:20:54][C][jbd_bms_ble:438]:   Device Class: 'voltage'
[17:20:54][C][jbd_bms_ble:438]:   State Class: 'measurement'
[17:20:54][C][jbd_bms_ble:438]:   Unit of Measurement: 'V'
[17:20:54][C][jbd_bms_ble:438]:   Accuracy Decimals: 3
[17:20:54][C][jbd_bms_ble:439]: Cell Voltage 28 'battery-connect cell voltage 28'
[17:20:54][C][jbd_bms_ble:439]:   Device Class: 'voltage'
[17:20:54][C][jbd_bms_ble:439]:   State Class: 'measurement'
[17:20:54][C][jbd_bms_ble:439]:   Unit of Measurement: 'V'
[17:20:54][C][jbd_bms_ble:439]:   Accuracy Decimals: 3
[17:20:54][C][jbd_bms_ble:440]: Cell Voltage 29 'battery-connect cell voltage 29'
[17:20:54][C][jbd_bms_ble:440]:   Device Class: 'voltage'
[17:20:54][C][jbd_bms_ble:440]:   State Class: 'measurement'
[17:20:54][C][jbd_bms_ble:440]:   Unit of Measurement: 'V'
[17:20:54][C][jbd_bms_ble:440]:   Accuracy Decimals: 3
[17:20:54][C][jbd_bms_ble:441]: Cell Voltage 30 'battery-connect cell voltage 30'
[17:20:54][C][jbd_bms_ble:441]:   Device Class: 'voltage'
[17:20:54][C][jbd_bms_ble:441]:   State Class: 'measurement'
[17:20:54][C][jbd_bms_ble:441]:   Unit of Measurement: 'V'
[17:20:54][C][jbd_bms_ble:441]:   Accuracy Decimals: 3
[17:20:54][C][jbd_bms_ble:442]: Cell Voltage 31 'battery-connect cell voltage 31'
[17:20:54][C][jbd_bms_ble:442]:   Device Class: 'voltage'
[17:20:54][C][jbd_bms_ble:442]:   State Class: 'measurement'
[17:20:54][C][jbd_bms_ble:442]:   Unit of Measurement: 'V'
[17:20:54][C][jbd_bms_ble:442]:   Accuracy Decimals: 3
[17:20:54][C][jbd_bms_ble:443]: Cell Voltage 32 'battery-connect cell voltage 32'
[17:20:54][C][jbd_bms_ble:443]:   Device Class: 'voltage'
[17:20:54][C][jbd_bms_ble:443]:   State Class: 'measurement'
[17:20:54][C][jbd_bms_ble:443]:   Unit of Measurement: 'V'
[17:20:54][C][jbd_bms_ble:443]:   Accuracy Decimals: 3
[17:20:54][C][jbd_bms_ble:445]: Operation status 'battery-connect operation status'
[17:20:54][C][jbd_bms_ble:445]:   Icon: 'mdi:heart-pulse'
[17:20:54][C][jbd_bms_ble:446]: Errors 'battery-connect errors'
[17:20:54][C][jbd_bms_ble:446]:   Icon: 'mdi:alert-circle-outline'
[17:20:54][C][jbd_bms_ble:447]: Device model 'battery-connect device model'
[17:20:54][C][jbd_bms_ble:447]:   Icon: 'mdi:chip'
[17:20:54][W][esp32_ble_tracker:114]: Too many BLE events to process. Some devices may not show up.
[17:20:54][C][ble_switch:068]: BLE Client Switch 'battery-connect enable bluetooth connection'
[17:20:54][C][ble_switch:070]:   Icon: 'mdi:bluetooth'
[17:20:54][C][ble_switch:091]:   Restore Mode: always OFF
[17:20:54][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:20:54][C][jbd_bms_ble.switch:068]: JbdBmsBle Switch 'battery-connect discharging'
[17:20:54][C][jbd_bms_ble.switch:070]:   Icon: 'mdi:battery-charging-50'
[17:20:54][C][jbd_bms_ble.switch:091]:   Restore Mode: always OFF
[17:20:54][C][jbd_bms_ble.switch:068]: JbdBmsBle Switch 'battery-connect charging'
[17:20:54][C][jbd_bms_ble.switch:070]:   Icon: 'mdi:battery-charging-50'
[17:20:54][C][jbd_bms_ble.switch:091]:   Restore Mode: always OFF
[17:20:54][C][esp32_ble:391]: ESP32 BLE:
[17:20:54][C][esp32_ble:393]:   MAC address: D0:EF:76:58:CC:82
[17:20:54][C][esp32_ble:394]:   IO Capability: none
[17:20:54][C][esp32_ble_tracker:653]: BLE Tracker:
[17:20:54][C][esp32_ble_tracker:654]:   Scan Duration: 300 s
[17:20:54][C][esp32_ble_tracker:655]:   Scan Interval: 320.0 ms
[17:20:54][C][esp32_ble_tracker:656]:   Scan Window: 30.0 ms
[17:20:54][C][esp32_ble_tracker:657]:   Scan Type: ACTIVE
[17:20:54][C][esp32_ble_tracker:658]:   Continuous Scanning: True
[17:20:54][C][ble_client:027]: BLE Client:
[17:20:54][C][ble_client:028]:   Address: A4:C1:37:04:2D:BE
[17:20:54][C][ble_client:029]:   Auto-Connect: TRUE
[17:20:54][C][captive_portal:088]: Captive Portal:
[17:20:54][C][mdns:116]: mDNS:
[17:20:54][C][mdns:117]:   Hostname: battery-connect
[17:20:54][C][esphome.ota:073]: Over-The-Air updates:
[17:20:54][C][esphome.ota:074]:   Address: 192.168.1.141:3232
[17:20:54][C][esphome.ota:075]:   Version: 2
[17:20:54][C][esphome.ota:078]:   Password configured
[17:20:54][C][safe_mode:018]: Safe Mode:
[17:20:54][C][safe_mode:020]:   Boot considered successful after 60 seconds
[17:20:54][C][safe_mode:021]:   Invoke after 10 boot attempts
[17:20:54][C][safe_mode:023]:   Remain in safe mode for 300 seconds
[17:20:54][C][api:139]: API Server:
[17:20:54][C][api:140]:   Address: 192.168.1.141:6053
[17:20:54][C][api:142]:   Using noise encryption: YES
[17:20:55][D][text_sensor:064]: 'battery-connect errors': Sending state 'Offline'
[17:20:55][D][sensor:094]: 'battery-connect state of charge': Sending state nan % with 0 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect total voltage': Sending state nan V with 2 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect current': Sending state nan A with 1 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect power': Sending state nan W with 1 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect charging power': Sending state nan W with 2 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect discharging power': Sending state nan W with 2 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect nominal capacity': Sending state nan Ah with 2 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect charging cycles': Sending state nan  with 0 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect capacity remaining': Sending state nan Ah with 2 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect min cell voltage': Sending state nan V with 3 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect max cell voltage': Sending state nan V with 3 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect min voltage cell': Sending state nan  with 0 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect max voltage cell': Sending state nan  with 0 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect delta cell voltage': Sending state nan V with 4 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect average cell voltage': Sending state nan V with 4 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect operation status bitmask': Sending state nan  with 0 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect errors bitmask': Sending state nan  with 0 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect balancer status bitmask': Sending state nan  with 0 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect battery strings': Sending state nan  with 0 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect software version': Sending state nan  with 1 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect temperature 1': Sending state nan °C with 1 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect temperature 2': Sending state nan °C with 1 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect temperature 3': Sending state nan °C with 1 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect temperature 4': Sending state nan °C with 1 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect temperature 5': Sending state nan °C with 1 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect temperature 6': Sending state nan °C with 1 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect cell voltage 1': Sending state nan V with 3 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect cell voltage 2': Sending state nan V with 3 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect cell voltage 3': Sending state nan V with 3 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect cell voltage 4': Sending state nan V with 3 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect cell voltage 5': Sending state nan V with 3 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect cell voltage 6': Sending state nan V with 3 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect cell voltage 7': Sending state nan V with 3 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect cell voltage 8': Sending state nan V with 3 decimals of accuracy
[17:20:55][D][sensor:094]: 'battery-connect cell voltage 9': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 10': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 11': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 12': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 13': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 14': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 15': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 16': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 17': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 18': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 19': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 20': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 21': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 22': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 23': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 24': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 25': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 26': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 27': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 28': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 29': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 30': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 31': Sending state nan V with 3 decimals of accuracy
[17:20:56][D][sensor:094]: 'battery-connect cell voltage 32': Sending state nan V with 3 decimals of accuracy
[17:20:56][W][component:237]: Component jbd_bms_ble took a long time for an operation (532 ms).
[17:20:56][W][component:238]: Components should block for at most 30 ms.
[17:20:56][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:20:57][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:20:59][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:01][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:03][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:05][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:07][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:09][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:11][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:13][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:15][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:17][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:19][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:21][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:23][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:25][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:27][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:29][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:31][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:33][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:35][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:37][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:38][I][safe_mode:041]: Boot seems successful; resetting boot loop counter
[17:21:38][D][esp32.preferences:114]: Saving 1 preferences to flash...
[17:21:38][D][esp32.preferences:143]: Saving 1 preferences to flash: 0 cached, 1 written, 0 failed
[17:21:39][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:41][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:43][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:45][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:47][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:49][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:51][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:53][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:55][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:57][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:21:59][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:22:01][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:22:03][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:22:05][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:22:07][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:22:09][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT
[17:22:11][D][esp32_ble_client:110]: [0] [A4:C1:37:04:2D:BE] ESP_GATTC_WRITE_CHAR_EVT

And the configuration:

substitutions:
  name: battery-connect
  device_description: "Monitor and control a Xiaoxiang Battery Management System (JBD-BMS) via BLE"
  external_components_source: github://syssi/esphome-jbd-bms@main
  mac_address: A4:C1:37:04:2D:BE

esphome:
  name: ${name}
  comment: ${device_description}
  project:
    name: "syssi.esphome-jbd-bms"
    version: 1.4.0

esp32:
  board: esp32dev
  framework:
    type: esp-idf
    # arduino

external_components:
  - source: ${external_components_source}
    refresh: 0s

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "XXXXEDITED="
ota:
  - platform: esphome
    password: "XXXXEDITED"
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.1.141
    gateway: 192.168.1.1
    subnet: 255.255.255.0
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Test Fallback Hotspot"
    password: "XXXXXXEDITED"

captive_portal:

#mqtt:
#  broker: !secret mqtt_host
#  username: !secret mqtt_username
#  password: !secret mqtt_password
#  id: mqtt_client

esp32_ble_tracker:
  on_ble_advertise:
    then:
      - lambda: |-
          if (x.get_name().rfind("xiaoxiang", 0) == 0) {
            ESP_LOGI("ble_adv", "New JBD-BMS found");
            ESP_LOGI("ble_adv", "  Name: %s", x.get_name().c_str());
            ESP_LOGI("ble_adv", "  MAC address: %s", x.address_str().c_str());
            ESP_LOGD("ble_adv", "  Advertised service UUIDs:");
            for (auto uuid : x.get_service_uuids()) {
              ESP_LOGD("ble_adv", "    - %s", uuid.to_string().c_str());
            }
          }
ble_client:
  - id: client0
    mac_address: ${mac_address}
jbd_bms_ble:
  - id: bms0
    ble_client_id: client0
    update_interval: 2s
binary_sensor:
  - platform: jbd_bms_ble
    jbd_bms_ble_id: bms0
    balancing:
      name: "${name} balancing"
    charging:
      name: "${name} charging"
    discharging:
      name: "${name} discharging"
sensor:
  - platform: jbd_bms_ble
    jbd_bms_ble_id: bms0
    battery_strings:
      name: "${name} battery strings"
    current:
      name: "${name} current"
    power:
      name: "${name} power"
    charging_power:
      name: "${name} charging power"
    discharging_power:
      name: "${name} discharging power"
    state_of_charge:
      name: "${name} state of charge"
    nominal_capacity:
      name: "${name} nominal capacity"
    charging_cycles:
      name: "${name} charging cycles"
    capacity_remaining:
      name: "${name} capacity remaining"
    battery_cycle_capacity:
      name: "${name} battery cycle capacity"
    total_voltage:
      name: "${name} total voltage"
    average_cell_voltage:
      name: "${name} average cell voltage"
    delta_cell_voltage:
      name: "${name} delta cell voltage"
    min_cell_voltage:
      name: "${name} min cell voltage"
    max_cell_voltage:
      name: "${name} max cell voltage"
    min_voltage_cell:
      name: "${name} min voltage cell"
    max_voltage_cell:
      name: "${name} max voltage cell"
    temperature_1:
      name: "${name} temperature 1"
    temperature_2:
      name: "${name} temperature 2"
    temperature_3:
      name: "${name} temperature 3"
    temperature_4:
      name: "${name} temperature 4"
    temperature_5:
      name: "${name} temperature 5"
    temperature_6:
      name: "${name} temperature 6"
    cell_voltage_1:
      name: "${name} cell voltage 1"
    cell_voltage_2:
      name: "${name} cell voltage 2"
    cell_voltage_3:
      name: "${name} cell voltage 3"
    cell_voltage_4:
      name: "${name} cell voltage 4"
    cell_voltage_5:
      name: "${name} cell voltage 5"
    cell_voltage_6:
      name: "${name} cell voltage 6"
    cell_voltage_7:
      name: "${name} cell voltage 7"
    cell_voltage_8:
      name: "${name} cell voltage 8"
    cell_voltage_9:
      name: "${name} cell voltage 9"
    cell_voltage_10:
      name: "${name} cell voltage 10"
    cell_voltage_11:
      name: "${name} cell voltage 11"
    cell_voltage_12:
      name: "${name} cell voltage 12"
    cell_voltage_13:
      name: "${name} cell voltage 13"
    cell_voltage_14:
      name: "${name} cell voltage 14"
    cell_voltage_15:
      name: "${name} cell voltage 15"
    cell_voltage_16:
      name: "${name} cell voltage 16"
    cell_voltage_17:
      name: "${name} cell voltage 17"
    cell_voltage_18:
      name: "${name} cell voltage 18"
    cell_voltage_19:
      name: "${name} cell voltage 19"
    cell_voltage_20:
      name: "${name} cell voltage 20"
    cell_voltage_21:
      name: "${name} cell voltage 21"
    cell_voltage_22:
      name: "${name} cell voltage 22"
    cell_voltage_23:
      name: "${name} cell voltage 23"
    cell_voltage_24:
      name: "${name} cell voltage 24"
    cell_voltage_25:
      name: "${name} cell voltage 25"
    cell_voltage_26:
      name: "${name} cell voltage 26"
    cell_voltage_27:
      name: "${name} cell voltage 27"
    cell_voltage_28:
      name: "${name} cell voltage 28"
    cell_voltage_29:
      name: "${name} cell voltage 29"
    cell_voltage_30:
      name: "${name} cell voltage 30"
    cell_voltage_31:
      name: "${name} cell voltage 31"
    cell_voltage_32:
      name: "${name} cell voltage 32"
    operation_status_bitmask:
      name: "${name} operation status bitmask"
    errors_bitmask:
      name: "${name} errors bitmask"
    balancer_status_bitmask:
      name: "${name} balancer status bitmask"
    software_version:
      name: "${name} software version"
text_sensor:
  - platform: jbd_bms_ble
    jbd_bms_ble_id: bms0
    errors:
      name: "${name} errors"
    operation_status:
      name: "${name} operation status"
    device_model:
      name: "${name} device model"
switch:
  - platform: ble_client
    ble_client_id: client0
    name: "${name} enable bluetooth connection"
  - platform: jbd_bms_ble
    jbd_bms_ble_id: bms0
    charging:
      name: "${name} charging"
    discharging:
      name: "${name} discharging"
syssi commented 2 weeks ago

Could you increse the log level and provide a complete log (in best case retrieved using a serial/USB connection)?

logger:
  level: VERY_VERBOSE
  logs:
    jbd_bms_ble: VERY_VERBOSE
    ble_client: DEBUG
    esp32_ble: DEBUG
    esp32_ble_tracker: DEBUG
    scheduler: DEBUG
    component: DEBUG
    sensor: DEBUG
    api: DEBUG
    api.service: DEBUG
HansWegman commented 2 weeks ago

Hello Sebastian, thanks for your quick response and your support. Unfortunately I do not have access to the device other than through Bluetooth since it is sealed. I added your log levels and have included the complete logs including the compilation and, in the end, where I move the device out of reach from the battery.

Hope this helps?

logs_test_run-4.txt

syssi commented 2 weeks ago

Your BMS doesn't respond. Do you have an Android app which is able to talk to the BMS? Could you share a link to this app?

HansWegman commented 2 weeks ago

No Android app but an iOS app called XiaoXiangElectric which works fine. Could it have something to do with the password I set and am unable to remove?

syssi commented 2 weeks ago

Yes. The password could probably be the root cause.

HansWegman commented 2 weeks ago

Okay, than I am stuck, I have been googling but there seems to be no way to get rid of it since my only connection option is bluetooth which won't work with a password set. Any suggestions other than breaking the seal and the guarantee of this new unit?

HansWegman commented 1 week ago

Hello Sebastian,

Any suggestions on how I can debug this further? I did find a link to an Android App which looks the same as my iPhone app if that helps: https://play.google.com/store/apps/details?id=com.jiabaida.little_elephant&hl=en_US&pli=1

syssi commented 1 week ago

Some special protocol details of your BMS model / firmware:

sendAppKeyFrame:            [FF, AA, 15, 06, 30, 30, 30, 30, 30, 30, 50]
                                                                     ^^--CRC

setFirstLevelPasswordFrame:               [FF, AA, 16, 06, 31, 32, 33, 34, 35, 36, 50] 
sendFirstLevelPasswordFrame:              [FF, AA, 18, 06, 31, 32, 33, 34, 35, 36, 50]
sendSecondLevelPasswordFrame:             [FF, AA, 1B, 06, 31, 32, 33, 34, 35, 36, 50]
                                                             ^^^^^^^^^^^^^^^^^^^^^^--6 bytes password

removePasswordFrame:          [DD, 5A, 09, 07, 06, 4A, 31, 42, 32, 44, 34, FE, 85, 77]
cleanFirstLevPswFrame:  [FF, AA, 23, 01, 01, 25]

cleanAppKeyFrame:       [FF, AA, 24, 01, 01, 20]
restoreSecondPswFrame:  [FF, AA, 1F, 01, 01, 21]

factoryResetFrame:     [FF, AA, 20, 01, 01, 22]
baseAppKeyFrame:        [FF, AA, 22, 06, 30, 30, 30, 30, 30, 30, 50]

testFrame:              [FF, AA, 1A, 42, 31, 35, 31, 36, 33, 38, 31, 32, 33, 33, 35, 34, 31, 32, 33, 33, 35, 34, 31, 32, 33, 33, 35, 34, 31, 32, 33, 33, 35, 34, 31, 32, 33, 33, 35, 34, 31, 32, 33, 33, 35, 34, 31, 32, 33, 33, 35, 34, 31, 32, 33, 33, 35, 34, 31, 32, 33, 33, 35, 34, 80]
randomFrame:            [FF, AA, 17, 00, 17]

It looks like the communication isn't using official BLE encryption/pin/authentication features. It's a custom protocol. I guess we have to send an authorization frame to establish proper communication.

syssi commented 1 week ago

Could you provide some screenshots of the Android or iOS app? I would like to understand which types of different passwords are used. It looks like the app key is something like a 6 chars value (always 000000). There is a first level password (6 chars) and second level password (6 chars) too and a root password (15 bytes).

syssi commented 1 week ago

Sorry, I have to ask another time: Are you able to borrow a Android smartphone somewhere? A BLE traffic capture would be super helpful (it's part of a standard bug report bundle and can be create pretty easily). The device doesn't need to be rooted.

HansWegman commented 1 week ago

Really appreciate your help here, thanks!

I can try to capture the BME traffic on my Mac using my iPhone I guess. I will give it a try and get back asap.

syssi commented 1 week ago

I've no experiences with iOS. A traffic capture (it called btsnoop / pcap file) would be helpful.

HansWegman commented 1 week ago

Well that went smoothly...:) See the attached log.

What I did, I removed and reinstalled the app so it would ask for the password again. I started the log I opened the app and entered the password 123123 Than the readings came in, battery 99% charged I switched to some other screens in the app I closed the app I reopened the app and this time I did not need to enter the password, I guess it saves it and uses the same or another way to connect The data reappeared

I hope this gives more insight in how to make it work. LeOr maybe it gives a pointer to remove the bluetooth password all together by maybe sending CLeanAppkeyframe or something which might do the trick as well.

Let me know if I need to get your other info, looking forward to hearing your judgement! btsnoop xiaoxiangelectric.log

HansWegman commented 1 week ago

I made a selection for you within the apple logger which might make things easier.

XiaoXiang log 2.log

syssi commented 1 week ago

Good job! This is the raw traffic:

ff:aa:15:06:30:30:30:30:30:30:3b
ff:aa:15:01:00:16
ff:aa:17:00:17
ff:aa:17:01:71:89
00:b1:2c:00:00:e5:2c:00:00:00:00
ff:aa:18:06:06:64:75:a6:90:fe:31
ff:aa:18:01:00:19
ff:aa:1d:0f:5f:f4:e4:d7:ca:3f:e8:d5:92:b1:94:a3:a1:a3:a4:62
ff:aa:1d:01:00:1e
dd:a5:03:00:ff:fd:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:f0:0b:ee:0b:eb:f9:bd:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:16:0d:15:0d:08:0d:0b:ff:86:77
dd:a5:fa:03:00:75:04:fe:8a:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:eb:0b:ee:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:16:0d:15:0d:08:0d:0b:ff:86:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:eb:0b:ee:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:16:0d:15:0d:08:0d:0b:ff:86:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:eb:0b:ee:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:15:0d:08:0d:0b:ff:87:77
dd:5a:00:02:56:78:ff:30:77
dd:00:00:00:00:00:77
dd:a5:16:00:ff:ea:77
dd:16:00:02:00:00:ff:fe:77
dd:a5:a2:00:ff:5e:77
dd:a2:00:01:00:ff:ff:77
dd:a5:a0:00:ff:60:77
dd:a0:00:06:05:44:47:4a:42:44:fe:9a:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:eb:0b:ee:0b:eb:f9:c2:77
dd:a5:15:00:ff:eb:77
dd:15:00:02:30:9b:ff:33:77
dd:a5:05:00:ff:fb:77
dd:05:00:0f:53:50:30:34:53:30:33:34:4c:34:53:32:30:30:41:fc
5a:77
dd:5a:01:02:00:00:ff:fd:77
dd:01:00:00:00:00:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:eb:0b:ee:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77:dd:04:00:08:0d:15:0d:14:0d:08:0d:0a:ff:89:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:eb:0b:ee:0b:eb:f9:c2:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:eb:0b:ee:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:15:0d:08:0d:0a:ff:88:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:eb:0b:ee:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:14:0d:08:0d:0a:ff:89:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ee:0b:eb:f9:c1:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:14:0d:08:0d:0a:ff:89:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ee:0b:eb:f9:c1:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:15:0d:08:0d:0a:ff:88:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ed:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:15:0d:08:0d:0b:ff:87:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ed:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:14:0d:08:0d:0a:ff:89:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ee:0b:eb:f9:c1:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:15:0d:08:0d:0a:ff:88:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ed:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:15:0d:08:0d:0a:ff:88:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ed:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:15:0d:08:0d:0a:ff:88:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ee:0b:eb:f9:c1:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:14:0d:08:0d:0a:ff:89:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ed:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:15:0d:08:0d:0a:ff:88:77
ff:aa:15:06:30:30:30:30:30:30:3b
ff:aa:15:01:00:16
ff:aa:17:00:17
ff:aa:17:01:e1:f9
ff:aa:18:06:76:d4:e5:16:00:6e:d1
ff:aa:18:01:00:19
ff:aa:1d:0f:cf:64:54:47:3a:af:58:45:02:21:04:13:11:13:14:f2
ff:aa:1d:01:00:1e
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ed:0b:eb:f9:c2:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ed:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:14:0d:08:0d:0a:ff:89:77
dd:a5:fa:03:00:75:04:fe:8a:77:00:b1:2c:00:00:e5:2c:00:00:00:00
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ed:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:14:0d:08:0d:0a:ff:89:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:ec:0b:ed:0b:eb:f9:c2:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:15:0d:14:0d:08:0d:0a:ff:89:77

Extract from XiaoXiang log 2.log / communication.json.txt

syssi commented 1 week ago

Long story short: Your BMS firmware supports some new / special commands to do some auth flow. We will try to replicate this behavior to get authenticated too.

HansWegman commented 1 week ago

Wow, I can read and understand the short version and that sounds absolutely marvellous! This is really highly appreciated and I am looking forward to it. Please let me know if I can be of any further help!

syssi commented 1 week ago

These are the most important parts of the communication:

# Write instructions -> Handle 0x0015
# Responses / notifications via 0x0011

>>> ff:aa:15:06:30:30:30:30:30:30:3b   # Send app key
<<< ff:aa:15:01:00:16                  # Send app key response (data_len: 1 byte, data: 0x00)
>>> ff:aa:17:00:17                     # Request random data
<<< ff:aa:17:01:71:89                  # Random data response (data_len: 1 byte, data: 0x71)

>>> Read blob request (0x0c), Handle 0x0003, Offset 19   # Device name?
<<< 00:b1:2c:00:00:e5:2c:00:00:00:00

>>> ff:aa:18:06:06:64:75:a6:90:fe:31    # Send first level password (64:75:a6:90:fe)
<<< ff:aa:18:01:00:19                   # First level password response (data_len: 1 byte, data: 0x00)

>>> ff:aa:1d:0f:5f:f4:e4:d7:ca:3f:e8:d5:92:b1:94:a3:a1:a3:a4:62    # Send root password (5f:f4:e4:d7:ca:3f:e8:d5:92:b1:94:a3:a1:a3:a4)
<<< ff:aa:1d:01:00:1e                                              # Root password response (data_len: 1, data: 0x00)

>>> dd:a5:03:00:ff:fd:77        # Request hardware info
>>> dd:a5:03:00:ff:fd:77
<<< dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:f0:0b:ee:0b:eb:f9:bd:77  # Hardware info response

>>> dd:a5:04:00:ff:fc:77    # Request cell info
<<< dd:04:00:08:0d:16:0d:15:0d:08:0d:0b:ff:86:77

>>> dd:a5:fa:03:00:75:04:fe:8a:77    # Unknown request
>>> dd:a5:03:00:ff:fd:77        # Request hardware info
<<< dd:03:00:1d:05:39:00:00:52:a8:53:34:00:01:30:9b:00:00:00:00:00:00:44:63:03:04:03:0b:eb:0b:ee:0b:eb:f9:c2:77

>>> indicates Requests. <<< are Responses.

syssi commented 1 week ago

Unusual question but could you provide your passwords for comparison?

syssi commented 1 week ago

The plaintext password is encrypted against the MAC address of the BMS. The plaintext password would be helpful to reverse engineer the encryption.

HansWegman commented 1 week ago

Sorry to only now notice your request but I already shared that, it is 123123 and that is the bluetooth password which is the only one I have set.

syssi commented 1 week ago

Oh. I missed the detail the first time.

HansWegman commented 1 week ago

Yeah, I guessed so ;). Let me know if I can help more, maybe set different passwords or so might ease the decryption?

syssi commented 1 week ago

Could you provide another capture in which you enter an incorrect (but known) password?

HansWegman commented 1 week ago

Okay, here is what I did. The password was first changed from 123123 to 123412 and the app removed and reinstalled. LOG started started the app and entered 000000 entered 111111 entered 123412, app opened and displayed data changed the password to 123123 and confirmed closed the app and reopened closed the app closed the LOG xiaoxiang [Live] - iPhone van H.log

Filtered the log on the battery only: just the battery.log

syssi commented 1 week ago

Content of the second capture: communications2.json.txt

# 1. attempt
ff:aa:15:06:30:30:30:30:30:30:3b
ff:aa:15:01:00:16
ff:aa:17:00:17
ff:aa:17:01:62:7a
00:b1:2c:00:00:e5:2c:00:00:00:00
>>> ff:aa:18:06:f6:53:69:96:7f:f0:d5    # password 000000
<<< ff:aa:18:01:01:1a
                ^^--NACK

# 2. attempt
ff:aa:15:06:30:30:30:30:30:30:3b
ff:aa:15:01:00:16
ff:aa:17:00:17
ff:aa:17:01:21:39
00:b1:2c:00:00:e5:2c:00:00:00:00
>>> ff:aa:18:06:b6:11:27:56:3d:b0:4f    # password 111111
<<< ff:aa:18:01:01:1a
                ^^--NACK

# 3. attempt
ff:aa:15:06:30:30:30:30:30:30:3b
ff:aa:15:01:00:16
ff:aa:17:00:17
ff:aa:17:01:61:79
00:b1:2c:00:00:e5:2c:00:00:00:00
>>> ff:aa:18:06:f6:54:65:91:7d:ed:c8    # password 123412
<<< ff:aa:18:01:00:19
                ^^--ACK

ff:aa:1d:0f:4f:e4:d4:c7:ba:2f:d8:c5:82:a1:84:93:91:93:94:72
ff:aa:1d:01:00:1e
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:36:00:00:4f:f2:53:34:00:01:30:9b:00:00:00:00
00:00:44:60:03:04:03:0b:b7:0b:bf:0b:b9:fa:16:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:36:ff:cb:4f:f2:53:34:00:01:30:9b:00:00:00:00
00:00:44:60:03:04:03:0b:b7:0b:bf:0b:b9:f8:4c:77

>>> ff:aa:16:06:31:32:33:31:32:33:48  # change password to 123123
<<< ff:aa:16:01:00:17
                ^^--ACK

# 4. attempt
ff:aa:15:06:30:30:30:30:30:30:3b
ff:aa:15:01:00:16
ff:aa:17:00:17
ff:aa:17:01:37:4f
>>> ff:aa:18:06:cc:2a:3b:6c:56:c4:d5    # password 123123
<<< ff:aa:18:01:00:19
                ^^--ACK

ff:aa:1d:0f:25:ba:aa:9d:90:05:ae:9b:58:77:5a:69:67:69:6a:fc
ff:aa:1d:01:00:1e
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:36:ff:ba:4f:f1:53:34:00:01:30:9b:00:00:00:00
00:00:44:60:03:04:03:0b:b7:0b:bf:0b:b9:f8:5e:77
dd:a5:03:00:ff:fd:77
dd:03:00:1d:05:36:ff:cb:4f:f1:53:34:00:01:30:9b:00:00:00:00
00:00:44:60:03:04:03:0b:b7:0b:bf:0b:b9:f8:4d:77
dd:a5:04:00:ff:fc:77
dd:04:00:08:0d:07:0d:06:0d:08:0d:08:ff:a7:77
dd:a5:fa:03:00:75:04:fe:8a:77
00:b1:2c:00:00:e5:2c:00:00:00:00
HansWegman commented 1 week ago

I am really impressed, looks like you are making progress! I was looking in Wireshark but cannot even see how you determine these packets, to me it looks completely different all together. Maybe I am using wrong settings or something. But never mind, don't let me distract you, let me know when you need me to test something! :)

Wireshark screen
syssi commented 1 week ago

I am really impressed, looks like you are making progress! I was looking in Wireshark but cannot even see how you determine these packets, to me it looks completely different all together. Maybe I am using wrong settings or something. But never mind, don't let me distract you, let me know when you need me to test something! :)

First of all you should filter for the important parts using:

bluetooth.addr == a4:c1:37:04:2d:be && (btatt.opcode == 0x1b || btatt.opcode == 0x52)

Expand the Bluetooth Attribute Protocol section and take a look at the Value: field. This is the payload per frame.

syssi commented 5 days ago

Could you try to start the App and retrieve some measurements from your BMS without any internet connection?

HansWegman commented 5 days ago

Sure, just did and no issue, got the data.

syssi commented 5 days ago

How to generate the payload of the "send first level password" frame:


>>> ff:aa:17:00:17     # Get random byte
<<< ff:aa:17:01:62:7a  # Random byte response. Value: 0x62 
>>> ff:aa:18:06:f6:53:69:96:7f:f0:d5    # Send password 000000

# Password "000000" = 0x30 0x30 0x30 0x30 0x30 0x30
# Random byte: 0x62
# MAC address: a4:c1:37:04:2d:be 

>>> hex(((0xA4^0x30 % 255) + 0x62) % 255)
'0xf6'
>>> hex(((0xC1^0x30 % 255) + 0x62) % 255)
'0x54' # <-- One off. 0x53 expected!
>>> hex(((0x37^0x30 % 255) + 0x62) % 255)
'0x69'
>>> hex(((0x04^0x30 % 255) + 0x62) % 255)
'0x96'
>>> hex(((0x2D^0x30 % 255) + 0x62) % 255)
'0x7f'
>>> hex(((0xBE^0x30 % 255) + 0x62) % 255)
'0xf0'    

# Expected output: f6:53:69:96:7f:f0
syssi commented 5 days ago
>>> ff:aa:17:00:17
<<< ff:aa:17:01:61:79  # Random byte response. Value: 0x61
>>> ff:aa:18:06:f6:54:65:91:7d:ed:c8    # password 123412

# Password "123412" = 0x31 0x32 0x33 0x34 0x31 0x32
# Random byte: 0x61
# MAC address: a4:c1:37:04:2d:be 

>>> hex(((0xA4^0x31 % 255) + 0x61) % 255)
'0xf6'
>>> hex(((0xC1^0x32 % 255) + 0x61) % 255)
'0x55' # <-- One off. 0x54 expected!
>>> hex(((0x37^0x33 % 255) + 0x61) % 255)
'0x65'
>>> hex(((0x04^0x34 % 255) + 0x61) % 255)
'0x91'
>>> hex(((0x2d^0x31 % 255) + 0x61) % 255)
'0x7d'
>>> hex(((0xbe^0x32 % 255) + 0x61) % 255)
'0xed'

# Expected output: f6:54:65:91:7d:ed
HansWegman commented 4 days ago

That's interesting! not very standard but looks like an algorithm, does it not? Do you need more examples, any specific ones maybe? Or would you like me to test possibly updated code which might support these passwords?

syssi commented 4 days ago

I will care about the so called root password as next step. This is what we have discovered already:

>>> ff:aa:15:06:30:30:30:30:30:30:3b   # Send a so called app key to the BMS
<<< ff:aa:15:01:00:16                  # BMS responds with success
>>> ff:aa:17:00:17                     # Retrieve random byte used to encrypt the password
<<< ff:aa:17:01:37:4f                  # Random byte response: Value 0x37
>>> ff:aa:18:06:cc:2a:3b:6c:56:c4:d5   # Send encrypted password (`123123`) using the algorithm above
<<< ff:aa:18:01:00:19                  # BMS responds with success (0x01) or failure (0x00)

>>> ff:aa:1d:0f:25:ba:aa:9d:90:05:ae:9b:58:77:5a:69:67:69:6a:fc    # Send root password 
<<< ff:aa:1d:01:00:1e                  # BMS responds with success (0x01) or failure (0x00)

# We are properly authenticated now and the BMS will respond with well known frames
>>> dd:a5:03:00:ff:fd:77
<<< dd:03:00:1d:05:36:ff:ba:4f:f1:53:34:00:01:30:9b:00:00:00:00

It looks like frame starting with ff:aa are control commands for the BMS module. As soon the client is properly authenticated the standard JBD BMS frames (frame starting with 0xdd) are passed to the BMS.