iotagent-node-lib 4.9.0 → 4.10.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 (43) hide show
  1. package/.github/workflows/ci.yml +6 -8
  2. package/Changelog +6 -0
  3. package/config.js +2 -1
  4. package/doc/admin.md +12 -0
  5. package/doc/api.md +33 -3
  6. package/doc/devel/northboundinteractions.md +200 -112
  7. package/lib/commonConfig.js +5 -1
  8. package/lib/model/Device.js +3 -1
  9. package/lib/model/Group.js +2 -1
  10. package/lib/services/common/iotManagerService.js +2 -1
  11. package/lib/services/devices/deviceRegistryMongoDB.js +5 -1
  12. package/lib/services/devices/deviceService.js +17 -1
  13. package/lib/services/devices/devices-NGSI-LD.js +3 -2
  14. package/lib/services/devices/devices-NGSI-mixed.js +16 -0
  15. package/lib/services/devices/devices-NGSI-v2.js +122 -8
  16. package/lib/services/devices/registrationUtils.js +97 -30
  17. package/lib/services/groups/groupRegistryMongoDB.js +2 -1
  18. package/lib/services/ngsi/subscription-NGSI-LD.js +2 -2
  19. package/lib/services/ngsi/subscription-NGSI-mixed.js +3 -3
  20. package/lib/services/ngsi/subscription-NGSI-v2.js +20 -6
  21. package/lib/services/ngsi/subscriptionService.js +2 -2
  22. package/lib/services/northBound/deviceProvisioningServer.js +6 -3
  23. package/lib/templates/updateDevice.json +12 -0
  24. package/lib/templates/updateDeviceLax.json +4 -0
  25. package/package.json +2 -2
  26. package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +2 -2
  27. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +1 -1
  28. package/test/unit/ngsi-ld/general/contextBrokerOAuthSecurityAccess-test.js +2 -2
  29. package/test/unit/ngsi-ld/general/https-support-test.js +1 -1
  30. package/test/unit/ngsi-ld/ngsiService/subscriptions-test.js +6 -6
  31. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands.json +24 -0
  32. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands2.json +24 -0
  33. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands3.json +24 -0
  34. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands4.json +24 -0
  35. package/test/unit/ngsiv2/examples/contextRequests/updateEntity.json +5 -0
  36. package/test/unit/ngsiv2/examples/contextRequests/updateEntity2.json +5 -0
  37. package/test/unit/ngsiv2/examples/contextRequests/updateEntity2b.json +7 -0
  38. package/test/unit/ngsiv2/examples/contextRequests/updateEntity3.json +5 -0
  39. package/test/unit/ngsiv2/examples/subscriptionRequests/simpleSubscriptionRequest.json +4 -2
  40. package/test/unit/ngsiv2/examples/subscriptionRequests/simpleSubscriptionRequest2.json +4 -2
  41. package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +2 -2
  42. package/test/unit/ngsiv2/general/https-support-test.js +1 -1
  43. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +245 -2
@@ -14,10 +14,10 @@ jobs:
14
14
  steps:
15
15
  - name: Git checkout
16
16
  uses: actions/checkout@v2
17
- - name: Use Node.js 16.x
17
+ - name: Use Node.js 24.x
18
18
  uses: actions/setup-node@v1
19
19
  with:
20
- node-version: 16.x
20
+ node-version: 24.x
21
21
  - name: Run Remark Markdown Linter
22
22
  run: |
23
23
  npm install
@@ -31,10 +31,10 @@ jobs:
31
31
  steps:
32
32
  - name: Git checkout
33
33
  uses: actions/checkout@v2
34
- - name: Use Node.js 16.x
34
+ - name: Use Node.js 24.x
35
35
  uses: actions/setup-node@v1
36
36
  with:
37
- node-version: 16.x
37
+ node-version: 24.x
38
38
  - name: Run EsLint Node.js Linter
39
39
  run: |
40
40
  npm install
@@ -51,8 +51,6 @@ jobs:
51
51
  strategy:
52
52
  matrix:
53
53
  node-version:
54
- - 16.x
55
- - 18.x
56
54
  - 20.x
57
55
  - 22.x
58
56
  - 24.x
@@ -80,10 +78,10 @@ jobs:
80
78
  steps:
81
79
  - name: Git checkout
82
80
  uses: actions/checkout@v2
83
- - name: 'Test Coverage with Node.js 16.x'
81
+ - name: 'Test Coverage with Node.js 24.x'
84
82
  uses: actions/setup-node@v1
85
83
  with:
86
- node-version: 16.x
84
+ node-version: 24.x
87
85
  - run: |
88
86
  npm install
89
87
  npm run test:coverage
package/Changelog CHANGED
@@ -1,3 +1,9 @@
1
+ 4.10.0 (Oct 6th, 2025)
2
+
3
+ - Add: command modes (new field cmdMode): legacy, notification and advancedNotification (#1732)
4
+ - Fix: update device with useCBflowControl
5
+ - Set Nodejs 20 as minimum version in packages.json (effectively removing Nodev16 and Nodev18 from supported versions)
6
+
1
7
  4.9.0 (Aug 22nd, 2025)
2
8
 
3
9
  - Add: support NGSI-LD QueryEntities endpoint for lazy attributes (#1722)
package/config.js CHANGED
@@ -79,7 +79,8 @@ var config = {
79
79
  defaultType: 'Thing',
80
80
  expressLimit: '1Mb',
81
81
  useCBflowControl: false,
82
- storeLastMeasure: false
82
+ storeLastMeasure: false,
83
+ cmdMode: 'legacy'
83
84
  };
84
85
 
85
86
  module.exports = config;
package/doc/admin.md CHANGED
@@ -452,6 +452,17 @@ If this flag is activated, when iotAgent invokes Context Broker will use
452
452
  [flowControl option](https://github.com/telefonicaid/fiware-orion/blob/master/doc/manuals/admin/perf_tuning.md#updates-flow-control-mechanism).
453
453
  This flag is overwritten by `useCBflowControl` flag in group or device. This flag is disabled by default.
454
454
 
455
+ #### `cmdMode`
456
+
457
+ Set command mode for the IoTAgent instance (it can be overriden by the `cmdMode` at group or device level). Possible values are:
458
+
459
+ * `legacy` (used as default if this setting is not defined): IoTAgent commands will use Context Broker registers
460
+ mechanims.
461
+ * `notification`: IoTAgent commands will use subscriptions to be notified for Context Broker commands.
462
+ * `advancedNotification`: IoTAgent commands will use subscriptions to be notified for Context Broker commands (but in a different way as in `notification` mode)
463
+
464
+ Have a look to [this document](devel/northboundinteractions.md) for more detail on how this modes work.
465
+
455
466
  ### Configuration using environment variables
456
467
 
457
468
  Some of the configuration parameters can be overriden with environment variables, to ease the use of those parameters
@@ -517,6 +528,7 @@ overrides.
517
528
  | IOTA_EXPRESS_LIMIT | `expressLimit` |
518
529
  | IOTA_STORE_LAST_MEASURE | `storeLastMeasure` |
519
530
  | IOTA_CB_FLOW_CONTROL | `useCBflowControl` |
531
+ | IOTA_CMD_MODE | `cmdMode` |
520
532
 
521
533
  Note:
522
534
 
package/doc/api.md CHANGED
@@ -12,6 +12,7 @@
12
12
  - [Special measures and attributes names](#special-measures-and-attributes-names)
13
13
  - [Device to NGSI Mapping](#device-to-ngsi-mapping)
14
14
  - [Device autoprovision and entity creation](#device-autoprovision-and-entity-creation)
15
+ - [Entity creation when `cmdMode` is `notification`](#entity-creation-when-cmdmode-is-notification)
15
16
  - [Entity Name expression support](#entity-name-expression-support)
16
17
  - [Multientity support](#multientity-support)
17
18
  - [Metadata support](#metadata-support)
@@ -257,9 +258,9 @@ Additionally for commands (which are attributes of type `command`) the following
257
258
  particular IOTAs documentation for allowed values of this field in each case.
258
259
  - **contentType**: `content-type` header used when send command by HTTP transport (ignored in other kinds of
259
260
  transports)
260
- - **headers**: extra customer headers used when send command by HTTP transport (ignored in other kinds of
261
- transports)
262
- Check full detail of these fields in [comand-transformations](https://github.com/telefonicaid/iotagent-json/blob/master/docs/usermanual.md#commands-transformations)
261
+ - **headers**: extra customer headers used when send command by HTTP transport (ignored in other kinds of transports)
262
+ Check full detail of these fields in
263
+ [comand-transformations](https://github.com/telefonicaid/iotagent-json/blob/master/docs/usermanual.md#commands-transformations)
263
264
 
264
265
  Note that, when information coming from devices, this means measures, are not defined neither in the group, nor in the
265
266
  device, the IoT agent will store that information into the destination entity using the same attribute name than the
@@ -276,6 +277,31 @@ If for any reason you need the entity at CB before the first measure of the corr
276
277
  IOTAgent, you can create it in advance using the Context Broker
277
278
  [NGSI v2 API](https://github.com/telefonicaid/fiware-orion/blob/master/doc/manuals/orion-api.md).
278
279
 
280
+ ## Entity creation when `cmdMode` is `notification`
281
+
282
+ Even when an entity should not be created (see [above section](#device-autoprovision-and-entity-creation)), when the device uses `cmdMode` set to `notification` an entity is created. In particular:
283
+
284
+ * An entity is created at device provision time
285
+ * That entity is created with an attribute corresponding to each commands. The value of that attribute at creation time is `null` (specifying in some way that the command has not been triggered yet). Note that if the attribute doesn't have any command, the entity is not created (even if `cmdMode` is `notification`).
286
+
287
+ For instance, if device has commands `ping` and `switch` the entity corresponding to that device will be created at provising time with the following attributes:
288
+
289
+ ```
290
+ ...
291
+ {
292
+ "ping": {
293
+ "type": "command",
294
+ "value": null
295
+ },
296
+ "switch": {
297
+ "type": "command",
298
+ "value": null
299
+ },
300
+ }
301
+ ```
302
+
303
+ **NOTE:** `command` is the usual type for attributes associated to commands, but the one used at provisioning time (`"command": [ ...]` field) will be actually used.
304
+
279
305
  ## Entity Name expression support
280
306
 
281
307
  By default, the entity name used to persist the device measures in the Context Broker can be defined in the device
@@ -1323,6 +1349,8 @@ as `command` in the [config group](#config-group-datamodel) or in the [device pr
1323
1349
  attributes are created using `command` as attribute type. Also, you can define the protocol you want the commands to be
1324
1350
  sent (HTTP/MQTT) with the `transport` parameter at the provisioning process.
1325
1351
 
1352
+ **NOTE**: in `advancedNotification` mode the command is not triggered updating an attribute, but creating a command execution entity. However, this mode has not been implemented yet so details are to be clarified.
1353
+
1326
1354
  For a given device provisioned with a `ping` command defined, any update on this attribute "ping" at the NGSI entity in
1327
1355
  the Context Broker will send a command to your device. For instance, to send the `ping` command with value
1328
1356
  `Ping request` you could use the following operation in the Context Broker API:
@@ -1784,6 +1812,7 @@ Config group is represented by a JSON object with the following fields:
1784
1812
  | `endpoint` | ✓ | `string` | | Endpoint where the group of device is going to receive commands, if any. |
1785
1813
  | `storeLastMeasure` | ✓ | `boolean` | | Store in device last measure received. See more info [in this section](admin.md#storelastmeasure). False by default |
1786
1814
  | `useCBflowControl` | ✓ | `boolean` | | Use Context Broker flow control. See more info [in this section](admin.md#useCBflowControl). False by default |
1815
+ | `cmdMode` | ✓ | `string` | | Command mode that will use iotagent with CB: **legacy**, **notification** and **advancedNotification**. **Legacy** is based on registers. **notification** based on simplified schema of subscriptions. **Legacy** by default. More information on how the different modes work can be found in [the northbound interactions documents](devel/northboundinteractions.md). |
1787
1816
 
1788
1817
  ### Config group operations
1789
1818
 
@@ -2007,6 +2036,7 @@ the API resource fields and the same fields in the database model.
2007
2036
  | `storeLastMeasure` | ✓ | `boolean` | | Store in device last measure received. Useful just for debugging purpose. See more info [in this section](admin.md#storelastmeasure). False by default. |
2008
2037
  | `lastMeasure` | ✓ | `object` | | last measure stored on device when `storeLastMeasure` is enabled. See more info [in this section](admin.md#storelastmeasure). This field can be cleared using `{}` in a device update request. In that case, `lastMeasure` is removed from device (until a next measure is received and `lastMesuare` gets created again). |
2009
2038
  | `useCBflowControl` | ✓ | `boolean` | | Use Context Broker flow control. See more info [in this section](admin.md#useCBflowControl). False by default. |
2039
+ | `cmdMode` | ✓ | `string` | | Command mode that will use iotagent with CB: **legacy**, **notification** and **advancedNotification**. **Legacy** is based on registers. **notification** based on simplified schema of subscriptions. **Legacy** by default. More information on how the different modes work can be found in [the northbound interactions documents](devel/northboundinteractions.md). |
2010
2040
 
2011
2041
  ### Device operations
2012
2042
 
@@ -346,6 +346,8 @@ queries (and thus P2 and R2 payloads).
346
346
 
347
347
  ![General ](./img/scenario3.png 'Scenario 3: commands')
348
348
 
349
+ **FIXME:** this scenario describes the registration-based commanding mechanism, which is currently deprecated. It should be reworked
350
+
349
351
  This scenario requires that the attributes that are going to be requested are marked as provided by the IoT Agent,
350
352
  through a registration process (NGSIv9). Examples of this registration process will be provided in the practical section
351
353
  of this document. It's worth mentioning that Orion Context Broker **will not** store locally any data about attributes
@@ -729,55 +731,58 @@ error, that error must follow the NGSI payloads described in the Scenario 1 erro
729
731
 
730
732
  ### Scenario 3: commands (happy path)
731
733
 
732
- #### Context Provider Registration
734
+ The interactions depend on the command mode (`cmdMode`):
735
+
736
+ * `legacy`
737
+ * `notification`
738
+ * `advancedNotification`
739
+
740
+ The way of setting up Context Broker to IotAgent communication and the interaction between Context Broker and IoTAgent when the command is executed depends on the mode (thus specific subsections about it are provided next for the three modes). However, the way in which the command result is provided is the same to all modes (so it is described in a [common section](#result-reporting)).
733
741
 
734
- Scenario 3 relies on the Context Provider mechanism of the Context Broker. For this scenario to work, the IoTAgent must
742
+ #### `legacy` mode
743
+
744
+ ##### Set up Context Broker to IotAgent comunication mechanism
745
+
746
+ This mode relies on the Context Provider mechanism of the Context Broker. For this scenario to work, the IoTAgent must
735
747
  register its commands for each device, with a request like the following:
736
748
 
737
749
  ```bash
738
750
  curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-service: workshop" \
739
751
  -H "fiware-servicepath: /iota2ngsi " -H "x-auth-token: <token>" -d '{
740
- "contextRegistrations": [
741
- {
742
- "entities": [
743
- {
744
- "type": "device",
745
- "isPattern": "false",
746
- "id": "Dev0001"
747
- }
748
- ],
749
- "attributes": [
750
- {
751
- "name": "switch",
752
- "type": "command",
753
- "isDomain": "false"
754
- }
755
- ],
756
- "providingApplication": "http://<target-host>:1026/v1"
757
- }
758
- ],
759
- "duration": "P1M"
752
+ "dataProvided": {
753
+ "entities": [
754
+ {
755
+ "id": "Dev0001",
756
+ "type": "Device"
757
+ }
758
+ ],
759
+ "attrs": [ "switch" ]
760
+ },
761
+ "provider": {
762
+ "http": {
763
+ "url": "<value of the IOTA_PROVIDER_URL>"
764
+ }
765
+ }
760
766
  }' "https://<platform-ip>:1026/v2/registrations"
761
767
  ```
762
768
 
763
- If everything has gone OK, the Context Broker will return the following payload:
769
+ If everything has gone OK, the Context Broker will return 201 Created with the ID of the registration in the `Location` header:
764
770
 
765
- ```json
766
- {
767
- "duration": "P1M",
768
- "registrationId": "41adf79dc5a0bba830a6f3824"
769
- }
771
+ ```
772
+ HTTP/1.1 201 Created
773
+ Date: ...
774
+ Fiware-Correlator: ...
775
+ Location: /v2/registrations/41adf79dc5a0bba830a6f3824
776
+ Content-Length: 0
770
777
  ```
771
778
 
772
779
  This ID can be used to update the registration in the future.
773
780
 
774
781
  The registration of the commands is performed once in the lifetime of the Device.
775
782
 
776
- #### Command Execution
783
+ ##### Command Execution
777
784
 
778
- ##### Based in update (classic way)
779
-
780
- Scenario 3 begins with the request for a command from the User to the Context Broker (P1):
785
+ Execution begins with the request for a command from the User to the Context Broker (P1):
781
786
 
782
787
  ```bash
783
788
  curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: workshop" \
@@ -785,7 +790,6 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
785
790
  "entities": [
786
791
  {
787
792
  "type": "device",
788
- "isPattern": "false",
789
793
  "id": "Dev0001",
790
794
  "switch": {
791
795
  "type": "command",
@@ -793,7 +797,7 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
793
797
  }
794
798
  }
795
799
  ],
796
- "updateAction": "append"
800
+ "updateAction": "update"
797
801
  } ' "https://<platform-ip>:1026/v2/op/update"
798
802
  ```
799
803
 
@@ -823,38 +827,154 @@ Fiware-Correlator: 9cae9496-8ec7-11e6-80fc-fa163e734aab
823
827
  }
824
828
  }
825
829
  ],
826
- "updateAction" : "append"
830
+ "updateAction" : "update"
827
831
  }
828
832
  ```
829
833
 
830
- The IoT Agent detects the selected attribute is a command, and replies to the Context Broker with a 204 OK (without
834
+ The IoT Agent detects the selected attribute is a command, and replies to the Context Broker with a 204 No Content (without
831
835
  payload).
832
836
 
833
837
  This response just indicates that the IoT Agent has received the command successfully, and gives no information about
834
838
  the requested information or command execution.
835
839
 
836
- The Context Broker, forwards the same response to the user, thus replying the original request (200 OK):
840
+ The Context Broker, forwards the same response to the user, thus replying the original request with 204 No Content.
837
841
 
838
- ```json
839
- [
840
- {
841
- "type": "device",
842
- "id": "Dev0001",
843
- "switch": {
844
- "type": "command",
845
- "value": ""
842
+ At this point, the command has been issued to the IoTAgent and the User doesn't still know what the result of its
843
+ request will be.
844
+
845
+ #### `notification` mode
846
+
847
+ ##### Set up Context Broker to IoTAgent comunication mechanism
848
+
849
+ This mode relies on the notification mechanism of the Context Broker. For this scenario to work, the IoTAgent must
850
+ subscribe its commands for each device, with a request like the following:
851
+
852
+ ```bash
853
+ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-service: workshop" \
854
+ -H "fiware-servicepath: /iota2ngsi " -H "x-auth-token: <token>" -d '{
855
+ "subject": {
856
+ "entities": [
857
+ {
858
+ "type": "device",
859
+ "id": "Dev0001",
860
+ }
861
+ ],
862
+ "condition": {
863
+ "attrs": [ "switch" ]
846
864
  }
865
+ },
866
+ "notification": {
867
+ "http": {
868
+ "url": "<value of the IOTA_PROVIDER_URL>/notify"
869
+ },
870
+ "attrsFormat": "simplifiedNormalized",
871
+ "attrs": [ "switch" ]
847
872
  }
848
- ]
873
+ }' "https://<platform-ip>:1026/v2/subscriptions"
849
874
  ```
850
875
 
876
+ If everything has gone OK, the Context Broker will return 201 Created with the ID of the subscription in the `Location` header:
877
+
878
+ ```
879
+ HTTP/1.1 201 Created
880
+ Date: ...
881
+ Fiware-Correlator: ...
882
+ Location: /v2/subscription/60b0cedd497e8b681d40b58e
883
+ Content-Length: 0
884
+ ```
885
+
886
+ This ID can be used to update the subscription in the future.
887
+
888
+ The subscription of the commands is performed once in the lifetime of the Device.
889
+
890
+ ##### Command Execution
891
+
892
+ As in the legacy mode, execution begins with the request for a command from the User to the Context Broker (P1):
893
+
894
+ ```bash
895
+ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: workshop" \
896
+ -H "Fiware-ServicePath: /iota2ngsi " -H "X-Auth-Token: <token>" -d '{
897
+ "entities": [
898
+ {
899
+ "type": "device",
900
+ "id": "Dev0001",
901
+ "switch": {
902
+ "type": "command",
903
+ "value": "54, 12"
904
+ }
905
+ }
906
+ ],
907
+ "updateAction": "update"
908
+ } ' "https://<platform-ip>:1026/v2/op/update"
909
+ ```
910
+
911
+ The Context Broker receives this update and detects that it triggers the subscription, so it
912
+ notifies to the IoT Agent, as follows:
913
+
914
+ ```bash
915
+ POST /notify HTTP/1.1
916
+ Host: <target-host>:<northbound_port>
917
+ Fiware-service: workshop
918
+ Fiware-ServicePath: /iota2ngsi
919
+ Accept: application/json
920
+ Content-length: ...
921
+ Content-type: application/json; charset=utf-8
922
+ Ngsiv2-Attrsformat: simplifiedNormalized
923
+ Fiware-Correlator: 9cae9496-8ec7-11e6-80fc-fa163e734aab
924
+
925
+ {
926
+ "id": "Dev0001",
927
+ "type": "device",
928
+ "switch": {
929
+ "type": "command",
930
+ "value": "54, 12",
931
+ "metadata": {}
932
+ }
933
+ }
934
+ ```
935
+
936
+ The IoT Agent detects the selected attribute is a command, and replies to the Context Broker with a 204 OK (without
937
+ payload).
938
+
939
+ This response just indicates that the IoT Agent has received the command successfully, and gives no information about
940
+ the requested information or command execution.
941
+
851
942
  At this point, the command has been issued to the IoTAgent and the User doesn't still know what the result of its
852
943
  request will be.
853
944
 
854
- ##### Based in notification (new way)
945
+ #### `advancedNotification` mode
946
+
947
+ ##### Set up ContextBroker to IOTA comunication mechanism
855
948
 
856
- A new way to ContextBroker provides a command to a IoTAgent is through notifications. In this case CB notify the command
857
- to the IotAgent with a request like the following:
949
+ The communication mechanism will be based on subscriptions, although a different one than the one used in `notification` mode. Note this mode has not been implemented yet, so following should be taken as a draft:
950
+
951
+ ```bash
952
+ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -H "Fiware-Service: workshop" \
953
+ -H "Fiware-ServicePath: /iota2ngsi " -H "X-Auth-Token: <token>" -d '{
954
+ "subject": {
955
+ "entities": [
956
+ {
957
+ "idPattern": ".*",
958
+ "type": "switchExecution"
959
+ }
960
+ ],
961
+ "condition": {
962
+ "expression": {
963
+ "q": "status:FORWARDED;targetEntityType:StreetLight"
964
+ }
965
+ }
966
+ },
967
+ "notification": {
968
+ "http": {
969
+ "url": "<value of the IOTA_PROVIDER_URL>/notify"
970
+ }
971
+ }
972
+ }' "https://<platform-ip>:1026/v2/subscriptions"
973
+ ```
974
+
975
+ ##### Command Execution
976
+
977
+ Command execution involves to create a *command execution entity* (details are yet to be implemented), which in sequence triggers a notification to IoTAgent as this one (draft)
858
978
 
859
979
  ```bash
860
980
  POST /notify HTTP/1.1
@@ -864,6 +984,7 @@ Fiware-ServicePath: /iota2ngsi
864
984
  Accept: application/json
865
985
  Content-length: 290
866
986
  Content-type: application/json; charset=utf-8
987
+ Ngsiv2-Attrsformat: normalized
867
988
  Fiware-Correlator: 9cae9496-8ec7-11e6-80fc-fa163e734aab
868
989
 
869
990
  {
@@ -945,8 +1066,36 @@ In this case relevant fields are just `targetEntityId`, `targetEntityType`, `cmd
945
1066
  The IoT Agent detects the selected attribute is a command, and replies to the Context Broker with a 204 OK (without
946
1067
  payload).
947
1068
 
1069
+ This response just indicates that the IoT Agent has received the command successfully, and gives no information about
1070
+ the requested information or command execution.
1071
+
1072
+ At this point, the command has been issued to the IoTAgent and the User doesn't still know what the result of its
1073
+ request will be.
1074
+
1075
+ As mentioned before, advanced notification mode has not been yet implemented. The following considerations are gap in the current implementation at IoT Agent side that should be addressed:
1076
+
1077
+ - Fields others than `targetEntityId`, `targetEntityType`, `cmd` and `params` (i.e. `execTs`, `status`, `info`,
1078
+ `onDelivered`, `onOk`, `onError`, `onInfo`, `cmdExecution` and `dataExpiration`), are not actually used. By the
1079
+ moment they are stored in the commands model (commands collection) but nothing is done with them appart from
1080
+ storing.
1081
+ - The "Result reporting" should not be a "hardwired" behaviour updating the entity associated to the device, but using
1082
+ the corresponding `on*` attribute in the notificaiton (e.g. `onOk` in the case of success). That attribute would
1083
+ typically be a [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS) object like this
1084
+ `"onOk": { "href": "/v2/entities/123456abcdefg/attrs/status?type=switchExecution", "method": "PUT" }`. Moreover, the
1085
+ entity to be updated in that HATEOAS would be the transient entity corresponding to command execuion, not the entity
1086
+ associated to the device.
1087
+
1088
+ ```
1089
+ PUT /v2/entities/123456abcdefg/attrs/status?type=switchExecution
1090
+ content-type: text/plain
1091
+
1092
+ OK
1093
+ ```
1094
+
948
1095
  #### Result reporting
949
1096
 
1097
+ No matter the command mode (legacy or notification based), the result reporting is the same in all cases.
1098
+
950
1099
  Once the IoT Agent has executed the command or retrieved the information from the device, it reports the results to the
951
1100
  Context Broker, with an updateContext (P1):
952
1101
 
@@ -956,7 +1105,6 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
956
1105
  "entities": [
957
1106
  {
958
1107
  "type": "device",
959
- "isPattern": "false",
960
1108
  "id": "Dev0001",
961
1109
  "switch_info": {
962
1110
  "type": "commandResult",
@@ -975,24 +1123,7 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
975
1123
  This update does not modify the original command attribute, but two auxiliary attributes, that are not provided by the
976
1124
  IoT Agent (usually, those attributes has the same name as the command, with an added suffix).
977
1125
 
978
- The Context Broker replies to the IoT Agent with a R1 payload (200 OK):
979
-
980
- ```json
981
- [
982
- {
983
- "type": "device",
984
- "id": "Dev0001",
985
- "switch_info": {
986
- "type": "commandResult",
987
- "value": ""
988
- },
989
- "switch_status": {
990
- "type": "commandStatus",
991
- "value": ""
992
- }
993
- }
994
- ]
995
- ```
1126
+ The Context Broker replies to the IoT Agent with 204 No Content response (no payload).
996
1127
 
997
1128
  This operation stores the retrieved values locally in the Context Broker, so it can be retrieved with standard NGSI
998
1129
  mechanisms.
@@ -1007,7 +1138,6 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
1007
1138
  -H "Fiware-ServicePath: /iota2ngsi " -H "X-Auth-Token: <token>" -d '{
1008
1139
  "entities": [
1009
1140
  {
1010
- "isPattern": "false",
1011
1141
  "id": "Dev0001",
1012
1142
  "type": "device"
1013
1143
  }
@@ -1038,30 +1168,6 @@ The Context Broker replies with all the desired data, in R2 format (200 OK):
1038
1168
  ]
1039
1169
  ```
1040
1170
 
1041
- #### Differences regarding the new commands mode
1042
-
1043
- A new commands flow has been defined (involving also modifications at ContextBroker). As part of that design, commands
1044
- are not sent to IOTAs using NGSIv2 notifications, but the current implementation has some differences regarding the
1045
- desired behaviour, which are described next:
1046
-
1047
- - Fields others than `targetEntityId`, `targetEntityType`, `cmd` and `params` (i.e. `execTs`, `status`, `info`,
1048
- `onDelivered`, `onOk`, `onError`, `onInfo`, `cmdExecution` and `dataExpiration`), are not actually used. By the
1049
- moment they are stored in the commands model (commands collection) but nothing is done with them appart from
1050
- storing.
1051
- - The "Result reporting" should not be a "hardwired" behaviour updating the entity associated to the device, but using
1052
- the corresponding `on*` attribute in the notificaiton (e.g. `onOk` in the case of success). That attribute would
1053
- typically be a [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS) object like this
1054
- `"onOk": { "href": "/v2/entities/123456abcdefg/attrs/status?type=switchExecution", "method": "PUT" }`. Moreover, the
1055
- entity to be updated in that HATEOAS would be the transient entity corresponding to command execuion, not the entity
1056
- associated to the device.
1057
-
1058
- ```
1059
- PUT /v2/entities/123456abcdefg/attrs/status?type=switchExecution
1060
- content-type: text/plain
1061
-
1062
- OK
1063
- ```
1064
-
1065
1171
  ### Scenario 3: commands (error)
1066
1172
 
1067
1173
  In Scenario 3, errors can happen asynchronously, out of the main interactions. When the IoTAgent detects an error
@@ -1074,7 +1180,6 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
1074
1180
  "entities": [
1075
1181
  {
1076
1182
  "type": "device",
1077
- "isPattern": "false",
1078
1183
  "id": "Dev0001",
1079
1184
  "switch_info":{
1080
1185
  "type": "commandResult",
@@ -1090,23 +1195,6 @@ curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -
1090
1195
  } ' "https://<platform-ip>:1026/v2/op/update"
1091
1196
  ```
1092
1197
 
1093
- In this case, the Context Broker reply with the following response (200 OK):
1094
-
1095
- ```json
1096
- [
1097
- {
1098
- "type": "device",
1099
- "id": "Dev0001",
1100
- "switch_info": {
1101
- "type": "commandResult",
1102
- "value": ""
1103
- },
1104
- "switch_status": {
1105
- "type": "commandStatus",
1106
- "value": ""
1107
- }
1108
- }
1109
- ]
1110
- ```
1198
+ In this case, the Context Broker reply with the a 204 No Content response (no payload).
1111
1199
 
1112
1200
  The User will acknowledge the error the next time he queries the Context Broker for information about the command.
@@ -160,7 +160,8 @@ function processEnvironmentVariables() {
160
160
  'IOTA_LD_SUPPORT_DATA_TYPE',
161
161
  'IOTA_EXPRESS_LIMIT',
162
162
  'IOTA_USE_CB_FLOW_CONTROL',
163
- 'IOTA_STORE_LAST_MEASURE'
163
+ 'IOTA_STORE_LAST_MEASURE',
164
+ 'IOTA_CMD_MODE'
164
165
  ];
165
166
  const iotamVariables = [
166
167
  'IOTA_IOTAM_URL',
@@ -500,6 +501,9 @@ function processEnvironmentVariables() {
500
501
  } else {
501
502
  config.storeLastMeasure = config.storeLastMeasure === true;
502
503
  }
504
+ if (process.env.IOTA_CMD_MODE) {
505
+ config.cmdMode = process.env.IOTA_CMD_MODE;
506
+ }
503
507
  }
504
508
 
505
509
  function setConfig(newConfig) {
@@ -57,7 +57,9 @@ const Device = new Schema({
57
57
  useCBflowControl: Boolean,
58
58
  storeLastMeasure: Boolean,
59
59
  lastMeasure: Object,
60
- oldCtxt: Object
60
+ oldCtxt: Object,
61
+ cmdMode: String,
62
+ subscriptionId: String
61
63
  });
62
64
 
63
65
  function load() {
@@ -67,7 +67,8 @@ const Group = new Schema({
67
67
  entityNameExp: String,
68
68
  payloadType: String,
69
69
  useCBflowControl: Boolean,
70
- storeLastMeasure: Boolean
70
+ storeLastMeasure: Boolean,
71
+ cmdMode: String
71
72
  });
72
73
 
73
74
  function load() {
@@ -65,7 +65,8 @@ function register(callback) {
65
65
  endpoint: service.endpoint,
66
66
  transport: service.transport,
67
67
  useCBflowControl: service.useCBflowControl,
68
- storeLastMeasure: service.storeLastMeasure
68
+ storeLastMeasure: service.storeLastMeasure,
69
+ cmdMode: service.cmdMode
69
70
  };
70
71
  }
71
72