Created
May 9, 2025 04:41
-
-
Save obiltschnig/b49ac5c5fe01c8743ff24a2be6d3bbf9 to your computer and use it in GitHub Desktop.
Access Xiaomi Mijia Temperature/Humidity Sensor via Bluetooth LE (macchina.io EDGE)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const GAP_SERVICE_ID = 0x1800; | |
const BATTERY_SERVICE_ID = 0x180F; | |
const DEVICE_NAME_CHAR_ID = 0x2A00; | |
const BATTERY_LEVEL_CHAR_ID = 0x2A19; | |
const CLIENT_CHAR_CONF_DESCR_ID = 0x2902; | |
const DEVICE_ADDRESS = '58:2D:34:35:D7:1D'; | |
const ENV_SENSORS_SERVICE_UUID = '226c0000-6476-4566-7562-66734470666d'; | |
const ENV_SENSORS_CHAR_UUID = '226caa55-6476-4566-7562-66734470666d'; | |
function parseValue(str) | |
{ | |
var parts = str.split('='); | |
if (parts.length == 2) | |
return parseFloat(parts[1]); | |
else | |
return 0.0; | |
} | |
const pmRef = serviceRegistry.findByName('io.macchina.btle.peripheralmanager'); | |
let pm; | |
if (pmRef) | |
{ | |
pm = pmRef.instance(); | |
const peripheralName = pm.findPeripheral(DEVICE_ADDRESS); | |
const peripheralRef = serviceRegistry.findByName(peripheralName); | |
const peripheral = peripheralRef.instance(); | |
peripheral.on('connected', ev => { | |
console.log('Peripheral connected: %s', peripheral.address()); | |
console.log('Device Name : %s', peripheral.deviceName()); | |
console.log('Manufacturer Name : %s', peripheral.manufacturerName()); | |
console.log('Model Number. : %s', peripheral.modelNumber()); | |
console.log('Hardware Revision : %s', peripheral.hardwareRevision()); | |
console.log('Firmware Revision : %s', peripheral.firmwareRevision()); | |
//console.log('Software Revision : %s', peripheral.softwareRevision()); | |
const serviceUUIDs = peripheral.services(); | |
for (const serviceUUID of serviceUUIDs) | |
{ | |
console.log('Service: %s', serviceUUID); | |
const charUUIDs = peripheral.characteristics(serviceUUID); | |
{ | |
for (const charUUID of charUUIDs) | |
{ | |
const char = peripheral.characteristic(serviceUUID, charUUID); | |
console.log('Characteristic %s: %O', charUUID, char); | |
} | |
} | |
} | |
const gaUUID = peripheral.serviceUUIDForAssignedNumber(GAP_SERVICE_ID); | |
if (!gaUUID.isNull()) | |
{ | |
const dnChar = peripheral.characteristicForAssignedNumber(gaUUID, DEVICE_NAME_CHAR_ID); | |
const deviceName = peripheral.readString0(dnChar.valueHandle); | |
console.log('DEVICE NAME: %s', deviceName); | |
} | |
const batUUID = peripheral.serviceUUIDForAssignedNumber(BATTERY_SERVICE_ID); | |
if (!batUUID.isNull()) | |
{ | |
const batChar = peripheral.characteristicForAssignedNumber(batUUID, BATTERY_LEVEL_CHAR_ID); | |
const level = peripheral.readUInt8(batChar.valueHandle); | |
console.log('BATTERY LEVEL: %d', level); | |
} | |
const descHandle = peripheral.handleForDescriptor(ENV_SENSORS_SERVICE_UUID, ENV_SENSORS_CHAR_UUID, peripheral.expandUUID(CLIENT_CHAR_CONF_DESCR_ID)); | |
peripheral.on('notificationReceived', ev => { | |
const values = ev.data.data.decodeString(); | |
// "T=25.2 H=52.2" | |
const parts = values.split(' '); | |
if (parts.length == 2) | |
{ | |
const temp = parseValue(parts[0]); | |
const hum = parseValue(parts[1]); | |
console.log('Temperature: %f C, Humidity: %f %', temp, hum); | |
} | |
}); | |
peripheral.writeInt16(descHandle, 1); | |
}); | |
peripheral.on('disconnected', ev => { | |
console.log('Peripheral disconnected: %s', ev.source.address()); | |
}); | |
peripheral.connectAsync(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment