UNPKG

iotagent-node-lib

Version:

IoT Agent library to interface with NGSI Context Broker

203 lines (175 loc) 6.5 kB
/* * Copyright 2016 Telefonica Investigación y Desarrollo, S.A.U * * This file is part of fiware-iotagent-lib * * fiware-iotagent-lib is free software: you can redistribute it and/or * modify it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * fiware-iotagent-lib 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public * License along with fiware-iotagent-lib. * If not, see http://www.gnu.org/licenses/. * * For those usages not covered by the GNU Affero General Public License * please contact with::daniel.moranjimenez@telefonica.com */ let registeredCommands = {}; const async = require('async'); const apply = async.apply; const logger = require('logops'); const intoTrans = require('../common/domain').intoTrans; const errors = require('../../errors'); const _ = require('underscore'); const context = { op: 'IoTAgentNGSI.InMemoryCommandRegister' }; let commandIds = 1; function findCommand(service, subservice, deviceId, name) { const keys = Object.keys(registeredCommands).filter(function filterByCriteria(item) { return ( registeredCommands[item].service === service && registeredCommands[item].subservice === subservice && registeredCommands[item].deviceId === deviceId, registeredCommands[item].name === name ); }); if (keys.length === 1) { return registeredCommands[keys[0]]; } return null; } function exists(service, subservice, deviceId, name) { const keys = _.keys(registeredCommands); for (const i in keys) { if ( registeredCommands[keys[i]].service === service && registeredCommands[keys[i]].subservice === subservice && registeredCommands[keys[i]].name === name && registeredCommands[keys[i]].deviceId === deviceId ) { return true; } } return false; } function updateCommand(service, subservice, deviceId, command, callback) { const foundCommand = findCommand(service, subservice, deviceId, command.name); if (foundCommand) { foundCommand.type = command.type; foundCommand.value = command.value; callback(null, foundCommand); } else { const deviceInfo = { service, subservice, deviceId }; callback(new errors.CommandNotFound(command.name, deviceInfo)); } } function addCommand(service, subservice, deviceId, command, callback) { if (exists(service, subservice, deviceId, command.name)) { updateCommand(service, subservice, deviceId, command, callback); } else { const storeCommand = _.clone(command); storeCommand._id = commandIds++; registeredCommands[storeCommand._id] = storeCommand; registeredCommands[storeCommand._id].creationDate = Date.now(); registeredCommands[storeCommand._id].service = service; registeredCommands[storeCommand._id].subservice = subservice; registeredCommands[storeCommand._id].deviceId = deviceId; logger.debug( context, 'Storing device command [%s] for service [%s], subservice [%s] and deviceId [%s]', command.name, storeCommand.service, storeCommand.subservice, deviceId ); callback(null); } } function getFilteredCommands(service, subservice, deviceId) { return Object.keys(registeredCommands).filter(function filterByCriteria(item) { return ( registeredCommands[item].service === service && registeredCommands[item].subservice === subservice && registeredCommands[item].deviceId === deviceId ); }); } /** * Retrieve all the commands for a given Id in a service and subservice. * * @param {Number} service Service for wich all the commands want to be retrieved. * @param {Number} subservice Subservice where the commands are stored. * @param {Number} deviceId Id of the target device for the commands. */ function listCommands(service, subservice, deviceId, callback) { const result = []; const filteredCommands = getFilteredCommands(service, subservice, deviceId); for (const i in filteredCommands) { result.push(registeredCommands[filteredCommands[i]]); } callback(null, { count: filteredCommands.length, commands: result }); } function remove(service, subservice, deviceId, name, callback) { const foundCommand = findCommand(service, subservice, deviceId, name); if (foundCommand) { delete registeredCommands[foundCommand._id]; callback(null, foundCommand); } else { const deviceInfo = { service, subservice, deviceId }; callback(new errors.CommandNotFound(name, deviceInfo)); } } function clear(callback) { registeredCommands = {}; callback(); } function getExpiredCommands(creationDate) { return Object.keys(registeredCommands).filter(function filterByDate(item) { return registeredCommands[item].creationDate < creationDate; }); } function removeFromDate(creationDate, callback) { const expiredCommands = getExpiredCommands(creationDate); const removalOrders = []; for (const i in expiredCommands) { removalOrders.push( apply( remove, registeredCommands[expiredCommands[i]].service, registeredCommands[expiredCommands[i]].subservice, registeredCommands[expiredCommands[i]].deviceId, registeredCommands[expiredCommands[i]].name ) ); } async.series(removalOrders, function (error) { if (error) { callback(error); } else { callback(null, expiredCommands); } }); } exports.add = intoTrans(context, addCommand); exports.list = intoTrans(context, listCommands); exports.remove = intoTrans(context, remove); exports.clear = intoTrans(context, clear); exports.removeFromDate = intoTrans(context, removeFromDate);