@wiotp/sdk 0.4.2 → 0.6.2

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 (48) hide show
  1. package/LICENSE +203 -203
  2. package/README.md +68 -68
  3. package/dist/BaseClient.js +259 -0
  4. package/dist/BaseConfig.js +194 -0
  5. package/dist/api/ApiClient.js +508 -0
  6. package/dist/api/ApiErrors.js +118 -0
  7. package/dist/api/DscClient.js +332 -0
  8. package/dist/api/LecClient.js +48 -0
  9. package/dist/api/MgmtClient.js +77 -0
  10. package/dist/api/RegistryClient.js +234 -0
  11. package/dist/api/RulesClient.js +105 -0
  12. package/dist/api/StateClient.js +738 -0
  13. package/dist/application/ApplicationClient.js +436 -0
  14. package/dist/application/ApplicationConfig.js +233 -0
  15. package/dist/application/index.js +23 -0
  16. package/dist/bundled/wiotp-bundle.js +35592 -0
  17. package/dist/bundled/wiotp-bundle.min.js +47 -0
  18. package/dist/device/DeviceClient.js +125 -0
  19. package/dist/device/DeviceConfig.js +216 -0
  20. package/dist/device/index.js +23 -0
  21. package/dist/gateway/GatewayClient.js +159 -0
  22. package/dist/gateway/GatewayConfig.js +52 -0
  23. package/dist/gateway/index.js +23 -0
  24. package/dist/index.js +55 -0
  25. package/dist/util.js +50 -0
  26. package/package.json +92 -84
  27. package/src/BaseClient.js +215 -215
  28. package/src/BaseConfig.js +157 -157
  29. package/src/api/ApiClient.js +454 -454
  30. package/src/api/ApiErrors.js +33 -33
  31. package/src/api/DscClient.js +164 -145
  32. package/src/api/LecClient.js +32 -32
  33. package/src/api/MgmtClient.js +57 -57
  34. package/src/api/RegistryClient.js +194 -194
  35. package/src/api/RulesClient.js +84 -84
  36. package/src/api/StateClient.js +650 -650
  37. package/src/application/ApplicationClient.js +348 -348
  38. package/src/application/ApplicationConfig.js +191 -191
  39. package/src/application/index.js +12 -12
  40. package/src/device/DeviceClient.js +78 -78
  41. package/src/device/DeviceConfig.js +175 -175
  42. package/src/device/index.js +14 -14
  43. package/src/gateway/GatewayClient.js +114 -114
  44. package/src/gateway/GatewayConfig.js +21 -21
  45. package/src/gateway/index.js +13 -13
  46. package/{index.js → src/index.js} +19 -19
  47. package/src/util.js +38 -38
  48. package/src/util/IoTFoundation.pem +0 -82
