iotagent-node-lib 4.5.0 → 4.7.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.
Files changed (124) hide show
  1. package/.github/workflows/ci.yml +0 -1
  2. package/Changelog +12 -0
  3. package/README.md +67 -272
  4. package/config.js +3 -1
  5. package/doc/README.md +1 -1
  6. package/doc/admin.md +40 -18
  7. package/doc/api.md +532 -136
  8. package/doc/deprecated.md +4 -0
  9. package/doc/devel/architecture.md +5 -135
  10. package/doc/devel/development.md +224 -12
  11. package/doc/getting-started.md +114 -53
  12. package/doc/requirements.txt +1 -1
  13. package/doc/roadmap.md +5 -5
  14. package/docker/Mosquitto/Dockerfile +2 -2
  15. package/docker/Mosquitto/README.md +14 -11
  16. package/lib/commonConfig.js +21 -2
  17. package/lib/constants.js +3 -0
  18. package/lib/fiware-iotagent-lib.js +12 -15
  19. package/lib/jexlTranformsMap.js +3 -1
  20. package/lib/model/Command.js +2 -2
  21. package/lib/model/Device.js +7 -3
  22. package/lib/model/Group.js +5 -3
  23. package/lib/model/dbConn.js +53 -115
  24. package/lib/services/commands/commandRegistryMongoDB.js +115 -75
  25. package/lib/services/common/alarmManagement.js +3 -0
  26. package/lib/services/common/iotManagerService.js +3 -1
  27. package/lib/services/devices/deviceRegistryMemory.js +36 -0
  28. package/lib/services/devices/deviceRegistryMongoDB.js +160 -87
  29. package/lib/services/devices/deviceService.js +33 -3
  30. package/lib/services/devices/devices-NGSI-v2.js +6 -1
  31. package/lib/services/groups/groupRegistryMongoDB.js +120 -83
  32. package/lib/services/groups/groupService.js +1 -1
  33. package/lib/services/ngsi/entities-NGSI-LD.js +320 -570
  34. package/lib/services/ngsi/entities-NGSI-v2.js +51 -3
  35. package/lib/services/ngsi/ngsiService.js +34 -1
  36. package/lib/services/northBound/deviceGroupAdministrationServer.js +42 -6
  37. package/lib/services/northBound/deviceProvisioningServer.js +12 -4
  38. package/lib/services/northBound/northboundServer.js +2 -0
  39. package/lib/services/stats/statsRegistry.js +128 -101
  40. package/lib/templates/createDevice.json +0 -24
  41. package/lib/templates/createDeviceLax.json +0 -23
  42. package/lib/templates/deviceGroup.json +1 -25
  43. package/lib/templates/updateDevice.json +12 -24
  44. package/lib/templates/updateDeviceLax.json +12 -23
  45. package/package.json +5 -5
  46. package/scripts/legacy_expression_tool/README.md +0 -1
  47. package/test/functional/README.md +22 -17
  48. package/test/functional/config-test.js +3 -2
  49. package/test/functional/functional-tests-runner.js +9 -4
  50. package/test/functional/functional-tests.js +4 -4
  51. package/test/functional/testCases.js +245 -4
  52. package/test/functional/testUtils.js +2 -2
  53. package/test/unit/examples/deviceProvisioningRequests/provisionFullDevice.json +1 -13
  54. package/test/unit/examples/groupProvisioningRequests/multipleConfigGroupsCreation.json +44 -0
  55. package/test/unit/examples/groupProvisioningRequests/provisionDuplicateConfigGroup.json +35 -0
  56. package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroup.json +36 -0
  57. package/test/unit/examples/groupProvisioningRequests/provisionFullConfigGroupAlternate.json +36 -0
  58. package/test/unit/examples/groupProvisioningRequests/provisionFullGroup.json +1 -0
  59. package/test/unit/general/config-multi-core-test.js +1 -2
  60. package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +5 -4
  61. package/test/unit/general/deviceService-test.js +106 -3
  62. package/test/unit/general/statistics-service_test.js +1 -74
  63. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +6 -5
  64. package/test/unit/mongodb/mongodb-configGroup-registry-test.js +452 -0
  65. package/test/unit/mongodb/mongodb-connectionoptions-test.js +9 -42
  66. package/test/unit/mongodb/mongodb-group-registry-test.js +34 -33
  67. package/test/unit/mongodb/mongodb-service-registry-test.js +477 -0
  68. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin1a.json +4 -4
  69. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin2.json +22 -22
  70. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin29.json +4 -4
  71. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin32.json +14 -15
  72. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin1.json +23 -23
  73. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin15.json +0 -5
  74. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin4.json +11 -16
  75. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin5.json +23 -28
  76. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin6.json +8 -13
  77. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin7.json +0 -5
  78. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin8.json +24 -29
  79. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +12 -17
  80. package/test/unit/ngsi-ld/examples/contextRequests/updateContextStaticLinkedAttributes.json +12 -10
  81. package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +1 -104
  82. package/test/unit/ngsi-ld/general/config-jsonld-contexts-test.js +1 -2
  83. package/test/unit/ngsi-ld/plugins/multientity-plugin_test.js +4 -5
  84. package/test/unit/ngsi-ld/provisioning/listProvisionedDevices-test.js +0 -4
  85. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +8 -5
  86. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +42 -41
  87. package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +11 -10
  88. package/test/unit/ngsiv2/general/deviceService-test.js +98 -4
  89. package/test/unit/ngsiv2/general/https-support-test.js +1 -1
  90. package/test/unit/ngsiv2/general/iotam-autoregistration-test.js +195 -0
  91. package/test/unit/ngsiv2/lazyAndCommands/active-devices-attribute-update-test.js +4 -3
  92. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +6 -5
  93. package/test/unit/ngsiv2/lazyAndCommands/lazy-devices-test.js +17 -16
  94. package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +10 -18
  95. package/test/unit/ngsiv2/ngsiService/active-devices-test.js +21 -20
  96. package/test/unit/ngsiv2/ngsiService/staticAttributes-test.js +8 -7
  97. package/test/unit/ngsiv2/plugins/alias-plugin_test.js +12 -11
  98. package/test/unit/ngsiv2/plugins/custom-plugin_test.js +3 -2
  99. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +28 -27
  100. package/test/unit/ngsiv2/provisioning/device-group-api-test.js +265 -4
  101. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +12 -11
  102. package/test/unit/ngsiv2/provisioning/device-provisioning-configGroup-api_test.js +1190 -0
  103. package/test/unit/ngsiv2/provisioning/device-registration_test.js +5 -4
  104. package/test/unit/ngsiv2/provisioning/listProvisionedDevices-test.js +6 -9
  105. package/test/unit/ngsiv2/provisioning/provisionDeviceMultientity-test.js +1 -1
  106. package/test/unit/ngsiv2/provisioning/removeProvisionedDevice-test.js +5 -4
  107. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +8 -7
  108. package/test/unit/statsRegistry/openmetrics-test.js +167 -0
  109. package/lib/templates/queryContext.json +0 -25
  110. package/test/unit/examples/deviceProvisioningRequests/provisionBidirectionalDevice.json +0 -35
  111. package/test/unit/examples/deviceProvisioningRequests/provisionDeviceBidirectionalGroup.json +0 -17
  112. package/test/unit/examples/groupProvisioningRequests/bidirectionalGroup.json +0 -31
  113. package/test/unit/general/statistics-persistence_test.js +0 -121
  114. package/test/unit/ngsi-ld/examples/contextRequests/createBidirectionalDevice.json +0 -17
  115. package/test/unit/ngsi-ld/examples/contextRequests/updateContextProcessTimestamp.json +0 -12
  116. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
  117. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +0 -21
  118. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -17
  119. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -23
  120. package/test/unit/ngsi-ld/plugins/timestamp-processing-plugin_test.js +0 -132
  121. package/test/unit/ngsiv2/examples/contextRequests/createBidirectionalDevice.json +0 -8
  122. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotification.json +0 -13
  123. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +0 -19
  124. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json +0 -24
@@ -22,7 +22,7 @@
22
22
  */
23
23
 
24
24
  const logger = require('logops');
25
- const dbService = require('../../model/dbConn');
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,8 +81,12 @@ 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.save(function saveHandler(error, deviceDAO) {
101
- if (error) {
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
 
@@ -108,10 +96,7 @@ function storeDevice(newDevice, callback) {
108
96
 
109
97
  callback(new errors.InternalDbError(error));
110
98
  }
111
- } else {
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, function (error) {
136
- if (error) {
137
- logger.debug(context, 'Internal MongoDB Error getting device: %s', error);
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
- async.series(
183
- [query.exec.bind(query), Device.model.countDocuments.bind(Device.model, condition)],
184
- function (error, results) {
185
- callback(error, {
186
- count: results[1],
187
- devices: results[0]
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
- query.lean().exec(function handleGet(error, data) {
198
- if (error) {
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
- } else if (data) {
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
- let queryParams = {
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
- let optionsQuery = {
256
- name: name,
257
- service: 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.lean().exec(function handleGet(error, data) {
269
- if (error) {
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
- } else if (data) {
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.save(saveDeviceHandler(callback));
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
- dbService.db.db.dropDatabase(callback);
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.exec(function handleGet(error, devices) {
360
- if (error) {
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
- } else if (devices) {
365
- callback(null, devices.map(itemToObject));
366
- } else {
367
- logger.debug(context, 'Device [%s] not found.', name);
397
+ });
398
+ }
368
399
 
369
- callback(new errors.DeviceNotFound(name, filter));
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);
@@ -179,6 +179,12 @@ function mergeDeviceWithConfiguration(fields, defaults, deviceData, configuratio
179
179
  if (configuration && configuration.payloadType !== undefined && deviceData.payloadType === undefined) {
180
180
  deviceData.payloadType = configuration.payloadType;
181
181
  }
182
+ if (configuration && configuration.useCBflowControl !== undefined && deviceData.useCBflowControl === undefined) {
183
+ deviceData.useCBflowControl = configuration.useCBflowControl;
184
+ }
185
+ if (configuration && configuration.storeLastMeasure !== undefined && deviceData.storeLastMeasure === undefined) {
186
+ deviceData.storeLastMeasure = configuration.storeLastMeasure;
187
+ }
182
188
  logger.debug(context, 'deviceData after merge with conf: %j', deviceData);
183
189
  callback(null, deviceData);
184
190
  }
@@ -277,7 +283,20 @@ function registerDevice(deviceObj, callback) {
277
283
  deviceData.ngsiVersion = configuration.ngsiVersion;
278
284
  }
279
285
  }
280
-
286
+ // Set polling and transport for autoprovisioned devices
287
+ if (!deviceData.transport && config.getConfig().defaultTransport) {
288
+ deviceData.transport =
289
+ configuration && configuration.transport
290
+ ? configuration.transport
291
+ : config.getConfig().defaultTransport;
292
+ }
293
+ if (deviceData.transport === 'HTTP') {
294
+ if (deviceData.endpoint) {
295
+ deviceData.polling = false;
296
+ } else {
297
+ deviceData.polling = !(configuration && configuration.endpoint);
298
+ }
299
+ }
281
300
  if (!deviceData.name) {
282
301
  let entityName = null;
283
302
  if (configuration && configuration.entityNameExp !== undefined && configuration.entityNameExp !== '') {
@@ -285,7 +304,7 @@ function registerDevice(deviceObj, callback) {
285
304
  let attrList = pluginUtils.getIdTypeServSubServiceFromDevice(deviceData);
286
305
  attrList = deviceData.staticAttributes ? attrList.concat(deviceData.staticAttributes) : attrList;
287
306
  attrList = configuration.staticAttributes ? attrList.concat(configuration.staticAttributes) : attrList;
288
- let ctxt = expressionPlugin.extractContext(attrList);
307
+ const ctxt = expressionPlugin.extractContext(attrList);
289
308
  try {
290
309
  entityName = expressionPlugin.applyExpression(configuration.entityNameExp, ctxt, deviceData);
291
310
  } catch (e) {
@@ -357,6 +376,12 @@ function registerDevice(deviceObj, callback) {
357
376
  if ('apikey' in deviceData && deviceData.apikey !== undefined) {
358
377
  deviceObj.apikey = deviceData.apikey;
359
378
  }
379
+ if ('transport' in deviceData && deviceData.transport !== undefined) {
380
+ deviceObj.transport = deviceData.transport;
381
+ }
382
+ if ('polling' in deviceData && deviceData.polling !== undefined) {
383
+ deviceObj.polling = deviceData.polling;
384
+ }
360
385
  logger.debug(context, 'Storing device :\n%s', JSON.stringify(deviceObj, null, 4));
361
386
  config.getRegistry().store(deviceObj, callback);
362
387
  }
@@ -616,7 +641,7 @@ function findOrCreate(deviceId, apikey, group, callback) {
616
641
  } else if (error.name === 'DEVICE_NOT_FOUND') {
617
642
  const newDevice = {
618
643
  id: deviceId,
619
- apikey: apikey,
644
+ apikey,
620
645
  service: group.service,
621
646
  subservice: group.subservice,
622
647
  type: group.type
@@ -692,6 +717,10 @@ function retrieveDevice(deviceId, apiKey, callback) {
692
717
  }
693
718
  }
694
719
 
720
+ function storeDeviceField(fieldName, fieldValue, typeInformation, callback) {
721
+ config.getRegistry().storeDeviceField(fieldName, fieldValue, typeInformation, callback);
722
+ }
723
+
695
724
  exports.listDevices = intoTrans(context, checkRegistry)(listDevices);
696
725
  exports.listDevicesWithType = intoTrans(context, checkRegistry)(listDevicesWithType);
697
726
  exports.getDevice = intoTrans(context, checkRegistry)(getDevice);
@@ -708,4 +737,5 @@ exports.retrieveDevice = intoTrans(context, checkRegistry)(retrieveDevice);
708
737
  exports.mergeDeviceWithConfiguration = mergeDeviceWithConfiguration;
709
738
  exports.findOrCreate = findOrCreate;
710
739
  exports.findConfigurationGroup = findConfigurationGroup;
740
+ exports.storeDeviceField = storeDeviceField;
711
741
  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));