UNPKG

barnacles

Version:

Efficient processor of ambient RF decodings enabling real-time hyperlocal context. We believe in an open Internet of Things.

171 lines (148 loc) 4.38 kB
/** * Copyright reelyActive 2024-2025 * We believe in an open Internet of Things */ const DEFAULT_KEEP_ALIVE_MILLISECONDS = 5000; const DEFAULT_ACCEPT_STALE_DYNAMBS = false; const DEFAULT_ACCEPT_FUTURE_DYNAMBS = true; const DEFAULT_DYNAMB_PROPERTIES = [ 'acceleration', 'accelerationSamplingRate', 'accelerationTimeSeries', 'ammoniaConcentration', 'amperage', 'amperages', 'angleOfRotation', 'angularVelocity', 'batteryPercentage', 'batteryVoltage', 'carbonDioxideConcentration', 'carbonMonoxideConcentration', 'dissolvedOxygen', 'distance', 'elevation', 'heading', 'heartRate', 'illuminance', 'interactionDigest', 'isButtonPressed', 'isContactDetected', 'isHealthy', 'isMotionDetected', 'isLiquidDetected', 'levelPercentage', 'luminousFlux', 'magneticField', 'methaneConcentration', 'nearest', 'nitrogenDioxideConcentration', 'numberOfOccupants', 'passageCounts', 'pm1.0', 'pm2.5', 'pm10', 'position', 'pressure', 'pressures', 'relativeHumidity', 'soundPressure', 'speed', 'temperature', 'temperatures', 'txCount', 'unicodeCodePoints', 'uptime', 'velocityOverall', 'volatileOrganicCompoundsConcentration', 'voltage', 'voltages' ]; /** * DynambManager Class * Collects and manages dynambs in an in-memory database. */ class DynambManager { /** * DynambManager constructor * @param {Barnacles} barnacles The barnacles instance. * @param {StoreManager} store The data store interface. * @param {Object} options The options as a JSON object. * @constructor */ constructor(barnacles, store, options) { options = options || {}; this.dynambProperties = options.dynambProperties || DEFAULT_DYNAMB_PROPERTIES; this.keepAliveMilliseconds = options.keepAliveMilliseconds || DEFAULT_KEEP_ALIVE_MILLISECONDS; this.acceptStaleDynambs = DEFAULT_ACCEPT_STALE_DYNAMBS; this.acceptFutureDynambs = DEFAULT_ACCEPT_FUTURE_DYNAMBS; if(options.hasOwnProperty('acceptStaleDynambs')) { this.acceptStaleDynambs = options.acceptStaleDynambs; } if(options.hasOwnProperty('acceptFutureDynambs')) { this.acceptFutureDynambs = options.acceptFutureDynambs; } this.barnacles = barnacles; this.store = store; } /** * Handle the given dynamb, rejecting that which does not meet the criteria. * @param {Object} dynamb The given dynamb data. */ handleDynamb(dynamb) { let self = this; if(isValidOrCorrectedDynamb(dynamb, self)) { if(isValidOrCorrectedTimestamp(dynamb, self)) { self.store.insertDynamb(dynamb); self.barnacles.handleEvent('dynamb', dynamb); } } } } /** * Determine if the dynamb is valid, correcting it if necessary and possible. * @param {Object} dynamb The dynamic ambient data. * @param {DynambManager} instance The DynambManager instance. */ function isValidOrCorrectedDynamb(dynamb, instance) { let hasDynambProperty = false; if(!dynamb || !(typeof dynamb.deviceId === 'string') || !Number.isInteger(dynamb.deviceIdType) || !Number.isInteger(dynamb.timestamp)) { return false; } for(const property in dynamb) { if(instance.dynambProperties.includes(property)) { hasDynambProperty = true; } else if((property !== 'deviceId') && (property !== 'deviceIdType') && (property !== 'timestamp')) { delete dynamb[property]; } } return hasDynambProperty; } /** * Determine if the dynamb has a valid timestamp, correcting it if necessary * and possible. * @param {Object} dynamb The dynamic ambient data. * @param {DynambManager} instance The DynambManager instance. */ function isValidOrCorrectedTimestamp(dynamb, instance) { let currentTimestamp = Date.now(); let staleTime = currentTimestamp - instance.keepAliveMilliseconds; let isStale = (dynamb.timestamp < staleTime); let isFuture = (dynamb.timestamp > currentTimestamp); if(!isStale && !isFuture) { return true; } if((isStale && instance.acceptStaleDynambs) || (isFuture && instance.acceptFutureDynambs)) { dynamb.timestamp = currentTimestamp; return true; } return false; } module.exports = DynambManager;