iotagent-node-lib 2.21.0 → 2.24.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 (62) hide show
  1. package/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
  2. package/.nyc_output/processinfo/{76bc24ff-5fac-4b5a-997d-de2799342eb0.json → 33364de2-1199-4ec2-b33c-cae063ef8cc4.json} +1 -1
  3. package/.nyc_output/processinfo/index.json +1 -1
  4. package/CHANGES_NEXT_RELEASE +0 -1
  5. package/doc/Contribution.md +3 -3
  6. package/doc/advanced-topics.md +73 -9
  7. package/doc/api.md +7 -5
  8. package/doc/architecture.md +52 -5
  9. package/doc/expressionLanguage.md +18 -3
  10. package/doc/operations.md +8 -5
  11. package/doc/usermanual.md +18 -16
  12. package/docker/Mosquitto/Dockerfile +1 -1
  13. package/lib/errors.js +9 -1
  14. package/lib/model/Group.js +2 -1
  15. package/lib/model/dbConn.js +4 -0
  16. package/lib/plugins/bidirectionalData.js +104 -6
  17. package/lib/plugins/expressionPlugin.js +18 -7
  18. package/lib/plugins/multiEntity.js +42 -29
  19. package/lib/plugins/pluginUtils.js +17 -0
  20. package/lib/request-shim.js +2 -1
  21. package/lib/services/commands/commandService.js +29 -2
  22. package/lib/services/common/iotManagerService.js +2 -1
  23. package/lib/services/devices/deviceService.js +35 -9
  24. package/lib/services/groups/groupRegistryMongoDB.js +13 -12
  25. package/lib/services/ngsi/entities-NGSI-LD.js +7 -0
  26. package/lib/services/ngsi/entities-NGSI-v2.js +70 -11
  27. package/lib/services/ngsi/ngsiService.js +1 -1
  28. package/lib/services/northBound/contextServer-NGSI-LD.js +110 -15
  29. package/lib/services/northBound/contextServer-NGSI-v2.js +8 -3
  30. package/lib/services/northBound/contextServerUtils.js +9 -9
  31. package/lib/services/northBound/deviceProvisioningServer.js +2 -1
  32. package/lib/templates/createDevice.json +1 -2
  33. package/lib/templates/createDeviceLax.json +2 -3
  34. package/lib/templates/updateDevice.json +1 -2
  35. package/package.json +24 -24
  36. package/test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice4.json +14 -0
  37. package/test/unit/memoryRegistry/deviceRegistryMemory_test.js +51 -0
  38. package/test/unit/mongodb/mongoDBUtils.js +2 -2
  39. package/test/unit/mongodb/mongodb-group-registry-test.js +25 -1
  40. package/test/unit/mongodb/mongodb-registry-test.js +51 -3
  41. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgentCommands.json +2 -1
  42. package/test/unit/ngsi-ld/examples/contextRequests/updateContextLanguageProperties1.json +15 -0
  43. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json +21 -0
  44. package/test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +17 -0
  45. package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +995 -27
  46. package/test/unit/ngsi-ld/ngsiService/languageProperties-test.js +112 -0
  47. package/test/unit/ngsi-ld/ngsiService/unsupported-endpoints-test.js +111 -0
  48. package/test/unit/ngsi-ld/plugins/bidirectional-plugin_test.js +221 -0
  49. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +1 -1
  50. package/test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice4.json +8 -0
  51. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus2.json +6 -0
  52. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin36.json +12 -1
  53. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin17.json +27 -0
  54. package/test/unit/ngsiv2/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json +19 -0
  55. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +10 -8
  56. package/test/unit/ngsiv2/lazyAndCommands/command-test.js +106 -0
  57. package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +151 -0
  58. package/test/unit/ngsiv2/plugins/bidirectional-plugin_test.js +115 -0
  59. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +63 -0
  60. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +60 -0
  61. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +2 -1
  62. package/.nyc_output/76bc24ff-5fac-4b5a-997d-de2799342eb0.json +0 -1
