iotagent-node-lib 2.19.0 → 2.22.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 (67) hide show
  1. package/.nyc_output/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
  2. package/.nyc_output/processinfo/33364de2-1199-4ec2-b33c-cae063ef8cc4.json +1 -0
  3. package/.nyc_output/processinfo/index.json +1 -0
  4. package/.readthedocs.yml +3 -1
  5. package/CHANGES_NEXT_RELEASE +1 -0
  6. package/README.md +5 -56
  7. package/doc/Contribution.md +3 -3
  8. package/doc/advanced-topics.md +8 -41
  9. package/doc/api.md +14 -3
  10. package/doc/expressionLanguage.md +17 -0
  11. package/doc/northboundinteractions.md +40 -33
  12. package/doc/operations.md +8 -5
  13. package/doc/requirements.txt +4 -0
  14. package/{docs → doc}/roadmap.md +21 -6
  15. package/doc/usermanual.md +4 -4
  16. package/docker/Mosquitto/Dockerfile +28 -12
  17. package/docker/Mosquitto/README.md +8 -7
  18. package/docker/Mosquitto/startMosquitto.sh +8 -0
  19. package/lib/fiware-iotagent-lib.js +1 -2
  20. package/lib/jexlTranformsMap.js +3 -1
  21. package/lib/model/Group.js +2 -1
  22. package/lib/model/dbConn.js +4 -0
  23. package/lib/plugins/expressionPlugin.js +56 -21
  24. package/lib/plugins/multiEntity.js +43 -49
  25. package/lib/plugins/pluginUtils.js +16 -0
  26. package/lib/services/commands/commandService.js +29 -2
  27. package/lib/services/common/domain.js +6 -2
  28. package/lib/services/common/iotManagerService.js +2 -1
  29. package/lib/services/devices/deviceRegistryMemory.js +13 -2
  30. package/lib/services/devices/deviceRegistryMongoDB.js +15 -7
  31. package/lib/services/devices/deviceService.js +52 -16
  32. package/lib/services/groups/groupRegistryMongoDB.js +13 -12
  33. package/lib/services/ngsi/entities-NGSI-LD.js +13 -4
  34. package/lib/services/ngsi/entities-NGSI-v2.js +8 -6
  35. package/lib/services/ngsi/ngsiService.js +3 -3
  36. package/lib/services/northBound/contextServer-NGSI-LD.js +20 -1
  37. package/lib/services/northBound/contextServer-NGSI-v2.js +39 -30
  38. package/lib/services/northBound/contextServerUtils.js +10 -10
  39. package/lib/services/northBound/deviceProvisioningServer.js +4 -1
  40. package/lib/templates/createDevice.json +13 -2
  41. package/lib/templates/createDeviceLax.json +2 -3
  42. package/lib/templates/updateDevice.json +13 -2
  43. package/package.json +27 -33
  44. package/test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice4.json +14 -0
  45. package/test/unit/mongodb/mongoDBUtils.js +2 -2
  46. package/test/unit/mongodb/mongodb-group-registry-test.js +1 -1
  47. package/test/unit/mongodb/mongodb-registry-test.js +2 -3
  48. package/test/unit/ngsi-ld/examples/contextAvailabilityRequests/registerIoTAgentCommands.json +2 -1
  49. package/test/unit/ngsi-ld/examples/contextRequests/updateContextLanguageProperties1.json +15 -0
  50. package/test/unit/ngsi-ld/lazyAndCommands/command-test.js +315 -1
  51. package/test/unit/ngsi-ld/ngsiService/languageProperties-test.js +112 -0
  52. package/test/unit/ngsi-mixed/provisioning/ngsi-versioning-test.js +1 -1
  53. package/test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice4.json +8 -0
  54. package/test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus2.json +6 -0
  55. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin35.json +2 -0
  56. package/test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin36.json +1 -0
  57. package/test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin17.json +27 -0
  58. package/test/unit/ngsiv2/expressions/jexlBasedTransformations-test.js +63 -2
  59. package/test/unit/ngsiv2/lazyAndCommands/polling-commands-test.js +151 -0
  60. package/test/unit/ngsiv2/plugins/multientity-plugin_test.js +63 -0
  61. package/test/unit/ngsiv2/provisioning/device-provisioning-api_test.js +60 -0
  62. package/test/unit/ngsiv2/provisioning/updateProvisionedDevices-test.js +2 -1
  63. package/bin/agentConsole.js +0 -257
  64. package/bin/iotAgentTester.js +0 -44
  65. package/lib/command/commandLine.js +0 -918
  66. package/lib/command/migration.js +0 -176
  67. package/test/unit/general/migration-test.js +0 -257
