patman15 / BMS_BLE-HA

This integration allows to monitor Bluetooth Low Energy (BLE) battery management systems (BMS) from within Home Assistant.
GNU Lesser General Public License v2.1
20 stars 3 forks source link

Supervolt BMS #22

Closed gerritb closed 3 months ago

gerritb commented 3 months ago

I want to add support for Supervolt BMS. I have two Supervolt POLAR LiFePO4 100Ah. There is an implementation in the reference project batmon-ha and this seems to be replicated from WoMoAtor.

I'm able to connect to the batteries through HomeAssistant on RPi4 but struggle to setup the "start_notify" callback in the connect function.

The initial device debug shows 5 service-uuids:

['00001800-0000-1000-8000-00805f9b34fb', 
 '00001801-0000-1000-8000-00805f9b34fb', 
 '0000180a-0000-1000-8000-00805f9b34fb', 
 '00002600-0000-1000-8000-00805f9b34fb', 
 '0000ff00-0000-1000-8000-00805f9b34fb']

Not sure which one to use in the code.

Pushed my first few changes here: https://github.com/gerritb/BMS_BLE-HA/tree/feature/supervolt_bms

I also added

logger:
  default: info
  logs:
    custom_components.bms_ble: debug

to my configuration.yaml but can't find a dedicated log file in the HA folders. Any advise on that?

Additional context

https://github.com/fl4p/batmon-ha/blob/master/bmslib/models/supervolt.py

https://github.com/BikeAtor/WoMoAtor/blob/main/src/main/python/supervolt/supervoltbatterybleak.py)

gerritb commented 3 months ago

Update: I used a BLE device scanner on Android and found that ff00 with ff01 for RX and ff02 for TX seems to d osomething. Getting a device timeout now. supervolt_ble

gerritb commented 3 months ago

And I was able to use the Android bluetooth snoop feature to log the packets when opening the Supervolt app, connect, and close the app after receiving the first value update. Log can be inspected using Wireshark. supervolt.log

gerritb commented 3 months ago

Seems like sending the messages from the log returns data

2024-06-16 12:13:08.107 DEBUG (MainThread) [custom_components.bms_ble] BMS SX100P-B230201 data update
2024-06-16 12:13:08.108 DEBUG (MainThread) [custom_components.bms_ble.plugins.supervolt_bms] connecting for update
2024-06-16 12:13:08.108 DEBUG (MainThread) [custom_components.bms_ble.plugins.supervolt_bms] BMS SX100P-B230201 already connected
2024-06-16 12:13:08.108 DEBUG (MainThread) [custom_components.bms_ble.plugins.supervolt_bms] sending first
2024-06-16 12:13:08.201 DEBUG (MainThread) [custom_components.bms_ble.plugins.supervolt_bms] Received BLE data
Length: 15
Data: bytearray(b"\xdd\x04\x00\x08\r\'\r&\r&\r$\xff-w")
2024-06-16 12:13:08.202 DEBUG (MainThread) [custom_components.bms_ble.plugins.supervolt_bms] sending second
2024-06-16 12:13:08.299 DEBUG (MainThread) [custom_components.bms_ble.plugins.supervolt_bms] Received BLE data
Length: 34
Data: bytearray(b"\xdd\x03\x00\x1b\x05B\x00\x00)j\'\x10\x00\x01/\x8f\x00\x00\x00\x00\x00\x00\x10d\x02\x04\x02\x0bV\x0bX\xfc\xd5w")
patman15 commented 3 months ago

Hey @gerritb, the information you provided looks pretty good, I think that way it should be possible to integrate the BMS quite fast. I usually create a fake battery to play around with using an ESP32 and try to fake all values in the app first. Then I use the fake battery to engineer the readout. Anyway from what I can see I think the implementation of the daly_bms should be a good reference as it works very similar, but with different commands. I can have a look in later next week but it seems you are making good progress!

gerritb commented 3 months ago

Interesting. You mean create a dummy on the ESP and change the response values to identify the byte/field order from the response message? I don't have a ESP32 here right now but will order one (only have spare 8266s).

patman15 commented 3 months ago

Well the data position you can gather from e.g. batmon-ha implementation, but to really verify, I used for the daly bms this emulation and checked it with the Android app. Then I verified the output of the integration so that it shows the same numbers. Since it is possible to play around quite easy it makes development faster. Of course, a test against a real battery is always more accurate, but values can be harder to be tested. Here is a simpler reference I tried to use for the JK BMS unfortunately, the Android app is broken, just as a starting point BLE_JK_BMS.zip

