iotagent-node-lib 2.21.0 → 2.24.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 (62) hide show
  1. package/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
  2. package/.nyc_output/processinfo/{76bc24ff-5fac-4b5a-997d-de2799342eb0.json → 33364de2-1199-4ec2-b33c-cae063ef8cc4.json} +1 -1
  3. package/.nyc_output/processinfo/index.json +1 -1
  4. package/CHANGES_NEXT_RELEASE +0 -1
  5. package/doc/Contribution.md +3 -3
  6. package/doc/advanced-topics.md +73 -9
  7. package/doc/api.md +7 -5
  8. package/doc/architecture.md +52 -5
  9. package/doc/expressionLanguage.md +18 -3
  10. package/doc/operations.md +8 -5
  11. package/doc/usermanual.md +18 -16
  12. package/docker/Mosquitto/Dockerfile +1 -1
  13. package/lib/errors.js +9 -1
  14. package/lib/model/Group.js +2 -1
  15. package/lib/model/dbConn.js +4 -0
  16. package/lib/plugins/bidirectionalData.js +104 -6
  17. package/lib/plugins/expressionPlugin.js +18 -7
  18. package/lib/plugins/multiEntity.js +42 -29
  19. package/lib/plugins/pluginUtils.js +17 -0
  20. package/lib/request-shim.js +2 -1
  21. package/lib/services/commands/commandService.js +29 -2
  22. package/lib/services/common/iotManagerService.js +2 -1
  23. package/lib/services/devices/deviceService.js +35 -9
  24. package/lib/services/groups/groupRegistryMongoDB.js +13 -12
  25. package/lib/services/ngsi/entities-NGSI-LD.js +7 -0
  26. package/lib/services/ngsi/entities-NGSI-v2.js +70 -11
  27. package/lib/services/ngsi/ngsiService.js +1 -1
  28. package/lib/services/northBound/contextServer-NGSI-LD.js +110 -15
  29. package/lib/services/northBound/contextServer-NGSI-v2.js +8 -3
  30. package/lib/services/northBound/contextServerUtils.js +9 -9
  31. package/lib/services/northBound/deviceProvisioningServer.js +2 -1
  32. package/lib/templates/createDevice.json +1 -2
  33. package/lib/templates/createDeviceLax.json +2 -3
  34. package/lib/templates/updateDevice.json +1 -2
  35. package/package.json +24 -24
  36. package/test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice4.json +14 -0
  37. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +51 -0
  38. package/test/unit/mongodb/mongoDBUtils.js +2 -2
  39. package/test/unit/mongodb/mongodb-group-registry-test.js +25 -1
  40. package/test/unit/mongodb/mongodb-registry-test.js +51 -3
  41. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgentCommands.json +2 -1
  42. package/test/unit/ngsi-ld/examples/contextRequests/updateContextLanguageProperties1.json +15 -0
  43. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +21 -0
  44. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +17 -0
  45. package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +995 -27
  46. package/test/unit/ngsi-ld/ngsiService/languageProperties-test.js +112 -0
  47. package/test/unit/ngsi-ld/ngsiService/unsupported-endpoints-test.js +111 -0
  48. package/test/unit/ngsi-ld/plugins/bidirectional-plugin_test.js +221 -0
  49. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +1 -1
  50. package/test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice4.json +8 -0
  51. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus2.json +6 -0
  52. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin36.json +12 -1
  53. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin17.json +27 -0
  54. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +19 -0
  55. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +10 -8
  56. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +106 -0
  57. package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +151 -0
  58. package/test/unit/ngsiv2/plugins/bidirectional-plugin_test.js +115 -0
  59. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +63 -0
  60. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +60 -0
  61. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +2 -1
  62. package/.nyc_output/76bc24ff-5fac-4b5a-997d-de2799342eb0.json +0 -1
