iotagent-node-lib 4.8.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 (124) hide show
  1. package/.github/workflows/ci.yml +10 -9
  2. package/.nyc_output/e4b1fe20-197e-4221-9f8d-6db65ff234b2.json +1 -0
  3. package/.nyc_output/processinfo/e4b1fe20-197e-4221-9f8d-6db65ff234b2.json +1 -0
  4. package/.nyc_output/processinfo/index.json +1 -0
  5. package/Changelog +791 -0
  6. package/config.js +2 -1
  7. package/doc/admin.md +20 -4
  8. package/doc/api.md +34 -4
  9. package/doc/devel/northboundinteractions.md +200 -112
  10. package/lib/commonConfig.js +16 -3
  11. package/lib/model/Device.js +3 -1
  12. package/lib/model/Group.js +2 -1
  13. package/lib/services/common/domain.js +4 -3
  14. package/lib/services/common/iotManagerService.js +2 -1
  15. package/lib/services/devices/deviceRegistryMongoDB.js +5 -1
  16. package/lib/services/devices/deviceService.js +17 -1
  17. package/lib/services/devices/devices-NGSI-LD.js +4 -4
  18. package/lib/services/devices/devices-NGSI-mixed.js +16 -0
  19. package/lib/services/devices/devices-NGSI-v2.js +123 -10
  20. package/lib/services/devices/registrationUtils.js +97 -30
  21. package/lib/services/groups/groupRegistryMongoDB.js +2 -1
  22. package/lib/services/ngsi/entities-NGSI-LD.js +69 -13
  23. package/lib/services/ngsi/ngsiService.js +3 -1
  24. package/lib/services/ngsi/subscription-NGSI-LD.js +2 -2
  25. package/lib/services/ngsi/subscription-NGSI-mixed.js +3 -3
  26. package/lib/services/ngsi/subscription-NGSI-v2.js +20 -6
  27. package/lib/services/ngsi/subscriptionService.js +2 -2
  28. package/lib/services/northBound/contextServer-NGSI-LD.js +5 -3
  29. package/lib/services/northBound/deviceProvisioningServer.js +6 -3
  30. package/lib/services/northBound/northboundServer.js +1 -1
  31. package/lib/services/northBound/restUtils.js +6 -2
  32. package/lib/templates/updateDevice.json +12 -0
  33. package/lib/templates/updateDeviceLax.json +4 -0
  34. package/package.json +2 -2
  35. package/test/functional/config-test.js +1 -1
  36. package/test/unit/general/contextBrokerKeystoneSecurityAccess-test.js +2 -2
  37. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +1 -1
  38. package/test/unit/ngsi-ld/examples/contextRequests/createDatetimeProvisionedDevice.json +1 -4
  39. package/test/unit/ngsi-ld/examples/contextRequests/createProvisionedDevice.json +3 -12
  40. package/test/unit/ngsi-ld/examples/contextRequests/createProvisionedDeviceMultientity.json +3 -12
  41. package/test/unit/ngsi-ld/examples/contextRequests/createProvisionedDeviceWithGroupAndStatic.json +6 -24
  42. package/test/unit/ngsi-ld/examples/contextRequests/createProvisionedDeviceWithGroupAndStatic2.json +1 -4
  43. package/test/unit/ngsi-ld/examples/contextRequests/updateContext1.json +1 -4
  44. package/test/unit/ngsi-ld/examples/contextRequests/updateContext3WithStatic.json +1 -4
  45. package/test/unit/ngsi-ld/examples/contextRequests/updateContext4.json +1 -4
  46. package/test/unit/ngsi-ld/examples/contextRequests/updateContext5.json +1 -4
  47. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAliasPlugin6.json +1 -4
  48. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAliasPlugin7.json +1 -4
  49. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAliasPlugin8.json +4 -2
  50. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAliasPlugin9.json +1 -4
  51. package/test/unit/ngsi-ld/examples/contextRequests/updateContextCommandError.json +3 -9
  52. package/test/unit/ngsi-ld/examples/contextRequests/updateContextCommandExpired.json +13 -19
  53. package/test/unit/ngsi-ld/examples/contextRequests/updateContextCommandFinish.json +13 -19
  54. package/test/unit/ngsi-ld/examples/contextRequests/updateContextCommandStatus1.json +4 -9
  55. package/test/unit/ngsi-ld/examples/contextRequests/updateContextCompressTimestamp1.json +1 -4
  56. package/test/unit/ngsi-ld/examples/contextRequests/updateContextCompressTimestamp2.json +1 -4
  57. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin1a.json +1 -4
  58. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin2.json +2 -8
  59. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin29.json +1 -4
  60. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin4.json +2 -8
  61. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin4a.json +3 -12
  62. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin6.json +3 -5
  63. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin7.json +1 -4
  64. package/test/unit/ngsi-ld/examples/contextRequests/updateContextExpressionPlugin8a.json +1 -4
  65. package/test/unit/ngsi-ld/examples/contextRequests/updateContextJsonProperty.json +13 -0
  66. package/test/unit/ngsi-ld/examples/contextRequests/updateContextListProperty.json +14 -0
  67. package/test/unit/ngsi-ld/examples/contextRequests/updateContextListRelationship.json +14 -0
  68. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin1.json +2 -8
  69. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin2.json +2 -8
  70. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin3.json +3 -8
  71. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin4.json +1 -4
  72. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin5.json +2 -8
  73. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityPlugin8.json +2 -8
  74. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin1.json +2 -8
  75. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin2.json +1 -4
  76. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin3.json +1 -4
  77. package/test/unit/ngsi-ld/examples/contextRequests/updateContextMultientityTimestampPlugin4.json +2 -8
  78. package/test/unit/ngsi-ld/examples/contextRequests/updateContextRelationship.json +11 -0
  79. package/test/unit/ngsi-ld/examples/contextRequests/updateContextValueType1.json +51 -0
  80. package/test/unit/ngsi-ld/examples/contextRequests/updateContextValueType2.json +65 -0
  81. package/test/unit/ngsi-ld/examples/contextRequests/updateContextVocabProperty.json +11 -0
  82. package/test/unit/ngsi-ld/examples/contextRequests/updateProvisionCommands1.json +2 -8
  83. package/test/unit/ngsi-ld/examples/contextRequests/updateProvisionDeviceStatic.json +1 -4
  84. package/test/unit/ngsi-ld/general/contextBrokerOAuthSecurityAccess-test.js +2 -2
  85. package/test/unit/ngsi-ld/general/https-support-test.js +1 -1
  86. package/test/unit/ngsi-ld/general/startup-test.js +3 -0
  87. package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +1 -1
  88. package/test/unit/ngsi-ld/lazyAndCommands/lazy-devices-test.js +71 -1
  89. package/test/unit/ngsi-ld/ngsiService/attributeTypes-test.js +293 -0
  90. package/test/unit/ngsi-ld/ngsiService/subscriptions-test.js +6 -6
  91. package/test/unit/ngsi-ld/ngsiService/unsupported-endpoints-test.js +0 -10
  92. package/test/unit/ngsi-ld/ngsiService/value-types-test.js +221 -0
  93. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands.json +24 -0
  94. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands2.json +24 -0
  95. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands3.json +24 -0
  96. package/test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands4.json +24 -0
  97. package/test/unit/ngsiv2/examples/contextRequests/updateEntity.json +5 -0
  98. package/test/unit/ngsiv2/examples/contextRequests/updateEntity2.json +5 -0
  99. package/test/unit/ngsiv2/examples/contextRequests/updateEntity2b.json +7 -0
  100. package/test/unit/ngsiv2/examples/contextRequests/updateEntity3.json +5 -0
  101. package/test/unit/ngsiv2/examples/subscriptionRequests/simpleSubscriptionRequest.json +4 -2
  102. package/test/unit/ngsiv2/examples/subscriptionRequests/simpleSubscriptionRequest2.json +4 -2
  103. package/test/unit/ngsiv2/general/contextBrokerOAuthSecurityAccess-test.js +2 -2
  104. package/test/unit/ngsiv2/general/https-support-test.js +1 -1
  105. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +245 -2
  106. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast1.json +0 -11
  107. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast10.json +0 -14
  108. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast2.json +0 -11
  109. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast3.json +0 -11
  110. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast4.json +0 -11
  111. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast5.json +0 -7
  112. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast6.json +0 -17
  113. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast7.json +0 -19
  114. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast8.json +0 -14
  115. package/test/unit/ngsi-ld/examples/contextRequests/updateContextAutocast9.json +0 -14
  116. package/test/unit/ngsi-ld/ngsiService/languageProperties-test.js +0 -109
  117. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast1.json +0 -8
  118. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast2.json +0 -8
  119. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast3.json +0 -8
  120. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast4.json +0 -8
  121. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast5.json +0 -8
  122. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast6.json +0 -8
  123. package/test/unit/ngsiv2/examples/contextRequests/updateContextAutocast7.json +0 -8
  124. /package/test/unit/ngsi-ld/examples/contextRequests/{updateContextLanguageProperties1.json → updateContextLanguageProperty.json} +0 -0
@@ -0,0 +1,221 @@
1
+ /*
2
+ * Copyright 2014 Telefonica Investigación y Desarrollo, S.A.U
3
+ *
4
+ * This file is part of fiware-iotagent-lib
5
+ *
6
+ * fiware-iotagent-lib is free software: you can redistribute it and/or
7
+ * modify it under the terms of the GNU Affero General Public License as
8
+ * published by the Free Software Foundation, either version 3 of the License,
9
+ * or (at your option) any later version.
10
+ *
11
+ * fiware-iotagent-lib is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+ * See the GNU Affero General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Affero General Public
17
+ * License along with fiware-iotagent-lib.
18
+ * If not, seehttp://www.gnu.org/licenses/.
19
+ *
20
+ * For those usages not covered by the GNU Affero General Public License
21
+ * please contact with::[contacto@tid.es]
22
+ *
23
+ * Developed by: Federico M. Facca - Martel Innovate
24
+ */
25
+
26
+ /* jshint camelcase: false */
27
+
28
+ const iotAgentLib = require('../../../../lib/fiware-iotagent-lib');
29
+ const utils = require('../../../tools/utils');
30
+ const should = require('should');
31
+ const nock = require('nock');
32
+ let contextBrokerMock;
33
+ const iotAgentConfig = {
34
+ logLevel: 'FATAL',
35
+ contextBroker: {
36
+ host: '192.168.1.1',
37
+ port: '1026',
38
+ ngsiVersion: 'ld',
39
+ jsonLdContext: 'http://context.json-ld'
40
+ },
41
+ server: {
42
+ port: 4041,
43
+ ldSupport: {
44
+ dataType: 'valueType'
45
+ }
46
+ },
47
+ types: {
48
+ Light: {
49
+ commands: [],
50
+ type: 'Light',
51
+ lazy: [],
52
+ active: [
53
+ {
54
+ object_id: 'p',
55
+ name: 'pressure',
56
+ type: 'Number'
57
+ },
58
+ {
59
+ object_id: 'e',
60
+ name: 'consumption',
61
+ type: 'Number'
62
+ },
63
+ {
64
+ object_id: 'a',
65
+ name: 'alive',
66
+ type: 'Property'
67
+ },
68
+ {
69
+ object_id: 'u',
70
+ name: 'updated',
71
+ type: 'Boolean'
72
+ },
73
+ {
74
+ object_id: 'm',
75
+ name: 'manufacturer',
76
+ type: 'Object'
77
+ },
78
+ {
79
+ object_id: 'r',
80
+ name: 'revisions',
81
+ type: 'Array'
82
+ },
83
+ {
84
+ object_id: 'd',
85
+ name: 'date',
86
+ type: 'Date'
87
+ },
88
+ {
89
+ object_id: 't',
90
+ name: 'time',
91
+ type: 'Time'
92
+ },
93
+ {
94
+ object_id: 'dt',
95
+ name: 'datetime',
96
+ type: 'DateTime'
97
+ }
98
+ ]
99
+ }
100
+ },
101
+ service: 'smartgondor',
102
+ subservice: 'gardens',
103
+ providerUrl: 'http://smartgondor.com',
104
+ deviceRegistrationDuration: 'P1M'
105
+ };
106
+
107
+ describe('NGSI-LD: Value Type', function () {
108
+ // Case: Expression which results is sent as a new attribute
109
+ const values = [
110
+ {
111
+ name: 'e',
112
+ type: 'Number',
113
+ value: 1
114
+ },
115
+ {
116
+ name: 'a',
117
+ type: 'Property',
118
+ value: 'foo'
119
+ },
120
+ {
121
+ name: 'u',
122
+ type: 'Boolean',
123
+ value: false
124
+ },
125
+ {
126
+ name: 'm',
127
+ type: 'Object',
128
+ value: '{"hello": "world"}'
129
+ },
130
+ {
131
+ name: 'r',
132
+ type: 'Array',
133
+ value: '[1,2]'
134
+ },
135
+ {
136
+ name: 'd',
137
+ type: 'Date',
138
+ value: '2025-07-18'
139
+ },
140
+ {
141
+ name: 't',
142
+ type: 'Time',
143
+ value: '14:22:11Z'
144
+ },
145
+ {
146
+ name: 'dt',
147
+ type: 'Datetime',
148
+ value: '2025-07-18T14:22:11Z'
149
+ }
150
+ ];
151
+
152
+ describe('When valueType is set to valueType', function () {
153
+ beforeEach(function (done) {
154
+ nock.cleanAll();
155
+
156
+ iotAgentConfig.contextBroker.valueType = 'valueType';
157
+ iotAgentLib.activate(iotAgentConfig, function () {
158
+ iotAgentLib.clearAll(function () {
159
+ done();
160
+ });
161
+ });
162
+
163
+ contextBrokerMock = nock('http://192.168.1.1:1026')
164
+ .matchHeader('fiware-service', 'smartgondor')
165
+ .matchHeader('fiware-servicepath', 'gardens')
166
+ .post(
167
+ '/ngsi-ld/v1/entityOperations/upsert/?options=update',
168
+ utils.readExampleFile('./test/unit/ngsi-ld/examples/contextRequests/updateContextValueType1.json')
169
+ )
170
+ .reply(204);
171
+ });
172
+
173
+ afterEach(function (done) {
174
+ iotAgentLib.clearAll(function () {
175
+ iotAgentLib.deactivate(done);
176
+ });
177
+ });
178
+
179
+ it('should add valueType to the payload', function (done) {
180
+ iotAgentLib.update('ws1', 'Light', '', values, function (error) {
181
+ should.not.exist(error);
182
+ contextBrokerMock.done();
183
+ done();
184
+ });
185
+ });
186
+ });
187
+ describe('When valueType is set to @type', function () {
188
+ beforeEach(function (done) {
189
+ iotAgentConfig.server.ldSupport.dataType = '@type';
190
+ iotAgentLib.activate(iotAgentConfig, function () {
191
+ iotAgentLib.clearAll(function () {
192
+ done();
193
+ });
194
+ });
195
+ nock.cleanAll();
196
+
197
+ contextBrokerMock = nock('http://192.168.1.1:1026')
198
+ .matchHeader('fiware-service', 'smartgondor')
199
+ .matchHeader('fiware-servicepath', 'gardens')
200
+ .post(
201
+ '/ngsi-ld/v1/entityOperations/upsert/?options=update',
202
+ utils.readExampleFile('./test/unit/ngsi-ld/examples/contextRequests/updateContextValueType2.json')
203
+ )
204
+ .reply(204);
205
+ });
206
+
207
+ afterEach(function (done) {
208
+ iotAgentLib.clearAll(function () {
209
+ iotAgentLib.deactivate(done);
210
+ });
211
+ });
212
+
213
+ it('should add @type to the payload', function (done) {
214
+ iotAgentLib.update('ws1', 'Light', '', values, function (error) {
215
+ should.not.exist(error);
216
+ contextBrokerMock.done();
217
+ done();
218
+ });
219
+ });
220
+ });
221
+ });
@@ -0,0 +1,24 @@
1
+ {
2
+ "description": "Managed by IOTA: Robot:r2d2 Robot position",
3
+ "subject": {
4
+ "entities":[
5
+ {
6
+ "id":"Robot:r2d2","type":"Robot"
7
+ }
8
+ ],
9
+ "condition": {
10
+ "attrs":["position"]
11
+ }
12
+ },
13
+ "notification":{
14
+ "http":{
15
+ "url":"http://smartgondor.com/notify"
16
+ },
17
+ "attrs":["position"],
18
+ "attrsFormat":"simplifiedNormalized",
19
+ "onlyChangedAttrs":true
20
+ }
21
+ }
22
+
23
+
24
+
@@ -0,0 +1,24 @@
1
+ {
2
+ "description": "Managed by IOTA: RobotT:r2d3 RobotT position",
3
+ "subject": {
4
+ "entities":[
5
+ {
6
+ "id":"RobotT:r2d3","type":"RobotT"
7
+ }
8
+ ],
9
+ "condition": {
10
+ "attrs":["position"]
11
+ }
12
+ },
13
+ "notification":{
14
+ "http":{
15
+ "url":"http://smartgondor.com/notify"
16
+ },
17
+ "attrs":["position"],
18
+ "attrsFormat":"simplifiedNormalized",
19
+ "onlyChangedAttrs":true
20
+ }
21
+ }
22
+
23
+
24
+
@@ -0,0 +1,24 @@
1
+ {
2
+ "description": "Managed by IOTA: RobotT:r2d4 RobotT position",
3
+ "subject": {
4
+ "entities":[
5
+ {
6
+ "id":"RobotT:r2d4","type":"RobotT"
7
+ }
8
+ ],
9
+ "condition": {
10
+ "attrs":["position"]
11
+ }
12
+ },
13
+ "notification":{
14
+ "http":{
15
+ "url":"http://smartgondor.com/notify"
16
+ },
17
+ "attrs":["position"],
18
+ "attrsFormat":"simplifiedNormalized",
19
+ "onlyChangedAttrs":true
20
+ }
21
+ }
22
+
23
+
24
+
@@ -0,0 +1,24 @@
1
+ {
2
+ "description": "Managed by IOTA: RobotT:r2d3 RobotT reset",
3
+ "subject": {
4
+ "entities":[
5
+ {
6
+ "id":"RobotT:r2d3","type":"RobotT"
7
+ }
8
+ ],
9
+ "condition": {
10
+ "attrs":["reset"]
11
+ }
12
+ },
13
+ "notification":{
14
+ "http":{
15
+ "url":"http://smartgondor.com/notify"
16
+ },
17
+ "attrs":["reset"],
18
+ "attrsFormat":"simplifiedNormalized",
19
+ "onlyChangedAttrs":true
20
+ }
21
+ }
22
+
23
+
24
+
@@ -0,0 +1,5 @@
1
+ {
2
+ "id":"Robot:r2d2",
3
+ "type":"Robot",
4
+ "position":{"type":"command","value":null}
5
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "id":"RobotT:r2d3",
3
+ "type":"RobotT",
4
+ "position":{"type":"command","value":null}
5
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "pressure":{"type":"Hgmm","value":null},
3
+ "reset": {
4
+ "type": "command",
5
+ "value": null
6
+ }
7
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "id":"RobotT:r2d4",
3
+ "type":"RobotT",
4
+ "position":{"type":"command","value":null}
5
+ }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "description": "Managed by IOTA: FirstMicroLight MicroLights attr_name",
2
3
  "subject": {
3
4
  "entities": [
4
5
  {
@@ -17,6 +18,7 @@
17
18
  "url": "http://smartgondor.com/notify"
18
19
  },
19
20
  "attrs": [],
20
- "attrsFormat": "normalized"
21
+ "attrsFormat": "normalized",
22
+ "onlyChangedAttrs": true
21
23
  }
22
- }
24
+ }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "description": "Managed by IOTA: light1 Light dimming",
2
3
  "subject": {
3
4
  "entities": [
4
5
  {
@@ -17,6 +18,7 @@
17
18
  "url": "http://smartgondor.com/notify"
18
19
  },
19
20
  "attrs": [],
20
- "attrsFormat": "normalized"
21
+ "attrsFormat": "normalized",
22
+ "onlyChangedAttrs": true
21
23
  }
22
- }
24
+ }
@@ -312,7 +312,7 @@ describe('NGSI-v2 - Secured access to the Context Broker with OAuth2 provider',
312
312
 
313
313
  it('subscribe requests use auth header', function (done) {
314
314
  iotAgentLib.getDevice('Light1', null, 'smartgondor', 'electricity', function (error, device) {
315
- iotAgentLib.subscribe(device, ['dimming'], null, function (error) {
315
+ iotAgentLib.subscribe(device, ['dimming'], null, 'normalized', function (error) {
316
316
  should.not.exist(error);
317
317
 
318
318
  contextBrokerMock.done();
@@ -333,7 +333,7 @@ describe('NGSI-v2 - Secured access to the Context Broker with OAuth2 provider',
333
333
  contextBrokerMock.delete('/v2/subscriptions/51c0ac9ed714fb3b37d7d5a8', '').reply(204);
334
334
 
335
335
  iotAgentLib.getDevice('Light1', null, 'smartgondor', 'electricity', function (error, device) {
336
- iotAgentLib.subscribe(device, ['dimming'], null, function (error) {
336
+ iotAgentLib.subscribe(device, ['dimming'], null, 'normalized', function (error) {
337
337
  iotAgentLib.unsubscribe(device, '51c0ac9ed714fb3b37d7d5a8', function (error) {
338
338
  contextBrokerMock.done();
339
339
  done();
@@ -211,7 +211,7 @@ describe('NGSI-v2 - HTTPS support tests', function () {
211
211
 
212
212
  it('should send the appropriate request to the Context Broker', function (done) {
213
213
  iotAgentLib.getDevice('MicroLight1', null, 'smartgondor', '/gardens', function (error, device) {
214
- iotAgentLib.subscribe(device, ['attr_name'], null, function (error) {
214
+ iotAgentLib.subscribe(device, ['attr_name'], null, 'normalized', function (error) {
215
215
  should.not.exist(error);
216
216
 
217
217
  contextBrokerMock.done();
@@ -31,6 +31,7 @@ const request = utils.request;
31
31
  const should = require('should');
32
32
  const logger = require('logops');
33
33
  const nock = require('nock');
34
+ const async = require('async');
34
35
  const mongoUtils = require('../../mongodb/mongoDBUtils');
35
36
 
36
37
  const timekeeper = require('timekeeper');
@@ -99,18 +100,98 @@ const iotAgentConfig = {
99
100
  lazy: [],
100
101
  staticAttributes: [],
101
102
  active: []
103
+ },
104
+ RobotT: {
105
+ commands: [
106
+ {
107
+ name: 'position',
108
+ type: 'Array'
109
+ }
110
+ ],
111
+ lazy: [],
112
+ staticAttributes: [],
113
+ active: [],
114
+ cmdMode: 'notification'
102
115
  }
103
116
  },
104
117
  service: 'smartgondor',
105
118
  subservice: 'gardens',
106
119
  providerUrl: 'http://smartgondor.com',
107
- useCBflowControl: true
120
+ useCBflowControl: true,
121
+ cmdMode: 'legacy'
108
122
  };
109
123
  const device3 = {
110
124
  id: 'r2d2',
111
125
  type: 'Robot',
112
126
  service: 'smartgondor',
113
- subservice: 'gardens'
127
+ subservice: 'gardens',
128
+ cmdMode: 'legacy'
129
+ };
130
+
131
+ const device4 = {
132
+ id: 'r2d2',
133
+ type: 'Robot',
134
+ service: 'smartgondor',
135
+ subservice: 'gardens',
136
+ cmdMode: 'notification',
137
+ apikey: null
138
+ };
139
+
140
+ const device5 = {
141
+ id: 'r2d3',
142
+ type: 'RobotT',
143
+ service: 'smartgondor',
144
+ subservice: 'gardens',
145
+ apikey: null,
146
+ cmdMode: 'notification'
147
+ };
148
+
149
+ const device5old = {
150
+ id: 'r2d3',
151
+ name: 'RobotT:r2d3',
152
+ type: 'RobotT',
153
+ service: 'smartgondor',
154
+ subservice: 'gardens',
155
+ apikey: null,
156
+ cmdMode: 'notification',
157
+ commands: [
158
+ {
159
+ name: 'position',
160
+ type: 'Array'
161
+ }
162
+ ],
163
+ subscriptions: [{ id: '6319a7f5254b05844116584d', triggers: ['position'] }],
164
+ subscriptionId: '6319a7f5254b05844116584d'
165
+ };
166
+
167
+ const device5updated = {
168
+ id: 'r2d3',
169
+ name: 'RobotT:r2d3',
170
+ type: 'RobotT',
171
+ service: 'smartgondor',
172
+ subservice: 'gardens',
173
+ apikey: null,
174
+ active: [
175
+ {
176
+ name: 'pressure',
177
+ type: 'Hgmm'
178
+ }
179
+ ],
180
+ commands: [
181
+ {
182
+ name: 'reset',
183
+ type: 'Array'
184
+ }
185
+ ],
186
+ cmdMode: 'notification'
187
+ };
188
+
189
+ const device6 = {
190
+ id: 'r2d4',
191
+ type: 'RobotT',
192
+ service: 'smartgondor',
193
+ subservice: 'gardens',
194
+ apikey: null
114
195
  };
115
196
 
116
197
  describe('NGSI-v2 - Command functionalities', function () {
@@ -414,3 +495,165 @@ describe('NGSI-v2 - Command functionalities', function () {
414
495
  });
415
496
  });
416
497
  });
498
+
499
+ describe('NGSI-v2 - Command notification functionalities', function () {
500
+ beforeEach(function (done) {
501
+ logger.setLevel('FATAL');
502
+ nock.cleanAll();
503
+
504
+ contextBrokerMock = nock('http://192.168.1.1:1026')
505
+ .matchHeader('fiware-service', 'smartgondor')
506
+ .matchHeader('fiware-servicepath', 'gardens')
507
+ .post(
508
+ '/v2/subscriptions',
509
+ utils.readExampleFile(
510
+ './test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands.json'
511
+ )
512
+ )
513
+ .reply(201, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
514
+
515
+ contextBrokerMock
516
+ .matchHeader('fiware-service', 'smartgondor')
517
+ .matchHeader('fiware-servicepath', 'gardens')
518
+ .post(
519
+ '/v2/entities?options=upsert',
520
+ utils.readExampleFile('./test/unit/ngsiv2/examples/contextRequests/updateEntity.json')
521
+ )
522
+ .reply(204);
523
+ iotAgentConfig.cmdMode = 'notification';
524
+ iotAgentLib.activate(iotAgentConfig, done);
525
+ });
526
+
527
+ afterEach(function (done) {
528
+ iotAgentLib.clearAll(function () {
529
+ iotAgentLib.deactivate(function () {
530
+ mongoUtils.cleanDbs(function () {
531
+ nock.cleanAll();
532
+ iotAgentLib.setDataUpdateHandler();
533
+ iotAgentLib.setCommandHandler();
534
+ done();
535
+ });
536
+ });
537
+ });
538
+ });
539
+
540
+ describe('When a device with commands by notifications is registered with with commands', function () {
541
+ it('should subscribe a Context Provider of the commands', function (done) {
542
+ iotAgentLib.register(device4, function (error) {
543
+ should.not.exist(error);
544
+ contextBrokerMock.done();
545
+ done();
546
+ });
547
+ });
548
+ });
549
+ });
550
+
551
+ describe('NGSI-v2 - Command update subscription and notification functionalities', function () {
552
+ afterEach(function (done) {
553
+ iotAgentLib.clearAll(function () {
554
+ iotAgentLib.deactivate(done);
555
+ });
556
+ });
557
+
558
+ describe('When a device with commands by notifications is registered with with commands and its updated', function () {
559
+ beforeEach(function (done) {
560
+ logger.setLevel('FATAL');
561
+ nock.cleanAll();
562
+ contextBrokerMock = nock('http://192.168.1.1:1026')
563
+ .post(
564
+ '/v2/subscriptions',
565
+ utils.readExampleFile(
566
+ './test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands2.json'
567
+ )
568
+ )
569
+ .reply(201, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
570
+ contextBrokerMock
571
+ .matchHeader('fiware-service', 'smartgondor')
572
+ .matchHeader('fiware-servicepath', 'gardens')
573
+ .post(
574
+ '/v2/entities?options=upsert',
575
+ utils.readExampleFile('./test/unit/ngsiv2/examples/contextRequests/updateEntity2.json')
576
+ )
577
+ .reply(204);
578
+
579
+ contextBrokerMock
580
+ .post(
581
+ '/v2/subscriptions',
582
+ utils.readExampleFile(
583
+ './test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands4.json'
584
+ )
585
+ )
586
+ .reply(201, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
587
+ contextBrokerMock
588
+ .matchHeader('fiware-service', 'smartgondor')
589
+ .matchHeader('fiware-servicepath', 'gardens')
590
+ .post(
591
+ '/v2/entities/RobotT:r2d3/attrs?type=RobotT',
592
+ utils.readExampleFile('./test/unit/ngsiv2/examples/contextRequests/updateEntity2b.json')
593
+ )
594
+ .reply(204);
595
+ contextBrokerMock
596
+ .matchHeader('fiware-service', 'smartgondor')
597
+ .matchHeader('fiware-servicepath', 'gardens')
598
+ .delete('/v2/subscriptions/6319a7f5254b05844116584d')
599
+ .reply(204, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
600
+
601
+ iotAgentLib.activate(iotAgentConfig, function (error) {
602
+ async.series([async.apply(iotAgentLib.clearAll), async.apply(iotAgentLib.register, device5)], done);
603
+ });
604
+ });
605
+
606
+ it('should update subscription in a Context Provider of the commands', function (done) {
607
+ iotAgentLib.updateRegister(device5updated, device5old, false, function (error) {
608
+ should.not.exist(error);
609
+ contextBrokerMock.done();
610
+ done();
611
+ });
612
+ });
613
+ });
614
+ });
615
+
616
+ describe('NGSI-v2 - Command unsubscribe notification functionalities', function () {
617
+ afterEach(function (done) {
618
+ iotAgentLib.clearAll(function () {
619
+ iotAgentLib.deactivate(done);
620
+ });
621
+ });
622
+
623
+ describe('When a device with commands by notifications is registered with with commands', function () {
624
+ beforeEach(function (done) {
625
+ logger.setLevel('FATAL');
626
+ nock.cleanAll();
627
+ contextBrokerMock = nock('http://192.168.1.1:1026')
628
+ .post(
629
+ '/v2/subscriptions',
630
+ utils.readExampleFile(
631
+ './test/unit/ngsiv2/examples/contextAvailabilityRequests/subscribeIoTAgentCommands3.json'
632
+ )
633
+ )
634
+ .reply(201, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
635
+ contextBrokerMock
636
+ .matchHeader('fiware-service', 'smartgondor')
637
+ .matchHeader('fiware-servicepath', 'gardens')
638
+ .post(
639
+ '/v2/entities?options=upsert',
640
+ utils.readExampleFile('./test/unit/ngsiv2/examples/contextRequests/updateEntity3.json')
641
+ )
642
+ .reply(204);
643
+ contextBrokerMock
644
+ .delete('/v2/subscriptions/6319a7f5254b05844116584d')
645
+ .reply(204, null, { Location: '/v2/subscriptions/6319a7f5254b05844116584d' });
646
+ iotAgentLib.activate(iotAgentConfig, function (error) {
647
+ async.series([async.apply(iotAgentLib.clearAll), async.apply(iotAgentLib.register, device6)], done);
648
+ });
649
+ });
650
+
651
+ it('should unsubscribe a Context Provider of the commands', function (done) {
652
+ iotAgentLib.unregister(device6.id, null, 'smartgondor', 'gardens', function (error) {
653
+ should.not.exist(error);
654
+ contextBrokerMock.done();
655
+ done();
656
+ });
657
+ });
658
+ });
659
+ });