iotagent-node-lib 4.6.0 → 4.8.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 +2 -3
- package/CHANGES_NEXT_RELEASE +1 -0
- package/Changelog +20 -0
- package/config.js +3 -1
- package/doc/README.md +1 -0
- package/doc/admin.md +39 -5
- package/doc/api.md +74 -9
- package/doc/devel/northboundinteractions.md +122 -15
- package/doc/models/models.md +260 -0
- package/doc/requirements.txt +1 -1
- package/docker/Mosquitto/Dockerfile +1 -1
- package/lib/commonConfig.js +21 -2
- package/lib/fiware-iotagent-lib.js +15 -11
- package/lib/jexlTranformsMap.js +182 -35
- package/lib/model/Command.js +11 -2
- package/lib/model/Device.js +8 -3
- package/lib/model/Group.js +5 -3
- package/lib/model/dbConn.js +53 -112
- package/lib/services/commands/commandRegistryMongoDB.js +130 -76
- package/lib/services/commands/commandService.js +3 -3
- package/lib/services/common/iotManagerService.js +3 -1
- package/lib/services/devices/deviceRegistryMemory.js +36 -0
- package/lib/services/devices/deviceRegistryMongoDB.js +161 -88
- package/lib/services/devices/deviceService.js +44 -5
- package/lib/services/devices/devices-NGSI-v2.js +6 -1
- package/lib/services/groups/groupRegistryMongoDB.js +120 -83
- package/lib/services/ngsi/entities-NGSI-v2.js +14 -1
- package/lib/services/ngsi/ngsiService.js +32 -1
- package/lib/services/northBound/contextServer-NGSI-v2.js +12 -3
- package/lib/services/northBound/contextServer.js +2 -1
- package/lib/services/northBound/deviceProvisioningServer.js +12 -3
- package/lib/services/northBound/northboundServer.js +1 -0
- package/lib/templates/createDevice.json +4 -0
- package/lib/templates/updateDevice.json +16 -0
- package/lib/templates/updateDeviceLax.json +12 -0
- package/package.json +4 -4
- package/test/functional/config-test.js +3 -2
- package/test/functional/testUtils.js +15 -4
- package/test/unit/examples/groupProvisioningRequests/provisionFullGroup.json +1 -0
- package/test/unit/expressions/jexlExpression-test.js +165 -1
- package/test/unit/general/config-multi-core-test.js +1 -2
- package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +5 -4
- package/test/unit/general/deviceService-test.js +6 -5
- package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +6 -5
- package/test/unit/mongodb/mongodb-connectionoptions-test.js +7 -39
- package/test/unit/ngsi-ld/expressions/jexlBasedTransformations-test.js +1 -2
- package/test/unit/ngsi-ld/general/config-jsonld-contexts-test.js +1 -2
- package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +8 -5
- package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +42 -41
- package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +11 -10
- package/test/unit/ngsiv2/general/deviceService-test.js +6 -5
- package/test/unit/ngsiv2/general/https-support-test.js +1 -1
- package/test/unit/ngsiv2/lazyAndCommands/active-devices-attribute-update-test.js +4 -3
- package/test/unit/ngsiv2/lazyAndCommands/command-test.js +6 -5
- package/test/unit/ngsiv2/lazyAndCommands/lazy-devices-test.js +17 -16
- package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +10 -18
- package/test/unit/ngsiv2/ngsiService/active-devices-test.js +21 -20
- package/test/unit/ngsiv2/ngsiService/staticAttributes-test.js +8 -7
- package/test/unit/ngsiv2/plugins/alias-plugin_test.js +12 -11
- package/test/unit/ngsiv2/plugins/custom-plugin_test.js +3 -2
- package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +28 -27
- package/test/unit/ngsiv2/provisioning/device-group-api-test.js +6 -4
- package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +12 -11
- package/test/unit/ngsiv2/provisioning/device-provisioning-configGroup-api_test.js +11 -10
- package/test/unit/ngsiv2/provisioning/device-registration_test.js +5 -4
- package/test/unit/ngsiv2/provisioning/listProvisionedDevices-test.js +6 -5
- package/test/unit/ngsiv2/provisioning/provisionDeviceMultientity-test.js +1 -1
- package/test/unit/ngsiv2/provisioning/removeProvisionedDevice-test.js +5 -4
- package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +8 -7
- package/test/unit/ngsiv2/ngsiService/subscriptions-test.js +0 -326
package/.github/workflows/ci.yml
CHANGED
|
@@ -45,13 +45,12 @@ jobs:
|
|
|
45
45
|
runs-on: ubuntu-latest
|
|
46
46
|
services:
|
|
47
47
|
mongodb:
|
|
48
|
-
image: mongo:
|
|
48
|
+
image: mongo:8.0
|
|
49
49
|
ports:
|
|
50
50
|
- 27017:27017
|
|
51
51
|
strategy:
|
|
52
52
|
matrix:
|
|
53
53
|
node-version:
|
|
54
|
-
- 14.x
|
|
55
54
|
- 16.x
|
|
56
55
|
- 18.x
|
|
57
56
|
steps:
|
|
@@ -72,7 +71,7 @@ jobs:
|
|
|
72
71
|
needs: unit-test
|
|
73
72
|
services:
|
|
74
73
|
mongodb:
|
|
75
|
-
image: mongo:
|
|
74
|
+
image: mongo:8.0
|
|
76
75
|
ports:
|
|
77
76
|
- 27017:27017
|
|
78
77
|
steps:
|
package/CHANGES_NEXT_RELEASE
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/Changelog
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
4.8.0 (May 23rd, 2025)
|
|
2
|
+
|
|
3
|
+
- Add: notification-based commands (#1455)
|
|
4
|
+
- Add: allow define headers in device commands (iotagent-json#873)
|
|
5
|
+
- Add: index for Device model based on {service: 1, subservice: 1, id: 1, apikey: 1} (#1576)
|
|
6
|
+
- Fix: Duplicated Devices when burst measures to non provisioned Device (iotagent-json#865)
|
|
7
|
+
- Fix: modified JEXL transformations (toisostring, gettime, parseint, etc.) to return null instead of NaN when some unexpected situation occurs (#1701)
|
|
8
|
+
|
|
9
|
+
4.7.0 (February 3rd, 2025)
|
|
10
|
+
|
|
11
|
+
- Add: store (and recover) previous jexlctxt and make available in current jexlctxt (#1690)
|
|
12
|
+
- Add: option to force to use CB flow control with new API field useCBflowControl at group and device device level (#1420)
|
|
13
|
+
- Add: useCBflowControl config setting (IOTA_CB_FLOW_CONTROL env var) to set CB flow control behaviour at instance level (#1420)
|
|
14
|
+
- Add: allow remove last measure in device
|
|
15
|
+
- Add: store last measure in device (by id, apikey, service and subservice) and new API field storeLastMeasure at group and device levels (#1669)
|
|
16
|
+
- Add: storeLastMeasure config setting (IOTA_STORE_LAST_MEASURE env var) to set default store last measure behaviour at instance level (#1669)
|
|
17
|
+
- Fix: set polling and transport for autoprovisioned devices
|
|
18
|
+
- Upgrade express dep from 4.19.2 to 4.21.2
|
|
19
|
+
- Upgrade mongodb devdep from 4.17.1 to 4.17.2
|
|
20
|
+
- Upgrade mongoose dep from 5.13.20 to 8.9.5 (solving vulnerabilies CVE-2024-53900 and CVE-2025-23061) (#1674)
|
package/config.js
CHANGED
|
@@ -77,7 +77,9 @@ var config = {
|
|
|
77
77
|
providerUrl: 'http://192.168.56.1:4041',
|
|
78
78
|
deviceRegistrationDuration: 'P1M',
|
|
79
79
|
defaultType: 'Thing',
|
|
80
|
-
expressLimit: '1Mb'
|
|
80
|
+
expressLimit: '1Mb',
|
|
81
|
+
useCBflowControl: false,
|
|
82
|
+
storeLastMeasure: false
|
|
81
83
|
};
|
|
82
84
|
|
|
83
85
|
module.exports = config;
|
package/doc/README.md
CHANGED
package/doc/admin.md
CHANGED
|
@@ -125,9 +125,9 @@ allowing the computer to interpret the rest of the data with more clarity and de
|
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
Under mixed mode, **NGSI v2** payloads are used for context broker communications by default, but this payload may also
|
|
128
|
-
be switched to **NGSI LD** at group or device provisioning time using the `ngsiVersion` field in the
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
be switched to **NGSI LD** at group or device provisioning time using the `ngsiVersion` field in the provisioning API.
|
|
129
|
+
The `ngsiVersion` field switch may be added at either group or device level, with the device level overriding the group
|
|
130
|
+
setting.
|
|
131
131
|
|
|
132
132
|
#### `server`
|
|
133
133
|
|
|
@@ -306,7 +306,8 @@ added `agentPath`:
|
|
|
306
306
|
|
|
307
307
|
#### `types`
|
|
308
308
|
|
|
309
|
-
This parameter includes additional groups configuration as described into the
|
|
309
|
+
This parameter includes additional groups configuration as described into the
|
|
310
|
+
[Config group API](api.md#config-group-api) section.
|
|
310
311
|
|
|
311
312
|
#### `service`
|
|
312
313
|
|
|
@@ -415,7 +416,38 @@ IotAgents, as all Express applications that use the body-parser middleware, have
|
|
|
415
416
|
size that the application will handle. This default limit for ioiotagnets are 1Mb. So, if your IotAgent receives a
|
|
416
417
|
request with a body that exceeds this limit, the application will throw a “Error: Request entity too large”.
|
|
417
418
|
|
|
418
|
-
The 1Mb default can be changed setting the `expressLimit` configuration parameter (or equivalente `IOTA_EXPRESS_LIMIT`
|
|
419
|
+
The 1Mb default can be changed setting the `expressLimit` configuration parameter (or equivalente `IOTA_EXPRESS_LIMIT`
|
|
420
|
+
environment variable).
|
|
421
|
+
|
|
422
|
+
#### `storeLastMeasure`
|
|
423
|
+
|
|
424
|
+
If this flag is activated, last measure arrived to Device IoTAgent without be processed will be stored in Device under
|
|
425
|
+
`lastMeasure` field (composed of sub-fields `timestamp` and `measure` for the measure itself, in multi-measure format).
|
|
426
|
+
This flag is overwritten by `storeLastMeasure` flag in group or device. This flag is disabled by default.
|
|
427
|
+
|
|
428
|
+
For example in a device document stored in MongoDB will be extended with a subdocument named lastMeasure like this:
|
|
429
|
+
|
|
430
|
+
```json
|
|
431
|
+
{
|
|
432
|
+
"lastMeasure": {
|
|
433
|
+
"timestamp": "2025-01-09T10:35:33.079Z",
|
|
434
|
+
"measure": [
|
|
435
|
+
[
|
|
436
|
+
{
|
|
437
|
+
"name": "level",
|
|
438
|
+
"type": "Text",
|
|
439
|
+
"value": 33
|
|
440
|
+
}
|
|
441
|
+
]
|
|
442
|
+
]
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
#### `useCBflowControl`
|
|
448
|
+
|
|
449
|
+
If this flag is activated, when iotAgent invokes Context Broker will use [flowControl option](https://github.com/telefonicaid/fiware-orion/blob/master/doc/manuals/admin/perf_tuning.md#updates-flow-control-mechanism). This flag is overwritten by
|
|
450
|
+
`useCBflowControl` flag in group or device. This flag is disabled by default.
|
|
419
451
|
|
|
420
452
|
### Configuration using environment variables
|
|
421
453
|
|
|
@@ -479,6 +511,8 @@ overrides.
|
|
|
479
511
|
| IOTA_DEFAULT_ENTITY_NAME_CONJUNCTION | `defaultEntityNameConjunction` |
|
|
480
512
|
| IOTA_RELAX_TEMPLATE_VALIDATION | `relaxTemplateValidation` |
|
|
481
513
|
| IOTA_EXPRESS_LIMIT | `expressLimit` |
|
|
514
|
+
| IOTA_STORE_LAST_MEASURE | `storeLastMeasure` |
|
|
515
|
+
| IOTA_CB_FLOW_CONTROL | `useCBflowControl` |
|
|
482
516
|
|
|
483
517
|
Note:
|
|
484
518
|
|
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 Name expression support](#entity-name-expression-support)
|
|
15
16
|
- [Multientity support](#multientity-support)
|
|
16
17
|
- [Metadata support](#metadata-support)
|
|
17
18
|
- [NGSI LD data and metadata considerations](#ngsi-ld-data-and-metadata-considerations)
|
|
@@ -164,7 +165,8 @@ parameters defined at device level in database, the parameters are inherit from
|
|
|
164
165
|
|
|
165
166
|
### Uniqueness of groups and devices
|
|
166
167
|
|
|
167
|
-
Group uniqueness is defined by the combination of:
|
|
168
|
+
Group uniqueness is defined by the combination of: resource and apikey. This is so because given a measure (identified
|
|
169
|
+
by an apikey) there is no way to identify group related if apikey is not unique for all services and subservices.
|
|
168
170
|
|
|
169
171
|
Device uniqueness is defined by the combination of: service, subservice, device_id and apikey. Note that several devices
|
|
170
172
|
with the same device_id are allowed in the same service and subservice as long as their apikeys are different.
|
|
@@ -187,9 +189,9 @@ configured for a single device in the device provisioning, or it can be defined
|
|
|
187
189
|
|
|
188
190
|
The entity type should be defined both in the group and in the device, but the entity name (entity ID) is not defined in
|
|
189
191
|
the group. In that case, if there is no a existing device the same device ID, the entity name of the device generated
|
|
190
|
-
will be a concatenation of the entity type and the device ID (I.E: `entityType:device_id`).
|
|
191
|
-
entity name
|
|
192
|
-
|
|
192
|
+
will be a concatenation of the entity type and the device ID (I.E: `entityType:device_id`). If you need to generate the
|
|
193
|
+
entity name differently, it is possible to define an expression to generate it, using the parameter `entityNameExp` in
|
|
194
|
+
the group as described in the [Entity Name expression support](#entity-name-expression-support) section.
|
|
193
195
|
|
|
194
196
|
It is also possible to configure how each of the measures obtained from the device is mapped to different attributes.
|
|
195
197
|
The name and type of the attribute is configured by the user (globally for all the devices in the group or in a per
|
|
@@ -255,6 +257,9 @@ Additionally for commands (which are attributes of type `command`) the following
|
|
|
255
257
|
particular IOTAs documentation for allowed values of this field in each case.
|
|
256
258
|
- **contentType**: `content-type` header used when send command by HTTP transport (ignored in other kinds of
|
|
257
259
|
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)
|
|
258
263
|
|
|
259
264
|
Note that, when information coming from devices, this means measures, are not defined neither in the group, nor in the
|
|
260
265
|
device, the IoT agent will store that information into the destination entity using the same attribute name than the
|
|
@@ -271,6 +276,59 @@ If for any reason you need the entity at CB before the first measure of the corr
|
|
|
271
276
|
IOTAgent, you can create it in advance using the Context Broker
|
|
272
277
|
[NGSI v2 API](https://github.com/telefonicaid/fiware-orion/blob/master/doc/manuals/orion-api.md).
|
|
273
278
|
|
|
279
|
+
## Entity Name expression support
|
|
280
|
+
|
|
281
|
+
By default, the entity name used to persist the device measures in the Context Broker can be defined in the device
|
|
282
|
+
provisioning or, if the device is autoprovisioned, it is generated by the IoT Agent as a concatenation of the entity
|
|
283
|
+
type and the device ID. If you need to generate the entity name differently, it is possible to define an expression to
|
|
284
|
+
generate it, using the [Expression Language](#expression-language-support) through the `entityNameExp` field in the
|
|
285
|
+
group.
|
|
286
|
+
|
|
287
|
+
With this feature, the entity name can be generated dynamically based not only on the device ID and entity type, but
|
|
288
|
+
also on the measures reported by the device or any other context information. The `entityNameExp` field is only
|
|
289
|
+
available at the group level. **Important**: when using `entityNameExp`, the `entity_name` field in the device
|
|
290
|
+
provisioning is ignored. This means that the entity name used to store the device information in the Context Broker is
|
|
291
|
+
always generated by the `entityNameExp` expression. If you need to explicitly define the entity name for a particular
|
|
292
|
+
device, you can include a particular condition in the `entityNameExp` expression to handle that case (e.g.
|
|
293
|
+
`id == 'myDevice' ? 'myEntity' : entityType + ':' + id`).
|
|
294
|
+
|
|
295
|
+
The following example shows how to define an entity name expression:
|
|
296
|
+
|
|
297
|
+
```json
|
|
298
|
+
{
|
|
299
|
+
"services": [
|
|
300
|
+
{
|
|
301
|
+
"resource": "/json",
|
|
302
|
+
"apikey": "801230BJKL23Y9090DSFL123HJK09H324HV8732",
|
|
303
|
+
"entity_type": "TemperatureSensor",
|
|
304
|
+
"entityNameExp": "id + '__' + sn",
|
|
305
|
+
"attributes": [
|
|
306
|
+
{
|
|
307
|
+
"object_id": "t",
|
|
308
|
+
"name": "temperature",
|
|
309
|
+
"type": "Number"
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
"object_id": "sn",
|
|
313
|
+
"name": "serialNumber",
|
|
314
|
+
"type": "Text"
|
|
315
|
+
}
|
|
316
|
+
]
|
|
317
|
+
}
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
As defined above, the `entityNameExp` is `id + '__' + sn` and it will generate the entity name by concatenating the
|
|
323
|
+
device ID and the serial number reported by the device. For example, for a given measure with `id` equal to `dev123` and
|
|
324
|
+
`sn` equal to `ABCDEF`, the resulting entity name will be `dev123__ABCDEF`.
|
|
325
|
+
|
|
326
|
+
Note that, when using `entityNameExp`, the `entity_name` of the device provisioning is set to the result of the
|
|
327
|
+
expression the first time the device is created. If the expression is modified later, the `entity_name` of the device
|
|
328
|
+
provisioning will not be updated, but the value used to persist the device measures in the Context Broker will be the
|
|
329
|
+
result of the new expression. This can lead to a situation where the `entity_name` of the device provisioning and the
|
|
330
|
+
entity name used in the Context Broker are different.
|
|
331
|
+
|
|
274
332
|
## Multientity support
|
|
275
333
|
|
|
276
334
|
The IOTA is able to persists measures coming from a single device to more than one entity, declaring the target entities
|
|
@@ -525,8 +583,8 @@ Case 5:
|
|
|
525
583
|
|
|
526
584
|
depending on the JEXL expression evaluation:
|
|
527
585
|
|
|
528
|
-
- If it evaluates to `
|
|
529
|
-
- If it evaluates to `
|
|
586
|
+
- If it evaluates to `false` every measure will be propagated to NGSI interface (as in case 1)
|
|
587
|
+
- If it evaluates to `true` just measures defined in active, static (plus conditionally TimeInstant) will be
|
|
530
588
|
propagated to NGSI interface (as in case 2)
|
|
531
589
|
- If it evaluates to an array just measures defined in the array (identified by their attribute names, not by their
|
|
532
590
|
object_id) will be will be propagated to NGSI interface (as in case 3)
|
|
@@ -555,7 +613,8 @@ of expression in the IoT Agent are:
|
|
|
555
613
|
- [Metadata](#expression-support-in-metadata)
|
|
556
614
|
- Commands payload transformation (push and pull).
|
|
557
615
|
- Auto provisioned devices entity name. It is configured at config Group level by setting the `entityNameExp`
|
|
558
|
-
parameter. It defines an expression to generate the Entity Name for autoprovisioned devices.
|
|
616
|
+
parameter. It defines an expression to generate the Entity Name for autoprovisioned devices. More information in the
|
|
617
|
+
[Entity Name expression support](#entity-name-expression-support) section.
|
|
559
618
|
- Dynamic `endpoint` definition. Configured at device level, it defines where the device listen for push http
|
|
560
619
|
commands. It can be either a static value or an expression.
|
|
561
620
|
|
|
@@ -568,6 +627,7 @@ expression. In all cases the following data is available to all expressions:
|
|
|
568
627
|
- `service`: device service (`Fiware-Service`)
|
|
569
628
|
- `subservice`: device subservice (`Fiware-ServicePath`)
|
|
570
629
|
- `staticAttributes`: static attributes defined in the device or config group
|
|
630
|
+
- `oldCtxt`: previous JEXL context (related to last processed measure)
|
|
571
631
|
|
|
572
632
|
Additionally, for attribute expressions (`expression`, `entity_name`), `entityNameExp` and metadata expressions
|
|
573
633
|
(`expression`) the following is available in the **context** used to evalute:
|
|
@@ -1715,13 +1775,15 @@ Config group is represented by a JSON object with the following fields:
|
|
|
1715
1775
|
| `static_attributes` | ✓ | | | this attributes will be added to all the entities of this group 'as is', additional `metadata` is optional. |
|
|
1716
1776
|
| `internal_attributes` | ✓ | | | optional section with free format, to allow specific IoT Agents to store information along with the devices in the Device Registry. |
|
|
1717
1777
|
| `explicitAttrs` | ✓ | string or bool | ✓ | optional field to support selective ignore of measures so that IOTA doesn’t progress. See details in [specific section](#explicitly-defined-attributes-explicitattrs) |
|
|
1718
|
-
| `entityNameExp` | ✓ | string | | optional field to allow use expressions to define entity name, instead default name, based on the device ID and the entity type (i.e. `<device_id>:<entity_type>`)
|
|
1778
|
+
| `entityNameExp` | ✓ | string | | optional field to allow use expressions to define entity name, instead default name, based on the device ID and the entity type (i.e. `<device_id>:<entity_type>`). More information in [specific section](#entity-name-expression-entitynameexp) |
|
|
1719
1779
|
| `ngsiVersion` | ✓ | string | | optional string value used in mixed mode to switch between **NGSI-v2** and **NGSI-LD** payloads. Possible values are: `v2` or `ld`. The default is `v2`. When not running in mixed mode, this field is ignored. |
|
|
1720
1780
|
| `defaultEntityNameConjunction` | ✓ | string | | optional string value to set default conjunction string used to compose a default `entity_name` when is not provided at device provisioning time. |
|
|
1721
1781
|
| `autoprovision` | ✓ | bool | ✓? | optional boolean: If `false`, autoprovisioned devices (i.e. devices that are not created with an explicit provision operation but when the first measure arrives) are not allowed in this group. Default (in the case of omitting the field) is `true`. |
|
|
1722
1782
|
| `payloadType` | ✓ | string | | optional string value used to switch between **IoTAgent**, **NGSI-v2** and **NGSI-LD** measure payloads types. Possible values are: `iotagent`, `ngsiv2` or `ngsild`. The default is `iotagent`. |
|
|
1723
1783
|
| `transport` | ✓ | `string` | | Transport protocol used by the group of devices to send updates, for the IoT Agents with multiple transport protocols. |
|
|
1724
1784
|
| `endpoint` | ✓ | `string` | | Endpoint where the group of device is going to receive commands, if any. |
|
|
1785
|
+
| `storeLastMeasure` | ✓ | `boolean` | | Store in device last measure received. See more info [in this section](admin.md#storelastmeasure). False by default |
|
|
1786
|
+
| `useCBflowControl` | ✓ | `boolean` | | Use Context Broker flow control. See more info [in this section](admin.md#useCBflowControl). False by default |
|
|
1725
1787
|
|
|
1726
1788
|
### Config group operations
|
|
1727
1789
|
|
|
@@ -1942,6 +2004,9 @@ the API resource fields and the same fields in the database model.
|
|
|
1942
2004
|
| `explicitAttrs` | ✓ | `boolean` | ✓ | Field to support selective ignore of measures so that IOTA doesn’t progress. See details in [specific section](#explicitly-defined-attributes-explicitattrs) |
|
|
1943
2005
|
| `ngsiVersion` | ✓ | `string` | | string value used in mixed mode to switch between **NGSI-v2** and **NGSI-LD** payloads. The default is `v2`. When not running in mixed mode, this field is ignored. |
|
|
1944
2006
|
| `payloadType` | ✓ | `string` | | optional string value used to switch between **IoTAgent**, **NGSI-v2** and **NGSI-LD** measure payloads types. Possible values are: `iotagent`, `ngsiv2` or `ngsild`. The default is `iotagent`. |
|
|
2007
|
+
| `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
|
+
| `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
|
+
| `useCBflowControl` | ✓ | `boolean` | | Use Context Broker flow control. See more info [in this section](admin.md#useCBflowControl). False by default. |
|
|
1945
2010
|
|
|
1946
2011
|
### Device operations
|
|
1947
2012
|
|
|
@@ -2398,4 +2463,4 @@ updateEntityRequestsError 5
|
|
|
2398
2463
|
[18]:
|
|
2399
2464
|
https://czosel.github.io/jexl-playground/#/?context=%7B%0A%20%20%22value%22%20%3A%206%2C%0A%20%20%22ts%22%3A%201637245214901%2C%0A%20%22name%22%3A%20%22DevId629%22%2C%0A%20%22object%22%3A%7Bname%3A%20%22John%22%2C%20surname%3A%20%22Doe%22%7D%2C%0A%20%20%22array%22%3A%5B1%2C3%5D%0A%7D&input=name%7Csubstr(0%2Cname%7CindexOf(%22e%22)%2B1)&transforms=%7B%0A%20%20%20%20jsonparse%3A%20(str)%20%3D%3E%20JSON.parse(str)%2C%0A%20%20%20%20jsonstringify%3A%20(obj)%20%3D%3E%20JSON.stringify(obj)%2C%0A%20%20%20%20indexOf%3A%20(val%2C%20char)%20%3D%3E%20String(val).indexOf(char)%2C%0A%20%20%20%20length%3A%20(val)%20%3D%3E%20String(val).length%2C%0A%20%20%20%20trim%3A%20(val)%20%3D%3E%20String(val).trim()%2C%0A%20%20%20%20substr%3A%20(val%2C%20int1%2C%20int2)%20%3D%3E%20String(val).substr(int1%2C%20int2)%2C%0A%20%20%20%20addreduce%3A%20(arr)%20%3D%3E%20arr.reduce((i%2C%20v)%20%3D%3E%20i%20%2B%20v)%2C%0A%20%20%20%20lengtharray%3A%20(arr)%20%3D%3E%20arr.length%2C%0A%20%20%20%20typeof%3A%20(val)%20%3D%3E%20typeof%20val%2C%0A%20%20%20%20isarray%3A%20(arr)%20%3D%3E%20Array.isArray(arr)%2C%0A%20%20%20%20isnan%3A%20(val)%20%3D%3E%20isNaN(val)%2C%0A%20%20%20%20parseint%3A%20(val)%20%3D%3E%20parseInt(val)%2C%0A%20%20%20%20parsefloat%3A%20(val)%20%3D%3E%20parseFloat(val)%2C%0A%20%20%20%20toisodate%3A%20(val)%20%3D%3E%20new%20Date(val).toISOString()%2C%0A%20%20%20%20timeoffset%3A%20(isostr)%20%3D%3E%20new%20Date(isostr).getTimezoneOffset()%2C%0A%20%20%20%20tostring%3A%20(val)%20%3D%3E%20val.toString()%2C%0A%20%20%20%20urlencode%3A%20(val)%20%3D%3E%20encodeURI(val)%2C%0A%20%20%20%20urldecode%3A%20(val)%20%3D%3E%20decodeURI(val)%2C%0A%20%20%20%20replacestr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replace(from%2C%20to)%2C%0A%20%20%20%20replaceregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20str.replace(new%20RegExp(reg)%2C%20to)%2C%0A%20%20%20%20replaceallstr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replaceAll(from%2C%20to)%2C%0A%20%20%20%20replaceallregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20str.replaceAll(new%20RegExp(reg%2C%20'g')%2C%20to)%2C%0A%20%20%20%20split%3A%20(str%2C%20ch)%20%3D%3E%20str.split(ch)%2C%0A%20%20%20%20mapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%20choices%5Bvalues.findIndex((target)%20%3D%3E%20target%20%3D%3D%3D%20val)%5D%2C%0A%20%20%20%20thmapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%0A%20%20%20%20%20%20%20%20choices%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20values.reduce((acc%2C%20curr%2C%20i)%20%3D%3E%20(acc%20%3D%3D%3D%200%20%7C%7C%20acc%20%3F%20acc%20%3A%20val%20%3C%3D%20curr%20%3F%20(acc%20%3D%20i)%20%3A%20(acc%20%3D%20null))%2C%20null)%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20bitwisemask%3A%20(i%2C%20mask%2C%20op%2C%20shf)%20%3D%3E%0A%20%20%20%20%20%20%20%20(op%20%3D%3D%3D%20'%26'%20%3F%20parseInt(i)%20%26%20mask%20%3A%20op%20%3D%3D%3D%20'%7C'%20%3F%20parseInt(i)%20%7C%20mask%20%3A%20op%20%3D%3D%3D%20'%5E'%20%3F%20parseInt(i)%20%5E%20mask%20%3A%20i)%20%3E%3E%0A%20%20%20%20%20%20%20%20shf%2C%0A%20%20%20%20slice%3A%20(arr%2C%20init%2C%20end)%20%3D%3E%20arr.slice(init%2C%20end)%0A%7D
|
|
2400
2465
|
[99]:
|
|
2401
|
-
https://czosel.github.io/jexl-playground/#/?context=%7B%0A%20%20%22text%22%20%3A%20%22%20%20foobar%7B%7D%20%20%22%0A%7D&input=text%20%7C%20replacestr(%22foo%22%2C%22FOO%22)%7Ctrim%7Curlencode&transforms=%7B%0A%20%20%20%20jsonparse%3A%20(str)%20%3D%3E%20JSON.parse(str)%2C%0A%20%20%20%20jsonstringify%3A%20(obj)%20%3D%3E%20JSON.stringify(obj)%2C%0A%20%20%20%20indexOf%3A%20(val%2C%20char)%20%3D%3E%20String(val).indexOf(char)%2C%0A%20%20%20%20length%3A%20(val)%20%3D%3E%20String(val).length%2C%0A%20%20%20%20trim%3A%20(val)%20%3D%3E%20String(val).trim()%2C%0A%20%20%20%20substr%3A%20(val%2C%20int1%2C%20int2)%20%3D%3E%20String(val).substr(int1%2C%20int2)%2C%0A%20%20%20%20addreduce%3A%20(arr)%20%3D%3E%20arr.reduce((i%2C%20v)%20%3D%3E%20i%20%2B%20v)%2C%0A%20%20%20%20lengtharray%3A%20(arr)%20%3D%3E%20arr.length%2C%0A%20%20%20%20typeof%3A%20(val)%20%3D%3E%20typeof%20val%2C%0A%20%20%20%20isarray%3A%20(arr)%20%3D%3E%20Array.isArray(arr)%2C%0A%20%20%20%20isnan%3A%20(val)%20%3D%3E%20isNaN(val)%2C%0A%20%20%20%20parseint%3A%20(val)%20%3D%3E%20parseInt(val)%2C%0A%20%20%20%20parsefloat%3A%20(val)%20%3D%3E%20parseFloat(val)%2C%0A%20%20%20%20toisodate%3A%20(val)%20%3D%3E%20new%20Date(val).toISOString()%2C%0A%20%20%20%20timeoffset%3A%20(isostr)%20%3D%3E%20new%20Date(isostr).getTimezoneOffset()%2C%0A%20%20%20%20tostring%3A%20(val)%20%3D%3E%20val.toString()%2C%0A%20%20%20%20urlencode%3A%20(val)%20%3D%3E%20encodeURI(val)%2C%0A%20%20%20%20urldecode%3A%20(val)%20%3D%3E%20decodeURI(val)%2C%0A%20%20%20%20replacestr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replace(from%2C%20to)%2C%0A%20%20%20%20replaceregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20str.replace(new%20RegExp(reg)%2C%20to)%2C%0A%20%20%20%20replaceallstr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replaceAll(from%2C%20to)%2C%0A%20%20%20%20replaceallregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20str.replaceAll(new%20RegExp(reg%2C%20'g')%2C%20to)%2C%0A%20%20%20%20split%3A%20(str%2C%20ch)%20%3D%3E%20str.split(ch)%2C%0A%20%20%20%20mapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%20choices%5Bvalues.findIndex((target)%20%3D%3E%20target%20%3D%3D%3D%20val)%5D%2C%0A%20%20%20%20thmapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%0A%20%20%20%20%20%20%20%20choices%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20values.reduce((acc%2C%20curr%2C%20i)%20%3D%3E%20(acc%20%3D%3D%3D%200%20%7C%7C%20acc%20%3F%20acc%20%3A%20val%20%3C%3D%20curr%20%3F%20(acc%20%3D%20i)%20%3A%20(acc%20%3D%20null))%2C%20null)%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20bitwisemask%3A%20(i%2C%20mask%2C%20op%2C%20shf)%20%3D%3E%0A%20%20%20%20%20%20%20%20(op%20%3D%3D%3D%20'%26'%20%3F%20parseInt(i)%20%26%20mask%20%3A%20op%20%3D%3D%3D%20'%7C'%20%3F%20parseInt(i)%20%7C%20mask%20%3A%20op%20%3D%3D%3D%20'%5E'%20%3F%20parseInt(i)%20%5E%20mask%20%3A%20i)%20%3E%3E%0A%20%20%20%20%20%20%20%20shf%2C%0A%20%20%20%20slice%3A%20(arr%2C%20init%2C%20end)%20%3D%3E%20arr.slice(init%2C%20end)%0A%7D
|
|
2466
|
+
https://czosel.github.io/jexl-playground/#/?context=%7B%0A%20%20%22text%22%20%3A%20%22%20%20foobar%7B%7D%20%20%22%0A%7D&input=text%20%7C%20replacestr(%22foo%22%2C%22FOO%22)%7Ctrim%7Curlencode&transforms=%7B%0A%20%20%20%20jsonparse%3A%20(str)%20%3D%3E%20JSON.parse(str)%2C%0A%20%20%20%20jsonstringify%3A%20(obj)%20%3D%3E%20JSON.stringify(obj)%2C%0A%20%20%20%20indexOf%3A%20(val%2C%20char)%20%3D%3E%20String(val).indexOf(char)%2C%0A%20%20%20%20length%3A%20(val)%20%3D%3E%20String(val).length%2C%0A%20%20%20%20trim%3A%20(val)%20%3D%3E%20String(val).trim()%2C%0A%20%20%20%20substr%3A%20(val%2C%20int1%2C%20int2)%20%3D%3E%20String(val).substr(int1%2C%20int2)%2C%0A%20%20%20%20addreduce%3A%20(arr)%20%3D%3E%20arr.reduce((i%2C%20v)%20%3D%3E%20i%20%2B%20v)%2C%0A%20%20%20%20lengtharray%3A%20(arr)%20%3D%3E%20arr.length%2C%0A%20%20%20%20typeof%3A%20(val)%20%3D%3E%20typeof%20val%2C%0A%20%20%20%20isarray%3A%20(arr)%20%3D%3E%20Array.isArray(arr)%2C%0A%20%20%20%20isnan%3A%20(val)%20%3D%3E%20isNaN(val)%2C%0A%20%20%20%20parseint%3A%20(val)%20%3D%3E%20parseInt(val)%2C%0A%20%20%20%20parsefloat%3A%20(val)%20%3D%3E%20parseFloat(val)%2C%0A%20%20%20%20toisodate%3A%20(val)%20%3D%3E%20new%20Date(val).toISOString()%2C%0A%20%20%20%20timeoffset%3A%20(isostr)%20%3D%3E%20new%20Date(isostr).getTimezoneOffset()%2C%0A%20%20%20%20tostring%3A%20(val)%20%3D%3E%20val.toString()%2C%0A%20%20%20%20urlencode%3A%20(val)%20%3D%3E%20encodeURI(val)%2C%0A%20%20%20%20urldecode%3A%20(val)%20%3D%3E%20decodeURI(val)%2C%0A%20%20%20%20replacestr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replace(from%2C%20to)%2C%0A%20%20%20%20replaceregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20str.replace(new%20RegExp(reg)%2C%20to)%2C%0A%20%20%20%20replaceallstr%3A%20(str%2C%20from%2C%20to)%20%3D%3E%20str.replaceAll(from%2C%20to)%2C%0A%20%20%20%20replaceallregexp%3A%20(str%2C%20reg%2C%20to)%20%3D%3E%20str.replaceAll(new%20RegExp(reg%2C%20'g')%2C%20to)%2C%0A%20%20%20%20split%3A%20(str%2C%20ch)%20%3D%3E%20str.split(ch)%2C%0A%20%20%20%20joinarrtostr%3A%20(arr%2C%20ch)%20%3D%3E%20arr.join(ch)%2C%0A%20%20%20%20concatarr%3A%20(arr%2C%20arr2)%20%3D%3E%20arr.concat(arr2)%2C%0A%20%20%20%20mapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%20choices%5Bvalues.findIndex((target)%20%3D%3E%20target%20%3D%3D%3D%20val)%5D%2C%0A%20%20%20%20thmapper%3A%20(val%2C%20values%2C%20choices)%20%3D%3E%0A%20%20%20%20%20%20%20%20choices%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20values.reduce((acc%2C%20curr%2C%20i)%20%3D%3E%20(acc%20%3D%3D%3D%200%20%7C%7C%20acc%20%3F%20acc%20%3A%20val%20%3C%3D%20curr%20%3F%20(acc%20%3D%20i)%20%3A%20(acc%20%3D%20null))%2C%20null)%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20bitwisemask%3A%20(i%2C%20mask%2C%20op%2C%20shf)%20%3D%3E%0A%20%20%20%20%20%20%20%20(op%20%3D%3D%3D%20'%26'%20%3F%20parseInt(i)%20%26%20mask%20%3A%20op%20%3D%3D%3D%20'%7C'%20%3F%20parseInt(i)%20%7C%20mask%20%3A%20op%20%3D%3D%3D%20'%5E'%20%3F%20parseInt(i)%20%5E%20mask%20%3A%20i)%20%3E%3E%0A%20%20%20%20%20%20%20%20shf%2C%0A%20%20%20%20slice%3A%20(arr%2C%20init%2C%20end)%20%3D%3E%20arr.slice(init%2C%20end)%2C%0A%20%20%20%20addset%3A%20(arr%2C%20x)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20return%20Array.from(new%20Set(arr).add(x))%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20removeset%3A%20(arr%2C%20x)%20%3D%3E%20%7B%0A%20%20%20%20%20%20%20%20let%20s%20%3D%20new%20Set(arr)%3B%0A%20%20%20%20%20%20%20%20s.delete(x)%3B%0A%20%20%20%20%20%20%20%20return%20Array.from(s)%3B%0A%20%20%20%20%7D%2C%0A%20%20%20%20touppercase%3A%20(val)%20%3D%3E%20String(val).toUpperCase()%2C%0A%20%20%20%20tolowercase%3A%20(val)%20%3D%3E%20String(val).toLowerCase()%2C%0A%20%20%20%20floor%3A%20(val)%20%3D%3E%20Math.floor(val)%2C%0A%20%20%20%20ceil%3A%20(val)%20%3D%3E%20Math.ceil(val)%2C%0A%20%20%20%20round%3A%20(val)%20%3D%3E%20Math.round(val)%2C%0A%20%20%20%20tofixed%3A%20(val%2C%20decimals)%20%3D%3E%20Number.parseFloat(val).toFixed(decimals)%2C%0A%20%20%20%20gettime%3A%20(d)%20%3D%3E%20new%20Date(d).getTime()%2C%0A%20%20%20%20toisostring%3A%20(d)%20%3D%3E%20new%20Date(d).toISOString()%2C%0A%20%20%20%20%2F%2F%20https%3A%2F%2Fdeveloper.mozilla.org%2Fes%2Fdocs%2FWeb%2FJavaScript%2FReference%2FGlobal_Objects%2FDate%2FtoLocaleString%0A%20%20%20%20localestring%3A%20(d%2C%20timezone%2C%20options)%20%3D%3E%20new%20Date(d).toLocaleString(timezone%2C%20options)%2C%0A%20%20%20%20now%3A%20()%20%3D%3E%20Date.now()%2C%0A%20%20%20%20hextostring%3A%20(val)%20%3D%3E%0A%20%20%20%20%20%20%20%20new%20TextDecoder().decode(new%20Uint8Array(val.match(%2F.%7B1%2C2%7D%2Fg).map((byte)%20%3D%3E%20parseInt(byte%2C%2016))))%2C%0A%20%20%20%20valuePicker%3A%20(val%2Cpick)%20%3D%3E%20Object.entries(val).filter((%5B%2C%20v%5D)%20%3D%3E%20v%20%3D%3D%3D%20pick).map((%5Bk%2C%5D)%20%3D%3E%20k)%2C%0A%20%20%20%20valuePickerMulti%3A%20(val%2Cpick)%20%3D%3E%20Object.entries(val).filter((%5B%2C%20v%5D)%20%3D%3E%20pick.includes(v)).map((%5Bk%2C%5D)%20%3D%3E%20k)%0A%7D
|
|
@@ -775,6 +775,8 @@ The registration of the commands is performed once in the lifetime of the Device
|
|
|
775
775
|
|
|
776
776
|
#### Command Execution
|
|
777
777
|
|
|
778
|
+
##### Based in update (classic way)
|
|
779
|
+
|
|
778
780
|
Scenario 3 begins with the request for a command from the User to the Context Broker (P1):
|
|
779
781
|
|
|
780
782
|
```bash
|
|
@@ -825,21 +827,8 @@ Fiware-Correlator: 9cae9496-8ec7-11e6-80fc-fa163e734aab
|
|
|
825
827
|
}
|
|
826
828
|
```
|
|
827
829
|
|
|
828
|
-
The IoT Agent detects the selected attribute is a command, and replies to the Context Broker with
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
```json
|
|
832
|
-
[
|
|
833
|
-
{
|
|
834
|
-
"type": "device",
|
|
835
|
-
"id": "Dev0001",
|
|
836
|
-
"switch": {
|
|
837
|
-
"type": "command",
|
|
838
|
-
"value": ""
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
]
|
|
842
|
-
```
|
|
830
|
+
The IoT Agent detects the selected attribute is a command, and replies to the Context Broker with a 204 OK (without
|
|
831
|
+
payload).
|
|
843
832
|
|
|
844
833
|
This response just indicates that the IoT Agent has received the command successfully, and gives no information about
|
|
845
834
|
the requested information or command execution.
|
|
@@ -862,6 +851,100 @@ The Context Broker, forwards the same response to the user, thus replying the or
|
|
|
862
851
|
At this point, the command has been issued to the IoTAgent and the User doesn't still know what the result of its
|
|
863
852
|
request will be.
|
|
864
853
|
|
|
854
|
+
##### Based in notification (new way)
|
|
855
|
+
|
|
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:
|
|
858
|
+
|
|
859
|
+
```bash
|
|
860
|
+
POST /notify HTTP/1.1
|
|
861
|
+
Host: <target-host>:<northbound_port>
|
|
862
|
+
fiware-service: workshop
|
|
863
|
+
Fiware-ServicePath: /iota2ngsi
|
|
864
|
+
Accept: application/json
|
|
865
|
+
Content-length: 290
|
|
866
|
+
Content-type: application/json; charset=utf-8
|
|
867
|
+
Fiware-Correlator: 9cae9496-8ec7-11e6-80fc-fa163e734aab
|
|
868
|
+
|
|
869
|
+
{
|
|
870
|
+
"subscriptionId": "60b0cedd497e8b681d40b58e",
|
|
871
|
+
"data": [{
|
|
872
|
+
"id": "123456abcdefg",
|
|
873
|
+
"type": "switchOnOffExecution",
|
|
874
|
+
"targetEntityId": {
|
|
875
|
+
"type": "Text",
|
|
876
|
+
"value": "Dev0001",
|
|
877
|
+
"metadata": {}
|
|
878
|
+
},
|
|
879
|
+
"targetEntityType": {
|
|
880
|
+
"type": "Text",
|
|
881
|
+
"value": "device",
|
|
882
|
+
"metadata": {}
|
|
883
|
+
},
|
|
884
|
+
"execTs": {
|
|
885
|
+
"type": "DateTime",
|
|
886
|
+
"value": "2020-05-27T00:00:00.000Z",
|
|
887
|
+
"metadata": {}
|
|
888
|
+
},
|
|
889
|
+
"cmd": {
|
|
890
|
+
"type": "Text",
|
|
891
|
+
"value": "switch",
|
|
892
|
+
"metadata": {}
|
|
893
|
+
},
|
|
894
|
+
"params": {
|
|
895
|
+
"type": "Text",
|
|
896
|
+
"value": "54, 12",
|
|
897
|
+
"metadata": {}
|
|
898
|
+
},
|
|
899
|
+
"status": {
|
|
900
|
+
"type": "Text",
|
|
901
|
+
"value": "FORWARDED",
|
|
902
|
+
"metadata": {}
|
|
903
|
+
},
|
|
904
|
+
"info": {
|
|
905
|
+
"type": "Text",
|
|
906
|
+
"value": null,
|
|
907
|
+
"metadata": {}
|
|
908
|
+
},
|
|
909
|
+
"onDelivered": {
|
|
910
|
+
"type": "Request",
|
|
911
|
+
"value": {
|
|
912
|
+
}
|
|
913
|
+
},
|
|
914
|
+
"onOk": {
|
|
915
|
+
"type": "Request",
|
|
916
|
+
"value": {
|
|
917
|
+
}
|
|
918
|
+
},
|
|
919
|
+
"onError": {
|
|
920
|
+
"type": "Request",
|
|
921
|
+
"value": {
|
|
922
|
+
}
|
|
923
|
+
},
|
|
924
|
+
"onInfo": {
|
|
925
|
+
"type": "Request",
|
|
926
|
+
"value": {
|
|
927
|
+
}
|
|
928
|
+
},
|
|
929
|
+
"cmdExecution": {
|
|
930
|
+
"type": "value",
|
|
931
|
+
"value": true,
|
|
932
|
+
"metadata": {}
|
|
933
|
+
},
|
|
934
|
+
"dateExpiration": {
|
|
935
|
+
"type": "DateTime",
|
|
936
|
+
"value": "2020-05-27T20:00:00.000Z",
|
|
937
|
+
"metadata": {}
|
|
938
|
+
}
|
|
939
|
+
}]
|
|
940
|
+
}
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
In this case relevant fields are just `targetEntityId`, `targetEntityType`, `cmd` and `params`.
|
|
944
|
+
|
|
945
|
+
The IoT Agent detects the selected attribute is a command, and replies to the Context Broker with a 204 OK (without
|
|
946
|
+
payload).
|
|
947
|
+
|
|
865
948
|
#### Result reporting
|
|
866
949
|
|
|
867
950
|
Once the IoT Agent has executed the command or retrieved the information from the device, it reports the results to the
|
|
@@ -955,6 +1038,30 @@ The Context Broker replies with all the desired data, in R2 format (200 OK):
|
|
|
955
1038
|
]
|
|
956
1039
|
```
|
|
957
1040
|
|
|
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
|
+
|
|
958
1065
|
### Scenario 3: commands (error)
|
|
959
1066
|
|
|
960
1067
|
In Scenario 3, errors can happen asynchronously, out of the main interactions. When the IoTAgent detects an error
|