gerritb commented 3 months ago

Thanks, will take a look. I don't have a lot of hope for the batmon-ha implementation. I didn't work at all with my batteries, so maybe there's a new version of the BMS or they changed the protocol.

patman15 commented 3 months ago

so maybe there's a new version of the BMS or they changed the protocol.

From the information you already provided it shouldn't be too hard to get it working. I already had bigger challenges. :wink: We can get that done.

gerritb commented 3 months ago

Sounds good, the ESP32s are in the mail. Will try to emulate the battery for the app when they arrive.

gerritb commented 3 months ago

I actually asked Supervolt for the spec and they sent it to me today. Will read through it and try to get it into code.

gerritb commented 3 months ago

I'm receiving faulty data from the BMS and can't decode it. The docs have an example: Host sending: DD A5 03 00 FF FD 77 BMS response:DD 03 00 1B 17 00 00 00 02 D0 03 E8 00 00 20 78 00 00 00 00 00 00 10 48 03 0F 02 0B 76 0B 82 FB FF 77 where FB FF at the end is the chekcsum and 77 the stop byte.

Here's the layout: 0xDD | 0x03 | Status, 0 means correct, error on 0x80 | Indicates the data length, excluding itself | Data content | checksum | 0x77

I'm receiving Data: bytearray(b"\xdd\x03\x00\x1b\x05:\x00\x00(\xd0\'\x10\x00\x02/\x8f\x00\x00\x00\x00\x00\x00\x10b\x03\x04\x02\x0b\x93\x0b\x95\xfb\xfew") Which means the status is correct but the data after that corrupted. What are the ":, (, '" in that array anyways? 😅

gerritb commented 3 months ago

Python, you never fail to confuse me. The bytearrays are rendered in ascii or unicode or whatever so the weird characters are valid bytes. Using int.from_bytes(self._data[4:6], "big") did the trick.

Et voila image

gerritb commented 3 months ago

Will sanity check everything, clean up the code and open a PR

patman15 commented 3 months ago

ok, just wanted to say that I finished the update for HA2024.6 and could support you. Seems you are making fast progress. :+1: Let me know if you need some support. I created a branch for Supervolt BMS.

patman15 commented 3 months ago

@gerritb should I continue from your fork or are you still busy cleaning up?

gerritb commented 3 months ago

I'm on vacation right now and back end of next week. Will open the PR then.

gerritb commented 3 months ago

https://github.com/patman15/BMS_BLE-HA/pull/27

gerritb commented 3 months ago

I had this version running for a little over a week in my RV with two batteries now and encountered no issues :sunglasses:

Supervolt asked me to write a short blog post for their website about the integration of their batteries with HA. Will post it here when I'm done writing.

patman15 commented 3 months ago

@gerritb I moved back from the PR to here, because

Sure, here's the link to the spec: https://support.supervolt.de/attachments/token/5JUwU9qRSLVOcqV9dTOZJqAD0/?name=%5BB%5D+bt+protocol.pdf I can reach out and ask about the naming. The BL spec has a part about the model and version. I didn't include that in the PR because I wanted to get it working for the trip now 😅

Just noticed from the spec, this is a JBD BMS and I already have an implementation for it. Protocol, service and characteristics are identical. Can you provide me with an decoded advertisement of the battery from nRF connect (Android app)? Possibly in raw? Alternatively, when in debug mode (with your current implementation), you should find a log message in home-assistant.log that starts like this: DEBUG (MainThread) [custom_components.bms_ble] Bluetooth device detected: <BluetoothServiceInfoBleak ...

If you could post this, I think I can get it easily working.

gerritb commented 3 months ago

This is the output from the HA log: Bluetooth device detected: <BluetoothServiceInfoBleak name=SX100P-B230193 address=E1:24:50:6D:B2:75 rssi=-52 manufacturer_data={} service_data={} service_uuids=['00001800-0000-1000-8000-00805f9b34fb', '00001801-0000-1000-8000-00805f9b34fb', '0000180a-0000-1000-8000-00805f9b34fb', '00002600-0000-1000-8000-00805f9b34fb', '0000ff00-0000-1000-8000-00805f9b34fb'] source=hci0 connectable=True time=985257.647496741 tx_power=None>

gerritb commented 3 months ago

Let me check the nRF app since you probably want the manufacturer_data or service_data?

patman15 commented 3 months ago

Yes, I have a fake JBD device (using ESP32), but the Supervolt app does not detect it, so they are checking some additional data that I have not set yet. :sunglasses:

gerritb commented 3 months ago

