UNPKG

domotz-remote-pawn

Version:

Domotz Agent

94 lines (83 loc) 3.18 kB
/** This file is part of Domotz Agent. * Copyright (C) 2018 Domotz Ltd * * Domotz Agent is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Domotz Agent is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>. * * * * Stores the discovered Bonjour services indexed by MAC address because Bonjour discovery tends to be unreliable * between different runs. * * That is, one run a device may report SERVICE_A and SERVICE_B, the following run it may report only SERVICE_A. * * This class provides a way to enrich the latest discovery with the previous discovered services, replaying a service * if it is missing for up to 'inertia' cycles: if a service is missing for more than 'inertia' cycles it is not reported * anymore. **/ var bonjourServicesAccumulator = function (inertia) { var servicesByMac = {}; function updateServicesByMacWithNewValues(result) { keys(result).forEach(function (mac) { var device = result[mac]; if (servicesByMac[mac] === undefined) { servicesByMac[mac] = {}; } keys(device).forEach(function (service) { if (service !== '$') { servicesByMac[mac][service] = { age: 0, serviceData: device[service] }; } }); }); } function enrichResultWithStoredData(result) { keys(result).forEach(function (mac) { var stored = servicesByMac[mac]; keys(stored).forEach(function (service) { result[mac][service] = result[mac][service] || stored[service].serviceData; }); }); return result; } function cleanupExpired() { keys(servicesByMac).forEach(function (mac) { var stored = servicesByMac[mac]; keys(stored).forEach(function (service) { stored[service].age++; if (stored[service].age > inertia) { delete stored[service]; } }); }); } function getActualServices(result) { // 1 - set new results with age = 0 updateServicesByMacWithNewValues(result); // 2 - prepare result to send by mixing new and old but still valid values result = enrichResultWithStoredData(result); // 3 - delete old and not still valid data cleanupExpired(); return result; } return getActualServices; }; function keys(object) { var k = []; for (var key in object) { if (object.hasOwnProperty(key)) { k.push(key); } } return k; } module.exports._accumulator = bonjourServicesAccumulator;