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.
- package/.github/workflows/ci.yml +6 -8
- package/Changelog +6 -0
- package/config.js +2 -1
- package/doc/admin.md +12 -0
- package/doc/api.md +33 -3
- package/doc/devel/northboundinteractions.md +200 -112
- package/lib/commonConfig.js +5 -1
- package/lib/model/Device.js +3 -1
- package/lib/model/Group.js +2 -1
- package/lib/services/common/iotManagerService.js +2 -1
- package/lib/services/devices/deviceRegistryMongoDB.js +5 -1
- package/lib/services/devices/deviceService.js +17 -1
- package/lib/services/devices/devices-NGSI-LD.js +3 -2
- package/lib/services/devices/devices-NGSI-mixed.js +16 -0
- package/lib/services/devices/devices-NGSI-v2.js +122 -8
- package/lib/services/devices/registrationUtils.js +97 -30
- package/lib/services/groups/groupRegistryMongoDB.js +2 -1
- package/lib/services/ngsi/subscription-NGSI-LD.js +2 -2
- package/lib/services/ngsi/subscription-NGSI-mixed.js +3 -3
- package/lib/services/ngsi/subscription-NGSI-v2.js +20 -6
- package/lib/services/ngsi/subscriptionService.js +2 -2
- package/lib/services/northBound/deviceProvisioningServer.js +6 -3
- package/lib/templates/updateDevice.json +12 -0
- package/lib/templates/updateDeviceLax.json +4 -0
- package/package.json +2 -2
- package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +2 -2
- package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +1 -1
- package/test/unit/ngsi-ld/general/contextBrokerOAuthSecurityAccess-test.js +2 -2
- package/test/unit/ngsi-ld/general/https-support-test.js +1 -1
- package/test/unit/ngsi-ld/ngsiService/subscriptions-test.js +6 -6
- package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands.json +24 -0
- package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands2.json +24 -0
- package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands3.json +24 -0
- package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands4.json +24 -0
- package/test/unit/ngsiv2/examples/contextRequests/updateEntity.json +5 -0
- package/test/unit/ngsiv2/examples/contextRequests/updateEntity2.json +5 -0
- package/test/unit/ngsiv2/examples/contextRequests/updateEntity2b.json +7 -0
- package/test/unit/ngsiv2/examples/contextRequests/updateEntity3.json +5 -0
- package/test/unit/ngsiv2/examples/subscriptionRequests/simpleSubscriptionRequest.json +4 -2
- package/test/unit/ngsiv2/examples/subscriptionRequests/simpleSubscriptionRequest2.json +4 -2
- package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +2 -2
- package/test/unit/ngsiv2/general/https-support-test.js +1 -1
- package/test/unit/ngsiv2/lazyAndCommands/command-test.js +245 -2
package/.github/workflows/ci.yml
CHANGED
|
@@ -14,10 +14,10 @@ jobs:
|
|
|
14
14
|
steps:
|
|
15
15
|
- name: Git checkout
|
|
16
16
|
uses: actions/checkout@v2
|
|
17
|
-
- name: Use Node.js
|
|
17
|
+
- name: Use Node.js 24.x
|
|
18
18
|
uses: actions/setup-node@v1
|
|
19
19
|
with:
|
|
20
|
-
node-version:
|
|
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
|
|
34
|
+
- name: Use Node.js 24.x
|
|
35
35
|
uses: actions/setup-node@v1
|
|
36
36
|
with:
|
|
37
|
-
node-version:
|
|
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
|
|
81
|
+
- name: 'Test Coverage with Node.js 24.x'
|
|
84
82
|
uses: actions/setup-node@v1
|
|
85
83
|
with:
|
|
86
|
-
node-version:
|
|
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
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
|
-
|
|
262
|
-
|
|
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
|

|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
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
|
|
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
|
-
```
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
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
|
-
|
|
783
|
+
##### Command Execution
|
|
777
784
|
|
|
778
|
-
|
|
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": "
|
|
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" : "
|
|
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
|
|
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
|
|
840
|
+
The Context Broker, forwards the same response to the user, thus replying the original request with 204 No Content.
|
|
837
841
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
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
|
-
|
|
945
|
+
#### `advancedNotification` mode
|
|
946
|
+
|
|
947
|
+
##### Set up ContextBroker to IOTA comunication mechanism
|
|
855
948
|
|
|
856
|
-
|
|
857
|
-
|
|
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
|
|
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
|
|
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.
|
package/lib/commonConfig.js
CHANGED
|
@@ -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) {
|
package/lib/model/Device.js
CHANGED
package/lib/model/Group.js
CHANGED
|
@@ -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
|
|