iotagent-node-lib 2.23.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 (36) hide show
  1. package/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
  2. package/.nyc_output/processinfo/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
  3. package/.nyc_output/processinfo/index.json +1 -1
  4. package/CHANGES_NEXT_RELEASE +0 -2
  5. package/doc/advanced-topics.md +55 -2
  6. package/doc/architecture.md +52 -5
  7. package/doc/expressionLanguage.md +2 -1
  8. package/doc/usermanual.md +18 -16
  9. package/lib/errors.js +9 -1
  10. package/lib/plugins/bidirectionalData.js +104 -6
  11. package/lib/plugins/expressionPlugin.js +10 -0
  12. package/lib/plugins/pluginUtils.js +2 -1
  13. package/lib/request-shim.js +2 -1
  14. package/lib/services/devices/deviceService.js +34 -20
  15. package/lib/services/ngsi/entities-NGSI-v2.js +14 -4
  16. package/lib/services/northBound/contextServer-NGSI-LD.js +96 -20
  17. package/lib/services/northBound/contextServer-NGSI-v2.js +1 -0
  18. package/package.json +1 -1
  19. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +51 -0
  20. package/test/unit/mongodb/mongodb-group-registry-test.js +24 -0
  21. package/test/unit/mongodb/mongodb-registry-test.js +49 -0
  22. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +21 -0
  23. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +17 -0
  24. package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +656 -2
  25. package/test/unit/ngsi-ld/ngsiService/unsupported-endpoints-test.js +111 -0
  26. package/test/unit/ngsi-ld/plugins/bidirectional-plugin_test.js +221 -0
  27. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +19 -0
  28. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +106 -0
  29. package/test/unit/ngsiv2/plugins/bidirectional-plugin_test.js +115 -0
  30. package/.nyc_output/6e3d7795-bf8c-4a50-bd2f-f8221f27aeae.json +0 -1
  31. package/.nyc_output/processinfo/6e3d7795-bf8c-4a50-bd2f-f8221f27aeae.json +0 -1
  32. package/config +0 -0
  33. package/docker/Mosquitto/Dockerfile.debian +0 -38
  34. package/docker/Mosquitto/Dockerfile.debian~ +0 -23
  35. package/lib/plugins/multiEntity.js_avg2 +0 -343
  36. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js_avg2 +0 -1224
@@ -0,0 +1 @@
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":{"6e3d7795-bf8c-4a50-bd2f-f8221f27aeae":{"parent":null,"children":[]}},"files":{"/home/avega/tid/fiware/iotagent-node-lib/lib/fiware-iotagent-lib.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/ngsi/ngsiService.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/common/domain.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/constants.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/errors.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/commonConfig.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/ngsi/ngsiUtils.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/common/genericMiddleware.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/model/dbConn.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/common/alarmManagement.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/ngsi/subscriptionService.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/stats/statsRegistry.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/devices/deviceService.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/groups/groupService.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/common/iotManagerService.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/request-shim.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/devices/registrationUtils.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/northBound/restUtils.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/plugins/expressionPlugin.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/plugins/expressionParser.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/plugins/jexlParser.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/jexlTranformsMap.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/plugins/pluginUtils.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/commands/commandService.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/northBound/northboundServer.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/northBound/contextServer.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/northBound/contextServerUtils.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/northBound/deviceProvisioningServer.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/northBound/deviceGroupAdministrationServer.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/plugins/compressTimestamp.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/plugins/attributeAlias.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/plugins/addEvent.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/plugins/timestampProcessPlugin.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/plugins/multiEntity.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/plugins/bidirectionalData.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/groups/groupRegistryMemory.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/common/securityServiceKeystone.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/devices/deviceRegistryMemory.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/commands/commandRegistryMemory.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/devices/devices-NGSI-v2.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/ngsi/entities-NGSI-v2.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-v2.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-v2.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/model/Device.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/model/Group.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/model/Command.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/devices/deviceRegistryMongoDB.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/groups/groupRegistryMongoDB.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/commands/commandRegistryMongoDB.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/devices/devices-NGSI-LD.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/ngsi/entities-NGSI-LD.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-LD.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-LD.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/common/securityServiceOAuth2.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/devices/devices-NGSI-mixed.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/ngsi/subscription-NGSI-mixed.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/northBound/contextServer-NGSI-mixed.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"],"/home/avega/tid/fiware/iotagent-node-lib/lib/services/ngsi/entities-NGSI-mixed.js":["6e3d7795-bf8c-4a50-bd2f-f8221f27aeae"]},"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,2 +0,0 @@
1
-
2
-
@@ -514,9 +514,9 @@ intercepted by the plugin, so the mapped values are included in the updated noti
514
514
 