@@ -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
+ }
@@ -319,7 +319,7 @@ const iotAgentConfig = {
319
319
  expression: "{coordinates: [lon,lat], type: 'Point'}"
320
320
  }
321
321
  ],
322
- explicitAttrs: '[ myattr ]'
322
+ explicitAttrs: "[ 'myattr' ]"
323
323
  },
324
324
  GPS6: {
325
325
  commands: [],
@@ -345,6 +345,30 @@ const iotAgentConfig = {
345
345
  }
346
346
  ],
347
347
  explicitAttrs: true
348
+ },
349
+ GPS7: {
350
+ commands: [],
351
+ type: 'GPS',
352
+ lazy: [],
353
+ static: [
354
+ {
355
+ name: 'color',
356
+ type: 'string',
357
+ value: 'blue'
358
+ }
359
+ ],
360
+ active: [
361
+ {
362
+ name: 'price',
363
+ type: 'number'
364
+ },
365
+ {
366
+ name: 'location',
367
+ type: 'geo:json',
368
+ expression: "{coordinates: [lon,lat], type: 'Point'}"
369
+ }
370
+ ],
371
+ explicitAttrs: '[ ]'
348
372
  }
349
373
  },
350
374
  service: 'smartgondor',
@@ -1180,7 +1204,7 @@ describe('Java expression language (JEXL) based transformations plugin', functio
1180
1204
  .patch(
1181
1205
  '/v2/entities/gps1/attrs',
1182
1206
  utils.readExampleFile(
1183
- './test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin34.json'
1207
+ './test/unit/ngsiv2/examples/contextRequests/updateContextExpressionPlugin36.json'
1184
1208
  )
1185
1209
  )
1186
1210
  .query({ type: 'GPS' })
@@ -1230,6 +1254,43 @@ describe('Java expression language (JEXL) based transformations plugin', functio
1230
1254
  });
1231
1255
  });
1232
1256
  });
1257
+
1258
+ describe('When there is an extra TimeInstant sent by the device to be removed by jexl expression with context but with empty explicitAttrs', function () {
1259
+ // Case: Expression which results is sent as a new attribute
1260
+ const values = [
1261
+ {
1262
+ name: 'lat',
1263
+ type: 'Number',
1264
+ value: 52
1265
+ },
1266
+ {
1267
+ name: 'lon',
1268
+ type: 'Number',
1269
+ value: 13
1270
+ },
1271
+ {
1272
+ name: 'myattr',
1273
+ type: 'String',
1274
+ value: 'location'
1275
+ },
1276
+ {
1277
+ name: 'TimeInstant',
1278
+ type: 'DateTime',
1279
+ value: '2015-08-05T07:35:01.468+00:00'
1280
+ }
1281
+ ];
1282
+
1283
+ beforeEach(function () {
1284
+ nock.cleanAll();
1285
+ });
1286
+
1287
+ it('should calculate them and remove non-explicitAttrs by jexl expression with context from the payload ', function (done) {
1288
+ iotAgentLib.update('gps1', 'GPS7', '', values, function (error) {
1289
+ should.not.exist(error);
1290
+ done();
1291
+ });
1292
+ });
1293
+ });
1233
1294
  });
