iotagent-node-lib 3.4.3 → 3.4.4

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.
@@ -1 +0,0 @@
1
- - Fix: ensure entity_id is a stirng when is result of entityNameExp (#1476)
package/doc/api.md CHANGED
@@ -152,7 +152,7 @@ parameters defined at device level in database, the parameters are inherit from
152
152
  ## Entity attributes
153
153
 
154
154
  In the config group/device model there are four list of attributes with different purpose to configure how the
155
- information coming from the device is mapped to the Context Broker attributes:
155
+ information coming from the device (measures) is mapped to the Context Broker attributes:
156
156
 
157
157
  - **`attributes`**: Are measures that are pushed from the device to the IoT agent. This measure changes will be sent
158
158
  to the Context Broker as updateContext requests over the device entity. NGSI queries to the context broker will be
@@ -179,7 +179,9 @@ information coming from the device is mapped to the Context Broker attributes:
179
179
  All of them have the same syntax, a list of objects with the following attributes:
180
180
 
181
181
  - **object_id** (optional): name of the attribute as coming from the device.
182
- - **name** (mandatory): ID of the attribute in the target entity in the Context Broker.
182
+ - **name** (mandatory): ID of the attribute in the target entity in the Context Broker. Note that `id` and `type`
183
+ are not valid attribute names at Context Broker. Thus, although a measure named `id` or `type` will not break the IOT Agent, they
184
+ are silently ignored and never progress toward Context Broker entities.
183
185
  - **type** (mandatory): name of the type of the attribute in the target entity.
184
186
  - **metadata** (optional): additional static metadata for the attribute in the target entity. (e.g. `unitCode`)
185
187
 
@@ -209,6 +211,10 @@ Additionally for commands (which are attributes of type `command`) the following
209
211
  - **contentType**: `content-type` header used when send command by HTTP transport (ignored in other kinds of
210
212
  transports)
211
213
 
214
+ Note that, when information comming from devices, this means measures, are not defined neither in the group, nor in the
215
+ device, the IoT agent will store that information into the destination entity using the same attribute name than the
216
+ measure name, unless `explicitAttrs` is defined. Measures `id` or `type` names are invalid, and will be ignored.
217
+
212
218
  ## Multientity support
213
219
 
214
220
  The IOTA is able to persists measures coming from a single device to more than one entity, declaring the target entities
@@ -340,6 +340,16 @@ function sendUpdateValueNgsi2(entityName, attributes, typeInformation, token, ca
340
340
  attributes,
341
341
  typeInformation
342
342
  );
343
+ // if any measure has name 'id' or 'type' it should be removed
344
+ // (as they cannot be progressed as attribute names, given that 'id' or 'type' are forbidden names for attributes in CB)
345
+ var attributesWithoutIdType = [];
346
+ attributes.forEach(function (attribute) {
347
+ if (attribute.name !== 'id' && attribute.name !== 'type') {
348
+ attributesWithoutIdType.push(attribute);
349
+ }
350
+ });
351
+ attributes = attributesWithoutIdType;
352
+
343
353
  const payload = {
344
354
  entities: [
345
355
  {
@@ -729,7 +739,9 @@ function sendUpdateValueNgsi2(entityName, attributes, typeInformation, token, ca
729
739
  attr,
730
740
  newAttr
731
741
  );
732
- delete payload.entities[0][attr.object_id];
742
+ if (!['id', 'type'].includes(attr.object_id)) {
743
+ delete payload.entities[0][attr.object_id];
744
+ }
733
745
  attr = undefined; // stop processing attr
734
746
  newAttr = undefined;
735
747
  } else {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "iotagent-node-lib",
3
3
  "license": "AGPL-3.0-only",
4
4
  "description": "IoT Agent library to interface with NGSI Context Broker",
5
- "version": "3.4.3",
5
+ "version": "3.4.4",
6
6
  "homepage": "https://github.com/telefonicaid/iotagent-node-lib",
7
7
  "keywords": [
8
8
  "fiware",
@@ -156,6 +156,52 @@ const iotAgentConfig = {
156
156
  }
157
157
  }
158
158
  ]
159
+ },
160
+ StupidDevice: {
161
+ type: 'StupidDevice',
162
+ commands: [],
163
+ lazy: [],
164
+ staticAttributes: [],
165
+ active: [
166
+ {
167
+ name: 'type',
168
+ object_id: 't',
169
+ type: 'text'
170
+ },
171
+ {
172
+ name: 'id',
173
+ object_id: 'i',
174
+ type: 'text'
175
+ },
176
+ {
177
+ name: 'meas',
178
+ object_id: 'm',
179
+ type: 'String'
180
+ }
181
+ ]
182
+ },
183
+ StupidDevice2: {
184
+ type: 'StupidDevice2',
185
+ commands: [],
186
+ lazy: [],
187
+ staticAttributes: [],
188
+ active: [
189
+ {
190
+ name: 'type',
191
+ object_id: 'type',
192
+ type: 'text'
193
+ },
194
+ {
195
+ name: 'id',
196
+ object_id: 'id',
197
+ type: 'text'
198
+ },
199
+ {
200
+ name: 'meas',
201
+ object_id: 'meas',
202
+ type: 'String'
203
+ }
204
+ ]
159
205
  }
160
206
  },
161
207
  service: 'smartgondor',
@@ -856,6 +902,150 @@ describe('NGSI-v2 - Active attributes test', function () {
856
902
  });
857
903
  });
858
904
 
905
+ describe('When the IoT Agent receives autoprovisioned id and type measures', function () {
906
+ const valuesIdType = [
907
+ {
908
+ name: 'id',
909
+ type: 'text',
910
+ value: 'idIoTA'
911
+ },
912
+ {
913
+ name: 'type',
914
+ type: 'text',
915
+ value: 'typeIoTA'
916
+ },
917
+ {
918
+ name: 'm',
919
+ type: 'text',
920
+ value: 'measIoTA'
921
+ }
922
+ ];
923
+
924
+ beforeEach(function (done) {
925
+
926
+ nock.cleanAll();
927
+
928
+ contextBrokerMock = nock('http://192.168.1.1:1026')
929
+ .matchHeader('fiware-service', 'smartgondor')
930
+ .matchHeader('fiware-servicepath', 'gardens')
931
+ .post('/v2/entities?options=upsert', {
932
+ id: 'stupiddevice1',
933
+ type: 'StupidDevice',
934
+ meas: {
935
+ value: 'measIoTA',
936
+ type: 'String'
937
+ }
938
+ })
939
+ .reply(204);
940
+
941
+ iotAgentLib.activate(iotAgentConfig, done);
942
+ });
943
+
944
+ it('should not affect to the real ID and Type to store in the context broker', function (done) {
945
+ iotAgentLib.update('stupiddevice1', 'StupidDevice', '', valuesIdType, function (error) {
946
+ should.not.exist(error);
947
+ contextBrokerMock.done();
948
+ done();
949
+ });
950
+ });
951
+ });
952
+
953
+ describe('When the IoT Agent receives provisioned id and type measures with different object_id names', function () {
954
+ const valuesIdType2 = [
955
+ {
956
+ name: 'i',
957
+ type: 'text',
958
+ value: 'idIoTA2'
959
+ },
960
+ {
961
+ name: 't',
962
+ type: 'text',
963
+ value: 'typeIoTA2'
964
+ },
965
+ {
966
+ name: 'm',
967
+ type: 'text',
968
+ value: 'measIoTA2'
969
+ }
970
+ ];
971
+
972
+ beforeEach(function (done) {
973
+
974
+ nock.cleanAll();
975
+
976
+ contextBrokerMock = nock('http://192.168.1.1:1026')
977
+ .matchHeader('fiware-service', 'smartgondor')
978
+ .matchHeader('fiware-servicepath', 'gardens')
979
+ .post('/v2/entities?options=upsert', {
980
+ id: 'stupiddevice2',
981
+ type: 'StupidDevice',
982
+ meas: {
983
+ value: 'measIoTA2',
984
+ type: 'String'
985
+ }
986
+ })
987
+ .reply(204);
988
+
989
+ iotAgentLib.activate(iotAgentConfig, done);
990
+ });
991
+
992
+ it('should not affect to the real ID and Type to store in the context broker', function (done) {
993
+ iotAgentLib.update('stupiddevice2', 'StupidDevice', '', valuesIdType2, function (error) {
994
+ should.not.exist(error);
995
+ contextBrokerMock.done();
996
+ done();
997
+ });
998
+ });
999
+ });
1000
+
1001
+ describe('When the IoT Agent receives provisioned id and type measures with the same object_id name', function () {
1002
+ const valuesIdType3 = [
1003
+ {
1004
+ name: 'id',
1005
+ type: 'text',
1006
+ value: 'idIoTA'
1007
+ },
1008
+ {
1009
+ name: 'type',
1010
+ type: 'text',
1011
+ value: 'typeIoTA'
1012
+ },
1013
+ {
1014
+ name: 'meas',
1015
+ type: 'text',
1016
+ value: 'measIoTA'
1017
+ }
1018
+ ];
1019
+
1020
+ beforeEach(function (done) {
1021
+
1022
+ nock.cleanAll();
1023
+
1024
+ contextBrokerMock = nock('http://192.168.1.1:1026')
1025
+ .matchHeader('fiware-service', 'smartgondor')
1026
+ .matchHeader('fiware-servicepath', 'gardens')
1027
+ .post('/v2/entities?options=upsert', {
1028
+ id: 'stupiddevice3',
1029
+ type: 'StupidDevice2',
1030
+ meas: {
1031
+ value: 'measIoTA',
1032
+ type: 'String'
1033
+ }
1034
+ })
1035
+ .reply(204);
1036
+
1037
+ iotAgentLib.activate(iotAgentConfig, done);
1038
+ });
1039
+
1040
+ it('should not affect to the real ID and Type to store in the context broker', function (done) {
1041
+ iotAgentLib.update('stupiddevice3', 'StupidDevice2', '', valuesIdType3, function (error) {
1042
+ should.not.exist(error);
1043
+ contextBrokerMock.done();
1044
+ done();
1045
+ });
1046
+ });
1047
+ });
1048
+
859
1049
  describe('When the IoT Agent receives new information from a device and CBis defined using environment variables', function () {
860
1050
  beforeEach(function (done) {
861
1051
  process.env.IOTA_CB_HOST = 'cbhost';
@@ -873,6 +1063,7 @@ describe('NGSI-v2 - Active attributes test', function () {
873
1063
 
874
1064
  iotAgentLib.activate(iotAgentConfig, done);
875
1065
  });
1066
+
876
1067
  it('should change the value of the corresponding attribute in the context broker', function (done) {
877
1068
  iotAgentLib.update('light1', 'Light', '', values, function (error) {
878
1069
  should.not.exist(error);