Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test and add support for Xiaomi Mijia Bluetooth Temperature Smart Humidity Sensor #18

Closed
vkolotov opened this issue Jan 16, 2018 · 39 comments
Assignees

Comments

@vkolotov
Copy link
Contributor

Xiaomi bluetooth temperature and humidity sensor is widely available for a cheap rice. Hopefully it is using standard GATT specification so that it can work out of the box.

@vkolotov vkolotov self-assigned this Jan 16, 2018
@dtony
Copy link

dtony commented Jan 31, 2018

Hi am really interested by this feature. I own the device myself and I am able to read temperature and humidity using this command on a Linux computer with a Bleutooth 4.0 dongle :
gatttool -b <MAC> --char-write-req --handle=0x0010 --value=0100 --listen
There is 12 readings that follows and then it is blocked but I can do ctrl-c and restart the command.

the output is in this following form :
Notification handle = 0x000e value: 54 3d 32 33 2e 36 20 48 3d 33 37 2e 33 00
It translates in ASCII to : T=23.6 H=37.3 which is a temperature of 23.6°C and a relative humidity of 37.3%
I hope this is enough to implement this sensor. If you need my help to test it, do not hesitate to ask !

@vkolotov
Copy link
Contributor Author

Hi @dtony, thanks for your input. It is planned to be implemented in the next release. It is already implemented in the GattParser, check this out: https://github.com/sputnikdev/bluetooth-gatt-parser/blob/12e2a73505232b1625ac3123fadf7043f6d0a9f0/src/test/java/org/sputnikdev/bluetooth/gattparser/GenericCharacteristicParserIntegrationTest.java#L220

It would be great if you could do the initial testing for this. Please stay tuned.

@dtony
Copy link

dtony commented Feb 5, 2018

Unfortunately I realized that my openhab installation was in a LXD container and using a a bluetooth usb dongle is not going to be easy at all. It could work with the libusb bluetooth stack but not with BlueZ.

@rliffredo
Copy link

I have just got a couple of those sensors, so I can do the testing.

@vkolotov
Copy link
Contributor Author

vkolotov commented Feb 8, 2018

Good news here is that I have managed to decode device advertising data. In short, it is quite easy to extract Temp, Humidity and battery level from the device advertising service data. Here is the data structure: https://github.com/sputnikdev/bluetooth-gatt-parser/blob/master/src/main/resources/gatt/characteristic/com.xiaomi.bluetooth.characteristic.advertised_data.xml

@rliffredo
Copy link

Awesome :)
Where should I put that definition?
In the documentation there is some reference to the fact that you can add definitions, but I have no idea how...

@vkolotov
Copy link
Contributor Author

vkolotov commented Feb 8, 2018

Give me a couple of days, I'll be releasing a new version of the binding where it is included.

@rliffredo
Copy link

OK, thanks :)

@RealLittleSherman
Copy link

Hello to all, i had a new unit, im open to tests

Regards

@RealLittleSherman
Copy link

Do you have any idea how to "decrypt" the battery info? In my case, my Hygromter send the following hex chars:

0xfd 0x44 0xec 0x1f 0x31 0x6f

In this case the ASCII transformation does not making sense.

Thanks in advance

@vkolotov
Copy link
Contributor Author

Hi @RealLittleSherman, thanks for your interested. This device is already supported in the upcoming version of the binding. I'm in the process of releasing it.

@franckFleet
Copy link

Hi,
I very apreciate the content of your work about xiaomi data advertising.
how have you find all of theses informations ?
do you have access to sources or does theses informations opened ?

@vkolotov
Copy link
Contributor Author

Hi @franckFleet,

do you have access to sources or does theses informations opened ?

I do not have access to Xiaomi sources. However it is still possible to decompile their official android apps.

how have you find all of theses informations ?