1234
1295
 
1235
1296
  describe('Java expression language (JEXL) based transformations plugin - Timestamps', function () {
@@ -98,6 +98,18 @@ const iotAgentConfig = {
98
98
  lazy: [],
99
99
  staticAttributes: [],
100
100
  active: []
101
+ },
102
+ RobotExp: {
103
+ commands: [
104
+ {
105
+ name: 'positionExp',
106
+ type: 'Array',
107
+ expression: '[22]'
108
+ }
109
+ ],
110
+ lazy: [],
111
+ staticAttributes: [],
112
+ active: []
101
113
  }
102
114
  },
103
115
  deviceRegistry: {
@@ -122,6 +134,14 @@ const device3 = {
122
134
  subservice: 'gardens',
123
135
  polling: true
124
136
  };
137
+ const device4 = {
138
+ id: 'r2d4',
139
+ type: 'RobotExp',
140
+ service: 'smartgondor',
141
+ subservice: 'gardens',
142
+ polling: true,
143
+ expressionLanguage: 'jexl'
144
+ };
125
145
 
126
146
  describe('NGSI-v2 - Polling commands', function () {
127
147
  beforeEach(function (done) {
@@ -386,3 +406,134 @@ describe('NGSI-v2 - Polling commands', function () {
386
406
  });
387
407
  });
388
408
  });
409
+
410
+ describe('NGSI-v2 - Polling commands expressions', function () {
411
+ beforeEach(function (done) {
412
+ logger.setLevel('FATAL');
413
+
414
+ nock.cleanAll();
415
+
416
+ contextBrokerMock = nock('http://192.168.1.1:1026')
417
+ .matchHeader('fiware-service', 'smartgondor')
418
+ .matchHeader('fiware-servicepath', 'gardens')
419
+ .post('/v2/registrations')
420
+ .reply(201, null, { Location: '/v2/registrations/6319a7f5254b05844116584m' });
421
+
422
+ contextBrokerMock
423
+ .matchHeader('fiware-service', 'smartgondor')
424
+ .matchHeader('fiware-servicepath', 'gardens')
425
+ .post('/v2/entities?options=upsert')
426
+ .reply(204);
427
+
428
+ iotAgentConfig.pollingExpiration = 0;
429
+ iotAgentConfig.pollingDaemonFrequency = 0;
430
+ iotAgentLib.activate(iotAgentConfig, done);
431
+ });
432
+
433
+ afterEach(function (done) {
434
+ delete device4.registrationId;
435
+ iotAgentLib.clearAll(function () {
436
+ iotAgentLib.deactivate(function () {
437
+ mongoUtils.cleanDbs(function () {
438
+ nock.cleanAll();
439
+ iotAgentLib.setDataUpdateHandler();
440
+ iotAgentLib.setCommandHandler();
441
+ done();
442
+ });
443
+ });
444
+ });
445
+ });
446
+
447
+ describe('When a command update arrives to the IoT Agent for a device with polling', function () {
448
+ const options = {
449
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/v2/op/update',
450
+ method: 'POST',
451
+ json: {
452
+ actionType: 'update',
453
+ entities: [
454
+ {
455
+ id: 'RobotExp:r2d4',
456
+ type: 'RobotExp',
457
+ positionExp: {
458
+ type: 'Array',
459
+ value: '[28, -104, 23]'
460
+ }
461
+ }
462
+ ]
463
+ },
464
+ headers: {
465
+ 'fiware-service': 'smartgondor',
466
+ 'fiware-servicepath': 'gardens'
467
+ }
468
+ };
469
+
470
+ beforeEach(function (done) {
471
+ statusAttributeMock = nock('http://192.168.1.1:1026')
472
+ .matchHeader('fiware-service', 'smartgondor')
473
+ .matchHeader('fiware-servicepath', 'gardens')
474
+ .patch(
475
+ '/v2/entities/RobotExp:r2d4/attrs?type=RobotExp',
476
+ utils.readExampleFile(
477
+ './test/unit/ngsiv2/examples/contextRequests/updateContextCommandStatus2.json'
478
+ )
479
+ )
480
+ .reply(204);
481
+
482
+ iotAgentLib.register(device4, function (error) {
483
+ done();
484
+ });
485
+ });
486
+
487
+ it('should not call the client handler', function (done) {
488
+ let handlerCalled = false;
489
+
490
+ iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
491
+ handlerCalled = true;
492
+ callback(null, {
493
+ id,
494
+ type,
495
+ attributes: [
496
+ {
497
+ name: 'positionExp',
498
+ type: 'Array',
499
+ value: '[28, -104, 23]'
500
+ }
501
+ ]
502
+ });
503
+ });
504
+
505
+ request(options, function (error, response, body) {
506
+ should.not.exist(error);
507
+ handlerCalled.should.equal(false);
508
+ done();
509
+ });
510
+ });
511
+ it('should create the attribute with the "_status" prefix in the Context Broker', function (done) {
512
+ iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
513
+ callback(null);
514
+ });
515
+
516
+ request(options, function (error, response, body) {
517
+ should.not.exist(error);
518
+ statusAttributeMock.done();
519
+ done();
520
+ });
521
+ });
522
+ it('should store the commands in the queue', function (done) {
523
+ iotAgentLib.setCommandHandler(function (id, type, service, subservice, attributes, callback) {
524
+ callback(null);
525
+ });
526
+
527
+ request(options, function (error, response, body) {
528
+ iotAgentLib.commandQueue('smartgondor', 'gardens', 'r2d4', function (error, listCommands) {
529
+ should.not.exist(error);
530
+ listCommands.count.should.equal(1);
531
+ listCommands.commands[0].name.should.equal('positionExp');
532
+ listCommands.commands[0].type.should.equal('Array');
533
+ listCommands.commands[0].value[0].should.equal(22);
534
+ done();
535
+ });
536
+ });
537
+ });
538
+ });
539
+ });
@@ -215,6 +215,31 @@ const iotAgentConfig = {
215
215
  }
