iotagent-node-lib 4.6.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +2 -3
- package/CHANGES_NEXT_RELEASE +1 -0
- package/Changelog +20 -0
- package/config.js +3 -1
- package/doc/README.md +1 -0
- package/doc/admin.md +39 -5
- package/doc/api.md +74 -9
- package/doc/devel/northboundinteractions.md +122 -15
- package/doc/models/models.md +260 -0
- package/doc/requirements.txt +1 -1
- package/docker/Mosquitto/Dockerfile +1 -1
- package/lib/commonConfig.js +21 -2
- package/lib/fiware-iotagent-lib.js +15 -11
- package/lib/jexlTranformsMap.js +182 -35
- package/lib/model/Command.js +11 -2
- package/lib/model/Device.js +8 -3
- package/lib/model/Group.js +5 -3
- package/lib/model/dbConn.js +53 -112
- package/lib/services/commands/commandRegistryMongoDB.js +130 -76
- package/lib/services/commands/commandService.js +3 -3
- package/lib/services/common/iotManagerService.js +3 -1
- package/lib/services/devices/deviceRegistryMemory.js +36 -0
- package/lib/services/devices/deviceRegistryMongoDB.js +161 -88
- package/lib/services/devices/deviceService.js +44 -5
- package/lib/services/devices/devices-NGSI-v2.js +6 -1
- package/lib/services/groups/groupRegistryMongoDB.js +120 -83
- package/lib/services/ngsi/entities-NGSI-v2.js +14 -1
- package/lib/services/ngsi/ngsiService.js +32 -1
- package/lib/services/northBound/contextServer-NGSI-v2.js +12 -3
- package/lib/services/northBound/contextServer.js +2 -1
- package/lib/services/northBound/deviceProvisioningServer.js +12 -3
- package/lib/services/northBound/northboundServer.js +1 -0
- package/lib/templates/createDevice.json +4 -0
- package/lib/templates/updateDevice.json +16 -0
- package/lib/templates/updateDeviceLax.json +12 -0
- package/package.json +4 -4
- package/test/functional/config-test.js +3 -2
- package/test/functional/testUtils.js +15 -4
- package/test/unit/examples/groupProvisioningRequests/provisionFullGroup.json +1 -0
- package/test/unit/expressions/jexlExpression-test.js +165 -1
- package/test/unit/general/config-multi-core-test.js +1 -2
- package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +5 -4
- package/test/unit/general/deviceService-test.js +6 -5
- package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +6 -5
- package/test/unit/mongodb/mongodb-connectionoptions-test.js +7 -39
- package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +1 -2
- package/test/unit/ngsi-ld/general/config-jsonld-contexts-test.js +1 -2
- package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +8 -5
- package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +42 -41
- package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +11 -10
- package/test/unit/ngsiv2/general/deviceService-test.js +6 -5
- package/test/unit/ngsiv2/general/https-support-test.js +1 -1
- package/test/unit/ngsiv2/lazyAndCommands/active-devices-attribute-update-test.js +4 -3
- package/test/unit/ngsiv2/lazyAndCommands/command-test.js +6 -5
- package/test/unit/ngsiv2/lazyAndCommands/lazy-devices-test.js +17 -16
- package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +10 -18
- package/test/unit/ngsiv2/ngsiService/active-devices-test.js +21 -20
- package/test/unit/ngsiv2/ngsiService/staticAttributes-test.js +8 -7
- package/test/unit/ngsiv2/plugins/alias-plugin_test.js +12 -11
- package/test/unit/ngsiv2/plugins/custom-plugin_test.js +3 -2
- package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +28 -27
- package/test/unit/ngsiv2/provisioning/device-group-api-test.js +6 -4
- package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +12 -11
- package/test/unit/ngsiv2/provisioning/device-provisioning-configGroup-api_test.js +11 -10
- package/test/unit/ngsiv2/provisioning/device-registration_test.js +5 -4
- package/test/unit/ngsiv2/provisioning/listProvisionedDevices-test.js +6 -5
- package/test/unit/ngsiv2/provisioning/provisionDeviceMultientity-test.js +1 -1
- package/test/unit/ngsiv2/provisioning/removeProvisionedDevice-test.js +5 -4
- package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +8 -7
- package/test/unit/ngsiv2/ngsiService/subscriptions-test.js +0 -326
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
24
|
const logger = require('logops');
|
|
25
|
-
const
|
|
25
|
+
const mongoose = require('mongoose');
|
|
26
26
|
const config = require('../../commonConfig');
|
|
27
27
|
const fillService = require('./../common/domain').fillService;
|
|
28
28
|
const alarmsInt = require('../common/alarmManagement').intercept;
|
|
@@ -57,27 +57,11 @@ const attributeList = [
|
|
|
57
57
|
'explicitAttrs',
|
|
58
58
|
'ngsiVersion',
|
|
59
59
|
'subscriptions',
|
|
60
|
-
'payloadType'
|
|
60
|
+
'payloadType',
|
|
61
|
+
'useCBflowControl',
|
|
62
|
+
'storeLastMeasure'
|
|
61
63
|
];
|
|
62
64
|
|
|
63
|
-
/**
|
|
64
|
-
* Generates a handler for the save device operations. The handler will take the customary error and the saved device
|
|
65
|
-
* as the parameters (and pass the serialized DAO as the callback value).
|
|
66
|
-
*
|
|
67
|
-
* @return {Function} The generated handler.
|
|
68
|
-
*/
|
|
69
|
-
function saveDeviceHandler(callback) {
|
|
70
|
-
return function saveHandler(error, deviceDAO) {
|
|
71
|
-
if (error) {
|
|
72
|
-
logger.debug(fillService(context, deviceDAO), 'Error storing device information: %s', error);
|
|
73
|
-
|
|
74
|
-
callback(new errors.InternalDbError(error));
|
|
75
|
-
} else {
|
|
76
|
-
callback(null, deviceDAO.toObject());
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
65
|
/**
|
|
82
66
|
* Create a new register for a device. The device object should contain the id, type and registrationId
|
|
83
67
|
*
|
|
@@ -97,21 +81,22 @@ function storeDevice(newDevice, callback) {
|
|
|
97
81
|
|
|
98
82
|
logger.debug(context, 'Storing device with id [%s] and type [%s]', newDevice.id, newDevice.type);
|
|
99
83
|
|
|
100
|
-
deviceObj
|
|
101
|
-
|
|
84
|
+
deviceObj
|
|
85
|
+
.save({})
|
|
86
|
+
.then((deviceDAO) => {
|
|
87
|
+
callback(null, deviceDAO.toObject());
|
|
88
|
+
})
|
|
89
|
+
.catch((error) => {
|
|
102
90
|
if (error.code === 11000) {
|
|
103
91
|
logger.debug(context, 'Tried to insert a device with duplicate ID in the database: %s', error);
|
|
104
92
|
|
|
105
|
-
callback(new errors.DuplicateDeviceId(newDevice));
|
|
93
|
+
callback(new errors.DuplicateDeviceId(newDevice), newDevice);
|
|
106
94
|
} else {
|
|
107
95
|
logger.debug(context, 'Error storing device information: %s', error);
|
|
108
96
|
|
|
109
97
|
callback(new errors.InternalDbError(error));
|
|
110
98
|
}
|
|
111
|
-
}
|
|
112
|
-
callback(null, deviceDAO.toObject());
|
|
113
|
-
}
|
|
114
|
-
});
|
|
99
|
+
});
|
|
115
100
|
}
|
|
116
101
|
|
|
117
102
|
/**
|
|
@@ -132,17 +117,17 @@ function removeDevice(id, apikey, service, subservice, callback) {
|
|
|
132
117
|
}
|
|
133
118
|
logger.debug(context, 'Removing device with id [%s]', id);
|
|
134
119
|
|
|
135
|
-
Device.model.deleteOne(condition
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
callback(new errors.InternalDbError(error));
|
|
140
|
-
} else {
|
|
120
|
+
const query = Device.model.deleteOne(condition);
|
|
121
|
+
query
|
|
122
|
+
.exec({})
|
|
123
|
+
.then(() => {
|
|
141
124
|
logger.debug(context, 'Device [%s] successfully removed.', id);
|
|
142
|
-
|
|
143
125
|
callback(null);
|
|
144
|
-
}
|
|
145
|
-
|
|
126
|
+
})
|
|
127
|
+
.catch((error) => {
|
|
128
|
+
logger.debug(context, 'Internal MongoDB Error getting device: %s', error);
|
|
129
|
+
callback(new errors.InternalDbError(error));
|
|
130
|
+
});
|
|
146
131
|
}
|
|
147
132
|
|
|
148
133
|
/**
|
|
@@ -170,7 +155,7 @@ function listDevices(type, service, subservice, limit, offset, callback) {
|
|
|
170
155
|
}
|
|
171
156
|
|
|
172
157
|
const query = Device.model.find(condition).sort();
|
|
173
|
-
|
|
158
|
+
const queryCount = Device.model.countDocuments(condition);
|
|
174
159
|
if (limit) {
|
|
175
160
|
query.limit(parseInt(limit, 10));
|
|
176
161
|
}
|
|
@@ -179,36 +164,55 @@ function listDevices(type, service, subservice, limit, offset, callback) {
|
|
|
179
164
|
query.skip(parseInt(offset, 10));
|
|
180
165
|
}
|
|
181
166
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
167
|
+
function funcQuery(cb) {
|
|
168
|
+
query
|
|
169
|
+
.exec({})
|
|
170
|
+
.then((res) => {
|
|
171
|
+
cb(null, res);
|
|
172
|
+
})
|
|
173
|
+
.catch((error) => {
|
|
174
|
+
cb(error);
|
|
188
175
|
});
|
|
189
|
-
|
|
190
|
-
)
|
|
176
|
+
}
|
|
177
|
+
function funcQueryCount(cb) {
|
|
178
|
+
queryCount
|
|
179
|
+
.exec({})
|
|
180
|
+
.then((res) => {
|
|
181
|
+
cb(null, res);
|
|
182
|
+
})
|
|
183
|
+
.catch((error) => {
|
|
184
|
+
cb(error);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
async.series([funcQuery, funcQueryCount], function (error, results) {
|
|
188
|
+
callback(error, {
|
|
189
|
+
count: results[1],
|
|
190
|
+
devices: results[0]
|
|
191
|
+
});
|
|
192
|
+
});
|
|
191
193
|
}
|
|
192
194
|
|
|
193
195
|
function findOneInMongoDB(queryParams, id, callback) {
|
|
194
196
|
const query = Device.model.findOne(queryParams);
|
|
195
197
|
query.select({ __v: 0 });
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
198
|
+
query.lean();
|
|
199
|
+
|
|
200
|
+
query
|
|
201
|
+
.exec({})
|
|
202
|
+
.then((data) => {
|
|
203
|
+
if (data) {
|
|
204
|
+
context = fillService(context, data);
|
|
205
|
+
logger.debug(context, 'Device data found: %j', data);
|
|
206
|
+
callback(null, data);
|
|
207
|
+
} else {
|
|
208
|
+
logger.debug(context, 'Device [%s] not found.', id);
|
|
209
|
+
callback(new errors.DeviceNotFound(id, queryParams));
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
.catch((error) => {
|
|
199
213
|
logger.debug(context, 'Internal MongoDB Error getting device: %s', error);
|
|
200
|
-
|
|
201
214
|
callback(new errors.InternalDbError(error));
|
|
202
|
-
}
|
|
203
|
-
context = fillService(context, data);
|
|
204
|
-
logger.debug(context, 'Device data found: %j', data);
|
|
205
|
-
callback(null, data);
|
|
206
|
-
} else {
|
|
207
|
-
logger.debug(context, 'Device [%s] not found.', id);
|
|
208
|
-
|
|
209
|
-
callback(new errors.DeviceNotFound(id, queryParams));
|
|
210
|
-
}
|
|
211
|
-
});
|
|
215
|
+
});
|
|
212
216
|
}
|
|
213
217
|
|
|
214
218
|
/**
|
|
@@ -220,7 +224,7 @@ function findOneInMongoDB(queryParams, id, callback) {
|
|
|
220
224
|
* @param {String} subservice Division inside the service (optional).
|
|
221
225
|
*/
|
|
222
226
|
function getDeviceById(id, apikey, service, subservice, callback) {
|
|
223
|
-
|
|
227
|
+
const queryParams = {
|
|
224
228
|
id,
|
|
225
229
|
service,
|
|
226
230
|
subservice
|
|
@@ -252,9 +256,9 @@ function getDevice(id, apikey, service, subservice, callback) {
|
|
|
252
256
|
|
|
253
257
|
function getByNameAndType(name, type, service, servicepath, callback) {
|
|
254
258
|
context = fillService(context, { service, subservice: servicepath });
|
|
255
|
-
|
|
256
|
-
name
|
|
257
|
-
service
|
|
259
|
+
const optionsQuery = {
|
|
260
|
+
name,
|
|
261
|
+
service,
|
|
258
262
|
subservice: servicepath
|
|
259
263
|
};
|
|
260
264
|
if (type) {
|
|
@@ -264,20 +268,23 @@ function getByNameAndType(name, type, service, servicepath, callback) {
|
|
|
264
268
|
const query = Device.model.findOne(optionsQuery);
|
|
265
269
|
|
|
266
270
|
query.select({ __v: 0 });
|
|
267
|
-
|
|
268
|
-
query
|
|
269
|
-
|
|
271
|
+
query.lean();
|
|
272
|
+
query
|
|
273
|
+
.exec({})
|
|
274
|
+
.then((data) => {
|
|
275
|
+
if (data) {
|
|
276
|
+
context = fillService(context, data);
|
|
277
|
+
logger.debug(context, 'Device data found: %j', data);
|
|
278
|
+
callback(null, data);
|
|
279
|
+
} else {
|
|
280
|
+
logger.debug(context, 'Device [%s] not found.', name);
|
|
281
|
+
callback(new errors.DeviceNotFound(name, optionsQuery));
|
|
282
|
+
}
|
|
283
|
+
})
|
|
284
|
+
.catch((error) => {
|
|
270
285
|
logger.debug(context, 'Internal MongoDB Error getting device: %s', error);
|
|
271
|
-
|
|
272
286
|
callback(new errors.InternalDbError(error));
|
|
273
|
-
}
|
|
274
|
-
callback(null, data);
|
|
275
|
-
} else {
|
|
276
|
-
logger.debug(context, 'Device [%s] not found.', name);
|
|
277
|
-
|
|
278
|
-
callback(new errors.DeviceNotFound(name, optionsQuery));
|
|
279
|
-
}
|
|
280
|
-
});
|
|
287
|
+
});
|
|
281
288
|
}
|
|
282
289
|
|
|
283
290
|
function getByName(name, service, servicepath, callback) {
|
|
@@ -314,11 +321,22 @@ function update(previousDevice, device, callback) {
|
|
|
314
321
|
data.timestamp = device.timestamp;
|
|
315
322
|
data.subscriptions = device.subscriptions;
|
|
316
323
|
data.payloadType = device.payloadType;
|
|
324
|
+
data.useCBflowControl = device.useCBflowControl;
|
|
325
|
+
data.storeLastMeasure = device.storeLastMeasure;
|
|
326
|
+
data.lastMeasure = device.lastMeasure;
|
|
317
327
|
|
|
318
328
|
/* eslint-disable-next-line new-cap */
|
|
319
329
|
const deviceObj = new Device.model(data);
|
|
320
330
|
deviceObj.isNew = false;
|
|
321
|
-
deviceObj
|
|
331
|
+
deviceObj
|
|
332
|
+
.save({})
|
|
333
|
+
.then((deviceDAO) => {
|
|
334
|
+
callback(null, deviceDAO.toObject());
|
|
335
|
+
})
|
|
336
|
+
.catch((error) => {
|
|
337
|
+
logger.debug(fillService(context, device), 'Error storing device information: %s', error);
|
|
338
|
+
callback(new errors.InternalDbError(error));
|
|
339
|
+
});
|
|
322
340
|
}
|
|
323
341
|
});
|
|
324
342
|
}
|
|
@@ -327,7 +345,14 @@ function update(previousDevice, device, callback) {
|
|
|
327
345
|
* Cleans all the information in the database, leaving it in a clean state.
|
|
328
346
|
*/
|
|
329
347
|
function clear(callback) {
|
|
330
|
-
|
|
348
|
+
mongoose.connection
|
|
349
|
+
.dropDatabase()
|
|
350
|
+
.then(() => {
|
|
351
|
+
callback(null);
|
|
352
|
+
})
|
|
353
|
+
.catch((error) => {
|
|
354
|
+
callback(error);
|
|
355
|
+
});
|
|
331
356
|
}
|
|
332
357
|
|
|
333
358
|
function itemToObject(i) {
|
|
@@ -355,24 +380,72 @@ function getDevicesByAttribute(name, value, service, subservice, callback) {
|
|
|
355
380
|
|
|
356
381
|
const query = Device.model.find(filter);
|
|
357
382
|
query.select({ __v: 0 });
|
|
358
|
-
|
|
359
|
-
query
|
|
360
|
-
|
|
383
|
+
query.lean();
|
|
384
|
+
query
|
|
385
|
+
.exec({})
|
|
386
|
+
.then((devices) => {
|
|
387
|
+
if (devices) {
|
|
388
|
+
callback(null, devices.map(itemToObject));
|
|
389
|
+
} else {
|
|
390
|
+
logger.debug(context, 'Device [%s] not found.', name);
|
|
391
|
+
callback(new errors.DeviceNotFound(name, filter));
|
|
392
|
+
}
|
|
393
|
+
})
|
|
394
|
+
.catch((error) => {
|
|
361
395
|
logger.debug(context, 'Internal MongoDB Error getting device: %s', error);
|
|
362
|
-
|
|
363
396
|
callback(new errors.InternalDbError(error));
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
} else {
|
|
367
|
-
logger.debug(context, 'Device [%s] not found.', name);
|
|
397
|
+
});
|
|
398
|
+
}
|
|
368
399
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
400
|
+
function storeDeviceField(fieldName, fieldValue, typeInformation, callback) {
|
|
401
|
+
if (
|
|
402
|
+
typeInformation &&
|
|
403
|
+
typeInformation.id &&
|
|
404
|
+
typeInformation.apikey &&
|
|
405
|
+
typeInformation.service &&
|
|
406
|
+
typeInformation.subservice
|
|
407
|
+
) {
|
|
408
|
+
getDevice(
|
|
409
|
+
typeInformation.id,
|
|
410
|
+
typeInformation.apikey,
|
|
411
|
+
typeInformation.service,
|
|
412
|
+
typeInformation.subservice,
|
|
413
|
+
function (error, data) {
|
|
414
|
+
if (error) {
|
|
415
|
+
callback(error);
|
|
416
|
+
} else {
|
|
417
|
+
if (fieldName === 'lastMeasure') {
|
|
418
|
+
data.lastMeasure = { timestamp: new Date().toISOString(), measure: fieldValue };
|
|
419
|
+
} else {
|
|
420
|
+
data[fieldName] = fieldValue;
|
|
421
|
+
}
|
|
422
|
+
/* eslint-disable-next-line new-cap */
|
|
423
|
+
const deviceObj = new Device.model(data);
|
|
424
|
+
deviceObj.isNew = false;
|
|
425
|
+
deviceObj
|
|
426
|
+
.save({})
|
|
427
|
+
.then((deviceDao) => {
|
|
428
|
+
callback(null, deviceDao.toObject());
|
|
429
|
+
})
|
|
430
|
+
.catch((error) => {
|
|
431
|
+
logger.debug(
|
|
432
|
+
fillService(context, deviceObj),
|
|
433
|
+
'Error storing device information: %s',
|
|
434
|
+
error
|
|
435
|
+
);
|
|
436
|
+
callback(new errors.InternalDbError(error));
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
);
|
|
441
|
+
} else {
|
|
442
|
+
callback(null, null);
|
|
443
|
+
}
|
|
372
444
|
}
|
|
373
445
|
|
|
374
446
|
exports.getDevicesByAttribute = alarmsInt(constants.MONGO_ALARM, getDevicesByAttribute);
|
|
375
447
|
exports.store = alarmsInt(constants.MONGO_ALARM, storeDevice);
|
|
448
|
+
exports.storeDeviceField = alarmsInt(constants.MONGO_ALARM, storeDeviceField);
|
|
376
449
|
exports.update = alarmsInt(constants.MONGO_ALARM, update);
|
|
377
450
|
exports.remove = alarmsInt(constants.MONGO_ALARM, removeDevice);
|
|
378
451
|
exports.list = alarmsInt(constants.MONGO_ALARM, listDevices);
|
|
@@ -40,6 +40,8 @@ const registrationUtils = require('./registrationUtils');
|
|
|
40
40
|
const subscriptions = require('../ngsi/subscriptionService');
|
|
41
41
|
const expressionPlugin = require('./../../plugins/expressionPlugin');
|
|
42
42
|
const pluginUtils = require('./../../plugins/pluginUtils');
|
|
43
|
+
const alarms = require('../common/alarmManagement');
|
|
44
|
+
const constants = require('../../constants');
|
|
43
45
|
const _ = require('underscore');
|
|
44
46
|
const context = {
|
|
45
47
|
op: 'IoTAgentNGSI.DeviceService'
|
|
@@ -179,6 +181,12 @@ function mergeDeviceWithConfiguration(fields, defaults, deviceData, configuratio
|
|
|
179
181
|
if (configuration && configuration.payloadType !== undefined && deviceData.payloadType === undefined) {
|
|
180
182
|
deviceData.payloadType = configuration.payloadType;
|
|
181
183
|
}
|
|
184
|
+
if (configuration && configuration.useCBflowControl !== undefined && deviceData.useCBflowControl === undefined) {
|
|
185
|
+
deviceData.useCBflowControl = configuration.useCBflowControl;
|
|
186
|
+
}
|
|
187
|
+
if (configuration && configuration.storeLastMeasure !== undefined && deviceData.storeLastMeasure === undefined) {
|
|
188
|
+
deviceData.storeLastMeasure = configuration.storeLastMeasure;
|
|
189
|
+
}
|
|
182
190
|
logger.debug(context, 'deviceData after merge with conf: %j', deviceData);
|
|
183
191
|
callback(null, deviceData);
|
|
184
192
|
}
|
|
@@ -244,7 +252,7 @@ function registerDevice(deviceObj, callback) {
|
|
|
244
252
|
/* eslint-disable-next-line no-unused-vars */
|
|
245
253
|
function (error, device) {
|
|
246
254
|
if (!error) {
|
|
247
|
-
innerCb(new errors.DuplicateDeviceId(deviceObj));
|
|
255
|
+
innerCb(new errors.DuplicateDeviceId(deviceObj), device);
|
|
248
256
|
} else {
|
|
249
257
|
innerCb();
|
|
250
258
|
}
|
|
@@ -277,7 +285,20 @@ function registerDevice(deviceObj, callback) {
|
|
|
277
285
|
deviceData.ngsiVersion = configuration.ngsiVersion;
|
|
278
286
|
}
|
|
279
287
|
}
|
|
280
|
-
|
|
288
|
+
// Set polling and transport for autoprovisioned devices
|
|
289
|
+
if (!deviceData.transport && config.getConfig().defaultTransport) {
|
|
290
|
+
deviceData.transport =
|
|
291
|
+
configuration && configuration.transport
|
|
292
|
+
? configuration.transport
|
|
293
|
+
: config.getConfig().defaultTransport;
|
|
294
|
+
}
|
|
295
|
+
if (deviceData.transport === 'HTTP') {
|
|
296
|
+
if (deviceData.endpoint) {
|
|
297
|
+
deviceData.polling = false;
|
|
298
|
+
} else {
|
|
299
|
+
deviceData.polling = !(configuration && configuration.endpoint);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
281
302
|
if (!deviceData.name) {
|
|
282
303
|
let entityName = null;
|
|
283
304
|
if (configuration && configuration.entityNameExp !== undefined && configuration.entityNameExp !== '') {
|
|
@@ -285,7 +306,7 @@ function registerDevice(deviceObj, callback) {
|
|
|
285
306
|
let attrList = pluginUtils.getIdTypeServSubServiceFromDevice(deviceData);
|
|
286
307
|
attrList = deviceData.staticAttributes ? attrList.concat(deviceData.staticAttributes) : attrList;
|
|
287
308
|
attrList = configuration.staticAttributes ? attrList.concat(configuration.staticAttributes) : attrList;
|
|
288
|
-
|
|
309
|
+
const ctxt = expressionPlugin.extractContext(attrList);
|
|
289
310
|
try {
|
|
290
311
|
entityName = expressionPlugin.applyExpression(configuration.entityNameExp, ctxt, deviceData);
|
|
291
312
|
} catch (e) {
|
|
@@ -357,6 +378,12 @@ function registerDevice(deviceObj, callback) {
|
|
|
357
378
|
if ('apikey' in deviceData && deviceData.apikey !== undefined) {
|
|
358
379
|
deviceObj.apikey = deviceData.apikey;
|
|
359
380
|
}
|
|
381
|
+
if ('transport' in deviceData && deviceData.transport !== undefined) {
|
|
382
|
+
deviceObj.transport = deviceData.transport;
|
|
383
|
+
}
|
|
384
|
+
if ('polling' in deviceData && deviceData.polling !== undefined) {
|
|
385
|
+
deviceObj.polling = deviceData.polling;
|
|
386
|
+
}
|
|
360
387
|
logger.debug(context, 'Storing device :\n%s', JSON.stringify(deviceObj, null, 4));
|
|
361
388
|
config.getRegistry().store(deviceObj, callback);
|
|
362
389
|
}
|
|
@@ -616,7 +643,7 @@ function findOrCreate(deviceId, apikey, group, callback) {
|
|
|
616
643
|
} else if (error.name === 'DEVICE_NOT_FOUND') {
|
|
617
644
|
const newDevice = {
|
|
618
645
|
id: deviceId,
|
|
619
|
-
apikey
|
|
646
|
+
apikey,
|
|
620
647
|
service: group.service,
|
|
621
648
|
subservice: group.subservice,
|
|
622
649
|
type: group.type
|
|
@@ -639,7 +666,14 @@ function findOrCreate(deviceId, apikey, group, callback) {
|
|
|
639
666
|
if (group.autoprovision === undefined || group.autoprovision === true) {
|
|
640
667
|
logger.debug(context, 'Registering autoprovision of Device %j for its conf %j', newDevice, group);
|
|
641
668
|
registerDevice(newDevice, function (error, device) {
|
|
642
|
-
|
|
669
|
+
if (error && error.name === 'DUPLICATE_DEVICE_ID') {
|
|
670
|
+
alarms.release(constants.MONGO_ALARM, error);
|
|
671
|
+
logger.warn(context, 'Error %j already registered autoprovisioned device: %j ', error, device);
|
|
672
|
+
callback(null, device, group);
|
|
673
|
+
} else {
|
|
674
|
+
logger.debug(context, 'registered autoprovisioned device: %j ', device);
|
|
675
|
+
callback(error, device, group);
|
|
676
|
+
}
|
|
643
677
|
});
|
|
644
678
|
} else {
|
|
645
679
|
logger.info(
|
|
@@ -692,6 +726,10 @@ function retrieveDevice(deviceId, apiKey, callback) {
|
|
|
692
726
|
}
|
|
693
727
|
}
|
|
694
728
|
|
|
729
|
+
function storeDeviceField(fieldName, fieldValue, typeInformation, callback) {
|
|
730
|
+
config.getRegistry().storeDeviceField(fieldName, fieldValue, typeInformation, callback);
|
|
731
|
+
}
|
|
732
|
+
|
|
695
733
|
exports.listDevices = intoTrans(context, checkRegistry)(listDevices);
|
|
696
734
|
exports.listDevicesWithType = intoTrans(context, checkRegistry)(listDevicesWithType);
|
|
697
735
|
exports.getDevice = intoTrans(context, checkRegistry)(getDevice);
|
|
@@ -708,4 +746,5 @@ exports.retrieveDevice = intoTrans(context, checkRegistry)(retrieveDevice);
|
|
|
708
746
|
exports.mergeDeviceWithConfiguration = mergeDeviceWithConfiguration;
|
|
709
747
|
exports.findOrCreate = findOrCreate;
|
|
710
748
|
exports.findConfigurationGroup = findConfigurationGroup;
|
|
749
|
+
exports.storeDeviceField = storeDeviceField;
|
|
711
750
|
exports.init = init;
|
|
@@ -285,7 +285,12 @@ function updateRegisterDeviceNgsi2(deviceObj, previousDevice, entityInfoUpdated,
|
|
|
285
285
|
if ('transport' in newDevice && newDevice.transport !== undefined) {
|
|
286
286
|
oldDevice.transport = newDevice.transport;
|
|
287
287
|
}
|
|
288
|
-
|
|
288
|
+
if ('useCBflowControl' in newDevice && newDevice.useCBflowControl !== undefined) {
|
|
289
|
+
oldDevice.useCBflowControl = newDevice.useCBflowControl;
|
|
290
|
+
}
|
|
291
|
+
if ('storeLastMeasure' in newDevice && newDevice.storeLastMeasure !== undefined) {
|
|
292
|
+
oldDevice.storeLastMeasure = newDevice.storeLastMeasure;
|
|
293
|
+
}
|
|
289
294
|
callback(null, oldDevice);
|
|
290
295
|
} else {
|
|
291
296
|
callback(new errors.DeviceNotFound(newDevice.id, newDevice));
|