Bluetooth-Devices / bthome-ble

Parser for BTHome BLE devices
https://bthome.io/
MIT License
64 stars 11 forks source link

Get BTHome V2 advertisement data (Temperature and Humidity) #118

Closed igorkietrz closed 3 months ago

igorkietrz commented 3 months ago

Hello. Is it possible to get the temperature and humidity data using python without connecting to the device?

Ernst79 commented 3 months ago

Yes, BTHome advertisements can be received by passively listening to BLE advertisements (either by passive scanning or active scanning). No connection required. Passive or active scanning can be setup with e.g bleak in python. https://bleak.readthedocs.io/en/latest/

igorkietrz commented 3 months ago

Yes, BTHome advertisements can be received by passively listening to BLE advertisements (either by passive scanning or active scanning). No connection required. Passive or active scanning can be setup with e.g bleak in python. https://bleak.readthedocs.io/en/latest/

I'm getting this data out of the advertisment:

{'0000fcd2-0000-1000-8000-00805f9b34fb': b'@\x00?\x01^\x02\x82\x08\x03\xac\x17\x0c\x83\x0b'}

Which translated to hex is:

40003f015e02820803ac170c830b

What could this mean? Or am I doing something wrong. Thanks for help in advance

Ernst79 commented 3 months ago

The format is explained here https://bthome.io/format/

Let's split it up 40 003f 015e 028208 03ac17 0c830b

40 --> After converting this to bits, we get 01000000. Note. bit 0 is the most right number, bit 7 is the most left number bit 0: 0 = False: No encryption bit 2: 0 = False: Device is sending regular data updates bit 5-7: 010 = 2: BTHome Version 2.

Sensor data needs to be converted from hex to decimals in little endian and multiplied with a factor (https://bthome.io/format/)

003f --> 00 = packet id (1 byte) 3f = 63 015e --> 01 = battery (1 byte) 5e = 94% 028208 --> 02 = temperature (2 bytes) 8208 --> read reversed as 0882 (little endian) = 2178 --> 21.78°C 03ac17 --> 03 = humidity (2 bytes) ac17 --> read reversed as 17ac (little endian) = 6060 --> 60.60% 0c830b --> 0c = voltage (2 bytes) 830b --> read reversed as 0b83 (little endian) = 2947 --> 2.947 Volt

igorkietrz commented 3 months ago

Thank you, really appreciate it :)