UNPKG

fibaro-beacon-scanner

Version:

Node.js beacon scanner based on noble that speaks to Fibaro

217 lines (172 loc) 6.68 kB
/****** Begin MODULES definition ******/ // Logger (Winston) let winston = require('winston'); const logFormatter = function (options) { return options.timestamp() + ' [' + options.level.toUpperCase() + '] ' + (options.message ? options.message : '') + (options.meta && Object.keys(options.meta).length ? '\n\t' + JSON.stringify(options.meta) : ''); }; const timestamp = function () { return new Date().toLocaleString(); }; const consoleLogger = new (winston.Logger)({ transports: [ new (winston.transports.Console)({ timestamp: timestamp, formatter: logFormatter, json: false, }) ] }); const fileLogger = new (winston.Logger)({ transports: [ new (winston.transports.File)({ timestamp: timestamp, formatter: logFormatter, filename: 'fibaro-beacon-scanner.log', maxsize: 15000000, json: false }) ] }); const consoleAndFileLogger = new (winston.Logger)({ transports: [ new (winston.transports.Console)({ timestamp: timestamp, formatter: logFormatter, json: false, }), new (winston.transports.File)({ timestamp: timestamp, formatter: logFormatter, filename: 'fibaro-beacon-scanner.log', maxsize: 15000000, json: false }) ] }); // Noble (BLE scanner) let noble = require('noble'); // Fibaro API var Fibaro = require('fibaro-api'); /****** End MODULES definition ******/ /****** Begin CLASSES definition ******/ function Pi(name, location) { this.name = name; this.location = location; } function Beacon(name, owner, address) { this.name = name; this.owner = owner; this.address = address; this.isInRange = function () { if (this.rssi < rssiTreshold) { return false; } else { return true; } } } // Timestamp Date.getTimestamp = function () { return Math.floor(Date.now() / 1000) }; /****** End CLASSES definition ******/ /*****************************************************/ /*************** SET YOUR CONFIGURATION HERE ***************/ /****** Begin CONFIGURATION ******/ // Debug mode let debugMode = true; // Fibaro HC2 // let hc2IP = "192.168.1.15"; // Home Center 2 IP address // let hc2User = "admin"; // Home Center 2 admin username // let hc2Password = "admin"; // Home Center 2 admin password // let presenceSceneID = 68; // Presence scene ID let hc2IP = "10.0.1.5"; // Home Center 2 IP address let hc2User = "jacgalka@icloud.com"; // Home Center 2 admin username let hc2Password = "J3bimnuC12a"; // Home Center 2 admin password let presenceSceneID = 44; // Presence scene ID // Raspberry Pi let piName = "Sleeping Floor Pi"; // Name of your Raspberry Pi let piLocation = "sleepingFloor"; // Location of your Raspberry Pi e.g "Kitchen" let pi = new Pi(piName, piLocation); // Beacons // let blackBeacon = new Beacon("black", "eric", "e690ac024a80"); // Beacon name, beacon owner, beacon address // let greenBeacon = new Beacon("green", "eveline", "d6feeec61549"); // Beacon name, beacon owner, beacon address let blackBeacon = new Beacon("black", "eric", "d0b5c2febb68"); // Beacon name, beacon owner, beacon address let greenBeacon = new Beacon("green", "eveline", "04a31604e7a3"); // Beacon name, beacon owner, beacon address let beacons = [blackBeacon, greenBeacon]; // BLE scanner setings let rssiTreshold = -1000; // RSSI treshold - When the RSSI of the found beacon is higher than this value the beacon is considered as not in range. let exitGracePeriod = 10 * 1000; // In miliseconds - when beacon is not found for this amount of time it it considered out of range /****** End CONFIGURATION ******/ /*****************************************************/ /****** Begin MAIN CODE block ******/ let fibaro = new Fibaro(hc2IP, hc2User, hc2Password); fibaro.call('settings/info', function (error, response, body) { if (error === null) { consoleLogger.info('Connection to HC2 established on ' + hc2IP); } else { consoleLogger.error("Couldn't connect to HC2... Check IP, username or password"); process.exit(); } }); var inRange = []; consoleLogger.info("Running BLE scanner..."); noble.on('stateChange', function (state) { if (state === 'poweredOn') { noble.startScanning([], true); } else { noble.stopScanning(); } }); noble.on('discover', function(foundBeacon) { if (foundBeacon.rssi < rssiTreshold) { // ignore return; } for (let beacon of beacons) { if (foundBeacon.id == beacon.address) { consoleLogger.info('Test'); var id = foundBeacon.id; var entered = !inRange[id]; if (entered) { consoleLogger.info('Test1'); inRange[id] = { beacon: beacon }; if (debugMode) { consoleLogger.info("Beacon entered! Owner: " + beacon.owner + " (" + beacon.name + "), RSSI: " + foundBeacon.rssi + ", Location: " + pi.location); } fileLogger.info("Beacon entered! Owner: " + beacon.owner + " (" + beacon.name + "), RSSI: " + foundBeacon.rssi + ", Location: " + pi.location); fibaro.api.scenes.start(presenceSceneID, { args: [ "{'name':'" + beacon.name + "', 'owner':'" + beacon.owner + "', 'rssi':'" + foundBeacon.rssi + "', 'status':'entered', 'location':'" + pi.location + "'}" ] }, function () {} ); } inRange[id].lastSeen = Date.now(); } } }); setInterval(function() { for (var id in inRange) { if (inRange[id].lastSeen < (Date.now() - exitGracePeriod)) { var beacon = inRange[id].beacon; if (debugMode) { consoleLogger.info("Beacon exited! Owner: " + beacon.owner + " (" + beacon.name + "), Location: " + pi.location); } fileLogger.info("Beacon exited! Owner: " + beacon.owner + " (" + beacon.name + "), Location: " + pi.location); fibaro.api.scenes.start(presenceSceneID, { args: [ "{'name':'" + beacon.name + "', 'owner':'" + beacon.owner + "', 'status':'exited', 'location':'" + pi.location + "'}" ] }, function () {} ); delete inRange[id]; } } }, exitGracePeriod / 2); /****** End MAIN CODE block ******/