iotagent-node-lib 2.23.0 → 2.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +6 -7
- package/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
- package/.nyc_output/processinfo/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -1
- package/CHANGES_NEXT_RELEASE +1 -2
- package/doc/advanced-topics.md +78 -3
- package/doc/apiary/iotagent.apib +5 -5
- package/doc/architecture.md +52 -5
- package/doc/deprecated.md +10 -7
- package/doc/expressionLanguage.md +46 -35
- package/doc/getting-started.md +1 -1
- package/doc/usermanual.md +18 -16
- package/examples/TTOpen-service.json +1 -1
- package/lib/errors.js +9 -1
- package/lib/fiware-iotagent-lib.js +2 -1
- package/lib/jexlTranformsMap.js +12 -1
- package/lib/plugins/bidirectionalData.js +104 -6
- package/lib/plugins/expressionPlugin.js +10 -0
- package/lib/plugins/jexlParser.js +2 -2
- package/lib/plugins/pluginUtils.js +2 -1
- package/lib/request-shim.js +2 -1
- package/lib/services/devices/deviceService.js +53 -21
- package/lib/services/devices/devices-NGSI-v2.js +3 -1
- package/lib/services/ngsi/entities-NGSI-v2.js +14 -4
- package/lib/services/northBound/contextServer-NGSI-LD.js +96 -20
- package/lib/services/northBound/contextServer-NGSI-v2.js +1 -0
- package/lib/services/northBound/restUtils.js +3 -5
- package/lib/templates/deviceGroup.json +1 -1
- package/package.json +2 -2
- package/test/unit/examples/deviceProvisioningRequests/provisionNewDeviceEmpty.json +43 -0
- package/test/unit/examples/mongoCollections/configurations.json +3 -3
- package/test/unit/expressions/jexlExpression-test.js +29 -8
- package/test/unit/general/deviceService-test.js +31 -29
- package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +62 -10
- package/test/unit/mongodb/mongodb-group-registry-test.js +24 -0
- package/test/unit/mongodb/mongodb-registry-test.js +68 -10
- package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin30.json +11 -0
- package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +21 -0
- package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +17 -0
- package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +18 -4
- package/test/unit/ngsi-ld/general/deviceService-test.js +31 -29
- package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +656 -2
- package/test/unit/ngsi-ld/ngsiService/unsupported-endpoints-test.js +111 -0
- package/test/unit/ngsi-ld/plugins/bidirectional-plugin_test.js +221 -0
- package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +0 -3
- package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityJexlExpressionPlugin1.json +22 -0
- package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +19 -0
- package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +21 -6
- package/test/unit/ngsiv2/general/deviceService-test.js +25 -23
- package/test/unit/ngsiv2/lazyAndCommands/command-test.js +106 -0
- package/test/unit/ngsiv2/plugins/bidirectional-plugin_test.js +115 -0
- package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +58 -0
- package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +25 -6
- package/.nyc_output/6e3d7795-bf8c-4a50-bd2f-f8221f27aeae.json +0 -1
- package/.nyc_output/processinfo/6e3d7795-bf8c-4a50-bd2f-f8221f27aeae.json +0 -1
- package/config +0 -0
- package/docker/Mosquitto/Dockerfile.debian +0 -38
- package/docker/Mosquitto/Dockerfile.debian~ +0 -23
- package/lib/plugins/multiEntity.js_avg2 +0 -343
- 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":{"
|
|
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":{}}
|
package/CHANGES_NEXT_RELEASE
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
|
package/doc/advanced-topics.md
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
- [Autoprovision configuration (autoprovision)](#autoprovision-configuration-autoprovision)
|
|
9
9
|
- [Explicitly defined attributes (explicitAttrs)](#explicitly-defined-attributes-explicitattrs)
|
|
10
10
|
- [Configuring operation to persist the data in Context Broker (appendMode)](#configuring-operation-to-persist-the-data-in-context-broker-appendmode)
|
|
11
|
+
- [Differences between `autoprovision`, `explicitAttrs` and `appendMode`](#differences-between-autoprovision-explicitattrs-and-appendmode)
|
|
11
12
|
- [Data mapping plugins](#data-mapping-plugins)
|
|
12
13
|
- [Development](#development)
|
|
13
14
|
- [Provided plugins](#provided-plugins)
|
|
@@ -20,7 +21,6 @@
|
|
|
20
21
|
- [Bidirectionality plugin (bidirectional)](#bidirectionality-plugin-bidirectional)
|
|
21
22
|
- [Autoprovision configuration (autoprovision)](#autoprovision-configuration-autoprovision)
|
|
22
23
|
- [Explicitly defined attributes (explicitAttrs)](#explicitly-defined-attributes-explicitattrs)
|
|
23
|
-
- [Configuring operation to persist the data in Context Broker (appendMode)](#configuring-operation-to-persist-the-data-in-context-broker-appendmode)
|
|
24
24
|
|
|
25
25
|
### Secured access to the Context Broker
|
|
26
26
|
|
|
@@ -368,6 +368,28 @@ This is a flag that can be enabled by activating the parameter `appendMode` in t
|
|
|
368
368
|
activated, the update requests to the Context Broker will be performed always with APPEND type, instead of the default
|
|
369
369
|
UPDATE. This have implications in the use of attributes with Context Providers, so this flag should be used with care.
|
|
370
370
|
|
|
371
|
+
### Differences between `autoprovision`, `explicitAttrs` and `appendMode`
|
|
372
|
+
|
|
373
|
+
Since those configuration parameters are quite similar, this section is intended to clarify the relation between them.
|
|
374
|
+
|
|
375
|
+
If `autoprovision` is set to `true` (default case), the agent will perform an initial request creating a new entity into
|
|
376
|
+
the Context Broker with **only** the static and active attributes provisioned in the config group, and also a new
|
|
377
|
+
Device in the agent, every time a measure arrives with a new `device_id`. Otherwise, this measure is ignored. This is
|
|
378
|
+
something related to the **southbound**.
|
|
379
|
+
|
|
380
|
+
What `explicitAttrs` does is to filter from the southbound the parameters that are not explicitly defined in the device
|
|
381
|
+
provision or config group. That also would avoid propagating the measures to the Context Broker.
|
|
382
|
+
|
|
383
|
+
The default way the agent updates the information into the Context Broker is by using an update request. If
|
|
384
|
+
`appendMode=true`, the IoTA will use an append request instead of an update one. This means it will store
|
|
385
|
+
the attributes even if they are not present in the entity. This seems the same functionality that the one provided by
|
|
386
|
+
`autoprovision`, but it is a different concept since the scope of this config is to setup how the IoT interacts with the
|
|
387
|
+
context broker, this is something related to the **northbound**.
|
|
388
|
+
|
|
389
|
+
Note that, even creating a group with `autoprovision=true` and `explicitAttrs=true`, if you do not provision previously
|
|
390
|
+
the entity in the Context Broker (having all attributes to be updated), it would fail if `appendMode=false`. For further
|
|
391
|
+
information check the issue [#1301](https://github.com/telefonicaid/iotagent-node-lib/issues/1301).
|
|
392
|
+
|
|
371
393
|
### Data mapping plugins
|
|
372
394
|
|
|
373
395
|
The IoT Agent Library provides a plugin mechanism in order to facilitate reusing code that makes small transformations
|
|
@@ -514,9 +536,9 @@ intercepted by the plugin, so the mapped values are included in the updated noti
|
|
|
514
536
|
|
|
515
537
|
When a device is provisioned with bidirectional attributes, the IoTAgent subscribes to changes in that attribute. When a
|
|
516
538
|
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.
|
|
539
|
+
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
540
|
|
|
519
|
-
The following `attributes` section shows an example of the plugin configuration (using IOTA_AUTOCAST=false to avoid
|
|
541
|
+
The following `attributes` section shows an example of the plugin configuration (using `IOTA_AUTOCAST=false` to avoid
|
|
520
542
|
translation from geo:point to geo:json)
|
|
521
543
|
|
|
522
544
|
```json
|
|
@@ -549,3 +571,56 @@ subscription payload.
|
|
|
549
571
|
For each attribute in the `reverse` array, an expression must be defined to calculate its value based on the
|
|
550
572
|
notification attributes. This value will be passed to the underlying protocol with the `object_id` name. Details about
|
|
551
573
|
how the value is then progressed to the device are protocol-specific.
|
|
574
|
+
|
|
575
|
+
##### NGSI-LD `datasetId` support
|
|
576
|
+
|
|
577
|
+
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:
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
```json
|
|
581
|
+
{
|
|
582
|
+
"id": "urn:ngsi-ld:Notification:5fd0fa684eb81930c97005f3",
|
|
583
|
+
"type": "Notification",
|
|
584
|
+
"subscriptionId": "urn:ngsi-ld:Subscription:5fd0f69b4eb81930c97005db",
|
|
585
|
+
"notifiedAt": "2020-12-09T16:25:12.193Z",
|
|
586
|
+
"data": [
|
|
587
|
+
{
|
|
588
|
+
"lampColor": [
|
|
589
|
+
{
|
|
590
|
+
"type": "Property",
|
|
591
|
+
"value": { "color": "green", "duration": "55 secs"},
|
|
592
|
+
"datasetId": "urn:ngsi-ld:Sequence:do-this"
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
"type": "Property",
|
|
596
|
+
"value": {"color": "red", "duration": "10 secs"},
|
|
597
|
+
"datasetId": "urn:ngsi-ld:Sequence:then-do-this"
|
|
598
|
+
}
|
|
599
|
+
]
|
|
600
|
+
}
|
|
601
|
+
]
|
|
602
|
+
}
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
This results in the following sequential array of attribute updates to be sent to the `NotificationHandler` of the IoT Agent itself:
|
|
606
|
+
|
|
607
|
+
```json
|
|
608
|
+
[
|
|
609
|
+
{
|
|
610
|
+
"name": "lampColor",
|
|
611
|
+
"type": "Property",
|
|
612
|
+
"datasetId": "urn:ngsi-ld:Sequence:do-this",
|
|
613
|
+
"metadata": {},
|
|
614
|
+
"value": { "color": "green", "duration": "55 secs"}
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
"name": "lampColor",
|
|
618
|
+
"type": "Property",
|
|
619
|
+
"datasetId": "urn:ngsi-ld:Sequence:then-do-this",
|
|
620
|
+
"metadata": {},
|
|
621
|
+
"value": {"color": "red", "duration": "10 secs"}
|
|
622
|
+
}
|
|
623
|
+
]
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
A `datasetId` is also maintained for each new attribute defined in the `reverse` field.
|
package/doc/apiary/iotagent.apib
CHANGED
|
@@ -80,7 +80,7 @@ Fields in JSON object representing a configuration group are:
|
|
|
80
80
|
|:-----------------------|:------------------------------------------------------------|
|
|
81
81
|
|`apikey` |It is a key used for devices belonging to this service. If "", service does not use apikey, but it must be specified.|
|
|
82
82
|
|`token` |If authentication/authorization system is configured, IoT Agent works as user when it publishes information. That token allows that other components to verify the identity of IoT Agent. Depends on authentication and authorization system.|
|
|
83
|
-
|`
|
|
83
|
+
|`cbHost` |Context Broker endpoint assigned to this service, it must be a real uri.|
|
|
84
84
|
|`outgoing_route` |It is an identifier for VPN/GRE tunnel. It is used when device is into a VPN and a command is sent.|
|
|
85
85
|
|`resource` |Path in IoTAgent. When protocol is HTTP a device could send information to this uri. In general, it is a uri in a HTTP server needed to load and execute a module.|
|
|
86
86
|
|`entity_type` |Entity type used in entity publication (overload default).|
|
|
@@ -126,7 +126,7 @@ Retrieve a configuration group.
|
|
|
126
126
|
"service": "service2",
|
|
127
127
|
"service_path": "/srvpath2",
|
|
128
128
|
"token": "token2",
|
|
129
|
-
"
|
|
129
|
+
"cbHost": "http://127.0.0.1:1026",
|
|
130
130
|
"entity_type": "thing",
|
|
131
131
|
"resource": "/iot/d"
|
|
132
132
|
}
|
|
@@ -152,7 +152,7 @@ Retrieve a configuration group.
|
|
|
152
152
|
"service": "service2",
|
|
153
153
|
"service_path": "/srvpath2",
|
|
154
154
|
"token": "token2",
|
|
155
|
-
"
|
|
155
|
+
"cbHost": "http://127.0.0.1:1026",
|
|
156
156
|
"entity_type": "thing",
|
|
157
157
|
"resource": "/iot/d"
|
|
158
158
|
}
|
|
@@ -162,7 +162,7 @@ Retrieve a configuration group.
|
|
|
162
162
|
|
|
163
163
|
### Create a configuration group [POST]
|
|
164
164
|
|
|
165
|
-
Create a new configuration group. From service model, mandatory fields are: apikey, resource (
|
|
165
|
+
Create a new configuration group. From service model, mandatory fields are: apikey, resource (cbHost field is temporary mandatory).
|
|
166
166
|
|
|
167
167
|
+ Request (application/json)
|
|
168
168
|
|
|
@@ -178,7 +178,7 @@ Create a new configuration group. From service model, mandatory fields are: apik
|
|
|
178
178
|
{
|
|
179
179
|
"apikey": "apikey3",
|
|
180
180
|
"token": "token2",
|
|
181
|
-
"
|
|
181
|
+
"cbHost": "http://127.0.0.1:1026",
|
|
182
182
|
"entity_type": "thing",
|
|
183
183
|
"resource": "/iot/d"
|
|
184
184
|
}
|
package/doc/architecture.md
CHANGED
|
@@ -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
|
|
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
|
-
|
|
219
|
-
|
|
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.
|
package/doc/deprecated.md
CHANGED
|
@@ -12,13 +12,15 @@ longer. In particular:
|
|
|
12
12
|
|
|
13
13
|
A list of deprecated features and the version in which they were deprecated follows:
|
|
14
14
|
|
|
15
|
-
- Support to NGSI v1.
|
|
15
|
+
- Support to NGSI v1 (finally removed in 2.18.0)
|
|
16
16
|
- Support to Node.js v4 in iotagent-node-lib 2.8.1 (finally removed in 2.9.0)
|
|
17
17
|
- Support to Node.js v6 in iotagent-node-lib 2.9.0 (finally removed in 2.10.0)
|
|
18
18
|
- Support to Node.js v8 in iotagent-node-lib 2.12.0 (finally removed in 2.13.0)
|
|
19
19
|
- Support to Node.js v10 in iotagent-node-lib 2.15.0 (finally removed in 2.16.0)
|
|
20
|
+
- Support to Node.js v12 in iotagent-node-lib 2.24.0 (finally removed in 2.25.0)
|
|
21
|
+
- Support to NGSI-LD v1.3 in iotagent-node-lib 2.25.0
|
|
20
22
|
|
|
21
|
-
The use of Node.js
|
|
23
|
+
The use of Node.js v14 is highly recommended.
|
|
22
24
|
|
|
23
25
|
## Using old iotagent-node-lib versions
|
|
24
26
|
|
|
@@ -38,8 +40,9 @@ The following table provides information about the last iotagent-node-lib versio
|
|
|
38
40
|
|
|
39
41
|
| **Removed feature** | **Last iotagent-node-lib version supporting feature** | **That version release date** |
|
|
40
42
|
| ---------------------- | ----------------------------------------------------- | ----------------------------- |
|
|
41
|
-
| NGSI v1 API |
|
|
42
|
-
| Support to Node.js v4 | 2.8.1 | December 19th, 2018
|
|
43
|
-
| Support to Node.js v6 | 2.9.0 | May 22nd, 2019
|
|
44
|
-
| Support to Node.js v8 | 2.12.0 | April 7th, 2020
|
|
45
|
-
| Support to Node.js v10 | 2.15.0
|
|
43
|
+
| NGSI v1 API | 2.17.0 | August 30th, 2021 |
|
|
44
|
+
| Support to Node.js v4 | 2.8.1 | December 19th, 2018 |
|
|
45
|
+
| Support to Node.js v6 | 2.9.0 | May 22nd, 2019 |
|
|
46
|
+
| Support to Node.js v8 | 2.12.0 | April 7th, 2020 |
|
|
47
|
+
| Support to Node.js v10 | 2.15.0 | February 18th, 2021 |
|
|
48
|
+
| Support to Node.js v12 | 2.24.0 | September 2nd, 2022 |
|
|
@@ -75,7 +75,7 @@ can check the following example:
|
|
|
75
75
|
"services": [
|
|
76
76
|
{
|
|
77
77
|
"apikey": "801230BJKL23Y9090DSFL123HJK09H324HV8732",
|
|
78
|
-
"
|
|
78
|
+
"cbHost": "http://orion:1026",
|
|
79
79
|
"entity_type": "Thing",
|
|
80
80
|
"resource": "/iot/d"
|
|
81
81
|
"expressionLanguage": "jexl",
|
|
@@ -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
|
-
- `
|
|
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
|
|
|
@@ -458,39 +459,49 @@ to incorporate new transformations from the IoT Agent configuration file in a fa
|
|
|
458
459
|
|
|
459
460
|
Current common transformation set:
|
|
460
461
|
|
|
461
|
-
| JEXL Transformation
|
|
462
|
-
|
|
|
463
|
-
| jsonparse: (str)
|
|
464
|
-
| jsonstringify: (obj)
|
|
465
|
-
| indexOf: (val, char)
|
|
466
|
-
| length: (val)
|
|
467
|
-
| trim: (val)
|
|
468
|
-
| substr: (val, int1, int2)
|
|
469
|
-
| addreduce: (arr)
|
|
470
|
-
| lengtharray: (arr)
|
|
471
|
-
| typeof: (val)
|
|
472
|
-
| isarray: (arr)
|
|
473
|
-
| isnan: (val)
|
|
474
|
-
| parseint: (val)
|
|
475
|
-
| parsefloat: (val)
|
|
476
|
-
| toisodate: (val)
|
|
477
|
-
| timeoffset:(isostr)
|
|
478
|
-
| tostring: (val)
|
|
479
|
-
| urlencode: (val)
|
|
480
|
-
| urldecode: (val)
|
|
481
|
-
| replacestr: (str, from, to)
|
|
482
|
-
| replaceregexp: (str, reg, to)
|
|
483
|
-
| replaceallstr: (str, from, to)
|
|
484
|
-
| replaceallregexp: (str, reg, to)
|
|
485
|
-
| split: (str, ch)
|
|
486
|
-
|
|
|
487
|
-
|
|
|
488
|
-
|
|
|
489
|
-
|
|
|
490
|
-
|
|
|
491
|
-
|
|
|
492
|
-
|
|
|
493
|
-
|
|
|
462
|
+
| JEXL Transformation | Equivalent JavaScript Function |
|
|
463
|
+
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
|
|
464
|
+
| jsonparse: (str) | `JSON.parse(str);` |
|
|
465
|
+
| jsonstringify: (obj) | `JSON.stringify(obj);` |
|
|
466
|
+
| indexOf: (val, char) | `String(val).indexOf(char);` |
|
|
467
|
+
| length: (val) | `String(val).length;` |
|
|
468
|
+
| trim: (val) | `String(val).trim();` |
|
|
469
|
+
| substr: (val, int1, int2) | `String(val).substr(int1, int2);` |
|
|
470
|
+
| addreduce: (arr) | <code>arr.reduce((i, v) | i + v));</code> |
|
|
471
|
+
| lengtharray: (arr) | `arr.length;` |
|
|
472
|
+
| typeof: (val) | `typeof val;` |
|
|
473
|
+
| isarray: (arr) | `Array.isArray(arr);` |
|
|
474
|
+
| isnan: (val) | `isNaN(val);` |
|
|
475
|
+
| parseint: (val) | `parseInt(val);` |
|
|
476
|
+
| parsefloat: (val) | `parseFloat(val);` |
|
|
477
|
+
| toisodate: (val) | `new Date(val).toISOString();` |
|
|
478
|
+
| timeoffset:(isostr) | `new Date(isostr).getTimezoneOffset();` |
|
|
479
|
+
| tostring: (val) | `val.toString();` |
|
|
480
|
+
| urlencode: (val) | `encodeURI(val);` |
|
|
481
|
+
| urldecode: (val) | `decodeURI(val);` |
|
|
482
|
+
| replacestr: (str, from, to) | `str.replace(from, to);` |
|
|
483
|
+
| replaceregexp: (str, reg, to) | `str.replace(new RegExp(reg), to);` |
|
|
484
|
+
| replaceallstr: (str, from, to) | `str.replaceAll(from, to);` |
|
|
485
|
+
| replaceallregexp: (str, reg, to) | `str.replaceAll(new RegExp(reg,"g"), to);` |
|
|
486
|
+
| split: (str, ch) | `str.split(ch);` |
|
|
487
|
+
| joinarrtostr: (arr, ch) | `arr.join(ch);` |
|
|
488
|
+
| concatarr: (arr, arr2) | `arr.concat(arr2);` |
|
|
489
|
+
| mapper: (val, values, choices) | <code>choices[values.findIndex((target) | target == val)]);</code> |
|
|
490
|
+
| thmapper: (val, values, choices) | <code>choices[values.reduce((acc,curr,i,arr) | (acc==0)||acc?acc:val<=curr?acc=i:acc=null,null)];</code> |
|
|
491
|
+
| bitwisemask: (i,mask,op,shf) | <code>(op==="&"?parseInt(i)&mask: op==="|"?parseInt(i)|mask: op==="^"?parseInt(i)^mask:i)>>shf;</code> |
|
|
492
|
+
| slice: (arr, init, end) | `arr.slice(init,end);` |
|
|
493
|
+
| addset: (arr, x) | <code>{ return Array.from((new Set(arr)).add(x)) }</code> |
|
|
494
|
+
| removeset: (arr, x) | <code>{ let s = new Set(arr); s.delete(x); return Array.from(s) }</code> |
|
|
495
|
+
| touppercase: (val) | `String(val).toUpperCase()` |
|
|
496
|
+
| tolowercase: (val) | `String(val).toLowerCase()` |
|
|
497
|
+
| round: (val) | `Math.round(val)` |
|
|
498
|
+
| floor: (val) | `Math.floor(val)` |
|
|
499
|
+
| ceil: (val) | `Math.ceil(val)` |
|
|
500
|
+
| tofixed: (val, decimals) | `Number.parseFloat(val).toFixed(decimals)` |
|
|
501
|
+
| gettime: (d) | `new Date(d).getTime()` |
|
|
502
|
+
| toisostring: (d) | `new Date(d).toISOString()` |
|
|
503
|
+
| localestring: (d, timezone, options) | `new Date(d).toLocaleString(timezone, options)` |
|
|
504
|
+
| now: () | `Date.now()` |
|
|
494
505
|
|
|
495
506
|
You have available this [JEXL interactive playground][99] with all the transformations already loaded, in which you can
|
|
496
507
|
test all the functions described above.
|
package/doc/getting-started.md
CHANGED
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(
|
|
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(
|
|
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`).
|
|
262
|
-
|
|
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:
|
|
270
|
+
type: "TheType",
|
|
269
271
|
isPattern: false,
|
|
270
|
-
id:
|
|
272
|
+
id: "EntityID",
|
|
271
273
|
attributes: [
|
|
272
274
|
{
|
|
273
|
-
name:
|
|
274
|
-
type:
|
|
275
|
-
value:
|
|
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
|
|
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:
|
|
308
|
+
type: "TheType",
|
|
307
309
|
isPattern: false,
|
|
308
|
-
id:
|
|
310
|
+
id: "EntityID",
|
|
309
311
|
attributes: [
|
|
310
312
|
{
|
|
311
|
-
name:
|
|
312
|
-
type:
|
|
313
|
-
value:
|
|
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
|
};
|
|
@@ -363,7 +363,8 @@ exports.dataPlugins = {
|
|
|
363
363
|
timestampProcess: require('./plugins/timestampProcessPlugin'),
|
|
364
364
|
expressionTransformation: require('./plugins/expressionPlugin'),
|
|
365
365
|
multiEntity: require('./plugins/multiEntity'),
|
|
366
|
-
bidirectionalData: require('./plugins/bidirectionalData')
|
|
366
|
+
bidirectionalData: require('./plugins/bidirectionalData'),
|
|
367
|
+
utils: require('./plugins/pluginUtils')
|
|
367
368
|
};
|
|
368
369
|
|
|
369
370
|
exports.alarms = require('./services/common/alarmManagement');
|