package/dist/util.js ADDED
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isString = isString;
7
+ exports.isNumber = isNumber;
8
+ exports.isBoolean = isBoolean;
9
+ exports.isDefined = isDefined;
10
+ exports.generateUUID = generateUUID;
11
+ exports.isNode = exports.isBrowser = void 0;
12
+
13
+ /**
14
+ *****************************************************************************
15
+ Copyright (c) 2014, 2019 IBM Corporation and other Contributors.
16
+ All rights reserved. This program and the accompanying materials
17
+ are made available under the terms of the Eclipse Public License v1.0
18
+ which accompanies this distribution, and is available at
19
+ http://www.eclipse.org/legal/epl-v10.html
20
+ *****************************************************************************
21
+ *
22
+ */
23
+ function isString(value) {
24
+ return typeof value === 'string';
25
+ }
26
+
27
+ function isNumber(value) {
28
+ return typeof value === 'number';
29
+ }
30
+
31
+ function isBoolean(value) {
32
+ return typeof value === 'boolean';
33
+ }
34
+
35
+ function isDefined(value) {
36
+ return value !== undefined && value !== null;
37
+ }
38
+
39
+ var isBrowser = new Function("try {return this===window;}catch(e){ return false;}");
40
+ exports.isBrowser = isBrowser;
41
+ var isNode = new Function("try {return this===global;}catch(e){return false;}");
42
+ exports.isNode = isNode;
43
+
44
+ function generateUUID() {
45
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
46
+ var r = Math.random() * 16 | 0,
47
+ v = c == 'x' ? r : r & 0x3 | 0x8;
48
+ return v.toString(16);
49
+ });
50
+ }
package/package.json CHANGED
@@ -1,84 +1,92 @@
1
- {
2
- "name": "@wiotp/sdk",
3
- "version": "0.4.2",
4
- "description": "SDK for developing device, gateway, and application clients for IBM Watson IoT Platform",
5
- "main": "index.js",
6
- "files": [
7
- "src",
8
- "index.js",
9
- "package.json",
10
- "README.md",
11
- "LICENCE"
12
- ],
13
- "publishConfig": {
14
- "access": "public"
15
- },
16
- "dependencies": {
17
- "axios": "^0.19.0",
18
- "bluebird": "^3.5.4",
19
- "btoa": "^1.2.1",
20
- "concat-stream": "^2.0.0",
21
- "events": "^3.0.0",
22
- "form-data": "^2.3.3",
23
- "format": "^0.2.2",
24
- "loglevel": "^1.6.1",
25
- "mqtt": "^2.18.8",
26
- "tinycache": "^1.1.2",
27
- "uuid": "^3.3.2",
28
- "yaml": "^1.6.0"
29
- },
30
- "devDependencies": {
31
- "@babel/cli": "7.4.4",
32
- "@babel/core": "7.4.4",
33
- "@babel/preset-env": "7.4.4",
34
- "@babel/register": "7.4.4",
35
- "@cloudant/cloudant": "2.1.0",
36
- "@istanbuljs/nyc-config-babel": "^2.1.1",
37
- "babel-plugin-istanbul": "^5.1.4",
38
- "chai": "4.2.0",
39
- "chai-as-promised": "7.1.1",
40
- "coveralls": "3.0.3",
41
- "mocha": "6.1.4",
42
- "mocha-steps": "^1.3.0",
43
- "nyc": "14.1.1",
44
- "rimraf": "2.6.3"
45
- },
46
- "scripts": {
47
- "clean": "rimraf dist/*",
48
- "build:commonjs": "babel src --out-dir dist --modules umd",
49
- "build": "npm run clean && npm run build:commonjs",
50
- "test": "mocha --require @babel/register --require mocha-steps",
51
- "test-cov": "nyc --reporter=lcov --reporter=text-summary mocha --require mocha-steps",
52
- "test:watch": "mocha --require @babel/register --require mocha-steps --watch"
53
- },
54
- "author": {
55
- "name": "David Parker",
56
- "email": "parkerda@uk.ibm.com"
57
- },
58
- "contributors": [
59
- {
60
- "name": "Bryan Boyd",
61
- "email": "bboyd@us.ibm.com"
62
- }
63
- ],
64
- "repository": {
65
- "type": "git",
66
- "url": "git+https://github.com/ibm-watson-iot/iot-nodejs.git"
67
- },
68
- "license": "EPL-1.0",
69
- "nyc": {
70
- "require": [
71
- "@babel/register"
72
- ],
73
- "all": true,
74
- "include": [
75
- "src/**/*.js"
76
- ],
77
- "reporter": [
78
- "lcov",
79
- "text"
80
- ],
81
- "sourceMap": false,
82
- "instrument": false
83
- }
84
- }
1
+ {
2
+ "name": "@wiotp/sdk",
3
+ "version": "0.6.2",
4
+ "description": "SDK for developing device, gateway, and application clients for IBM Watson IoT Platform",
5
+ "main": "dist/index.js",
6
+ "files": [
7
+ "dist",
8
+ "src",
9
+ "package.json",
10
+ "README.md",
11
+ "LICENCE"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "dependencies": {
17
+ "axios": "^0.19.0",
18
+ "bluebird": "^3.5.4",
19
+ "browserify": "^16.5.0",
20
+ "btoa": "^1.2.1",
21
+ "concat-stream": "^2.0.0",
22
+ "events": "^3.0.0",
23
+ "form-data": "^2.3.3",
24
+ "format": "^0.2.2",
25
+ "loglevel": "^1.6.1",
26
+ "mqtt": "^3.0.0",
27
+ "tinycache": "^1.1.2",
28
+ "uuid": "^3.3.2",
29
+ "yaml": "^1.7.2"
30
+ },
31
+ "devDependencies": {
32
+ "@babel/cli": "7.7.7",
33
+ "@babel/core": "7.7.7",
34
+ "@babel/preset-env": "7.7.7",
35
+ "@babel/register": "7.7.7",
36
+ "@cloudant/cloudant": "^2.1.0",
37
+ "@istanbuljs/nyc-config-babel": "^3.0.0",
38
+ "babel-plugin-istanbul": "^6.0.0",
39
+ "chai": "^4.2.0",
40
+ "chai-as-promised": "^7.1.1",
41
+ "coveralls": "3.0.9",
42
+ "mocha": "6.2.2",
43
+ "mocha-steps": "^1.3.0",
44
+ "nyc": "15.0.0",
45
+ "rimraf": "2.6.3",
46
+ "terser": "^4.4.3"
47
+ },
48
+ "scripts": {
49
+ "clean": "rimraf dist/*",
50
+ "build": "npm run clean && npm run build:commonjs && npm run build:bundle && npm run build:min",
51
+ "build:commonjs": "babel src --out-dir dist",
52
+ "build:bundle": "browserify dist/index.js --outfile dist/bundled/wiotp-bundle.js",
53
+ "build:min": "terser dist/bundled/wiotp-bundle.js -o dist/bundled/wiotp-bundle.min.js",
54
+ "test": "mocha --require @babel/register --require mocha-steps",
55
+ "test-cov": "nyc --reporter=lcov --reporter=text-summary mocha --require mocha-steps",
56
+ "test:watch": "mocha --require @babel/register --require mocha-steps --watch"
57
+ },
58
+ "author": {
59
+ "name": "David Parker",
60
+ "email": "parkerda@uk.ibm.com"
61
+ },
62
+ "contributors": [
63
+ {
64
+ "name": "Tom Klapiscak",
65
+ "email": "klapitom@uk.ibm.com"
66
+ },
67
+ {
68
+ "name": "Bryan Boyd",
69
+ "email": "bboyd@us.ibm.com"
70
+ }
71
+ ],
72
+ "repository": {
73
+ "type": "git",
74
+ "url": "git+https://github.com/ibm-watson-iot/iot-nodejs.git"
75
+ },
76
+ "license": "EPL-1.0",
77
+ "nyc": {
78
+ "require": [
79
+ "@babel/register"
80
+ ],
81
+ "all": true,
82
+ "include": [
83
+ "src/**/*.js"
84
+ ],
85
+ "reporter": [
86
+ "lcov",
87
+ "text"
88
+ ],
89
+ "sourceMap": false,
90
+ "instrument": true
91
+ }
92
+ }
package/src/BaseClient.js CHANGED
@@ -1,215 +1,215 @@
1
- /**
2
- *****************************************************************************
3
- Copyright (c) 2014, 2019 IBM Corporation and other Contributors.
4
- All rights reserved. This program and the accompanying materials
5
- are made available under the terms of the Eclipse Public License v1.0
6
- which accompanies this distribution, and is available at
7
- http://www.eclipse.org/legal/epl-v10.html
8
- *****************************************************************************
9
- *
10
- */
11
- import events from 'events';
12
- import mqtt from 'mqtt';
13
- import log from 'loglevel';
14
-
15
- import TinyCache from 'tinycache';
16
-
17
- const uuidv4 = require('uuid/v4');
18
-
19
- export default class BaseClient extends events.EventEmitter {
20
- constructor(config){
21
- super();
22
- this.log = log;
23
- this.log.setDefaultLevel(config.options.logLevel);
24
-
25
- this.config = config;
26
-
27
- this.reconnectLog = 0;
28
- this.mqtt = null;
29
-
30
- this.lostConnectionLog = new TinyCache();
31
-
32
- }
33
-
34
-
35
- isConnected() {
36
- if (this.mqtt == null) {
37
- return false;
38
- }
39
- return this.mqtt.connected;
40
- }
41
-
42
-
43
- connect(){
44
- if(this.mqtt != null) {
45
- this.log.info("[BaseClient:connect] Reconnecting to " + this.config.getMqttHost() + " as " + this.config.getClientId());
46
- this.mqtt.reconnect();
47
- return;
48
- }
49
-
50
- this.log.info("[BaseClient:connect] Connecting to " + this.config.getMqttHost() + " as " + this.config.getClientId());
51
-
52
- this.mqtt = mqtt.connect(this.config.getMqttHost(), this.config.getMqttConfig());
53
-
54
- /* Events coming from mqtt
55
- * Event 'connect' - Emitted on successful (re)connection (i.e. connack rc=0).
56
- * Event 'reconnect' - Emitted when a reconnect starts.
57
- * Event 'close' - Emitted after a disconnection.
58
- * Event 'offline' - Emitted when the client goes offline.
59
- * Event 'error' - Emitted when the client cannot connect (i.e. connack rc != 0) or when a parsing error occurs.
60
- * Event 'end' - Emitted when mqtt.Client#end() is called. If a callback was passed to mqtt.Client#end(), this event is emitted once the callback returns.
61
- * Event 'message' - Emitted when the client receives a publish packet
62
- * Event 'packetsend' - Emitted when the client sends any packet. This includes .published() packets as well as packets used by MQTT for managing subscriptions and connections
63
- * Event 'packetreceive' - Emitted when the client receives any packet. This includes packets from subscribed topics as well as packets used by MQTT for managing subscriptions and connections
64
- */
65
-
66
- this.mqtt.on('connect', () => {
67
- this.log.info("[BaseClient:onConnect] MQTT client is connected.");
68
- this.emit('connect');
69
-
70
- // less than 3 connect attempts you get put to a connect delay of 1 second
71
- // after 3 connect attempts you get put to a connect delay of 2 seconds (3 seconds elapsed - 3 attempts @ 1 second intervals)
72
- // after 6 connect attempts you get put to a connect delay of 5 seconds (3 + 6 seconds elapsed - 3 attempts @ 2 second intervals)
73
- // after 9 connect attempts you get put to a connect delay of 20 seconds (3 + 6 + 15 seconds elapsed - 3 attempts @ 5 second intervals)
74
- let connectionLostCount = this.lostConnectionLog.size;
75
-
76
- // Default is 1 second reconnect period
77
- let reconnectPeriod = 1000;
78
- if (connectionLostCount >= 9) {
79
- reconnectPeriod = 20000;
80
-
81
- // Log this and raise the error EVERY time we reconnect under these conditions.
82
- this.log.warn("[BaseClient:onOffline] This client is likely suffering from clientId stealing (where two connections try to use the same client Id).");
83
- this.emit("error", "Exceeded 9 connection losses in a 5 minute period. Check for clientId conflict with another connection.")
84
- }
85
- else if (connectionLostCount >= 6) {
86
- reconnectPeriod = 5000;
87
- }
88
- else if (connectionLostCount >= 3) {
89
- reconnectPeriod = 2000;
90
- }
91
-
92
- if (reconnectPeriod != this.mqtt.options.reconnectPeriod) {
93
- this.log.info("[BaseClient:onOffline] Client has lost connection " + connectionLostCount + " times during the last 5 minutes, reconnect delay adjusted to " + reconnectPeriod + " ms");
94
- this.mqtt.options.reconnectPeriod = reconnectPeriod;
95
- }
96
-
97
- });
98
-
99
- this.mqtt.on('reconnect', () => {
100
- this.log.info("[BaseClient:onReconnect] MQTT client is reconnecting.");
101
- // this.log.debug("[BaseClient:onReconnect] Resubscribe topics:");
102
- // this.log.debug(this.mqtt._resubscribeTopics);
103
- this.emit('reconnect');
104
- });
105
-
106
- this.mqtt.on('close', () => {
107
- this.log.info("[BaseClient:onClose] MQTT client connection was closed.");
108
- this.emit('close');
109
- });
110
-
111
- this.mqtt.on('offline', () => {
112
- let newId = uuidv4();
113
- this.log.info("[BaseClient:onOffline] MQTT client connection is offline. [" + newId + "]");
114
- this.emit('offline');
115
- // Record the disconnect event for 5 minutes
116
- this.lostConnectionLog.put( newId, '1', 300000 );
117
-
118
- let connectionLostCount = this.lostConnectionLog.size;
119
- this.log.info("[BaseClient:onOffline] Connection losses in the last 5 minutes: " + connectionLostCount);
120
-
121
- });
122
-
123
- this.mqtt.on('error', (error) => {
124
- this.log.error("[BaseClient:onError] " + error);
125
-
126
- let errorMsg = '' + error;
127
- if (errorMsg.indexOf('Not authorized') > -1) {
128
- this.log.error("[BaseClient:onError] One or more configuration parameters are wrong. Modify the configuration before trying to reconnect.");
129
- this.mqtt.end(false, () => {
130
- this.log.info("[BaseClient:onError] Closed the MQTT connection due to client misconfiguration");
131
- });
132
- }
133
- this.emit('error', error);
134
- });
135
- }
136
-
137
-
138
- disconnect(){
139
- if(this.mqtt == null) {
140
- this.log.info("[BaseClient:disconnect] Client was never connected");
141
- return;
142
- }
143
-
144
- this.mqtt.end(false, () => {
145
- this.log.info("[BaseClient:disconnect] Closed the MQTT connection due to disconnect() call");
146
- });
147
- }
148
-
149
-
150
- _subscribe(topic, QoS, callback) {
151
- if (this.mqtt == null) {
152
- this.emit('error', "[BaseClient:_subscribe] MQTT Client is not initialized - call connect() first");
153
- return;
154
- }
155
- if (!this.mqtt.connected) {
156
- this.emit('error', "[BaseClient:_subscribe] MQTT Client is not connected - call connect() first");
157
- return;
158
- }
159
-
160
- QoS = QoS || 0;
161
- callback = callback || function (err, granted) {
162
- if (err == null) {
163
- for (var index in granted) {
164
- let grant = granted[index];
165
- this.log.debug("[BaseClient:_subscribe] Subscribed to " + grant.topic + " at QoS " + grant.qos);
166
- }
167
- } else {
168
- this.log.error("[BaseClient:_subscribe] " + err);
169
- this.emit("error", err);
170
- }
171
- }.bind(this);
172
-
173
- this.log.debug("[BaseClient:_subscribe] Subscribing to topic " + topic + " with QoS " + QoS);
174
- this.mqtt.subscribe(topic, { qos: parseInt(QoS) }, callback);
175
- }
176
-
177
-
178
- _unsubscribe(topic, callback) {
179
- if (this.mqtt == null) {
180
- this.emit('error', "[BaseClient:_unsubscribe] MQTT Client is not initialized - call connect() first");
181
- return;
182
- }
183
- if (!this.mqtt.connected) {
184
- this.emit('error', "[BaseClient:_unsubscribe] MQTT Client is not connected - call connect() first");
185
- return;
186
- }
187
-
188
- callback = callback || function (err) {
189
- if (err == null) {
190
- this.log.debug("[BaseClient:_unsubscribe] Unsubscribed from: " + topic);
191
- } else {
192
- this.log.error("[BaseClient:_unsubscribe] " + err);
193
- this.emit("error", err);
194
- }
195
- }.bind(this);
196
-
197
- this.log.debug("[BaseClient:_unsubscribe] Unsubscribe: " + topic);
198
- this.mqtt.unsubscribe(topic, callback);
199
- }
200
-
201
-
202
- _publish(topic, msg, QoS, callback) {
203
- QoS = QoS || 0;
204
-
205
- if ((typeof msg === 'object' || typeof msg === 'boolean' || typeof msg === 'number') && !Buffer.isBuffer(msg)) {
206
- // mqtt library does not support sending JSON/Boolean/Number data. So stringifying it.
207
- // All JSON object, array will be encoded.
208
- msg = JSON.stringify(msg);
209
- }
210
-
211
- this.log.debug("[BaseClient:_publish] Publish: " + topic + ", " + msg + ", QoS : " + QoS);
212
- this.mqtt.publish(topic, msg, { qos: parseInt(QoS) }, callback);
213
- }
214
-
215
- }
1
+ /**
2
+ *****************************************************************************
3
+ Copyright (c) 2014, 2019 IBM Corporation and other Contributors.
4
+ All rights reserved. This program and the accompanying materials
5
+ are made available under the terms of the Eclipse Public License v1.0
6
+ which accompanies this distribution, and is available at
7
+ http://www.eclipse.org/legal/epl-v10.html
8
+ *****************************************************************************
9
+ *
10
+ */
11
+ import events from 'events';
12
+ import mqtt from 'mqtt';
13
+ import log from 'loglevel';
14
+
15
+ import TinyCache from 'tinycache';
16
+
17
+ const uuidv4 = require('uuid/v4');
18
+
19
+ export default class BaseClient extends events.EventEmitter {
20
+ constructor(config){
21
+ super();
22
+ this.log = log;
23
+ this.log.setDefaultLevel(config.options.logLevel);
24
+
25
+ this.config = config;
26
+
27
+ this.reconnectLog = 0;
28
+ this.mqtt = null;
29
+
30
+ this.lostConnectionLog = new TinyCache();
31
+
32
+ }
33
+
34
+
35
+ isConnected() {
36
+ if (this.mqtt == null) {
37
+ return false;
38
+ }
39
+ return this.mqtt.connected;
40
+ }
41
+
42
+
43
+ connect(){
44
+ if(this.mqtt != null) {
45
+ this.log.info("[BaseClient:connect] Reconnecting to " + this.config.getMqttHost() + " as " + this.config.getClientId());
46
+ this.mqtt.reconnect();
47
+ return;
48
+ }
49
+
50
+ this.log.info("[BaseClient:connect] Connecting to " + this.config.getMqttHost() + " as " + this.config.getClientId());
51
+
52
+ this.mqtt = mqtt.connect(this.config.getMqttHost(), this.config.getMqttConfig());
53
+
54
+ /* Events coming from mqtt
55
+ * Event 'connect' - Emitted on successful (re)connection (i.e. connack rc=0).
56
+ * Event 'reconnect' - Emitted when a reconnect starts.
57
+ * Event 'close' - Emitted after a disconnection.
58
+ * Event 'offline' - Emitted when the client goes offline.
59
+ * Event 'error' - Emitted when the client cannot connect (i.e. connack rc != 0) or when a parsing error occurs.
60
+ * Event 'end' - Emitted when mqtt.Client#end() is called. If a callback was passed to mqtt.Client#end(), this event is emitted once the callback returns.
61
+ * Event 'message' - Emitted when the client receives a publish packet
62
+ * Event 'packetsend' - Emitted when the client sends any packet. This includes .published() packets as well as packets used by MQTT for managing subscriptions and connections
63
+ * Event 'packetreceive' - Emitted when the client receives any packet. This includes packets from subscribed topics as well as packets used by MQTT for managing subscriptions and connections
64
+ */
65
+
66
+ this.mqtt.on('connect', () => {
67
+ this.log.info("[BaseClient:onConnect] MQTT client is connected.");
68
+ this.emit('connect');
69
+
70
+ // less than 3 connect attempts you get put to a connect delay of 1 second
71
+ // after 3 connect attempts you get put to a connect delay of 2 seconds (3 seconds elapsed - 3 attempts @ 1 second intervals)
72
+ // after 6 connect attempts you get put to a connect delay of 5 seconds (3 + 6 seconds elapsed - 3 attempts @ 2 second intervals)
73
+ // after 9 connect attempts you get put to a connect delay of 20 seconds (3 + 6 + 15 seconds elapsed - 3 attempts @ 5 second intervals)
74
+ let connectionLostCount = this.lostConnectionLog.size;
75
+
76
+ // Default is 1 second reconnect period
77
+ let reconnectPeriod = 1000;
78
+ if (connectionLostCount >= 9) {
79
+ reconnectPeriod = 20000;
80
+
81
+ // Log this and raise the error EVERY time we reconnect under these conditions.
82
+ this.log.warn("[BaseClient:onOffline] This client is likely suffering from clientId stealing (where two connections try to use the same client Id).");
83
+ this.emit("error", "Exceeded 9 connection losses in a 5 minute period. Check for clientId conflict with another connection.")
84
+ }
85
+ else if (connectionLostCount >= 6) {
86
+ reconnectPeriod = 5000;
87
+ }
88
+ else if (connectionLostCount >= 3) {
89
+ reconnectPeriod = 2000;
90
+ }
91
+
92
+ if (reconnectPeriod != this.mqtt.options.reconnectPeriod) {
93
+ this.log.info("[BaseClient:onOffline] Client has lost connection " + connectionLostCount + " times during the last 5 minutes, reconnect delay adjusted to " + reconnectPeriod + " ms");
94
+ this.mqtt.options.reconnectPeriod = reconnectPeriod;
95
+ }
96
+
97
+ });
98
+
99
+ this.mqtt.on('reconnect', () => {
100
+ this.log.info("[BaseClient:onReconnect] MQTT client is reconnecting.");
101
+ // this.log.debug("[BaseClient:onReconnect] Resubscribe topics:");
102
+ // this.log.debug(this.mqtt._resubscribeTopics);
103
+ this.emit('reconnect');
104
+ });
105
+
106
+ this.mqtt.on('close', () => {
107
+ this.log.info("[BaseClient:onClose] MQTT client connection was closed.");
108
+ this.emit('close');
109
+ });
110
+
111
+ this.mqtt.on('offline', () => {
112
+ let newId = uuidv4();
113
+ this.log.info("[BaseClient:onOffline] MQTT client connection is offline. [" + newId + "]");
114
+ this.emit('offline');
115
+ // Record the disconnect event for 5 minutes
116
+ this.lostConnectionLog.put( newId, '1', 300000 );
117
+
118
+ let connectionLostCount = this.lostConnectionLog.size;
119
+ this.log.info("[BaseClient:onOffline] Connection losses in the last 5 minutes: " + connectionLostCount);
120
+
121
+ });
122
+
123
+ this.mqtt.on('error', (error) => {
124
+ this.log.error("[BaseClient:onError] " + error);
125
+
126
+ let errorMsg = '' + error;
127
+ if (errorMsg.indexOf('Not authorized') > -1) {
128
+ this.log.error("[BaseClient:onError] One or more configuration parameters are wrong. Modify the configuration before trying to reconnect.");
129
+ this.mqtt.end(false, () => {
130
+ this.log.info("[BaseClient:onError] Closed the MQTT connection due to client misconfiguration");
131
+ });
132
+ }
133
+ this.emit('error', error);
134
+ });
135
+ }
136
+
137
+
138
+ disconnect(){
139
+ if(this.mqtt == null) {
140
+ this.log.info("[BaseClient:disconnect] Client was never connected");
141
+ return;
142
+ }
143
+
144
+ this.mqtt.end(false, () => {
145
+ this.log.info("[BaseClient:disconnect] Closed the MQTT connection due to disconnect() call");
146
+ });
147
+ }
148
+
149
+
150
+ _subscribe(topic, QoS, callback) {
151
+ if (this.mqtt == null) {
152
+ this.emit('error', "[BaseClient:_subscribe] MQTT Client is not initialized - call connect() first");
153
+ return;
154
+ }
155
+ if (!this.mqtt.connected) {
156
+ this.emit('error', "[BaseClient:_subscribe] MQTT Client is not connected - call connect() first");
157
+ return;
158
+ }
159
+
160
+ QoS = QoS || 0;
161
+ callback = callback || function (err, granted) {
162
+ if (err == null) {
163
+ for (var index in granted) {
164
+ let grant = granted[index];
165
+ this.log.debug("[BaseClient:_subscribe] Subscribed to " + grant.topic + " at QoS " + grant.qos);
166
+ }
167
+ } else {
168
+ this.log.error("[BaseClient:_subscribe] " + err);
169
+ this.emit("error", err);
170
+ }
171
+ }.bind(this);
172
+
173
+ this.log.debug("[BaseClient:_subscribe] Subscribing to topic " + topic + " with QoS " + QoS);
174
+ this.mqtt.subscribe(topic, { qos: parseInt(QoS) }, callback);
175
+ }
176
+
177
+
178
+ _unsubscribe(topic, callback) {
179
+ if (this.mqtt == null) {
180
+ this.emit('error', "[BaseClient:_unsubscribe] MQTT Client is not initialized - call connect() first");
181
+ return;
182
+ }
183
+ if (!this.mqtt.connected) {
184
+ this.emit('error', "[BaseClient:_unsubscribe] MQTT Client is not connected - call connect() first");
185
+ return;
186
+ }
187
+
188
+ callback = callback || function (err) {
189
+ if (err == null) {
190
+ this.log.debug("[BaseClient:_unsubscribe] Unsubscribed from: " + topic);
191
+ } else {
192
+ this.log.error("[BaseClient:_unsubscribe] " + err);
193
+ this.emit("error", err);
194
+ }
195
+ }.bind(this);
196
+
197
+ this.log.debug("[BaseClient:_unsubscribe] Unsubscribe: " + topic);
198
+ this.mqtt.unsubscribe(topic, callback);
199
+ }
200
+
201
+
202
+ _publish(topic, msg, QoS, callback) {
203
+ QoS = QoS || 0;
204
+
205
+ if ((typeof msg === 'object' || typeof msg === 'boolean' || typeof msg === 'number') && !Buffer.isBuffer(msg)) {
206
+ // mqtt library does not support sending JSON/Boolean/Number data. So stringifying it.
207
+ // All JSON object, array will be encoded.
208
+ msg = JSON.stringify(msg);
209
+ }
210
+
211
+ this.log.debug("[BaseClient:_publish] Publish: " + topic + ", " + msg + ", QoS : " + QoS);
212
+ this.mqtt.publish(topic, msg, { qos: parseInt(QoS) }, callback);
213
+ }
214
+
215
+ }