UNPKG

chimps

Version:

Spatial-temporal dynamics processor for context-aware physical spaces. We believe in an open Internet of Things.

181 lines (146 loc) 4.95 kB
/** * Copyright reelyActive 2020-2022 * We believe in an open Internet of Things */ const Raddec = require('raddec'); const Device = require('./device'); const DEFAULT_MAX_STORED_SPATEMS = 1; const DEFAULT_OBSERVED_EVENTS = [ 'position', 'location' ]; const DEFAULT_HISTORY_MILLISECONDS = 5000; const DEFAULT_PURGE_MILLISECONDS = 1000; /** * MapManager Class * Manages a JavaScript Map instance. */ class MapManager { /** * MapManager constructor * @param {Object} options The options as a JSON object. * @constructor */ constructor(options) { let self = this; options = options || {}; this.parameters = createParameters(options); this.store = new Map(); removeStaleDevices(self); } /** * Retrieve the most recent data regarding all active/specified devices. * @param {String} deviceId The device identifier. * @param {Number} deviceIdType The device identifier type. * @param {Array} properties The optional properties to include. * @param {callback} callback Function to call on completion. */ retrieveDevices(deviceId, deviceIdType, properties, callback) { let self = this; let devices = {}; let isSpecificDevice = (deviceId && deviceIdType); let isSpecificProperties = Array.isArray(properties) && (properties.length > 0); if(isSpecificDevice) { let signature = deviceId + Raddec.identifiers.SIGNATURE_SEPARATOR + deviceIdType; let isDevicePresent = self.store.has(signature); if(isDevicePresent) { let device = self.store.get(signature); devices[signature] = device.assemble(properties); return callback(devices); } } else { for(const signature of self.store.keys()) { if(isSpecificProperties) { let device = self.store.get(signature); devices[signature] = device.assemble(properties); } else { devices[signature] = {}; } } return callback(devices); } return callback(null); } /** * Retrieve the most recent context regarding all active/specified devices. * @param {Array} signatures The deviceId signatures to query. * @param {callback} callback Function to call on completion. */ retrieveContext(signatures, callback) { let self = this; let devices = {}; let isAllDevices = !signatures || (Array.isArray(signatures) && (signatures.length === 0)); if(isAllDevices) { self.store.forEach((device, signature) => { devices[signature] = device.assembleContext(); }); } else { signatures.forEach((signature) => { if(self.store.has(signature)) { devices[signature] = self.store.get(signature).assembleContext(); } }); } let isNoneFound = (Object.keys(devices).length === 0); if(!isAllDevices && isNoneFound) { return callback(null); } return callback(devices); } /** * Insert the given spatem. * @param {spatem} spatem The given spatem instance. * @param {function} handleEvent The function to call if event is triggered. */ insertSpatem(spatem, handleEvent) { let self = this; let device; let signature = spatem.deviceId + Raddec.identifiers.SIGNATURE_SEPARATOR + spatem.deviceIdType; let isDevicePresent = self.store.has(signature); if(isDevicePresent) { device = self.store.get(signature); } else { device = new Device(spatem.deviceId, spatem.deviceIdType, self.parameters); self.store.set(signature, device); } device.handleSpatem(spatem, self.parameters, handleEvent); } } /** * Remove devices with a stale spatem timestamp. * @param {MapManager} instance The MapManager instance. */ function removeStaleDevices(instance) { let staleTimestamp = Date.now() - instance.parameters.historyMilliseconds; instance.store.forEach((device, signature) => { let spatem = device.assemble().spatem; let isStale = (!spatem || (spatem.timestamp < staleTimestamp)); if(isStale) { instance.store.delete(signature); } }); setTimeout(removeStaleDevices, DEFAULT_PURGE_MILLISECONDS, instance); } /** * Create from the given options the parameters for determining and preparing * events. * @param {Object} options The options as a JSON object. */ function createParameters(options) { let maxStoredSpatems = options.maxStoredSpatems || DEFAULT_MAX_STORED_SPATEMS; let observedEvents = options.observedEvents || DEFAULT_OBSERVED_EVENTS; let historyMilliseconds = options.historyMilliseconds || DEFAULT_HISTORY_MILLISECONDS; return { maxStoredSpatems: maxStoredSpatems, observedEvents: observedEvents, historyMilliseconds: historyMilliseconds }; } module.exports = MapManager;