Skip to content

Instantly share code, notes, and snippets.

@obiltschnig
Created May 9, 2025 04:41
Show Gist options
  • Save obiltschnig/b49ac5c5fe01c8743ff24a2be6d3bbf9 to your computer and use it in GitHub Desktop.
Save obiltschnig/b49ac5c5fe01c8743ff24a2be6d3bbf9 to your computer and use it in GitHub Desktop.
Access Xiaomi Mijia Temperature/Humidity Sensor via Bluetooth LE (macchina.io EDGE)
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