@@ -0,0 +1,112 @@
1
+ /*
2
+ * Copyright 2022 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, see http://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
+ * Modified by: Daniel Calvo - ATOS Research & Innovation
24
+ */
25
+
26
+ /* eslint-disable no-unused-vars */
27
+
28
+ const iotAgentLib = require('../../../../lib/fiware-iotagent-lib');
29
+ const utils = require('../../../tools/utils');
30
+ const request = utils.request;
31
+ const should = require('should');
32
+ const logger = require('logops');
33
+ const nock = require('nock');
34
+ let contextBrokerMock;
35
+ const iotAgentConfig = {
36
+ autocast: true,
37
+ contextBroker: {
38
+ host: '192.168.1.1',
39
+ port: '1026',
40
+ ngsiVersion: 'ld',
41
+ jsonLdContext: 'http://context.json-ld'
42
+ },
43
+ server: {
44
+ port: 4041
45
+ },
46
+ types: {
47
+ Light: {
48
+ commands: [],
49
+ type: 'Light',
50
+ active: [
51
+ {
52
+ name: 'name',
53
+ type: 'LanguageProperty'
54
+ }
55
+ ]
56
+ }
57
+ },
58
+ service: 'smartgondor',
59
+ subservice: 'gardens',
60
+ providerUrl: 'http://smartgondor.com'
61
+ };
62
+
63
+ describe('NGSI-LD - LanguageProperty test', function () {
64
+ beforeEach(function () {
65
+ logger.setLevel('FATAL');
66
+ });
67
+
68
+ afterEach(function (done) {
69
+ iotAgentLib.deactivate(done);
70
+ });
71
+
72
+ describe(
73
+ 'When the IoT Agent receives new exonym from a device name with LanguageProperty type and a JSON object',
74
+ function () {
75
+ const values = [
76
+ {
77
+ name: 'name',
78
+ type: 'LanguageProperty',
79
+ value: {
80
+ el: "Κωνσταντινούπολις",
81
+ en: "Constantinople",
82
+ tr: "İstanbul"
83
+ }
84
+ }
85
+ ];
86
+
87
+ beforeEach(function (done) {
88
+ nock.cleanAll();
89
+
90
+ contextBrokerMock = nock('http://192.168.1.1:1026')
91
+ .matchHeader('fiware-service', 'smartgondor')
92
+ .post(
93
+ '/ngsi-ld/v1/entityOperations/upsert/?options=update',
94
+ utils.readExampleFile(
95
+ './test/unit/ngsi-ld/examples/contextRequests/updateContextLanguageProperties1.json'
96
+ )
97
+ )
98
+ .reply(204);
99
+
100
+ iotAgentLib.activate(iotAgentConfig, done);
101
+ });
102
+
103
+ it('should change the value of the corresponding attribute in the context broker', function (done) {
104
+ iotAgentLib.update('light1', 'Light', '', values, function (error) {
105
+ should.not.exist(error);
106
+ contextBrokerMock.done();
107
+ done();
108
+ });
109
+ });
110
+ }
111
+ );
112
+ });
@@ -0,0 +1,111 @@
1
+ /*
2
+ * Copyright 2022 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, see http://www.gnu.org/licenses/.
19
+ *
20
+ * For those usages not covered by the GNU Affero General Public License
21
+ * please contact with::daniel.moranjimenez@telefonica.com
22
+ *
23
+ * Modified by: Jason Fox - FIWARE Foundation
24
+ */
25
+
26
+ /* eslint-disable no-unused-vars */
27
+
28
+ const iotAgentLib = require('../../../../lib/fiware-iotagent-lib');
29
+ const utils = require('../../../tools/utils');
30
+ const request = utils.request;
31
+ const should = require('should');
32
+
33
+ let contextBrokerMock;
34
+ const iotAgentConfig = {
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
+ },
44
+ types: {},
45
+ service: 'smartgondor',
46
+ subservice: 'gardens',
47
+ providerUrl: 'http://smartgondor.com'
48
+ };
49
+
50
+ describe('NGSI-LD - Unsupported Endpoints', function () {
51
+ beforeEach(function (done) {
52
+ iotAgentLib.activate(iotAgentConfig, function () {
53
+ iotAgentLib.clearAll(function () {
54
+ done();
55
+ });
56
+ });
57
+ });
58
+
59
+ afterEach(function (done) {
60
+ iotAgentLib.clearAll(function () {
61
+ iotAgentLib.deactivate(done);
62
+ });
63
+ });
64
+
65
+ describe('When accessing an Unsupported Endpoint', function () {
66
+ it('GET /entities should return a valid NSGI-LD error message', function (done) {
67
+ const options = {
68
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/ngsi-ld/v1/entities',
69
+ method: 'GET'
70
+ };
71
+ request(options, function (error, response, body) {
72
+ response.statusCode.should.equal(501);
73
+ done();
74
+ });
75
+ });
76
+ it('POST /entities should return a valid NSGI-LD error message', function (done) {
77
+ const options = {
78
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/ngsi-ld/v1/entities',
79
+ method: 'POST',
80
+ json: {}
81
+ };
82
+ request(options, function (error, response, body) {
83
+ response.statusCode.should.equal(501);
84
+ done();
85
+ });
86
+ });
87
+ it('DELETE /entities/<entity-id> should return a valid NSGI-LD error message', function (done) {
88
+ const options = {
89
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/ngsi-ld/v1/entities/urn:ngsi-ld:entity',
90
+ method: 'DELETE'
91
+ };
92
+ request(options, function (error, response, body) {
93
+ response.statusCode.should.equal(501);
94
+ done();
95
+ });
96
+ });
97
+ it('DELETE /entities/<entity-id>/attrs/<attr-name> should return a valid NSGI-LD error message', function (done) {
98
+ const options = {
99
+ url:
100
+ 'http://localhost:' +
101
+ iotAgentConfig.server.port +
102
+ '/ngsi-ld/v1/entities/urn:ngsi-ld:entity/attrs/att',
103
+ method: 'DELETE'
104
+ };
105
+ request(options, function (error, response, body) {
106
+ response.statusCode.should.equal(501);
107
+ done();
108
+ });
109
+ });
110
+ });
111
+ });
@@ -264,6 +264,227 @@ describe('NGSI-LD - Bidirectional data plugin', function () {
264
264
  });