It was quite easy to fine out what each advertisement packet means by just looking at it (what's changing).

@vkolotov
Copy link
Contributor Author

Support for this device has been added in v1.1

@GerSant
Copy link

GerSant commented Mar 7, 2018

@vkolotov i try to write a HomeBridge PlugIn in NodeJS for this device, can you helpme to understand and decode the Advertisement data with noble? My twittwer is @sdnpro

Thanks for advance

@tuzzo77
Copy link

tuzzo77 commented May 31, 2018

Please someone can help me:
Where can i found temp/humidity from this bytes? Thanks.

54 3D 32 38 2E 39 20 48 3D 35 33 2E 35 00

@GerSant
Copy link

GerSant commented May 31, 2018

Hi Tuzzo, its perfectly explained in the README.md of @hannseman in the "Technical details" section of her plugin https://github.com/hannseman/homebridge-mi-hygrothermograph.

Regards

@tuzzo77
Copy link

tuzzo77 commented May 31, 2018

Thanks for the reply, but my packet length is 14 bytes and not 16 as explained in the README. Is it possible?

@GerSant
Copy link

GerSant commented May 31, 2018 via email

@tuzzo77
Copy link

tuzzo77 commented May 31, 2018

Thanks so much, but my device disconnected after few seconds:
"Disconnected MJ_HT_V1"

@tuzzo77
Copy link

tuzzo77 commented May 31, 2018

My MJ_HT_V1 got disconnected after few seconds. I receive only 14 bytes packet.

@GerSant
Copy link

GerSant commented May 31, 2018

You don´t need to establish a connection with the Hygrometer, because you don't have the secret Token to maitain the connection up, you need only "hear" the advertisement messages ;)

@tuzzo77
Copy link

tuzzo77 commented May 31, 2018

Maybe I'm reading the wrong UUID.
First UUID: 226C0000-6476-4566-7562-66734470666D
Second UUID: 226CAA55-6476-4566-7562-66734470666D.

What's inside UUID: FE95?
Thanks

@marcvandam2
Copy link

For those how are interested.

I was able to authenticate on the Xiaomi Temp sensor since yesterday. I have it working now on a rpi 3 with Android Things installed on it. With Android studio I was able to import project:
https://github.com/MiEcosystem/XmPluginSDK/tree/master/BluetoothDemo/app
with some minor changes this just works.

I can confirm that library found in https://github.com/MiEcosystem/XmPluginSDK/XmPluginSDK/BluetoothDemo/app/src/main/jniLibs/armeabi-v7a will work on rpi.
But to get it working on a normal not "Android Things" environment some extra .so library files are needed I think. Don't know that yet.

From a high level view:
Software generates a token. And sends that encrypted to sensor. Also using BLECipher.mixA method. This method needs mac of sensor and device type. Please note, device type of temp sensor is 426. Default in the project is 156. That is an other device..

        byte[] var1 = BLECipher.mixA("my mac", deviceid);
        byte[] var2 = BLECipher.encrypt(var1, this.f);

The token is then encrypted and send over the ble line. The "not encrypted token" is used together with the "answer" that is received from the sensor to give a "final answer".

        byte[] var4 = BLECipher.mixA(this.b, this.c);
        byte[] var5 = BLECipher.mixB(this.b, this.c);
        byte[] var6 = BLECipher.encrypt(var5, BLECipher.encrypt(var4, var3));

After this the device remained connected for me. No more disconnects after few seconds.

Regards,
Marc van Dam

@vkolotov
Copy link
Contributor Author

vkolotov commented Jun 5, 2018

Nice one @marcvandam2! I'll have a look later if I can add a proper authentication. Just so you know, this might be not necessary to do authentication and keep connection always open for this type of sensor (temp and humidity). Especially if you are limited with available connections. Xiaomi sensors advertise enough data without establishing connection to them. Reading these advertisements have been implemented in this binding sometime ago (two releases back I believe).

@marcvandam2
Copy link

yes. it is indeed true that tempurature is given even without authentication. By my opinion conecting to device is required. Normally after 5 seconds it throughs out the connection because no authentication took place. The fun part in that ~5 seconds it is possible to read 2 or 3 temp/hum values. But that could only be done in limited time. If a more continuation is needed authentication would be required.

In my use case these temp sensors will be used in thermostat setting. During morning hours I would like them to report to the software on an more event driven way. I want to know each temp change. Specially during morning hours.

@vkolotov
Copy link
Contributor Author

vkolotov commented Jun 5, 2018

It seems to me there is a confusion. That sensors (and some other Xiaomi sensors) constantly advertises temp and humidity readings without establishing any connections to them. It is a broadcasting mechanism in Bluetooth protocol, in other words it is 1 to many relationship, e.g. one sensor can be read/listened by many receivers (adapters) without establishing any connection to it.

@emericg
Copy link

emericg commented Aug 13, 2018

Hey guys, does anyone know if it's possible to get battery level without advertisment datas?
My bluetooth library doesn't support them (yet) unfortunately...

@GerSant
Copy link

GerSant commented Aug 14, 2018

If you do "gatttool -b BLE_MAC_ADDRESS --char-read --handle=0x0018" you will be obtain an Hexa value, yo need to convert it to uint8, thats the percent of battery life!! ;)

