iobroker.zigbee2mqtt 3.0.10 → 3.0.13

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/lib/rgb.js CHANGED
@@ -1,4 +1,4 @@
1
- /* eslint-disable no-prototype-builtins */
1
+
2
2
  /*
3
3
  With these functions you can convert the CIE color space to the RGB color space and vice versa.
4
4
 
@@ -44,7 +44,11 @@ const colors = require('./colors.js');
44
44
 
45
45
  /**
46
46
  * Converts CIE color space to RGB color space
47
- * @return {Array} Array that contains the color values for red, green and blue
47
+ *
48
+ * @param x
49
+ * @param y
50
+ * @param brightness
51
+ * @returns {Array} Array that contains the color values for red, green and blue
48
52
  */
49
53
  function cie_to_rgb(x, y, brightness) {
50
54
  //Set to maximum brightness if no custom value was given (Not the slick ECMAScript 6 way for compatibility reasons)
@@ -54,17 +58,17 @@ function cie_to_rgb(x, y, brightness) {
54
58
 
55
59
  const z = 1.0 - x - y;
56
60
  const Y = (brightness / 254).toFixed(2);
57
- // @ts-ignore
61
+
58
62
  const X = (Y / y) * x;
59
- // @ts-ignore
63
+
60
64
  const Z = (Y / y) * z;
61
65
 
62
66
  //Convert to RGB using Wide RGB D65 conversion
63
- // @ts-ignore
67
+
64
68
  let red = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
65
- // @ts-ignore
69
+
66
70
  let green = -X * 0.707196 + Y * 1.655397 + Z * 0.036152;
67
- // @ts-ignore
71
+
68
72
  let blue = X * 0.051713 - Y * 0.121364 + Z * 1.01153;
69
73
 
70
74
  //If red, green or blue is larger than 1.0 set it back to the maximum of 1.0
@@ -109,10 +113,11 @@ function cie_to_rgb(x, y, brightness) {
109
113
 
110
114
  /**
111
115
  * Converts RGB color space to CIE color space
112
- * @param {Number} red
113
- * @param {Number} green
114
- * @param {Number} blue
115
- * @return {Array} Array that contains the CIE color values for x and y
116
+ *
117
+ * @param {number} red
118
+ * @param {number} green
119
+ * @param {number} blue
120
+ * @returns {Array} Array that contains the CIE color values for x and y
116
121
  */
117
122
  function rgb_to_cie(red, green, blue) {
118
123
  // Apply a gamma correction to the RGB values, which makes the color more vivid and more the like the color displayed on the screen of your device
@@ -129,21 +134,27 @@ function rgb_to_cie(red, green, blue) {
129
134
  let x = (X / (X + Y + Z)).toFixed(4);
130
135
  let y = (Y / (X + Y + Z)).toFixed(4);
131
136
 
132
- // @ts-ignore
137
+
133
138
  if (isNaN(x)) {
134
- // @ts-ignore
139
+
135
140
  x = 0;
136
141
  }
137
142
 
138
- // @ts-ignore
143
+
139
144
  if (isNaN(y)) {
140
- // @ts-ignore
145
+
141
146
  y = 0;
142
147
  }
143
148
 
144
149
  return [x, y];
145
150
  }
146
151
 
152
+ /**
153
+ *
154
+ * @param h
155
+ * @param s
156
+ * @param v
157
+ */
147
158
  function hsvToRGB(h, s, v) {
148
159
  h = (h % 360) / 360;
149
160
  s = s / 100;
@@ -187,6 +198,13 @@ function hsvToRGB(h, s, v) {
187
198
  };
188
199
  }
189
200
 
201
+ /**
202
+ *
203
+ * @param r
204
+ * @param g
205
+ * @param b
206
+ * @param numeric
207
+ */
190
208
  function rgbToHSV(r, g, b, numeric) {
191
209
  if (arguments.length === 1) {
192
210
  (g = r.g), (b = r.b), (r = r.r);
@@ -215,21 +233,26 @@ function rgbToHSV(r, g, b, numeric) {
215
233
  h /= 6 * d;
216
234
  break;
217
235
  }
218
- if (numeric)
219
- return {
220
- // @ts-ignore
236
+ if (numeric) {
237
+ return {
238
+
221
239
  h: Math.round(h * 360),
222
240
  s: Math.round(s * 100),
223
241
  v: Math.round(v * 100),
224
242
  };
243
+ }
225
244
  return {
226
- // @ts-ignore
245
+
227
246
  h: (h * 360).toFixed(3),
228
247
  s: (s * 100).toFixed(3),
229
248
  v: (v * 100).toFixed(3),
230
249
  };
231
250
  }
232
251
 
252
+ /**
253
+ *
254
+ * @param value
255
+ */
233
256
  function colorArrayFromString(value) {
234
257
  if (typeof value === 'string') {
235
258
  const rv = [];
@@ -241,6 +264,10 @@ function colorArrayFromString(value) {
241
264
  return [{ r: 0, g: 128, b: 255 }];
242
265
  }
243
266
 
267
+ /**
268
+ *
269
+ * @param payload
270
+ */
244
271
  function colorStringFromRGBArray(payload) {
245
272
  const rv = [];
246
273
  payload.forEach((element) => {
@@ -249,6 +276,12 @@ function colorStringFromRGBArray(payload) {
249
276
  return rv.toString();
250
277
  }
251
278
 
279
+ /**
280
+ *
281
+ * @param h
282
+ * @param s
283
+ * @param v
284
+ */
252
285
  function hsv_to_cie(h, s, v) {
253
286
  const rgb = hsvToRGB(h, s, v);
254
287
  return rgb_to_cie(rgb.r, rgb.g, rgb.b);
@@ -256,20 +289,35 @@ function hsv_to_cie(h, s, v) {
256
289
 
257
290
  function rgb_to_rgbstring(element) {
258
291
  let col = '#';
259
- if (element && element.hasOwnProperty('r')) col = col + element.r.toString(16).padStart(2, '0');
260
- else col = col + '00';
261
- if (element && element.hasOwnProperty('g')) col = col + element.g.toString(16).padStart(2, '0');
262
- else col = col + '00';
263
- if (element && element.hasOwnProperty('b')) col = col + element.b.toString(16).padStart(2, '0');
264
- else col = col + '00';
292
+ if (element && element.hasOwnProperty('r')) {
293
+ col = col + element.r.toString(16).padStart(2, '0');
294
+ } else {
295
+ col = `${col }00`;
296
+ }
297
+ if (element && element.hasOwnProperty('g')) {
298
+ col = col + element.g.toString(16).padStart(2, '0');
299
+ } else {
300
+ col = `${col }00`;
301
+ }
302
+ if (element && element.hasOwnProperty('b')) {
303
+ col = col + element.b.toString(16).padStart(2, '0');
304
+ } else {
305
+ col = `${col }00`;
306
+ }
265
307
  return col;
266
308
  }
267
309
 
310
+ /**
311
+ *
312
+ * @param h
313
+ * @param s
314
+ * @param b
315
+ */
268
316
  function hsbToRGB(h, s, b) {
269
317
  const br = Math.round(b * 2.55);
270
318
  if (s == 0) {
271
319
  return [br, br, br];
272
- } else {
320
+ }
273
321
  const hue = h % 360;
274
322
  const f = hue % 60;
275
323
  const p = Math.round(b * (100 - s) * 0.0255);
@@ -289,10 +337,16 @@ function hsbToRGB(h, s, b) {
289
337
  case 5:
290
338
  return [br, p, q];
291
339
  }
292
- }
340
+
293
341
  return false;
294
342
  }
295
343
 
344
+ /**
345
+ *
346
+ * @param h
347
+ * @param s
348
+ * @param v
349
+ */
296
350
  function hsvToRGBString(h, s, v) {
297
351
  return rgb_to_rgbstring(hsvToRGB(h, s, v));
298
352
  }
@@ -2,7 +2,18 @@ const utils = require('./utils');
2
2
  const incStatsQueue = [];
3
3
  const timeOutCache = {};
4
4
 
5
+ /**
6
+ *
7
+ */
5
8
  class StatesController {
9
+ /**
10
+ *
11
+ * @param adapter
12
+ * @param deviceCache
13
+ * @param groupCache
14
+ * @param logCustomizations
15
+ * @param createCache
16
+ */
6
17
  constructor(adapter, deviceCache, groupCache, logCustomizations, createCache) {
7
18
  this.adapter = adapter;
8
19
  this.groupCache = groupCache;
@@ -11,6 +22,10 @@ class StatesController {
11
22
  this.createCache = createCache;
12
23
  }
13
24
 
25
+ /**
26
+ *
27
+ * @param messageObj
28
+ */
14
29
  processDeviceMessage(messageObj) {
15
30
  // Is payload present?
16
31
  if (messageObj.payload == '') {
@@ -30,6 +45,11 @@ class StatesController {
30
45
  }
31
46
  }
32
47
 
48
+ /**
49
+ *
50
+ * @param messageObj
51
+ * @param device
52
+ */
33
53
  async setDeviceStateSafely(messageObj, device) {
34
54
  if (this.logCustomizations.debugDevices.includes(device.ieee_address)) {
35
55
  this.adapter.log.warn(`--->>> fromZ2M -> ${device.ieee_address} states: ${JSON.stringify(messageObj)}`);
@@ -103,19 +123,15 @@ class StatesController {
103
123
  // Is an action
104
124
  if (state.prop && state.prop == 'action') {
105
125
  actionStates.push(state);
106
- }
107
- // Is not an action
126
+ } else if (
127
+ // Is not an action
108
128
  // check if its a motion sensor (occupancy state) and if configuration is set to update state every time
109
129
  // if yes, use setStateSafelyAsync instead of setStateChangedSafelyAsync
110
- else if (
111
- this.adapter.config.allwaysUpdateOccupancyState === true &&
112
- state.id === 'occupancy' &&
113
- value === true
130
+ this.adapter.config.allwaysUpdateOccupancyState === true && state.id === 'occupancy' && value === true
114
131
  ) {
115
132
  await this.setStateSafelyAsync(stateName, value);
116
- }
117
- // end section for motion sensor update
118
- else {
133
+ } else {
134
+ // end section for motion sensor update
119
135
  if (state.getter) {
120
136
  await this.setStateChangedSafelyAsync(stateName, state.getter(messageObj.payload));
121
137
  } else {
@@ -134,11 +150,17 @@ class StatesController {
134
150
 
135
151
  try {
136
152
  if (state.isEvent && state.isEvent == true) {
153
+ const gettr = state.getter(messageObj.payload);
137
154
  if (state.type == 'boolean') {
138
- await this.setStateWithTimeoutAsync(stateName, state.getter(messageObj.payload), 450);
155
+ await this.setStateWithTimeoutAsync(stateName, gettr, 450);
139
156
  } else {
140
- await this.setStateSafelyAsync(stateName, state.getter(messageObj.payload));
157
+ await this.setStateSafelyAsync(stateName, gettr);
141
158
  }
159
+ // publish the action into action dp
160
+ if (state.prop && state.prop == 'action') {
161
+ await this.setStateSafelyAsync(`${device.ieee_address}.action`, messageObj.payload.action);
162
+ }
163
+
142
164
  } else {
143
165
  await this.setStateChangedSafelyAsync(stateName, state.getter(messageObj.payload));
144
166
  }
@@ -149,6 +171,11 @@ class StatesController {
149
171
  }
150
172
  }
151
173
 
174
+ /**
175
+ *
176
+ * @param stateName
177
+ * @param value
178
+ */
152
179
  async setStateSafelyAsync(stateName, value) {
153
180
  if (value === undefined || value === null) {
154
181
  return;
@@ -156,6 +183,11 @@ class StatesController {
156
183
  await this.adapter.setStateAsync(stateName, value, true);
157
184
  }
158
185
 
186
+ /**
187
+ *
188
+ * @param stateName
189
+ * @param value
190
+ */
159
191
  async setStateChangedSafelyAsync(stateName, value) {
160
192
  if (value === undefined || value === null) {
161
193
  return;
@@ -163,6 +195,12 @@ class StatesController {
163
195
  await this.adapter.setStateChangedAsync(stateName, value, true);
164
196
  }
165
197
 
198
+ /**
199
+ *
200
+ * @param stateName
201
+ * @param value
202
+ * @param timeout
203
+ */
166
204
  async setStateWithTimeoutAsync(stateName, value, timeout) {
167
205
  if (value === undefined || value === null) {
168
206
  return;
@@ -174,9 +212,13 @@ class StatesController {
174
212
  }
175
213
  timeOutCache[stateName] = setTimeout(() => {
176
214
  this.adapter.setStateAsync(stateName, !value, true);
215
+
177
216
  }, timeout);
178
217
  }
179
218
 
219
+ /**
220
+ *
221
+ */
180
222
  processQueue() {
181
223
  const oldIncStatsQueue = [];
182
224
  utils.moveArray(incStatsQueue, oldIncStatsQueue);
@@ -185,6 +227,9 @@ class StatesController {
185
227
  }
186
228
  }
187
229
 
230
+ /**
231
+ *
232
+ */
188
233
  async subscribeWritableStates() {
189
234
  await this.adapter.unsubscribeObjectsAsync('*');
190
235
  for (const device of this.groupCache.concat(this.deviceCache)) {
@@ -199,6 +244,9 @@ class StatesController {
199
244
  this.adapter.subscribeStates('info.coordinator_check');
200
245
  }
201
246
 
247
+ /**
248
+ *
249
+ */
202
250
  async setAllAvailableToFalse() {
203
251
  const availableStates = await this.adapter.getStatesAsync('*.available');
204
252
  for (const availableState in availableStates) {
@@ -206,6 +254,9 @@ class StatesController {
206
254
  }
207
255
  }
208
256
 
257
+ /**
258
+ *
259
+ */
209
260
  async allTimerClear() {
210
261
  for (const timer in timeOutCache) {
211
262
  clearTimeout(timeOutCache[timer]);
package/lib/utils.js CHANGED
@@ -1,5 +1,7 @@
1
1
  /**
2
2
  * Converts a bulb level of range [0...254] to an adapter level of range [0...100]
3
+ *
4
+ * @param bulbLevel
3
5
  */
4
6
  function bulbLevelToAdapterLevel(bulbLevel) {
5
7
  // Convert from bulb levels [0...254] to adapter levels [0...100]:
@@ -19,14 +21,16 @@ function bulbLevelToAdapterLevel(bulbLevel) {
19
21
  if (bulbLevel >= 2) {
20
22
  // Perform linear mapping of range [2...254] to [1...100]
21
23
  return Math.round(((bulbLevel - 2) * 99) / 252) + 1;
22
- } else {
24
+ }
23
25
  // The bulb is considered off. Even a bulb level of "1" is considered as off.
24
26
  return 0;
25
- } // else
27
+ // else
26
28
  }
27
29
 
28
30
  /**
29
31
  * Converts an adapter level of range [0...100] to a bulb level of range [0...254]
32
+ *
33
+ * @param adapterLevel
30
34
  */
31
35
  function adapterLevelToBulbLevel(adapterLevel) {
32
36
  // Convert from adapter levels [0...100] to bulb levels [0...254].
@@ -35,13 +39,17 @@ function adapterLevelToBulbLevel(adapterLevel) {
35
39
  if (adapterLevel) {
36
40
  // Perform linear mapping of range [1...100] to [2...254]
37
41
  return Math.round(((adapterLevel - 1) * 252) / 99) + 2;
38
- } else {
42
+ }
39
43
  // Switch the bulb off. Some bulbs need "0" (IKEA), others "1" (HUE), and according to the
40
44
  // ZigBee docs "1" is the "minimum possible level"... we choose "0" here which seems to work.
41
45
  return 0;
42
- } // else
46
+ // else
43
47
  }
44
48
 
49
+ /**
50
+ *
51
+ * @param ba
52
+ */
45
53
  function bytesArrayToWordArray(ba) {
46
54
  const wa = [];
47
55
  for (let i = 0; i < ba.length; i++) {
@@ -52,6 +60,10 @@ function bytesArrayToWordArray(ba) {
52
60
 
53
61
  // If the value is greater than 1000, kelvin is assumed.
54
62
  // If smaller, it is assumed to be mired.
63
+ /**
64
+ *
65
+ * @param t
66
+ */
55
67
  function toMired(t) {
56
68
  let miredValue = t;
57
69
  if (t > 1000) {
@@ -60,12 +72,19 @@ function toMired(t) {
60
72
  return miredValue;
61
73
  }
62
74
 
75
+ /**
76
+ *
77
+ * @param t
78
+ */
63
79
  function miredKelvinConversion(t) {
64
80
  return Math.round(1000000 / t);
65
81
  }
66
82
 
67
83
  /**
68
84
  * Converts a decimal number to a hex string with zero-padding
85
+ *
86
+ * @param decimal
87
+ * @param padding
69
88
  */
70
89
  function decimalToHex(decimal, padding) {
71
90
  let hex = Number(decimal).toString(16);
@@ -78,32 +97,60 @@ function decimalToHex(decimal, padding) {
78
97
  return hex;
79
98
  }
80
99
 
100
+ /**
101
+ *
102
+ * @param adapterDevId
103
+ */
81
104
  function getZbId(adapterDevId) {
82
105
  const idx = adapterDevId.indexOf('group');
83
- if (idx > 0) return adapterDevId.substr(idx + 6);
84
- return '0x' + adapterDevId.split('.')[2];
106
+ if (idx > 0) {
107
+ return adapterDevId.substr(idx + 6);
108
+ }
109
+ return `0x${ adapterDevId.split('.')[2]}`;
85
110
  }
86
111
 
112
+ /**
113
+ *
114
+ * @param adapter
115
+ * @param id
116
+ */
87
117
  function getAdId(adapter, id) {
88
- return adapter.namespace + '.' + id.split('.')[2]; // iobroker device id
118
+ return `${adapter.namespace }.${ id.split('.')[2]}`; // iobroker device id
89
119
  }
90
120
 
121
+ /**
122
+ *
123
+ * @param array
124
+ */
91
125
  function clearArray(array) {
92
126
  while (array.length > 0) {
93
127
  array.pop();
94
128
  }
95
129
  }
96
130
 
131
+ /**
132
+ *
133
+ * @param source
134
+ * @param target
135
+ */
97
136
  function moveArray(source, target) {
98
137
  while (source.length > 0) {
99
138
  target.push(source.shift());
100
139
  }
101
140
  }
102
141
 
142
+ /**
143
+ *
144
+ * @param item
145
+ */
103
146
  function isObject(item) {
104
147
  return typeof item === 'object' && !Array.isArray(item) && item !== null;
105
148
  }
106
149
 
150
+ /**
151
+ *
152
+ * @param item
153
+ */
107
154
  function isJson(item) {
108
155
  let value = typeof item !== 'string' ? JSON.stringify(item) : item;
109
156
  try {
@@ -6,11 +6,21 @@ let ping;
6
6
  let pingTimeout;
7
7
  let autoRestartTimeout;
8
8
 
9
+ /**
10
+ *
11
+ */
9
12
  class WebsocketController {
13
+ /**
14
+ *
15
+ * @param adapter
16
+ */
10
17
  constructor(adapter) {
11
18
  this.adapter = adapter;
12
19
  }
13
20
 
21
+ /**
22
+ *
23
+ */
14
24
  initWsClient() {
15
25
  try {
16
26
  let wsURL = `${this.adapter.config.wsScheme}://${this.adapter.config.wsServerIP}:${this.adapter.config.wsServerPort}/api`;
@@ -53,6 +63,10 @@ class WebsocketController {
53
63
  }
54
64
  }
55
65
 
66
+ /**
67
+ *
68
+ * @param message
69
+ */
56
70
  send(message) {
57
71
  if (wsClient.readyState !== WebSocket.OPEN) {
58
72
  this.adapter.log.warn('Cannot set State, no websocket connection to Zigbee2MQTT!');
@@ -61,6 +75,9 @@ class WebsocketController {
61
75
  wsClient.send(message);
62
76
  }
63
77
 
78
+ /**
79
+ *
80
+ */
64
81
  sendPingToServer() {
65
82
  //this.logDebug('Send ping to server');
66
83
  wsClient.ping();
@@ -69,6 +86,9 @@ class WebsocketController {
69
86
  }, wsHeartbeatIntervall);
70
87
  }
71
88
 
89
+ /**
90
+ *
91
+ */
72
92
  wsHeartbeat() {
73
93
  clearTimeout(pingTimeout);
74
94
  pingTimeout = setTimeout(() => {
@@ -77,6 +97,9 @@ class WebsocketController {
77
97
  }, wsHeartbeatIntervall + 3000);
78
98
  }
79
99
 
100
+ /**
101
+ *
102
+ */
80
103
  async autoRestart() {
81
104
  this.adapter.log.warn(`Start try again in ${restartTimeout / 1000} seconds...`);
82
105
  autoRestartTimeout = setTimeout(() => {
@@ -84,12 +107,18 @@ class WebsocketController {
84
107
  }, restartTimeout);
85
108
  }
86
109
 
110
+ /**
111
+ *
112
+ */
87
113
  closeConnection() {
88
114
  if (wsClient && wsClient.readyState !== WebSocket.CLOSED) {
89
115
  wsClient.close();
90
116
  }
91
117
  }
92
118
 
119
+ /**
120
+ *
121
+ */
93
122
  async allTimerClear() {
94
123
  clearTimeout(pingTimeout);
95
124
  clearTimeout(ping);
@@ -1,4 +1,14 @@
1
+ /**
2
+ *
3
+ */
1
4
  class Z2mController {
5
+ /**
6
+ *
7
+ * @param adapter
8
+ * @param deviceCache
9
+ * @param groupCache
10
+ * @param logCustomizations
11
+ */
2
12
  constructor(adapter, deviceCache, groupCache, logCustomizations) {
3
13
  this.adapter = adapter;
4
14
  this.groupCache = groupCache;
@@ -6,6 +16,11 @@ class Z2mController {
6
16
  this.logCustomizations = logCustomizations;
7
17
  }
8
18
 
19
+ /**
20
+ *
21
+ * @param id
22
+ * @param state
23
+ */
9
24
  async createZ2MMessage(id, state) {
10
25
  const splitedID = id.split('.');
11
26
  if (splitedID.length < 4) {
@@ -114,6 +129,10 @@ class Z2mController {
114
129
  return controlObj;
115
130
  }
116
131
 
132
+ /**
133
+ *
134
+ * @param messageObj
135
+ */
117
136
  async proxyZ2MLogs(messageObj) {
118
137
  const logMessage = messageObj.payload.message;
119
138
  if (this.logCustomizations.logfilter.some((x) => logMessage.includes(x))) {
package/main.js CHANGED
@@ -68,8 +68,7 @@ class Zigbee2mqtt extends core.Adapter {
68
68
  }
69
69
 
70
70
  const logfilterState = await this.getStateAsync('info.logfilter');
71
- if (logfilterState && logfilterState.val) {
72
- // @ts-ignore
71
+ if (logfilterState && logfilterState.val) {
73
72
  logCustomizations.logfilter = String(logfilterState.val)
74
73
  .split(';')
75
74
  .filter((x) => x); // filter removes empty strings here
@@ -111,9 +110,8 @@ class Zigbee2mqtt extends core.Adapter {
111
110
  `mqtt://${this.config.externalMqttServerIP}:${this.config.externalMqttServerPort}`,
112
111
  mqttClientOptions
113
112
  );
114
- }
113
+ } else {
115
114
  // Internal MQTT-Server
116
- else {
117
115
  mqttServerController = new MqttServerController(this);
118
116
  await mqttServerController.createMQTTServer();
119
117
  await this.delay(1500);
@@ -137,9 +135,8 @@ class Zigbee2mqtt extends core.Adapter {
137
135
  const newMessage = `{"payload":${payload.toString() == '' ? '"null"' : payload.toString()},"topic":"${topic.slice(topic.search('/') + 1)}"}`;
138
136
  this.messageParse(newMessage);
139
137
  });
140
- }
138
+ } else if (this.config.connectionType == 'ws') {
141
139
  // Websocket
142
- else if (this.config.connectionType == 'ws') {
143
140
  if (this.config.wsServerIP == '') {
144
141
  this.log.warn('Please configure the Websoket connection!');
145
142
  return;
@@ -316,9 +313,8 @@ class Zigbee2mqtt extends core.Adapter {
316
313
  } catch (e) {
317
314
  this.log.error(e);
318
315
  }
319
- }
316
+ } else if (this.config.connectionType == 'ws') {
320
317
  // Websocket
321
- else if (this.config.connectionType == 'ws') {
322
318
  try {
323
319
  if (websocketController) {
324
320
  websocketController.closeConnection();
@@ -352,6 +348,8 @@ class Zigbee2mqtt extends core.Adapter {
352
348
  this.log.error(e);
353
349
  }
354
350
 
351
+ this.setState('info.connection', false, true);
352
+
355
353
  callback();
356
354
  }
357
355
 
@@ -382,8 +380,8 @@ class Zigbee2mqtt extends core.Adapter {
382
380
  if (require.main !== module) {
383
381
  // Export the constructor in compact mode
384
382
  /**
385
- * @param {Partial<core.AdapterOptions>} [options={}]
386
- */
383
+ * @param {Partial<core.AdapterOptions>} [options]
384
+ */
387
385
  module.exports = (options) => new Zigbee2mqtt(options);
388
386
  } else {
389
387
  // otherwise start the instance directly