265
265
  });
266
266
 
267
+ describe('When a notification with metadata arrives for a bidirectional attribute', function () {
268
+ const notificationOptions = {
269
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/notify',
270
+ method: 'POST',
271
+ json: utils.readExampleFile(
272
+ './test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithMetadata.json'
273
+ ),
274
+ headers: {
275
+ 'fiware-service': 'smartgondor',
276
+ 'fiware-servicepath': '/gardens'
277
+ }
278
+ };
279
+ let executedHandler = false;
280
+
281
+ beforeEach(function () {
282
+ contextBrokerMock
283
+ .matchHeader('fiware-service', 'smartgondor')
284
+ .post(
285
+ '/ngsi-ld/v1/subscriptions/',
286
+ utils.readExampleFile(
287
+ './test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json'
288
+ )
289
+ )
290
+ .reply(201, null, { Location: '/ngsi-ld/v1/subscriptions/51c0ac9ed714fb3b37d7d5a8' });
291
+
292
+ contextBrokerMock
293
+ .matchHeader('fiware-service', 'smartgondor')
294
+ .post(
295
+ '/ngsi-ld/v1/entityOperations/upsert/',
296
+ utils.readExampleFile('./test/unit/ngsi-ld/examples/contextRequests/createBidirectionalDevice.json')
297
+ )
298
+ .reply(204);
299
+ });
300
+
301
+ afterEach(function () {
302
+ iotAgentLib.setNotificationHandler();
303
+ });
304
+
305
+ it('should execute the original handler', function (done) {
306
+ function mockedHandler(device, notification, callback) {
307
+ notification[0].name.should.equal('location');
308
+ notification[0].value.should.equal('12.4, -9.6');
309
+ notification[0].metadata.qos.value.should.equal(1);
310
+ executedHandler = true;
311
+ callback();
312
+ }
313
+
314
+ iotAgentLib.setNotificationHandler(mockedHandler);
315
+
316
+ request(options, function (error, response, body) {
317
+ request(notificationOptions, function (error, response, body) {
318
+ executedHandler.should.equal(true);
319
+ contextBrokerMock.done();
320
+ done();
321
+ });
322
+ });
323
+ });
324
+
325
+ it('should return a 200 OK', function (done) {
326
+ function mockedHandler(device, notification, callback) {
327
+ executedHandler = true;
328
+ callback();
329
+ }
330
+
331
+ iotAgentLib.setNotificationHandler(mockedHandler);
332
+
333
+ request(options, function (error, response, body) {
334
+ request(notificationOptions, function (error, response, body) {
335
+ response.statusCode.should.equal(200);
336
+ contextBrokerMock.done();
337
+ done();
338
+ });
339
+ });
340
+ });
341
+
342
+ it('should return the transformed values', function (done) {
343
+ let transformedHandler = false;
344
+
345
+ function mockedHandler(device, values, callback) {
346
+ let latitudeFound = false;
347
+ let longitudeFound = false;
348
+
349
+ for (let i = 0; i < values.length; i++) {
350
+ if (values[i].name === 'latitude' && values[i].type === 'string' && values[i].value === '-9.6') {
351
+ latitudeFound = true;
352
+ }
353
+
354
+ if (values[i].name === 'longitude' && values[i].type === 'string' && values[i].value === '12.4') {
355
+ longitudeFound = true;
356
+ }
357
+ }
358
+
359
+ transformedHandler = values.length >= 2 && longitudeFound && latitudeFound;
360
+ callback();
361
+ }
362
+
363
+ iotAgentLib.setNotificationHandler(mockedHandler);
364
+
365
+ request(options, function (error, response, body) {
366
+ request(notificationOptions, function (error, response, body) {
367
+ contextBrokerMock.done();
368
+ transformedHandler.should.equal(true);
369
+ done();
370
+ });
371
+ });
372
+ });
373
+ });
374
+
375
+ describe('When a sequential notification with datasetId arrives for a bidirectional attribute', function () {
376
+ const notificationOptions = {
377
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/notify',
378
+ method: 'POST',
379
+ json: utils.readExampleFile(
380
+ './test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalNotificationWithDatasetId.json'
381
+ ),
382
+ headers: {
383
+ 'fiware-service': 'smartgondor',
384
+ 'fiware-servicepath': '/gardens'
385
+ }
386
+ };
387
+ let executedHandler = false;
388
+
389
+ beforeEach(function () {
390
+ contextBrokerMock
391
+ .matchHeader('fiware-service', 'smartgondor')
392
+ .post(
393
+ '/ngsi-ld/v1/subscriptions/',
394
+ utils.readExampleFile(
395
+ './test/unit/ngsi-ld/examples/subscriptionRequests/bidirectionalSubscriptionRequest.json'
396
+ )
397
+ )
398
+ .reply(201, null, { Location: '/ngsi-ld/v1/subscriptions/51c0ac9ed714fb3b37d7d5a8' });
399
+
400
+ contextBrokerMock
401
+ .matchHeader('fiware-service', 'smartgondor')
402
+ .post(
403
+ '/ngsi-ld/v1/entityOperations/upsert/',
404
+ utils.readExampleFile('./test/unit/ngsi-ld/examples/contextRequests/createBidirectionalDevice.json')
405
+ )
406
+ .reply(204);
407
+ });
408
+
409
+ afterEach(function () {
410
+ iotAgentLib.setNotificationHandler();
411
+ });
412
+
413
+ it('should execute the original handler', function (done) {
414
+ function mockedHandler(device, notification, callback) {
415
+ notification[0].name.should.equal('location');
416
+ notification[0].value.should.equal('12.4, -9.6');
417
+ notification[0].datasetId.should.equal('urn:ngsi-ld:Property:do-this');
418
+
419
+ notification[1].name.should.equal('location');
420
+ notification[1].value.should.equal('6, 10');
421
+ notification[1].datasetId.should.equal('urn:ngsi-ld:Property:then-do-this');
422
+
423
+ executedHandler = true;
424
+ callback();
425
+ }
426
+
427
+ iotAgentLib.setNotificationHandler(mockedHandler);
428
+
429
+ request(options, function (error, response, body) {
430
+ request(notificationOptions, function (error, response, body) {
431
+ executedHandler.should.equal(true);
432
+ contextBrokerMock.done();
433
+ done();
434
+ });
435
+ });
436
+ });
437
+
438
+ it('should return a 200 OK', function (done) {
439
+ function mockedHandler(device, notification, callback) {
440
+ executedHandler = true;
441
+ callback();
442
+ }
443
+
444
+ iotAgentLib.setNotificationHandler(mockedHandler);
445
+
446
+ request(options, function (error, response, body) {
447
+ request(notificationOptions, function (error, response, body) {
448
+ response.statusCode.should.equal(200);
449
+ contextBrokerMock.done();
450
+ done();
451
+ });
452
+ });
453
+ });
454
+
455
+ it('should return the transformed values', function (done) {
456
+ let transformedHandler = false;
457
+
458
+ function mockedHandler(device, values, callback) {
459
+ let latitudeFound = false;
460
+ let longitudeFound = false;
461
+
462
+ for (let i = 0; i < values.length; i++) {
463
+ if (values[i].name === 'latitude' && values[i].type === 'string' && values[i].value === '-9.6') {
464
+ latitudeFound = true;
465
+ }
466
+
467
+ if (values[i].name === 'longitude' && values[i].type === 'string' && values[i].value === '12.4') {
468
+ longitudeFound = true;
469
+ }
470
+ }
471
+
472
+ transformedHandler = values.length >= 2 && longitudeFound && latitudeFound;
473
+ callback();
474
+ }
475
+
476
+ iotAgentLib.setNotificationHandler(mockedHandler);
477
+
478
+ request(options, function (error, response, body) {
479
+ request(notificationOptions, function (error, response, body) {
480
+ contextBrokerMock.done();
481
+ transformedHandler.should.equal(true);
482
+ done();
483
+ });
484
+ });
485
+ });
486
+ });
487
+
267
488
  describe('When a new Group provisioning request arrives with bidirectional attributes', function () {
268
489
  const provisionGroup = {
269
490
  url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/services',
@@ -171,7 +171,7 @@ describe('Mixed Mode: ngsiVersion test', function () {
171
171
  beforeEach(function (done) {
172
172
  mongoUtils.cleanDbs(function () {
173
173
  iotAgentLib.activate(iotAgentConfig, function () {
174
- mongo.connect('mongodb://localhost:27017/iotagent', { useNewUrlParser: true }, function (err, db) {
174
+ mongo.connect('mongodb://localhost:27017/iotagent', function (err, db) {
175
175
  iotAgentDb = db;
176
176
  done();
177
177
  });
@@ -0,0 +1,8 @@
1
+ {
2
+ "id": "EntityNameByExp",
3
+ "type": "MicroLights",
4
+ "attr_name": {
5
+ "type": "string",
6
+ "value": null
7
+ }
8
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "positionExp_status": {
3
+ "type": "commandStatus",
4
+ "value": "PENDING"
5
+ }
6
+ }
@@ -1 +1,12 @@
1
- {"myattr":{"type": "String","value": "location"}}
1
+ {
2
+ "mylocation": {
3
+ "type": "geo:json",
4
+ "value": {
5
+ "coordinates": [
6
+ 13,
7
+ 52
8
+ ],
9
+ "type": "Point"
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "actionType": "update",
3
+ "entities": [
4
+ {
5
+ "id": "ws9b",
6
+ "type": "WeatherStation",
7
+ "pressure": {
8
+ "type": "Hgmm",
9
+ "value": "52"
10
+ }
11
+ },
12
+ {
13
+ "humidity": {
14
+ "type": "Percentage",
15
+ "value": "12",
16
+ "metadata": {
17
+ "unitCode": {
18
+ "type": "Text",
19
+ "value": "Hgmm"
20
+ }
21
+ }
22
+ },
23
+ "type": "Higrometer",
24
+ "id": "ws9b"
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "subscriptionId": "51c0ac9ed714fb3b37d7d5a8",
3
+ "data": [
4
+ {
5
+ "location": {
6
+ "type": "geo:point",
7
+ "value": "12.4, -9.6",
8
+ "metadata": {
9
+ "qos": {
10
+ "type": "Number",
11
+ "value": 1
12
+ }
13
+ }
14
+ },
15
+ "type": "TheLightType",
16
+ "id": "TheFirstLight"
17
+ }
18
+ ]
19
+ }
@@ -271,7 +271,7 @@ const iotAgentConfig = {
271
271
  expression: "{coordinates: [lon,lat], type: 'Point'}"
272
272
  }
273
273
  ],
274
- explicitAttrs: '[ "location" ]'
274
+ explicitAttrs: ' location&&price ? [ "location", "price" ] : location ? [ "location" ] : []'
275
275
  },
276
276
  GPS4: {
277
277
  commands: [],
@@ -314,12 +314,14 @@ const iotAgentConfig = {
314
314
  type: 'number'
315
315
  },
316
316
  {
317
- name: 'location',
318
- type: 'geo:json',
319
- expression: "{coordinates: [lon,lat], type: 'Point'}"
317
+ object_id: 'theLocation',
318
+ name: 'mylocation',
319
+ type: 'geo:json'
320
320
  }
321
321
  ],
322
- explicitAttrs: "[ 'myattr' ]"
322
+ explicitAttrs: "theLocation ? ['mylocation'] : []"
323
+ // #1267 this is not working:
324
+ //explicitAttrs: "theLocation ? [{object_id: 'theLocation'}] : []"
323
325
  },
324
326
  GPS6: {
325
327
  commands: [],
@@ -1184,9 +1186,9 @@ describe('Java expression language (JEXL) based transformations plugin', functio
1184
1186
  value: 13
1185
1187
  },
1186
1188
  {
1187
- name: 'myattr',
1188
- type: 'String',
1189
- value: 'location'
1189
+ name: 'theLocation',
1190
+ type: 'geo:json',
1191
+ value: { coordinates: [13, 52], type: 'Point' }
1190
1192
  },
1191
1193
  {
1192
1194
  name: 'TimeInstant',