@@ -1 +1 @@
1
- {"parent":null,"pid":26617,"argv":["/home/fermin/.nvm/versions/node/v10.24.1/bin/node","/home/fermin/src/iotagent-node-lib/node_modules/.bin/mocha","--recursive","test/**/*.js","--reporter","spec","--timeout","8000","--ui","bdd","--exit","--color","true"],"execArgv":[],"cwd":"/home/fermin/src/iotagent-node-lib","time":1646066946112,"ppid":26606,"coverageFilename":"/home/fermin/src/iotagent-node-lib/.nyc_output/76bc24ff-5fac-4b5a-997d-de2799342eb0.json","externalId":"","uuid":"76bc24ff-5fac-4b5a-997d-de2799342eb0","files":["/home/fermin/src/iotagent-node-lib/lib/fiware-iotagent-lib.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/ngsiService.js","/home/fermin/src/iotagent-node-lib/lib/services/common/domain.js","/home/fermin/src/iotagent-node-lib/lib/constants.js","/home/fermin/src/iotagent-node-lib/lib/errors.js","/home/fermin/src/iotagent-node-lib/lib/commonConfig.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/ngsiUtils.js","/home/fermin/src/iotagent-node-lib/lib/services/common/genericMiddleware.js","/home/fermin/src/iotagent-node-lib/lib/model/dbConn.js","/home/fermin/src/iotagent-node-lib/lib/services/common/alarmManagement.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscriptionService.js","/home/fermin/src/iotagent-node-lib/lib/services/stats/statsRegistry.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceService.js","/home/fermin/src/iotagent-node-lib/lib/services/groups/groupService.js","/home/fermin/src/iotagent-node-lib/lib/services/common/iotManagerService.js","/home/fermin/src/iotagent-node-lib/lib/request-shim.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/registrationUtils.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/restUtils.js","/home/fermin/src/iotagent-node-lib/lib/services/commands/commandService.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/northboundServer.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServerUtils.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/deviceProvisioningServer.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/deviceGroupAdministrationServer.js","/home/fermin/src/iotagent-node-lib/lib/plugins/compressTimestamp.js","/home/fermin/src/iotagent-node-lib/lib/plugins/pluginUtils.js","/home/fermin/src/iotagent-node-lib/lib/plugins/attributeAlias.js","/home/fermin/src/iotagent-node-lib/lib/plugins/addEvent.js","/home/fermin/src/iotagent-node-lib/lib/plugins/timestampProcessPlugin.js","/home/fermin/src/iotagent-node-lib/lib/plugins/expressionPlugin.js","/home/fermin/src/iotagent-node-lib/lib/plugins/expressionParser.js","/home/fermin/src/iotagent-node-lib/lib/plugins/jexlParser.js","/home/fermin/src/iotagent-node-lib/lib/jexlTranformsMap.js","/home/fermin/src/iotagent-node-lib/lib/plugins/multiEntity.js","/home/fermin/src/iotagent-node-lib/lib/plugins/bidirectionalData.js","/home/fermin/src/iotagent-node-lib/lib/services/groups/groupRegistryMemory.js","/home/fermin/src/iotagent-node-lib/lib/services/common/securityServiceKeystone.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceRegistryMemory.js","/home/fermin/src/iotagent-node-lib/lib/services/commands/commandRegistryMemory.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-v2.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-v2.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-v2.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-v2.js","/home/fermin/src/iotagent-node-lib/lib/model/Device.js","/home/fermin/src/iotagent-node-lib/lib/model/Group.js","/home/fermin/src/iotagent-node-lib/lib/model/Command.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceRegistryMongoDB.js","/home/fermin/src/iotagent-node-lib/lib/services/groups/groupRegistryMongoDB.js","/home/fermin/src/iotagent-node-lib/lib/services/commands/commandRegistryMongoDB.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-LD.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-LD.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-LD.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-LD.js","/home/fermin/src/iotagent-node-lib/lib/services/common/securityServiceOAuth2.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-mixed.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-mixed.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-mixed.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-mixed.js"]}
1
+ {"parent":null,"pid":78202,"argv":["/home/fermin/.nvm/versions/node/v16.15.0/bin/node","/home/fermin/src/iotagent-node-lib/node_modules/.bin/mocha","--recursive","test/**/*.js","--reporter","spec","--timeout","8000","--ui","bdd","--exit","--color","true"],"execArgv":[],"cwd":"/home/fermin/src/iotagent-node-lib","time":1655738400548,"ppid":78191,"coverageFilename":"/home/fermin/src/iotagent-node-lib/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json","externalId":"","uuid":"33364de2-1199-4ec2-b33c-cae063ef8cc4","files":["/home/fermin/src/iotagent-node-lib/lib/fiware-iotagent-lib.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/ngsiService.js","/home/fermin/src/iotagent-node-lib/lib/services/common/domain.js","/home/fermin/src/iotagent-node-lib/lib/constants.js","/home/fermin/src/iotagent-node-lib/lib/errors.js","/home/fermin/src/iotagent-node-lib/lib/commonConfig.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/ngsiUtils.js","/home/fermin/src/iotagent-node-lib/lib/services/common/genericMiddleware.js","/home/fermin/src/iotagent-node-lib/lib/model/dbConn.js","/home/fermin/src/iotagent-node-lib/lib/services/common/alarmManagement.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscriptionService.js","/home/fermin/src/iotagent-node-lib/lib/services/stats/statsRegistry.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceService.js","/home/fermin/src/iotagent-node-lib/lib/services/groups/groupService.js","/home/fermin/src/iotagent-node-lib/lib/services/common/iotManagerService.js","/home/fermin/src/iotagent-node-lib/lib/request-shim.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/registrationUtils.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/restUtils.js","/home/fermin/src/iotagent-node-lib/lib/services/commands/commandService.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/northboundServer.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServerUtils.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/deviceProvisioningServer.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/deviceGroupAdministrationServer.js","/home/fermin/src/iotagent-node-lib/lib/plugins/compressTimestamp.js","/home/fermin/src/iotagent-node-lib/lib/plugins/pluginUtils.js","/home/fermin/src/iotagent-node-lib/lib/plugins/attributeAlias.js","/home/fermin/src/iotagent-node-lib/lib/plugins/addEvent.js","/home/fermin/src/iotagent-node-lib/lib/plugins/timestampProcessPlugin.js","/home/fermin/src/iotagent-node-lib/lib/plugins/expressionPlugin.js","/home/fermin/src/iotagent-node-lib/lib/plugins/expressionParser.js","/home/fermin/src/iotagent-node-lib/lib/plugins/jexlParser.js","/home/fermin/src/iotagent-node-lib/lib/jexlTranformsMap.js","/home/fermin/src/iotagent-node-lib/lib/plugins/multiEntity.js","/home/fermin/src/iotagent-node-lib/lib/plugins/bidirectionalData.js","/home/fermin/src/iotagent-node-lib/lib/services/groups/groupRegistryMemory.js","/home/fermin/src/iotagent-node-lib/lib/services/common/securityServiceKeystone.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceRegistryMemory.js","/home/fermin/src/iotagent-node-lib/lib/services/commands/commandRegistryMemory.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-v2.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-v2.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-v2.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-v2.js","/home/fermin/src/iotagent-node-lib/lib/model/Device.js","/home/fermin/src/iotagent-node-lib/lib/model/Group.js","/home/fermin/src/iotagent-node-lib/lib/model/Command.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceRegistryMongoDB.js","/home/fermin/src/iotagent-node-lib/lib/services/groups/groupRegistryMongoDB.js","/home/fermin/src/iotagent-node-lib/lib/services/commands/commandRegistryMongoDB.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-LD.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-LD.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-LD.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-LD.js","/home/fermin/src/iotagent-node-lib/lib/services/common/securityServiceOAuth2.js","/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-mixed.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-mixed.js","/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-mixed.js","/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-mixed.js"]}
@@ -1 +1 @@
1
- {"processes":{"76bc24ff-5fac-4b5a-997d-de2799342eb0":{"parent":null,"children":[]}},"files":{"/home/fermin/src/iotagent-node-lib/lib/fiware-iotagent-lib.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/ngsiService.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/common/domain.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/constants.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/errors.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/commonConfig.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/ngsiUtils.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/common/genericMiddleware.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/model/dbConn.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/common/alarmManagement.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscriptionService.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/stats/statsRegistry.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceService.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/groups/groupService.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/common/iotManagerService.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/request-shim.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/registrationUtils.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/restUtils.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/commands/commandService.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/northboundServer.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServerUtils.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/deviceProvisioningServer.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/deviceGroupAdministrationServer.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/plugins/compressTimestamp.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/plugins/pluginUtils.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/plugins/attributeAlias.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/plugins/addEvent.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/plugins/timestampProcessPlugin.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/plugins/expressionPlugin.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/plugins/expressionParser.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/plugins/jexlParser.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/jexlTranformsMap.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/plugins/multiEntity.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/plugins/bidirectionalData.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/groups/groupRegistryMemory.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/common/securityServiceKeystone.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceRegistryMemory.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/commands/commandRegistryMemory.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-v2.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-v2.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-v2.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-v2.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/model/Device.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/model/Group.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/model/Command.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceRegistryMongoDB.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/groups/groupRegistryMongoDB.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/commands/commandRegistryMongoDB.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-LD.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-LD.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-LD.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-LD.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/common/securityServiceOAuth2.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-mixed.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-mixed.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-mixed.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-mixed.js":["76bc24ff-5fac-4b5a-997d-de2799342eb0"]},"externalIds":{}}
1
+ {"processes":{"33364de2-1199-4ec2-b33c-cae063ef8cc4":{"parent":null,"children":[]}},"files":{"/home/fermin/src/iotagent-node-lib/lib/fiware-iotagent-lib.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/ngsiService.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/common/domain.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/constants.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/errors.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/commonConfig.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/ngsiUtils.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/common/genericMiddleware.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/model/dbConn.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/common/alarmManagement.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscriptionService.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/stats/statsRegistry.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceService.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/groups/groupService.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/common/iotManagerService.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/request-shim.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/registrationUtils.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/restUtils.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/commands/commandService.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/northboundServer.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServerUtils.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/deviceProvisioningServer.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/deviceGroupAdministrationServer.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/plugins/compressTimestamp.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/plugins/pluginUtils.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/plugins/attributeAlias.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/plugins/addEvent.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/plugins/timestampProcessPlugin.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/plugins/expressionPlugin.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/plugins/expressionParser.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/plugins/jexlParser.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/jexlTranformsMap.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/plugins/multiEntity.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/plugins/bidirectionalData.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/groups/groupRegistryMemory.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/common/securityServiceKeystone.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceRegistryMemory.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/commands/commandRegistryMemory.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-v2.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-v2.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-v2.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-v2.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/model/Device.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/model/Group.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/model/Command.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/deviceRegistryMongoDB.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/groups/groupRegistryMongoDB.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/commands/commandRegistryMongoDB.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-LD.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-LD.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-LD.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-LD.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/common/securityServiceOAuth2.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/devices/devices-NGSI-mixed.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-mixed.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-mixed.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"],"/home/fermin/src/iotagent-node-lib/lib/services/ngsi/entities-NGSI-mixed.js":["33364de2-1199-4ec2-b33c-cae063ef8cc4"]},"externalIds":{}}
@@ -1 +0,0 @@
1
-
@@ -33,7 +33,7 @@ contributions are done using a pull request (PR). The detailed "protocol" used i
33
33
 
34
34
  * Direct commits to master branch (even single-line modifications) are not allowed. Every modification has to come as a PR
35
35
  * In case the PR is implementing/fixing a numbered issue, the issue number has to be referenced in the body of the PR at creation time
36
- * Anybody is welcome to provide comments to the PR (either direct comments or using the review feature offered by Github)
36
+ * Anybody is welcome to provide comments to the PR (either direct comments or using the review feature offered by GitHub)
37
37
  * Use *code line comments* instead of *general comments*, for traceability reasons (see comments lifecycle below)
38
38
  * Comments lifecycle
39
39
  * Comment is created, initiating a *comment thread*
@@ -142,7 +142,7 @@ point to each of the released versions of the project, they are permanent and th
142
142
 
143
143
  ## Change log
144
144
 
145
- The project contains a version changelog, called CHANGES_NEXT_RELEASE, that can be found in the root of the project.
145
+ The project contains a version change log, called CHANGES_NEXT_RELEASE, that can be found in the root of the project.
146
146
  Whenever a new feature or bug fix is going to be merged with `master`, a new entry should be added to this changelog.
147
147
  The new entry should contain the reference number of the issue it is solving (if any).
148
148
 
@@ -159,7 +159,7 @@ The process of making a release consists of the following steps:
159
159
  new target version (without any sufix), and PR into `master`. Also, in this task, the contents of the Change log are
160
160
  copied to the RPM spec.
161
161
  2. Create a tag from the last version of `master` named with the version number and push it to the repository.
162
- 3. Create the release in Github, from the created tag. In the description, add the contents of the Change log.
162
+ 3. Create the release in GitHub, from the created tag. In the description, add the contents of the Change log.
163
163
  4. Create a release branch from the last version of `master` named with the version number.
164
164
  5. Create a new task for preparing the next release, adding the sufix `-next` to the current version number (to signal
165
165
  this as the development version), and flush the contents of the CHANGES_NEXT_RELEASE file.
@@ -197,7 +197,7 @@ e.g.:
197
197
  When provisioning devices for an NGSI-LD Context Broker, `type` values should typically correspond to one of the
198
198
  following:
199
199
 
200
- - `Property`, `Relationship`, `Geoproperty`
200
+ - `Property`, `Relationship`, `GeoProperty`, `LanguageProperty`
201
201
  - Native JSON types (e.g. `String`, `Boolean`, `Float` , `Integer` `Number`)
202
202
  - Temporal Properties (e.g. `Datetime`, `Date` , `Time`)
203
203
  - GeoJSON types (e.g `Point`, `LineString`, `Polygon`, `MultiPoint`, `MultiLineString`, `MultiPolygon`)
@@ -305,7 +305,7 @@ stored in the Context Broker by adding a new attribute to the entity with the sa
305
305
  element. By adding the field `explicitAttrs` with `true` value to device or group provision, the IoTAgent rejects the
306
306
  measure elements that are not defined in the mappings of device or group provision, persisting only the one defined in
307
307
  the mappings of the provision. If `explicitAttrs` is provided both at device and group level, the device level takes
308
- precedence. Additionally `explicitAttrs` can be used to define which meassures (identified by their attribute names, not
308
+ precedence. Additionally `explicitAttrs` can be used to define which meassures (identified by their attribute names, not
309
309
  by their object_id) defined in JSON/JEXL array will be propagated to NGSI interface.
310
310
 
311
311
  The different possibilities are summarized below:
@@ -332,11 +332,22 @@ Case 3:
332
332
  "explicitAttrs": "['attr1','atrr2']"
333
333
  ```
334
334
 
335
- just measures defined in the array (identified by their attribute names, not by their object_id) will be will be
336
- propagated to NGSI interface (note that in this case the value of `explicitAttrs` is not a JSON but a string that looks likes a JSON).
335
+ just NGSI attributes defined in the array (identified by their attribute names, not by their object_id, plus
336
+ conditionally TimeInstant) will be propagated to NGSI interface (note that in this case the value of `explicitAttrs` is
337
+ not a JSON but a JEXL Array that looks likes a JSON).
337
338
 
338
339
  Case 4:
339
340
 
341
+ ```
342
+ "explicitAttrs": "['attr1','atrr2',{object_id:'active_id'}]"
343
+ ```
344
+
345
+ just NGSI attributes defined in the array (identified by their attribute names and/or by their object_id) will be
346
+ propagated to NGSI interface (note that in this case the value of `explicitAttrs` is not a JSON but a JEXL Array/Object
347
+ that looks likes a JSON). This is necessary when same attribute names are used within multiple entities.
348
+
349
+ Case 5:
350
+
340
351
  ```
341
352
  "explicitAtttr": "<JEXL expression resulting in bool or array>"
342
353
  ```
@@ -346,8 +357,8 @@ depending on the JEXL expression evaluation:
346
357
  - If it evaluates to `true` every measure will be propagated to NGSI interface (as in case 1)
347
358
  - If it evaluates to `false` just measures defined in active, static (plus conditionally TimeInstant) will be
348
359
  propagated to NGSI interface (as in case 2)
349
- - If it evaluates to an array just measures defined in the array (identified by their attribute names, not by their object_id)
350
- will be will be propagated to NGSI interface (as in case 3)
360
+ - If it evaluates to an array just measures defined in the array (identified by their attribute names, not by their
361
+ object_id) will be will be propagated to NGSI interface (as in case 3)
351
362
 
352
363
  ### Configuring operation to persist the data in Context Broker (appendMode)
353
364
 
@@ -440,7 +451,7 @@ events in the IoT Agent with the configured type name will be marked as events.
440
451
 
441
452
  ##### Timestamp Processing Plugin (timestampProcess)
442
453
 
443
- This plugin processes the entity attributes looking for a `TimeInstant` attribute. If one is found, for NGSIv2, the
454
+ This plugin processes the entity attributes looking for a `TimeInstant` attribute. If one is found, for NGSI v2, the
444
455
  plugin adds a `TimeInstant` attribute as metadata for every other attribute in the same request. With NGSI-LD, the
445
456
  Standard `observedAt` property-of-a-property is used instead.
446
457
 
@@ -503,9 +514,9 @@ intercepted by the plugin, so the mapped values are included in the updated noti
503
514
 
504
515
  When a device is provisioned with bidirectional attributes, the IoTAgent subscribes to changes in that attribute. When a
505
516
  change notification for that attribute arrives to the IoTA, it applies the transformation defined in the device
506
- provisioning payload to the notification, and calls the underlying notification handler with the transformed entity.
517
+ provisioning payload to the notification, and calls the underlying notification handler with the transformed entity including the `value` along with any `metadata`, and in the case of an NGSI-LD bidirectional attribute a `datasetId` if provided.
507
518
 
508
- The following `attributes` section shows an example of the plugin configuration (using IOTA_AUTOCAST=false to avoid
519
+ The following `attributes` section shows an example of the plugin configuration (using `IOTA_AUTOCAST=false` to avoid
509
520
  translation from geo:point to geo:json)
510
521
 
511
522
  ```json
@@ -538,3 +549,56 @@ subscription payload.
538
549
  For each attribute in the `reverse` array, an expression must be defined to calculate its value based on the
539
550
  notification attributes. This value will be passed to the underlying protocol with the `object_id` name. Details about
540
551
  how the value is then progressed to the device are protocol-specific.
552
+
553
+ ##### NGSI-LD `datasetId` support
554
+
555
+ Limited support for parsing the NGSI-LD `datasetId` attribute is included within the library. A series of sequential commands for a single attribute can be sent as an NGSI-LD notification as follows:
556
+
557
+
558
+ ```json
559
+ {
560
+ "id": "urn:ngsi-ld:Notification:5fd0fa684eb81930c97005f3",
561
+ "type": "Notification",
562
+ "subscriptionId": "urn:ngsi-ld:Subscription:5fd0f69b4eb81930c97005db",
563
+ "notifiedAt": "2020-12-09T16:25:12.193Z",
564
+ "data": [
565
+ {
566
+ "lampColor": [
567
+ {
568
+ "type": "Property",
569
+ "value": { "color": "green", "duration": "55 secs"},
570
+ "datasetId": "urn:ngsi-ld:Sequence:do-this"
571
+ },
572
+ {
573
+ "type": "Property",
574
+ "value": {"color": "red", "duration": "10 secs"},
575
+ "datasetId": "urn:ngsi-ld:Sequence:then-do-this"
576
+ }
577
+ ]
578
+ }
579
+ ]
580
+ }
581
+ ```
582
+
583
+ This results in the following sequential array of attribute updates to be sent to the `NotificationHandler` of the IoT Agent itself:
584
+
585
+ ```json
586
+ [
587
+ {
588
+ "name": "lampColor",
589
+ "type": "Property",
590
+ "datasetId": "urn:ngsi-ld:Sequence:do-this",
591
+ "metadata": {},
592
+ "value": { "color": "green", "duration": "55 secs"}
593
+ },
594
+ {
595
+ "name": "lampColor",
596
+ "type": "Property",
597
+ "datasetId": "urn:ngsi-ld:Sequence:then-do-this",
598
+ "metadata": {},
599
+ "value": {"color": "red", "duration": "10 secs"}
600
+ }
601
+ ]
602
+ ```
603
+
604
+ A `datasetId` is also maintained for each new attribute defined in the `reverse` field.
package/doc/api.md CHANGED
@@ -92,6 +92,7 @@ correspondence between the API resource fields and the same fields in the databa
92
92
  | `internal_attributes` | `internalAttributes` | optional section with free format, to allow specific IoT Agents to store information along with the devices in the Device Registry. |
93
93
  | `expressionLanguage` | `expresionLanguage` | optional boolean value, to set expression language used to compute expressions, possible values are: legacy or jexl. When not set or wrongly set, `legacy` is used as default value. |
94
94
  | `explicitAttrs` | `explicitAttrs` | optional field to support selective ignore of measures so that IOTA doesn’t progress. See details in [specific section](advanced-topics.md#explicitly-defined-attributes-explicitattrs) |
95
+ | `entityNameExp` | `entityNameExp` | optional field to allow use expressions to define entity name, instead default `id` and `type` |
95
96
  | `ngsiVersion` | `ngsiVersion` | optional string value used in mixed mode to switch between **NGSI-v2** and **NGSI-LD** payloads. Possible values are: `v2` or `ld`. The default is `v2`. When not running in mixed mode, this field is ignored. |
96
97
  | `defaultEntityNameConjunction` | `defaultEntityNameConjunction` | optional string value to set default conjunction string used to compose a default `entity_name` when is not provided at device provisioning time. |
97
98
  | `autoprovision` | `autoprovision` | optional boolean: If `false`, autoprovisioned devices (i.e. devices that are not created with an explicit provision operation but when the first measure arrives) are not allowed in this group. Default (in the case of omitting the field) is `true`. |
@@ -247,8 +248,8 @@ the API resource fields and the same fields in the database model.
247
248
 
248
249
  #### Attribute lists
249
250
 
250
- In the group/device model there are three list of attributes that can be declared: attributes, lazy and commands. All of them
251
- have the same syntax, an object containing the following attributes:
251
+ In the group/device model there are three list of attributes that can be declared: attributes, lazy and commands. All of
252
+ them have the same syntax, an object containing the following attributes:
252
253
 
253
254
  - **object_id** (optional): name of the attribute as coming from the device.
254
255
  - **name** (mandatory): ID of the attribute in the target entity in the Context Broker.
@@ -273,9 +274,10 @@ Additionally for commands (which are attributes of type `command`) the following
273
274
  - **expression** indicates that the value of the target command will not be the plain value or the command, but an
274
275
  expression based on a combination of the returned values. See the
275
276
  [Expression Language definition](expressionLanguage.md) for details
276
- - **payloadType**: indicates how command payload will be transformed before be sent to device. Please have a look to particular
277
- IOTAs documentation for allowed values of this field in each case.
278
- - **contentType**: `content-type` header used when send command by HTTP transport (ignored in other kinds of transports)
277
+ - **payloadType**: indicates how command payload will be transformed before be sent to device. Please have a look to
278
+ particular IOTAs documentation for allowed values of this field in each case.
279
+ - **contentType**: `content-type` header used when send command by HTTP transport (ignored in other kinds of
280
+ transports)
279
281
 
280
282
  See the transformation plugins Section for more details.
281
283
 
@@ -113,13 +113,14 @@ response to the caller, transparently.
113
113
 
114
114
  #### Commands
115
115
 
116
- **IMPORTANT NOTE:** at the present moment, commands (both push and poll) are supported only in the case of explictely
116
+ **IMPORTANT NOTE:** at the present moment, commands (both push and poll) are supported only in the case of explicitly
117
117
  provisioned agents. For autoprovisioned agents commands are not currently supported, although
118
118
  [an issue](https://github.com/telefonicaid/iot-agent-node-lib/issues/572) has been created about this functionality.
119
119
 
120
120
  Commands are modelled as updates over a lazy attribute. As in the case of the lazy attributes, updates over a command
121
121
  will be forwarded by the Context Broker to the IoT Agent, that will in turn interact with the device to perform the
122
- requested action. Parameters for the command will be passed inside the command value.
122
+ requested action. Parameters for the command will be passed inside the command `value` along with any `metadata`, and in
123
+ the case of an NGSI-LD command a `datasetId` if provided.
123
124
 
124
125
  There are two differences with the lazy attributes:
125
126
 
@@ -164,6 +165,52 @@ taking too much to pick them up. See the configuration section for details.
164
165
  The library does not deal with protocol transformation or South Bound communications for neither of the command types
165
166
  (that's the task for those specific IoT Agents using the library).
166
167
 
168
+ ##### NGSI-LD `datasetId` support
169
+
170
+ Limited support for parsing the NGSI-LD `datasetId` attribute is included within the library. A series of sequential
171
+ commands for a single attribute can be sent as an NGSI-LD PATCH payload as follows:
172
+
173
+ ```json
174
+ {
175
+ "lampColor": [
176
+ {
177
+ "type": "Property",
178
+ "value": { "color": "green", "duration": "55 secs" },
179
+ "datasetId": "urn:ngsi-ld:Sequence:do-this"
180
+ },
181
+ {
182
+ "type": "Property",
183
+ "value": { "color": "red", "duration": "10 secs" },
184
+ "datasetId": "urn:ngsi-ld:Sequence:then-do-this"
185
+ }
186
+ ]
187
+ }
188
+ ```
189
+
190
+ This results in the following sequential array of attribute updates to be sent to the `UpdateHandler` of the IoT Agent
191
+ itself:
192
+
193
+ ```json
194
+ [
195
+ {
196
+ "name": "lampColor",
197
+ "type": "Property",
198
+ "datasetId": "urn:ngsi-ld:Sequence:do-this",
199
+ "metadata": {},
200
+ "value": { "color": "green", "duration": "55 secs" }
201
+ },
202
+ {
203
+ "name": "lampColor",
204
+ "type": "Property",
205
+ "datasetId": "urn:ngsi-ld:Sequence:then-do-this",
206
+ "metadata": {},
207
+ "value": { "color": "red", "duration": "10 secs" }
208
+ }
209
+ ]
210
+ ```
211
+
212
+ The equivalent for NGSI-v2 is not required since `datasetId` syntax is not supported by NGSI-v2.
213
+
167
214
  #### Active attributes
168
215
 
169
216
  Whenever a device proactively sends a message to the IoT Agent, it should transform its data to the appropriate NGSI
@@ -214,9 +261,9 @@ device to a command update to the device.
214
261
  As part of the device to entity mapping process the IoT Agent creates and updates automatically a special timestamp.
215
262
  This timestamp is represented as two different properties of the mapped entity::
216
263
 
217
- - With NGSI-v2, an attribute metadata named `TimeInstant` (per dynamic attribute mapped, which captures as an
218
- ISO8601 timestamp when the associated measurement (represented as attribute value) was observed. With NGSI-LD, the
219
- Standard `observedAt` property-of-a-property is used instead.
264
+ - With NGSI-v2, an attribute metadata named `TimeInstant` (per dynamic attribute mapped, which captures as an ISO8601
265
+ timestamp when the associated measurement (represented as attribute value) was observed. With NGSI-LD, the Standard
266
+ `observedAt` property-of-a-property is used instead.
220
267
 
221
268
  - For NGSI-v2 only, an additional attribute `TimeInstant` is added to the entity which captures as an ISO8601
222
269
  timestamp when the last measurement received from the device was observed.
@@ -342,6 +342,22 @@ Will now generate the following NGSI v2 payload:
342
342
  }
343
343
  ```
344
344
 
345
+ ## Available keys for all Expressions
346
+
347
+ Apart from measurement transformations (including multientity cases), expressions can be used in the following cases:
348
+
349
+ - Default EntityName defined at group level and used for provision and autoprovision of devices
350
+ - Commands (push and pull)
351
+ - Endpoint of push http commands
352
+
353
+ In all of them the following device data is available to all expressions
354
+
355
+ - `id`: device ID
356
+ - `entity_name`: NGSI entity Name (principal)
357
+ - `type`: NGSI entity type (principal)
358
+ - `service`: device service
359
+ - `subservice`: device subservice
360
+
345
361
  ## JEXL Based Transformations
346
362
 
347
363
  The recommended expression language for the IoTAgent Library is [JEXL](https://github.com/TomFrost/jexl). To use JEXL,
@@ -474,10 +490,9 @@ Current common transformation set:
474
490
  | slice: (arr, init, end) | `arr.slice(init,end);` |
475
491
  | addset: (arr, x) | <code>{ return Array.from((new Set(arr)).add(x)) }</code> |
476
492
  | removeset: (arr, x) | <code>{ let s = new Set(arr); s.delete(x); return Array.from(s) }</code> |
477
- | touppercase: (val) | `String(val).toUpperCase()` |
478
- | tolowercase: (val) | `String(val).toLowerCase()` |
493
+ | touppercase: (val) | `String(val).toUpperCase()` |
494
+ | tolowercase: (val) | `String(val).toLowerCase()` |
479
495
 
480
-
481
496
  You have available this [JEXL interactive playground][99] with all the transformations already loaded, in which you can
482
497
  test all the functions described above.
483
498
 
package/doc/operations.md CHANGED
@@ -99,11 +99,11 @@ The following table shows the alarms that can be raised in the IoTAgent library.
99
99
  log starting with the prefix "Raising [%s]:" (where %s is the alarm name). All the alarms are released by an info log
100
100
  with the prefix "Releasing [%s]". These texts appear in the `msg=` field of the generic log record format.
101
101
 
102
- | Alarm name | Severity | Description |
103
- | :---------- | :----------- | :------------------------------------------------------- |
104
- | MONGO-ALARM | **Critical** | Indicates an error in the MongoDB connectivity |
105
- | ORION-ALARM | **Critical** | Indicates a persistent error accesing the Context Broker |
106
- | IOTAM-ALARM | **Critical** | Indicates a persistent error accessing the IoTAM |
102
+ | Alarm name | Severity | Description |
103
+ | :------------- | :----------- | :------------------------------------------------------- |
104
+ | MONGO-ALARM_XX | **Critical** | Indicates an error in the MongoDB connectivity |
105
+ | ORION-ALARM | **Critical** | Indicates a persistent error accesing the Context Broker |
106
+ | IOTAM-ALARM | **Critical** | Indicates a persistent error accessing the IoTAM |
107
107
 
108
108
  while the 'Severity' criterium is as follows:
109
109
 
@@ -111,6 +111,9 @@ while the 'Severity' criterium is as follows:
111
111
  - **Major** - The system has a problem that degrades the service and must be addressed
112
112
  - **Warning** - It is happening something that must be notified
113
113
 
114
+ In order to identify the internal flow which origins a mongo alarm, there is a suffix `_XX` which identifies from `01` to
115
+ `11` each flow.
116
+
114
117
  ## Error naming code
115
118
 
116
119
  Every error has a code composed of a prefix and an ID, codified with the following table:
package/doc/usermanual.md CHANGED
@@ -25,7 +25,7 @@ More values will be added in the future to the library. The applications using t
25
25
  Registry just by using the following function:
26
26
 
27
27
  ```javascript
28
- iotagentLib.statsRegistry.add('statName', statIncrementalValue, callback);
28
+ iotagentLib.statsRegistry.add("statName", statIncrementalValue, callback);
29
29
  ```
30
30
 
31
31
  The first time this function is invoked, it will add the new stat to the registry. Subsequent calls will add the value
@@ -80,7 +80,7 @@ In order to use the library, add the following dependency to your package.json f
80
80
  In order to use this library, first you must require it:
81
81
 
82
82
  ```javascript
83
- var iotagentLib = require('iotagent-node-lib');
83
+ var iotagentLib = require("iotagent-node-lib");
84
84
  ```
85
85
 
86
86
  The library supports four groups of features, one for each direction of the communication: client-to-server and
@@ -258,21 +258,23 @@ function setDataUpdateHandler(newHandler)
258
258
  ###### Description
259
259
 
260
260
  Sets the new user handler for Entity update requests. This handler will be called whenever an update request arrives
261
- with the following parameters: (id, type, service, subservice, attributes, callback). The handler is in charge of
262
- updating the corresponding values in the devices with the appropriate protocol.
261
+ with the following parameters: (`id`, `type`, `service`, `subservice`, `attributes`, `callback`). Every object within of
262
+ the `attributes` array contains `name`, `type` and `value` attributes, and may also include additional attributes for
263
+ `metadata` and `datasetId`. The handler is in charge of updating the corresponding values in the devices with the
264
+ appropriate protocol.
263
265
 
264
266
  Once all the updates have taken place, the callback must be invoked with the updated Context Element. E.g.:
265
267
 
266
268
  ```javascript
267
269
  callback(null, {
268
- type: 'TheType',
270
+ type: "TheType",
269
271
  isPattern: false,
270
- id: 'EntityID',
272
+ id: "EntityID",
271
273
  attributes: [
272
274
  {
273
- name: 'lumniscence',
274
- type: 'Lumens',
275
- value: '432'
275
+ name: "lumniscence",
276
+ type: "Lumens",
277
+ value: "432"
276
278
  }
277
279
  ]
278
280
  });
@@ -296,21 +298,21 @@ function setDataQueryHandler(newHandler)
296
298
  ###### Description
297
299
 
298
300
  Sets the new user handler for Entity query requests. This handler will be called whenever a query request arrives, with
299
- the following parameters: (id, type, service, subservice, attributes, callback). The handler must retrieve all the
300
- corresponding information from the devices and return a NGSI entity with the requested values.
301
+ the following parameters: (`id`, `type`, `service`, `subservice`, `attributes`, `callback`). The handler must retrieve
302
+ all the corresponding information from the devices and return a NGSI entity with the requested values.
301
303
 
302
304
  The callback must be invoked with the updated Context Element, using the information retrieved from the devices. E.g.:
303
305
 
304
306
  ```javascript
305
307
  callback(null, {
306
- type: 'TheType',
308
+ type: "TheType",
307
309
  isPattern: false,
308
- id: 'EntityID',
310
+ id: "EntityID",
309
311
  attributes: [
310
312
  {
311
- name: 'lumniscence',
312
- type: 'Lumens',
313
- value: '432'
313
+ name: "lumniscence",
314
+ type: "Lumens",
315
+ value: "432"
314
316
  }
315
317
  ]
316
318
  });
@@ -1,4 +1,4 @@
1
- ARG IMAGE_TAG=11.2-slim
1
+ ARG IMAGE_TAG=11.3-slim
2
2
  FROM debian:${IMAGE_TAG}
3
3
 
4
4
  ARG CLEAN_DEV_TOOLS
package/lib/errors.js CHANGED
@@ -242,6 +242,13 @@ class BadGeocoordinates {
242
242
  this.code = 400;
243
243
  }
244
244
  }
245
+ class MethodNotSupported {
246
+ constructor(method, path) {
247
+ this.name = 'METHOD_NOT_IMPLEMENTED';
248
+ this.message = 'IoT Agents do not support the endpoint: ' + method + ' ' + path;
249
+ this.code = 501;
250
+ }
251
+ }
245
252
 
246
253
  module.exports = {
247
254
  RegistrationError,
@@ -273,5 +280,6 @@ module.exports = {
273
280
  InvalidExpression,
274
281
  BadAnswer,
275
282
  BadTimestamp,
276
- BadGeocoordinates
283
+ BadGeocoordinates,
284
+ MethodNotSupported
277
285
  };
@@ -62,7 +62,8 @@ const Group = new Schema({
62
62
  expressionLanguage: String,
63
63
  explicitAttrs: ExplicitAttrsType,
64
64
  defaultEntityNameConjunction: String,
65
- ngsiVersion: String
65
+ ngsiVersion: String,
66
+ entityNameExp: String
66
67
  });
67
68
 
68
69
  function load(db) {
@@ -113,6 +113,10 @@ function init(host, db, port, options, callback) {
113
113
  options,
114
114
  retries
115
115
  );
116
+ // FIXME: useNewUrlParser is no longer used in underlying mongodb driver 4.x
117
+ // (see https://github.com/mongodb/node-mongodb-native/blob/HEAD/etc/notes/CHANGES_4.0.0.md)
118
+ // but not sure if current mongoose version is still using mongodb 3.x internally
119
+ // probably mongodb-connectionoptions-test.js needs to be fixed if useNewUrlParser is removed at the end
116
120
  options.useNewUrlParser = true;
117
121
  mongoose.set('useCreateIndex', true);
118
122
  /* eslint-disable-next-line no-unused-vars */