216
216
  ]
217
217
  },
218
+ WeatherStation9: {
219
+ commands: [],
220
+ type: 'WeatherStation',
221
+ name: 'ws9b',
222
+ lazy: [],
223
+ active: [
224
+ {
225
+ object_id: 'p',
226
+ name: 'pressure',
227
+ type: 'Hgmm'
228
+ },
229
+ {
230
+ object_id: 'h',
231
+ name: 'humidity',
232
+ type: 'Percentage',
233
+ entity_type: 'Higrometer',
234
+ metadata: {
235
+ unitCode: {
236
+ type: 'Text',
237
+ value: 'Hgmm'
238
+ }
239
+ }
240
+ }
241
+ ]
242
+ },
218
243
  WeatherStation8Jexl: {
219
244
  commands: [],
220
245
  type: 'WeatherStation',
@@ -581,6 +606,44 @@ describe('NGSI-v2 - Multi-entity plugin', function () {
581
606
  });
582
607
  });
583
608
 
609
+ describe('When an update comes for a multientity measurement based on entity_type', function () {
610
+ const values = [
611
+ {
612
+ name: 'p',
613
+ type: 'centigrades',
614
+ value: '52'
615
+ },
616
+ {
617
+ name: 'h',
618
+ type: 'Percentage',
619
+ value: '12'
620
+ }
621
+ ];
622
+
623
+ beforeEach(function () {
624
+ nock.cleanAll();
625
+
626
+ contextBrokerMock = nock('http://192.168.1.1:1026')
627
+ .matchHeader('fiware-service', 'smartgondor')
628
+ .matchHeader('fiware-servicepath', 'gardens')
629
+ .post(
630
+ '/v2/op/update',
631
+ utils.readExampleFile(
632
+ './test/unit/ngsiv2/examples/contextRequests/updateContextMultientityPlugin17.json'
633
+ )
634
+ )
635
+ .reply(204);
636
+ });
637
+
638
+ it('should send two context elements, one for each entity', function (done) {
639
+ iotAgentLib.update('ws9b', 'WeatherStation9', '', values, function (error) {
640
+ should.not.exist(error);
641
+ contextBrokerMock.done();
642
+ done();
643
+ });
644
+ });
645
+ });
646
+
584
647
  describe('When an update comes for a multientity measurement with same attribute name', function () {
585
648
  const values = [
586
649
  {
@@ -705,6 +705,66 @@ describe('NGSI-v2 - Device provisioning API: Provision devices', function () {
705
705
  }
706
706
  );
707
707
 
708
+ describe('When a device provisioning request arrives to the IoTA and entityNameExp was configured at group level', function () {
709
+ const options = {
710
+ url: 'http://localhost:' + iotAgentConfig.server.port + '/iot/devices',
711
+ method: 'POST',
712
+ json: utils.readExampleFile('./test/unit/examples/deviceProvisioningRequests/provisionMinimumDevice4.json'),
713
+ headers: {
714
+ 'fiware-service': 'smartgondor',
715
+ 'fiware-servicepath': '/gardens'
716
+ }
717
+ };
718
+ const groupCreation = {
719
+ url: 'http://localhost:4041/iot/services',
720
+ method: 'POST',
721
+ json: {
722
+ services: [
723
+ {
724
+ resource: '/Thing',
725
+ apikey: '801230BJKL23Y9090DSFL123HJK09H324HV8732',
726
+ /*jshint camelcase: false */
727
+ entity_type: 'MicroLights',
728
+ entityNameExp: 'EntityNameByExp',
729
+ cbroker: 'http://192.168.1.1:1026'
730
+ }
731
+ ]
732
+ },
733
+ headers: {
734
+ 'fiware-service': 'smartgondor',
735
+ 'fiware-servicepath': '/gardens'
736
+ }
737
+ };
738
+
739
+ beforeEach(function (done) {
740
+ nock.cleanAll();
741
+ contextBrokerMock = nock('http://192.168.1.1:1026')
742
+ .matchHeader('fiware-service', 'smartgondor')
743
+ .matchHeader('fiware-servicepath', '/gardens')
744
+ .post(
745
+ '/v2/entities?options=upsert',
746
+ utils.readExampleFile(
747
+ './test/unit/ngsiv2/examples/contextRequests/createMinimumProvisionedDevice4.json'
748
+ )
749
+ )
750
+ .reply(204);
751
+
752
+ done();
753
+ });
754
+
755
+ it('should store the entity name defined by expression', function (done) {
756
+ request(groupCreation, function (error, response, body) {
757
+ request(options, function (error, response, body) {
758
+ iotAgentLib.listDevices('smartgondor', '/gardens', function (error, results) {
759
+ should.exist(results.devices[0].name);
760
+ results.devices[0].name.should.equal('EntityNameByExp');
761
+ done();
762
+ });
763
+ });
764
+ });
765
+ });
766
+ });
767
+
708
768
  describe(
709
769
  'When a device provisioning request with static attributes arrives to the IoTA' +
710
770
  ' and same static attribute is also configured at group level',
@@ -484,10 +484,11 @@ describe('NGSI-v2 - Device provisioning API: Update provisioned devices', functi
484
484
 
485
485
  it('should provision the explicitAttrs attribute appropriately', function (done) {
486
486
  request(optionsUpdate, function (error, response, body) {
487
+ should.not.exist(error);
488
+ response.statusCode.should.equal(204);
487
489
  request(optionsGetDevice, function (error, response, body) {
488
490
  should.not.exist(error);
489
491
  response.statusCode.should.equal(200);
490
-
491
492
  body.explicitAttrs.should.equal(false);
492
493
  done();
493
494
  });
@@ -1,257 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /*
4
- * Copyright 2014 Telefonica Investigación y Desarrollo, S.A.U
5
- *
6
- * This file is part of fiware-iotagent-lib
7
- *
8
- * fiware-iotagent-lib is free software: you can redistribute it and/or
9
- * modify it under the terms of the GNU Affero General Public License as
10
- * published by the Free Software Foundation, either version 3 of the License,
11
- * or (at your option) any later version.
12
- *
13
- * fiware-iotagent-lib is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
- * See the GNU Affero General Public License for more details.
17
- *
18
- * You should have received a copy of the GNU Affero General Public
19
- * License along with fiware-iotagent-lib.
20
- * If not, see http://www.gnu.org/licenses/.
21
- *
22
- * For those usages not covered by the GNU Affero General Public License
23
- * please contact with::[contacto@tid.es]
24
- */
25
-
26
- /* eslint-disable no-unused-vars */
27
- /* eslint-disable no-console */
28
-
29
- const readline = require('readline');
30
- const iotAgentLib = require('../lib/fiware-iotagent-lib');
31
- const commandUtils = require('command-shell-lib');
32
- let config = require('../config');
33
- const logger = require('logops');
34
- const async = require('async');
35
- const separator = '\n\n\t';
36
-
37
- const commands = {
38
- start: {
39
- parameters: [],
40
- description: '\tStart the IoT Agent',
41
- handler: startApp
42
- },
43
- stop: {
44
- parameters: [],
45
- description: '\tStop the IoT Agent',
46
- handler: stopApp
47
- },
48
- register: {
49
- parameters: ['id', 'type'],
50
- description:
51
- '\tRegister a new device in the IoT Agent. The attributes to register will be extracted from the\n' +
52
- '\ttype configuration',
53
- handler: registerDevice
54
- },
55
- unregister: {
56
- parameters: ['id', 'type'],
57
- description: '\tUnregister the selected device',
58
- handler: unregisterDevice
59
- },
60
- showConfig: {
61
- parameters: [],
62
- description: '\tShow the current configuration file',
63
- handler: showConfig
64
- },
65
- config: {
66
- parameters: ['newConfig'],
67
- description: '\tChange the configuration file to a new one',
68
- handler: changeConfig
69
- },
70
- updatevalue: {
71
- parameters: ['deviceId', 'deviceType', 'attributes'],
72
- description:
73
- '\tUpdate a device value in the Context Broker. The attributes should be triads with the following\n' +
74
- '\tformat: "name/type/value" sepparated by commas.',
75
- handler: updateDeviceValue
76
- },
77
- listdevices: {
78
- parameters: [],
79
- description: '\tList all the devices that have been registered in this IoT Agent session\n',
80
- handler: listDevices
81
- }
82
- };
83
-
84
- function handleError(message) {
85
- return function (error) {
86
- if (error) {
87
- console.log('\n\\033[31mERROR:\\033[0m %s', error.message);
88
- } else {
89
- console.log(message);
90
- }
91
-
92
- commandUtils.prompt();
93
- };
94
- }
95
-
96
- function listDevices() {
97
- iotAgentLib.listDevices(config.service, config.subservice, function (error, devices) {
98
- if (error) {
99
- console.log('\n\\033[31mERROR:\\033[0m %s', error.message);
100
- } else {
101
- const keys = Object.keys(devices);
102
-
103
- for (let i = 0; i < keys.length; i++) {
104
- console.log('\n\n%s\n', JSON.stringify(devices[keys[i]], null, 4));
105
- }
106
-
107
- commandUtils.prompt();
108
- }
109
- });
110
- }
111
-
112
- function extractAttributes(attributeString, callback) {
113
- const attributes = attributeString.split(',');
114
- const attributesResult = [];
115
-
116
- for (let i = 0; i < attributes.length; i++) {
117
- const fields = attributes[i].split('/');
118
- const attribute = {
119
- name: fields[0],
120
- type: fields[1]
121
- };
122
-
123
- if (fields[2]) {
124
- attribute.value = fields[2];
125
- }
126
-
127
- attributesResult.push(attribute);
128
- }
129
-
130
- callback(null, attributesResult);
131
- }
132
-
133
- function showConfig() {
134
- console.log('Current configuration file:\n\n%s', JSON.stringify(config, null, 4));
135
- }
136
-
137
- function changeConfig(command) {
138
- config = require(command[0]);
139
- }
140
-
141
- function writeHandler(id, type, attributes, callback) {
142
- console.log(
143
- '\n\nFake WRITE handler for update in entity [%s] with type [%s]\n%s\n',
144
- id,
145
- type,
146
- JSON.stringify(attributes, null, 4)
147
- );
148
-
149
- callback(null, {
150
- id,
151
- type,
152
- attributes
153
- });
154
- }
155
-
156
- function readHandler(id, type, attributes, callback) {
157
- console.log(
158
- '\n\nFake READ handler for update in entity [%s] with type [%s]\n%s\n',
159
- id,
160
- type,
161
- JSON.stringify(attributes, null, 4)
162
- );
163
-
164
- const sensorData = {
165
- id,
166
- isPattern: false,
167
- type,
168
- attributes: [
169
- {
170
- name: 'luminance',
171
- type: 'lumens',
172
- value: 19
173
- }
174
- ]
175
- };
176
-
177
- callback(null, sensorData);
178
- }
179
-
180
- function startApp(command) {
181
- iotAgentLib.setDataUpdateHandler(writeHandler);
182
- iotAgentLib.setCommandHandler(writeHandler);
183
- iotAgentLib.setDataQueryHandler(readHandler);
184
- iotAgentLib.activate(config, handleError('Application started'));
185
- }
186
-
187
- function stopApp(command) {
188
- iotAgentLib.deactivate(handleError('Application stopped'));
189
- }
190
-
191
- function exitAgent(command) {
192
- process.exit(0);
193
- }
194
-
195
- function registerDevice(command) {
196
- const device = {
197
- id: command[0],
198
- type: command[1]
199
- };
200
-
201
- console.log('Registering device');
202
- iotAgentLib.register(device, handleError('Device registered in the Context Broker'));
203
- }
204
-
205
- function unregisterDevice(command) {
206
- console.log('Unregistering device');
207
- iotAgentLib.unregister(command[0], handleError('Device unregistered'));
208
- }
209
-
210
- function updateDeviceValue(command) {
211
- iotAgentLib.getDevice(command[0], function (error, device) {
212
- if (device) {
213
- extractAttributes(command[2], function (error, attributes) {
214
- iotAgentLib.update(
215
- device.name,
216
- device.type,
217
- '',
218
- attributes,
219
- device,
220
- handleError('Device value updated')
221
- );
222
- });
223
- } else {
224
- async.waterfall(
225
- [
226
- async.apply(extractAttributes, command[2]),
227
- async.apply(iotAgentLib.update, command[0], command[1], '')
228
- ],
229
- handleError('Device value updated')
230
- );
231
- }
232
- });
233
- }
234
-
235
- function queryHandler(id, type, attributes, callback) {
236
- console.log('Handling query for [%s] of type [%s]:\n%s', JSON.stringify(attributes));
237
-
238
- callback(null, {
239
- type,
240
- isPattern: false,
241
- id,
242
- attributes: []
243
- });
244
- }
245
-
246
- function updateHandler(id, type, attributes, callback) {
247
- console.log('Update message received for device with id [%s] and type [%s]', id, type);
248
-
249
- callback(null, {
250
- type,
251
- isPattern: false,
252
- id,
253
- attributes: []
254
- });
255
- }
256
-
257
- commandUtils.initialize(commands, 'IoTAgent> ');