I got this from the app Screenshot_20240630-163339~2

gerritb commented 3 months ago

Should the 0 responses contain more specific manufacturer data?

gerritb commented 3 months ago

or let me know how I should dump logs from the app, don't quite understand the app yet

patman15 commented 3 months ago

Can you check the first page ("scanner") with the list of devices? (Before you hit "connect") There should be a button raw, showing the advertisement in raw and when you just click on the device it should show the decoded advertisement.

gerritb commented 3 months ago

0x020106030200FF0F095358313030502D4232333032303107FF7B0002FFFF7D

gerritb commented 3 months ago

Screenshot_20240630-164519

patman15 commented 3 months ago

Got my fake battery working, now it is pretty easy to proceed. supervolt

patman15 commented 3 months ago

@gerritb can you please check release 1.5.0rc2? You can also install via HACS. It should auto detect your battery and show all values. A log would be cool just to verify.

gerritb commented 3 months ago

Works perfectly and is in sync with the values from my app

gerritb commented 3 months ago

2024-06-30 19:52:24.276 DEBUG (MainThread) [custom_components.bms_ble] BMS SX100P-B230201 data update 2024-06-30 19:52:24.277 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] BMS SX100P-B230201 already connected 2024-06-30 19:52:24.357 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] (SX100P-B230201) Rx BLE data (start): bytearray(b"\xdd\x03\x00\x1b\x05O\x00\x00)S\'\x10\x00\x03/\x8f\x00\x00\x00\x00\x00\x00\x10c\x03\x04\x02\x0b\x82\x0b\x83\xfc\x86w") 2024-06-30 19:52:24.454 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] (SX100P-B230201) Rx BLE data (start): bytearray(b'\xdd\x04\x00\x08\rG\rH\rH\rD\xfe\xa9w') 2024-06-30 19:52:24.455 DEBUG (MainThread) [custom_components.bms_ble] BMS data sample {'temp_sensors': 2, 'voltage': 13.59, 'current': 0.0, 'battery_level': 99, 'cycle_charge': 105.79, 'cycles': 3, 'temperature': 21.55, 'cell#0': 3.399, 'cell#1': 3.4, 'cell#2': 3.4, 'cell#3': 3.396, 'cycle_capacity': 1437.6861000000001, 'power': 0.0, 'battery_charging': False, 'delta_voltage': 0.004, 'rssi': -44} 2024-06-30 19:52:24.455 DEBUG (MainThread) [custom_components.bms_ble] Finished fetching SX100P-B230201 data in 0.179 seconds (success: True) 2024-06-30 19:52:38.235 DEBUG (MainThread) [custom_components.bms_ble] BMS SX100P-B230193 data update 2024-06-30 19:52:38.235 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] BMS SX100P-B230193 already connected 2024-06-30 19:52:38.303 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] (SX100P-B230193) Rx BLE data (start): bytearray(b"\xdd\x03\x00\x1b\x05M\x00\x00)A\'\x10\x00\x03/\x8f\x00\x00\x00\x00\x00\x00\x10c\x03\x04\x02\x0b\x80\x0b\x80\xfc\x9fw") 2024-06-30 19:52:38.400 DEBUG (MainThread) [custom_components.bms_ble.plugins.jbd_bms] (SX100P-B230193) Rx BLE data (start): bytearray(b'\xdd\x04\x00\x08\rD\rB\rD\r=\xfe\xbdw') 2024-06-30 19:52:38.401 DEBUG (MainThread) [custom_components.bms_ble] BMS data sample {'temp_sensors': 2, 'voltage': 13.57, 'current': 0.0, 'battery_level': 99, 'cycle_charge': 105.61, 'cycles': 3, 'temperature': 21.3, 'cell#0': 3.396, 'cell#1': 3.394, 'cell#2': 3.396, 'cell#3': 3.389, 'cycle_capacity': 1433.1277, 'power': 0.0, 'battery_charging': False, 'delta_voltage': 0.007, 'rssi': -50} 2024-06-30 19:52:38.402 DEBUG (MainThread) [custom_components.bms_ble] Finished fetching SX100P-B230193 data in 0.167 seconds (success: True) 2024-06-30 19:52:54.276 DEBUG (MainThread) [custom_components.bms_ble] BMS SX100P-B230201 data update

patman15 commented 3 months ago

Thanks for your support, release v1.5.0 should cover everything. If there is something more, please do not hesitate to open a new issue.

gerritb commented 3 months ago

Thank you too for the explanations and patience. Definitely learned a lot about BLE.