Hi all, just want to share a code snippet and some thoughts/ideas on how to interact with Xiaomi devices.
There are a few Xiaomi devices that have internal bluetooth module, e.g.:
Mi Flora plant sensor
Temperature and Humidity sensor
Mi Smart Scale
Mi Smart Kettle
Xiaomi uses its own proprietary authentication protocol in their devices. The protocol logic is encapsulated into a native shared library (Android JNI library) that is used to generate/encode/decode authentication tokens which must be exchanged with the central device. Xiaomi devices only allow a very short lived connection while they are expecting to receive an authentication token. Once authentication fails, device drops its connection. More info on the Xiaomi authentication protocol can be found here. Fortunately, Xiaomi devices actively advertise their data which can be easily received and decoded.
It turns out that all Xiaomi devices (that I'm aware of) use a common protocol/data structure for their advertisement messages that can be easily decoded, hence no need in establishing any direct connection with the device. I've decoded them and came up with some custom GATT definitions that describes the protocol and data structure here and here.
Here is a code snippet that shows how to decode Temperature and Humidity sensor data:
var temp = null;
var humidity = null;
var battery = null;
function getSensorData() {
NRF.findDevices(function(devices) {
if (devices[0] && devices[0].serviceData.fe95) {
var data = devices[0].serviceData.fe95;
var flag = data[11];
switch (flag) {
case 4: {
// temp
temp = (data[14] | data[15] << 8) / 10;
break;
}
case 6: {
// humidity
humidity = (data[14] | data[15] << 8) / 10;
break;
}
case 10: {
// battery
battery = devices[0].serviceData.fe95[14];
break;
}
case 13: {
// temp and humidity
temp = (data[14] | data[15] << 8) / 10;
humidity = (data[16] | data[17] << 8) / 10;
break;
}
default : {
print("Unknown flag: " + flag);
}
}
}
for (var i = 0; i < devices.length; i++) {
devices[i] = null;
}
devices = null;
}, {
filters: [
{ id: "4c:65:a8:d0:7a:ee public" }
],
timeout: 2000
}
);
}
setInterval(function () {
print("Temp: " + temp + " humidity: " + humidity + " battery: " + battery);
getSensorData();
}, 5000);
As I mentioned, all devices share the same notification data structure, hence it is easy to come up with very similar code that would decode advertisements from other Xiaomi devices by following the gatt specs that I provided.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
Hi all, just want to share a code snippet and some thoughts/ideas on how to interact with Xiaomi devices.
There are a few Xiaomi devices that have internal bluetooth module, e.g.:
Xiaomi uses its own proprietary authentication protocol in their devices. The protocol logic is encapsulated into a native shared library (Android JNI library) that is used to generate/encode/decode authentication tokens which must be exchanged with the central device. Xiaomi devices only allow a very short lived connection while they are expecting to receive an authentication token. Once authentication fails, device drops its connection. More info on the Xiaomi authentication protocol can be found here. Fortunately, Xiaomi devices actively advertise their data which can be easily received and decoded.
It turns out that all Xiaomi devices (that I'm aware of) use a common protocol/data structure for their advertisement messages that can be easily decoded, hence no need in establishing any direct connection with the device. I've decoded them and came up with some custom GATT definitions that describes the protocol and data structure here and here.
Here is a code snippet that shows how to decode Temperature and Humidity sensor data:
As I mentioned, all devices share the same notification data structure, hence it is easy to come up with very similar code that would decode advertisements from other Xiaomi devices by following the gatt specs that I provided.
PS. The provided gatt spec files is a part of Gatt Parser, Java Bluetooth Manager and Eclipse SmartHome binding that I'm working on, you may find it useful too. The official discussion thread here.
Let me know if you have any questions.