515
515
  When a device is provisioned with bidirectional attributes, the IoTAgent subscribes to changes in that attribute. When a
516
516
  change notification for that attribute arrives to the IoTA, it applies the transformation defined in the device
517
- 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.
518
518
 
519
- 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
520
520
  translation from geo:point to geo:json)
521
521
 
522
522
  ```json
@@ -549,3 +549,56 @@ subscription payload.
549
549
  For each attribute in the `reverse` array, an expression must be defined to calculate its value based on the
550
550
  notification attributes. This value will be passed to the underlying protocol with the `object_id` name. Details about
551
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.
@@ -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.
@@ -353,7 +353,8 @@ Apart from measurement transformations (including multientity cases), expression
353
353
  In all of them the following device data is available to all expressions
354
354
 
355
355
  - `id`: device ID
356
- - `type`: device type
356
+ - `entity_name`: NGSI entity Name (principal)
357
+ - `type`: NGSI entity type (principal)
357
358
  - `service`: device service
358
359
  - `subservice`: device subservice
359
360
 
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
  });
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
  };
@@ -26,8 +26,9 @@
26
26
  const async = require('async');
27
27
  const apply = async.apply;
28
28
  const _ = require('underscore');
29
- const parser = require('./expressionParser');
29
+ const parser = require('./expressionPlugin');
30
30
  const logger = require('logops');
31
+ const config = require('../commonConfig');
31
32
  const subscriptions = require('../services/ngsi/subscriptionService');
32
33
  const deviceService = require('../services/devices/deviceService');
33
34
  const context = {
@@ -180,14 +181,17 @@ function getReverseTransformations(list, values, callback) {
180
181
  }
181
182
 
182
183
  /**
183
- * Apply a list of transformations to the reported values, generating a new array of values with the additional data.
184
+ * Apply a list of transformations to the reported values,
185
+ * generating a new array of values with the additional data.
186
+ * For NGSI-v2 this consists of value transformations only
184
187
  *
185
188
  * @param {Array} values List of reported attributes (with their name, type and value).
189
+ * @param {Object} typeInformation Provisioning information about the device represented by the entity.
186
190
  * @param {Array} transformations List of transformations to apply (with their name, type and expression).
187
191
  */
188
- function processTransformations(values, transformations, callback) {
192
+ function processTransformationsNGSIv2(values, typeInformation, transformations, callback) {
189
193
  let cleanedExpression;
190
- const ctx = parser.extractContext(values);
194
+ const ctx = parser.extractContext(values, typeInformation);
191
195
  let resultTransformations = [];
192
196
 
193
197
  for (let j = 0; j < 2; j++) {
@@ -205,13 +209,107 @@ function processTransformations(values, transformations, callback) {
205
209
  values.push({
206
210
  name: resultTransformations[i].object_id,
207
211
  type: resultTransformations[i].type,
208
- value: parser.parse(cleanedExpression, ctx, 'String')
212
+ value: parser.parse(cleanedExpression, ctx, 'String', typeInformation)
209
213
  });
210
214
  }
211
215
 
212
216
  callback(null, values);
213
217
  }
214
218
 
219
+ /**
220
+ * Apply a list of transformations to the reported values,
221
+ * generating a new array of values with the additional data.
222
+ * For NGSI-LD the output includes value, metadata and datasetId
223
+ *
224
+ * @param {Array} values List of reported attributes (with their name, type and value).
225
+ * @param {Object} typeInformation Provisioning information about the device represented by the entity.
226
+ * @param {Array} transformations List of transformations to apply (with their name, type and expression).
227
+ */
228
+ function processTransformationsNGSILD(values, typeInformation, transformations, callback) {
229
+ let cleanedExpression;
230
+ const defaultValues = [];
231
+ const datasetIds = {};
232
+
233
+ // Split incoming values into those with and without datasetId
234
+ values.forEach((value) => {
235
+ if (value.datasetId) {
236
+ datasetIds[value.datasetId] = datasetIds[value.datasetId] || [];
237
+ datasetIds[value.datasetId].push(value);
238
+ } else {
239
+ defaultValues.push(value);
240
+ }
241
+ });
242
+
243
+ let resultTransformations = [];
244
+
245
+ for (let j = 0; j < 2; j++) {
246
+ if (transformations[j]) {
247
+ resultTransformations = resultTransformations.concat(transformations[j]);
248
+ }
249
+ }
250
+
251
+ // Process Transformations using the default datasetId
252
+ // This is the direct equivalent of the NGSI-v2 function
253
+ if (!_.isEmpty(defaultValues)) {
254
+ for (let i = 0; i < resultTransformations.length; i++) {
255
+ cleanedExpression = resultTransformations[i].expression.substr(
256
+ 2,
257
+ resultTransformations[i].expression.length - 3
258
+ );
259
+ values.push({
260
+ name: resultTransformations[i].object_id,
261
+ type: resultTransformations[i].type,
262
+ metadata: {},
263
+ value: parser.parse(
264
+ cleanedExpression,
265
+ parser.extractContext(defaultValues, typeInformation),
266
+ 'String',
267
+ typeInformation
268
+ )
269
+ });
270
+ }
271
+ }
272
+
273
+ // Process Transformations using an explicit datasetId
274
+ // There is no equivalent with NGSI-v2
275
+ _.keys(datasetIds).forEach((datasetId) => {
276
+ for (let i = 0; i < resultTransformations.length; i++) {
277
+ cleanedExpression = resultTransformations[i].expression.substr(
278
+ 2,
279
+ resultTransformations[i].expression.length - 3
280
+ );
281
+ values.push({
282
+ name: resultTransformations[i].object_id,
283
+ type: resultTransformations[i].type,
284
+ datasetId,
285
+ metadata: {},
286
+ value: parser.parse(
287
+ cleanedExpression,
288
+ parser.extractContext(datasetIds[datasetId], typeInformation),
289
+ 'String',
290
+ typeInformation
291
+ )
292
+ });
293
+ }
294
+ });
295
+ callback(null, values);
296
+ }
297
+
298
+ /**
299
+ * Apply a list of transformations to the reported values, generating a new array of values with the additional data.
300
+ *
301
+ * @param {Array} values List of reported attributes (with their name, type and value).
302
+ * @param {Object} typeInformation Provisioning information about the device represented by the entity.
303
+ * @param {Array} transformations List of transformations to apply (with their name, type and expression).
304
+ */
305
+ function processTransformations(values, typeInformation, transformations, callback) {
306
+ if (config.checkNgsiLD({})) {
307
+ processTransformationsNGSILD(values, typeInformation, transformations, callback);
308
+ } else {
309
+ processTransformationsNGSIv2(values, typeInformation, transformations, callback);
310
+ }
311
+ }
312
+
215
313
  /**
216
314
  * Middleware to handle incoming Configuration group provisions. Should check for the existence of reverse active
217
315
  * attributes and create subscriptions for the modifciation of those values.
@@ -259,7 +357,7 @@ function handleNotification(device, values, callback) {
259
357
  apply(getReverseTransformations, deviceAttributes, values),
260
358
  apply(getReverseTransformations, groupAttributes, values)
261
359
  ]),
262
- apply(processTransformations, values)
360
+ apply(processTransformations, values, device)
263
361
  ],
264
362
  function (error, results) {
265
363
  callback(error, device, results);
@@ -60,6 +60,13 @@ function extractContext(attributeList, typeInformation) {
60
60
  return parser.extractContext(attributeList);
61
61
  }
62
62
 
63
+ function parse(expression, context, type, typeInformation) {
64
+ if (!checkJexl(typeInformation)) {
65
+ return legacyParser.parse(expression, context, type);
66
+ }
67
+ return jexlParser.parse(expression, context);
68
+ }
69
+
63
70
  function mergeAttributes(attrList1, attrList2) {
64
71
  const finalCollection = _.clone(attrList1);
65
72
  const additionalItems = [];
@@ -120,6 +127,8 @@ function update(entity, typeInformation, callback) {
120
127
  attributesCtxt.push(att);
121
128
  });
122
129
  }
130
+ let idTypeSSSList = utils.getIdTypeServSubServiceFromDevice(typeInformation);
131
+ attributesCtxt = attributesCtxt.concat(idTypeSSSList);
123
132
  const ctx = parser.extractContext(attributesCtxt);
124
133
 
125
134
  if (typeInformation.active) {
@@ -156,6 +165,7 @@ function update(entity, typeInformation, callback) {
156
165
  }
157
166
  }
158
167
 
168
+ exports.parse = parse;
159
169
  exports.update = update;
160
170
  exports.setJEXLTransforms = setJEXLTransforms;
161
171
  exports.applyExpression = applyExpression;
@@ -177,7 +177,8 @@ function getIdTypeServSubServiceFromDevice(typeInformation) {
177
177
  { name: 'id', type: 'String', value: typeInformation.id },
178
178
  { name: 'type', type: 'String', value: typeInformation.type },
179
179
  { name: 'service', type: 'String', value: typeInformation.service },
180
- { name: 'subservice', type: 'String', value: typeInformation.subservice }
180
+ { name: 'subservice', type: 'String', value: typeInformation.subservice },
181
+ { name: 'entity_name', type: 'String', value: typeInformation.name }
181
182
  ];
182
183
  return attrList;
183
184
  }
@@ -26,6 +26,7 @@ const logger = require('logops');
26
26
  const context = {
27
27
  op: 'IoTAgentNGSI.Request'
28
28
  };
29
+ const util = require('util');
29
30
 
30
31
  /**
31
32
  * Transform the "request" options into "got" options and add additional "got" defaults
@@ -103,7 +104,7 @@ function request(options, callback) {
103
104
  return callback(null, response, response.body);
104
105
  })
105
106
  .catch((error) => {
106
- logger.debug(context, 'Error: %s', JSON.stringify(error, null, 4));
107
+ logger.debug(context, 'Error: %s', JSON.stringify(util.inspect(error), null, 4));
107
108
  return callback(error);
108
109
  });
109
110
  }
@@ -282,32 +282,24 @@ function registerDevice(deviceObj, callback) {
282
282
  }
283
283
 
284
284
  if (!deviceData.name) {
285
- if (configuration && configuration.entityNameExp !== undefined) {
285
+ let entityName = null;
286
+ if (configuration && configuration.entityNameExp !== undefined && configuration.entityNameExp !== '') {
286
287
  // Add device ID, TYPE, S, SS to the context for the JEXL expression
287
288
  let attrList = pluginUtils.getIdTypeServSubServiceFromDevice(deviceData);
288
289
  attrList = deviceData.staticAttributes ? attrList.concat(deviceData.staticAttributes) : attrList;
289
290
  let ctxt = expressionPlugin.extractContext(attrList, deviceData);
290
- let entityName = expressionPlugin.applyExpression(configuration.entityNameExp, ctxt, deviceData);
291
- deviceData.name = entityName ? entityName : configuration.entityNameExp;
292
- } else {
293
- let conjunction;
294
- if (configuration && configuration.defaultEntityNameConjunction !== undefined) {
295
- conjunction = configuration.defaultEntityNameConjunction;
296
- } else {
297
- conjunction = config.getConfig().defaultEntityNameConjunction;
298
- }
299
- deviceData.name = deviceData.type + conjunction + deviceData.id;
300
-
301
- if (config.checkNgsiLD(configuration)) {
302
- deviceData.name = 'urn:ngsi-ld:' + deviceData.type + conjunction + deviceData.id;
291
+ try {
292
+ entityName = expressionPlugin.applyExpression(configuration.entityNameExp, ctxt, deviceData);
293
+ } catch (e) {
294
+ logger.debug(
295
+ context,
296
+ 'Error evaluating expression for entityName: %s with context: %s',
297
+ configuration.entityNameExp,
298
+ ctxt
299
+ );
303
300
  }
304
- logger.debug(
305
- context,
306
- 'Device name not found, falling back to deviceType%sdeviceId [%s]',
307
- conjunction,
308
- deviceData.name
309
- );
310
301
  }
302
+ deviceData.name = entityName ? entityName : defaultName();
311
303
  }
312
304
 
313
305
  if (!configuration && config.getConfig().types[deviceData.type]) {
@@ -316,6 +308,28 @@ function registerDevice(deviceObj, callback) {
316
308
  selectedConfiguration = configuration;
317
309
  }
318
310
  callback(null, deviceData, selectedConfiguration);
311
+
312
+ function defaultName() {
313
+ let conjunction;
314
+ let name;
315
+ if (configuration && configuration.defaultEntityNameConjunction !== undefined) {
316
+ conjunction = configuration.defaultEntityNameConjunction;
317
+ } else {
318
+ conjunction = config.getConfig().defaultEntityNameConjunction;
319
+ }
320
+ name = deviceData.type + conjunction + deviceData.id;
321
+
322
+ if (config.checkNgsiLD(configuration)) {
323
+ name = 'urn:ngsi-ld:' + deviceData.type + conjunction + deviceData.id;
324
+ }
325
+ logger.debug(
326
+ context,
327
+ 'Device name not found, falling back to deviceType%sdeviceId [%s]',
328
+ conjunction,
329
+ deviceData.name
330
+ );
331
+ return name;
332
+ }
319
333
  }
320
334
 
321
335
  function completeRegistrations(error, deviceData) {