Skip to content

Instantly share code, notes, and snippets.

@fascinated
Created June 28, 2020 04:19
Show Gist options
  • Save fascinated/10f7efb4cac1f8626154b13f1702c8be to your computer and use it in GitHub Desktop.
Save fascinated/10f7efb4cac1f8626154b13f1702c8be to your computer and use it in GitHub Desktop.
/*
Uses https://github.com/noble/noble / https://github.com/abandonware/noble to read temperature and humidity from the iBeacon advertising packets from the Moat Technolgies sensor (likely a branded version of OEM iB004N by AnkhMaway / Jaalee)
Before using, you need to get the Mac address of your beacon, and the beacon itself has to be configured to provide temp/humidity in the advertising packets (the Moat version is pre-configured this way, but the OEM may not be).
npm install @abandonware/noble
node read-th.js
*/
const noble = require('@abandonware/noble');
const DEVICE_MAC = '';
var last_ts = 0;
noble.on('stateChange', function(state) {
console.log('on -> stateChange: ' + state);
if (state === 'poweredOn') {
if(DEVICE_MAC) {
noble.startScanning([], true); // if we are tracking a specific device, read all of their ad packets (true=allows dupes)
} else {
noble.startScanning();
}
} else {
noble.stopScanning();
}
});
noble.on('scanStart', function() {
console.log('on -> scanStart');
});
noble.on('scanStop', function() {
console.log('on -> scanStop');
});
noble.on('discover', function(peripheral) {
// sample output
// {"id":"470be4bf20334f6f8d87bc0922b9195d","address":"d1-c4-a7-95-ed-f0","addressType":"random","connectable":true,"advertisement":{"manufacturerData":{"type":"Buffer","data":[76,0,2,21,187,128,158,42,120,150,70,159,187,191,76,24,56,186,29,91,112,74,7,0,197,100]}},"rssi":-90,"mtu":null,"state":"disconnected"}
if(!DEVICE_MAC) {
console.log('on -> discover: ' + peripheral);
return;
} else if (peripheral.address!=DEVICE_MAC) {
return;
}
if (parseInt(new Date() / 1000) - last_ts < 60) { return; } // don't print too many updates
major = peripheral.advertisement.manufacturerData.readUInt16BE(20);
minor = peripheral.advertisement.manufacturerData.readUInt16BE(22);
// the Moat technologies math subtracts an additional 0.09599609375, but it's not clear this is needed according to the SHT20 datasheet (the temp/humidity chip): https://github.com/DFRobot/DFRobot_SHT20/blob/master/Sensirion-Humidity-SHT20-Datasheet.pdf
// t = -46.85 + (( (((major & 255) << 8) | ((minor & 49152) >> 8)) / 65536) * 175.72) - 0.09599609375;
// h = -6 + (125 * (major & 65280) / 65536) - 0.75; // also not sure we need to adjust the humidity value like this
t = -46.85 + (( (((major & 255) << 8) | ((minor & 49152) >> 8)) / 65536) * 175.72);
t_f = t * 9/5 + 32;
h = -6 + (125 * (major & 65280) / 65536);
console.log((new Date).toISOString() + " " + peripheral.advertisement.manufacturerData.toString('hex').replace(/(.{4})/g, '$1 ').replace(/(^\s+|\s+$)/,'') + " • t: " + Math.round(t*10,1)/10 + "C / " + Math.round(t_f*10,1)/10 + "F, h: " + Math.round(h*10,1)/10 + "%");
last_ts = parseInt(new Date() / 1000);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment