UNPKG

domotz-remote-pawn

Version:

Domotz Agent

167 lines (144 loc) 6.17 kB
/** This file is part of Domotz Agent. * Copyright (C) 2016 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/>. * * Maintains a cache with the devices list, as the engine knows it * * Created by Tommaso Latini <tommaso@domotz.com> on 23/09/15. */ var devicesInfo = function (q, async, time, engineRequest, configuration) { var toMs = time.toMs; var maxCacheAge = configuration.device_cache_duration || toMs(0, 10); var servicesRunInterval = configuration.cache_expiration_time || toMs(6); var devicesCache = null; var servicesExecutions = {}; var cacheFillTime = null; var deviceFetchQueue = async.queue(_getList, 1); function _handleError(error) { console.warn("DeviceCache: Cannot fetch devices list from engine"); console.warn(JSON.stringify(error)); } function isCacheValid() { "use strict"; var currentCacheAge = new Date() - (cacheFillTime || 0); return devicesCache !== null && currentCacheAge <= maxCacheAge; } function _getList(_, callback) { "use strict"; _ = null; // ignore parameter, suppress js lint error if (isCacheValid()) { console.debug("DeviceCache: Devices cache valid, returning it"); callback(devicesCache); } else { if (devicesCache === null) { console.info("DeviceCache: Devices cache empty, filling it"); } else { console.info("DeviceCache: Devices cache expired, refreshing it"); } engineRequest.sendWithPromise('/device', 'GET', {}) .then(function (devicesList) { console.info("DeviceCache: engine reply arrived"); devicesCache = {}; devicesList.forEach(function (device) { devicesCache[device.mac] = device; }); cacheFillTime = new Date(); }) .catch(function (error) { _handleError(error); }).finally(function () { callback(devicesCache); }); } } function getList() { var deferred = q.defer(); deviceFetchQueue.push(['devices'], function (deviceList) { deferred.resolve(deviceList); }); return deferred.promise; } function assureServiceExecutionExists(mac, service) { "use strict"; servicesExecutions[mac] = servicesExecutions[mac] || {}; servicesExecutions[mac][service] = servicesExecutions[mac][service] || {last_run: null}; } function isToBeUpdated(mac, service) { assureServiceExecutionExists(mac, service); var oldOrMissing = false; if (servicesExecutions[mac][service].last_run === null) { oldOrMissing = true; console.debug("DeviceDiscovery: %s for device with mac %s has not executed yet", service, mac); } else { var elapsed = new Date() - servicesExecutions[mac][service].last_run; oldOrMissing = elapsed > servicesRunInterval; if (oldOrMissing) { console.info("DeviceDiscovery: %s last run too old for device with mac %s (%s seconds)", service, mac, (elapsed / 1000)); } } return oldOrMissing; } function setUpdateTimeToNow(mac, service) { "use strict"; assureServiceExecutionExists(mac, service); servicesExecutions[mac][service].last_run = new Date(); console.info("DeviceDiscovery: %s last run set now: %s " + servicesExecutions[mac][service].last_run, service, mac); } function get(mac) { return getList().then(function (devicesList) { if (devicesList[mac] === undefined) { console.info("DeviceCache: cache miss for device " + mac); return forceRefreshList().then(function () { console.debug("DeviceCache: device just fetched from Engine: " + mac + " - " + JSON.stringify(devicesCache[mac])); return devicesCache[mac]; }); } else { var deferred = q.defer(); deferred.resolve(devicesList[mac]); console.debug("DeviceCache: hit for device " + mac + " - " + JSON.stringify(devicesList[mac])); return deferred.promise; } }); } function forceRefreshList() { "use strict"; console.info("DeviceCache: forcing refresh"); devicesCache = null; return getList(); } function getDevicesCache(){ if(devicesCache){ return devicesCache; } else{ return {}; } } return { isToBeUpdated: isToBeUpdated, get: get, getList: getList, invalidateList: forceRefreshList, setUpdateTimeToNow: setUpdateTimeToNow, getDevicesCache: getDevicesCache }; } ; module.exports.factory = devicesInfo;