@emericg
Copy link

emericg commented Aug 14, 2018

Thanks for the very quick answer!
Using btgatt-client I can indeed read this value, thanks! With weird results, 70% for a fully charged ni-mh, 9x% for a new AA battery while all the screen indiator seems to be full in both case, but that is the device fault anyway...

I know why I didn't picked up this value while looking around though... the associated service, {0000180f-0000-1000-8000-00805f9b34fb} (I think) and the {00002a19-0000-1000-8000-00805f9b34fb} characteristic are just completely invisible from my bluetooth library, I'm not really sure why.
I'm using Qt Bluetooth and... there is a few undocumented caveats :-(

@vkolotov
Copy link
Contributor Author

Hi @emericg, Bluez 5.48+ makes it invisible unfortunately. And just in general newer Bluez are more unstable from my observation.

@emericg
Copy link

emericg commented Aug 15, 2018

Humm maybe that's it, I am using bluez 5.50.
But btgatt-client does report the service, and Qt Bluetooth (using the bluez D-Bus API now) doesn't?
Why is this service special though, is it just a bug?

Thanks for all these infos!

@vkolotov
Copy link
Contributor Author

Nope, it is not a bug, it is a new bloody feature... https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/battery-api.txt

@emericg
Copy link

emericg commented Aug 15, 2018

Soo, I guess it will be hidden by Bluez on linux, available instead through a new API that will maybe implemented next year on Qt Bluetooth, but will still be available directly on other OSes... Yeah that's great...

I'll just mask the battery icon dynamically if no value is available then ^^ Thanks!

@BikeAtor
Copy link

Its just ASCII:
54 3D 32 38 2E 39 20 48 3D 35 33 2E 35 00
T = 2 8 . 9 H = 5 3 . 5 EOS

@mahlich
Copy link

mahlich commented Jan 29, 2019

Hi,
i am using these sensors within openhab and the bluetooth BLE binding. I have placed one of my sensors outside and the moment the temperature is below 0°C the reading is not converted correctly. The sensors shows -0.3°C, the item reads 6553.3 °C. Do I have to adjust something for the item?
Thanks!
I just saw that there is already an open issue for that (#78), sorry for placing the question here...

@tomascrespo
Copy link

Hi! I see you know this Mi Temp Humidity sensor very well.

I'm trying to get the historical values of the sensor, but I don't know how to do it. I can sniff how the Mi Home app does it, because it doesn't do it. You need a BLE Gateway to obtain historical values of temp and humidity. Perhaps sniffing the communication between BLE Gateway and Mi Temp and Humidity sensor it could be achieved.

In another Xiaomi sensor, Mi Flower Care sensor, it is possible read historical values, playing with two handles, this way:

  1. Write the magic word 0xa00000 in handle 0x003e
  2. Read the historical entry count in handle 0x003c
  3. Write the address of the historical entry we want in 0x003e
  4. Read the values of the given address in 0x003c

If it were possible to know what are these two handles and the magic word for Mi Temp and Humidity sensor will be great.

Thanks!

Could it be that Mi Temp and Humidity sensor does not store historical values? Could it be that the values were stored in the BLE gateway? I don't think so.

@matbra
Copy link

matbra commented Oct 24, 2022

Specifically regarding fetching of historic data: This Python library is able to do that for the lywsd03mmc sensor: https://github.com/uduncanu/lywsd03mmc.

Maybe this helps with investigating how it's done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests