iotagent-node-lib 3.4.2 → 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.
package/CHANGES_NEXT_RELEASE
CHANGED
|
@@ -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
|
{
|
|
@@ -352,7 +362,8 @@ function sendUpdateValueNgsi2(entityName, attributes, typeInformation, token, ca
|
|
|
352
362
|
let url = '/v2/op/update';
|
|
353
363
|
|
|
354
364
|
if (typeInformation && typeInformation.type) {
|
|
355
|
-
|
|
365
|
+
// CB entity type should be always a String
|
|
366
|
+
payload.entities[0].type = String(typeInformation.type);
|
|
356
367
|
}
|
|
357
368
|
|
|
358
369
|
payload.actionType = 'append';
|
|
@@ -728,7 +739,9 @@ function sendUpdateValueNgsi2(entityName, attributes, typeInformation, token, ca
|
|
|
728
739
|
attr,
|
|
729
740
|
newAttr
|
|
730
741
|
);
|
|
731
|
-
|
|
742
|
+
if (!['id', 'type'].includes(attr.object_id)) {
|
|
743
|
+
delete payload.entities[0][attr.object_id];
|
|
744
|
+
}
|
|
732
745
|
attr = undefined; // stop processing attr
|
|
733
746
|
newAttr = undefined;
|
|
734
747
|
} else {
|
|
@@ -833,10 +846,10 @@ function sendUpdateValueNgsi2(entityName, attributes, typeInformation, token, ca
|
|
|
833
846
|
payload
|
|
834
847
|
);
|
|
835
848
|
}
|
|
836
|
-
|
|
849
|
+
// CB entity id and type should be always a String
|
|
837
850
|
let newEntity = {
|
|
838
|
-
id: newEntityName ? newEntityName : payload.entities[0].id,
|
|
839
|
-
type: attr.entity_type ? attr.entity_type : payload.entities[0].type
|
|
851
|
+
id: newEntityName ? String(newEntityName) : String(payload.entities[0].id),
|
|
852
|
+
type: attr.entity_type ? String(attr.entity_type) : String(payload.entities[0].type)
|
|
840
853
|
};
|
|
841
854
|
// Check if there is already a newEntity created
|
|
842
855
|
const alreadyEntity = payload.entities.find((entity) => {
|
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.
|
|
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);
|