iobroker.zigbee2mqtt 0.2.0 → 2.1.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.
package/main.js CHANGED
@@ -7,31 +7,29 @@
7
7
  // The adapter-core module gives you access to the core ioBroker functions
8
8
  // you need to create an adapter
9
9
  const core = require('@iobroker/adapter-core');
10
- const WebSocket = require('ws');
11
- const defineDeviceFromExposes = require('./lib/exposes').defineDeviceFromExposes;
12
- const defineGroupDevice = require('./lib/groups').defineGroupDevice;
13
- const clearArray = require('./lib/utils').clearArray;
14
- let wsClient;
15
- let adapter;
16
- let createDevicesOrReady = false;
17
- let isConnected = false;
18
- const incStatsQueue = [];
19
- const createCache = {};
10
+ const mqtt = require('mqtt');
11
+ const checkConfig = require('./lib/check').checkConfig;
12
+ const adapterInfo = require('./lib/messages').adapterInfo;
13
+ const zigbee2mqttInfo = require('./lib/messages').zigbee2mqttInfo;
14
+ const Z2mController = require('./lib/z2mController').Z2mController;
15
+ const DeviceController = require('./lib/deviceController').DeviceController;
16
+ const StatesController = require('./lib/statesController').StatesController;
17
+ const WebsocketController = require('./lib/websocketController').WebsocketController;
18
+ const MqttServerController = require('./lib/mqttServerController').MqttServerController;
19
+
20
+
21
+ let mqttClient;
20
22
  // eslint-disable-next-line prefer-const
21
23
  let deviceCache = [];
22
24
  // eslint-disable-next-line prefer-const
23
25
  let groupCache = [];
24
- let ping;
25
- let pingTimeout;
26
- let autoRestartTimeout;
27
- const wsHeartbeatIntervall = 5000;
28
- const restartTimeout = 1000;
29
- let debugLogEnabled;
30
- let proxyZ2MLogsEnabled;
31
- let checkAvailableTimout;
32
- let debugDevices = '';
33
- let logfilter = [];
34
- let useKelvin = false;
26
+ const logCustomizations = { debugDevices: '', logfilter: [] };
27
+ let showInfo = true;
28
+ let statesController;
29
+ let deviceController;
30
+ let z2mController;
31
+ let websocketController;
32
+ let mqttServerController;
35
33
 
36
34
  class Zigbee2mqtt extends core.Adapter {
37
35
 
@@ -46,96 +44,87 @@ class Zigbee2mqtt extends core.Adapter {
46
44
  }
47
45
 
48
46
  async onReady() {
47
+ statesController = new StatesController(this, deviceCache, groupCache, logCustomizations);
48
+ deviceController = new DeviceController(this, deviceCache, groupCache, this.config);
49
+ z2mController = new Z2mController(this, deviceCache, groupCache, logCustomizations);
50
+
49
51
  // Initialize your adapter here
50
- adapter = this;
51
- this.log.info(`Zigbee2MQTT Frontend Server: ${this.config.server}`);
52
- this.log.info(`Zigbee2MQTT Frontend Port: ${this.config.port}`);
53
- this.log.info(`Zigbee2MQTT Debug Log: ${this.config.debugLogEnabled ? 'activated' : 'deactivated'}`);
54
- this.log.info(`Proxy Zigbee2MQTT Logs to ioBroker Logs: ${this.config.proxyZ2MLogs ? 'activated' : 'deactivated'}`);
55
- this.log.info(`Use Kelvin: ${this.config.useKelvin ? 'yes' : 'no'}`);
52
+ adapterInfo(this.config, this.log);
56
53
 
57
54
  this.setStateAsync('info.connection', false, true);
58
- this.createWsClient(this.config.server, this.config.port);
59
-
60
- debugLogEnabled = this.config.debugLogEnabled;
61
- proxyZ2MLogsEnabled = this.config.proxyZ2MLogs;
62
- useKelvin = this.config.useKelvin;
63
55
 
64
56
  const debugDevicesState = await this.getStateAsync('info.debugmessages');
65
57
  if (debugDevicesState && debugDevicesState.val) {
66
- debugDevices = String(debugDevicesState.val);
58
+ logCustomizations.debugDevices = String(debugDevicesState.val);
67
59
  }
68
60
 
69
61
  const logfilterState = await this.getStateAsync('info.logfilter');
70
62
  if (logfilterState && logfilterState.val) {
71
- logfilter = String(logfilterState.val).split(';').filter(x => x); // filter removes empty strings here
63
+ // @ts-ignore
64
+ logCustomizations.logfilter = String(logfilterState.val).split(';').filter(x => x); // filter removes empty strings here
72
65
  }
66
+ // MQTT
67
+ if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
68
+ // External MQTT-Server
69
+ if (this.config.connectionType == 'exmqtt') {
70
+ if (this.config.externalMqttServerIP == '') {
71
+ this.log.warn('Please configure the External MQTT-Server connection!');
72
+ return;
73
+ }
74
+ mqttClient = mqtt.connect(`mqtt://${this.config.externalMqttServerIP}:${this.config.externalMqttServerPort}`, { clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`, clean: true, reconnectPeriod: 500 });
73
75
 
76
+ }
77
+ // Internal MQTT-Server
78
+ else {
79
+ mqttServerController = new MqttServerController(this);
80
+ await mqttServerController.createMQTTServer();
81
+ await this.delay(1500);
82
+ mqttClient = mqtt.connect(`mqtt://${this.config.mqttServerIPBind}:${this.config.mqttServerPort}`, { clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`, clean: true, reconnectPeriod: 500 });
83
+ }
74
84
 
75
- this.subscribeStatesAsync('*');
76
- }
77
-
78
- async createWsClient(server, port) {
79
- try {
80
- wsClient = new WebSocket(`ws://${server}:${port}/api`);
81
- wsClient.on('open', () => {
82
- this.logDebug('Websocket connectet');
83
- // Set connection state
84
- this.setState('info.connection', true, true);
85
- this.log.info('Connect to server over websocket connection.');
86
- isConnected = true;
87
- // Send ping to server
88
- this.sendPingToServer();
89
- // Start Heartbeat
90
- this.wsHeartbeat();
85
+ // MQTT Client
86
+ mqttClient.on('connect', () => {
87
+ this.log.info(`Connect to Zigbee2MQTT over ${this.config.connectionType == 'exmqtt' ? 'external mqtt' : 'internal mqtt'} connection.`);
91
88
  });
92
- wsClient.on('pong', () => {
93
- //this.logDebug('Receive pong from server');
94
- this.wsHeartbeat();
95
- });
96
- // On Close
97
- wsClient.on('close', async () => {
98
- this.setState('info.connection', false, true);
99
- this.log.warn('Websocket disconnectet');
100
- await this.setAllAvailableToFalse();
101
- clearTimeout(ping);
102
- clearTimeout(pingTimeout);
103
- isConnected = false;
104
89
 
105
- if (wsClient.readyState === WebSocket.CLOSED) {
106
- this.autoRestart();
107
- }
108
- });
90
+ mqttClient.subscribe('zigbee2mqtt/#');
109
91
 
110
- wsClient.on('message', (message) => { this.messageParse(message); });
111
- wsClient.on('error', (err) => { adapter.logDebug(err); });
112
- } catch (err) {
113
- this.logDebug(err);
92
+ mqttClient.on('message', (topic, payload) => {
93
+ const newMessage = `{"payload":${payload.toString() == '' ? '"null"' : payload.toString()},"topic":"${topic.slice(topic.search('/') + 1)}"}`;
94
+ this.messageParse(newMessage);
95
+ });
114
96
  }
115
- }
97
+ // Websocket
98
+ else if (this.config.connectionType == 'ws') {
99
+ if (this.config.wsServerIP == '') {
100
+ this.log.warn('Please configure the Websoket connection!');
101
+ return;
102
+ }
116
103
 
117
- async sendPingToServer() {
118
- //this.logDebug('Send ping to server');
119
- wsClient.ping();
120
- ping = setTimeout(() => {
121
- this.sendPingToServer();
122
- }, wsHeartbeatIntervall);
123
- }
104
+ // Dummy MQTT-Server
105
+ if (this.config.dummyMqtt == true) {
106
+ mqttServerController = new MqttServerController(this);
107
+ await mqttServerController.createDummyMQTTServer();
108
+ await this.delay(1500);
109
+ }
124
110
 
125
- async wsHeartbeat() {
126
- clearTimeout(pingTimeout);
127
- pingTimeout = setTimeout(() => {
128
- this.logDebug('Websocked connection timed out');
129
- wsClient.terminate();
130
- clearTimeout(checkAvailableTimout);
131
- }, wsHeartbeatIntervall + 1000);
132
- }
111
+ websocketController = new WebsocketController(this);
112
+ const wsClient = await websocketController.initWsClient(this.config.wsServerIP, this.config.wsServerPort);
133
113
 
134
- async autoRestart() {
135
- this.log.warn(`Start try again in ${restartTimeout / 1000} seconds...`);
136
- autoRestartTimeout = setTimeout(() => {
137
- this.onReady();
138
- }, restartTimeout);
114
+ wsClient.on('open', () => {
115
+ this.log.info('Connect to Zigbee2MQTT over websocket connection.');
116
+ });
117
+
118
+ wsClient.on('message', (message) => {
119
+ this.messageParse(message);
120
+ });
121
+
122
+ wsClient.on('clo', async () => {
123
+ this.setStateChangedAsync('info.connection', false, true);
124
+ await statesController.setAllAvailableToFalse();
125
+ this.log.warn('Websocket disconnectet');
126
+ });
127
+ }
139
128
  }
140
129
 
141
130
  async messageParse(message) {
@@ -145,36 +134,45 @@ class Zigbee2mqtt extends core.Adapter {
145
134
  case 'bridge/config':
146
135
  break;
147
136
  case 'bridge/info':
137
+ if (showInfo) {
138
+ zigbee2mqttInfo(messageObj.payload, this.log);
139
+ checkConfig(messageObj.payload.config, this.log);
140
+ showInfo = false;
141
+ }
148
142
  break;
149
143
  case 'bridge/state':
144
+ if (messageObj.payload.state != 'online') {
145
+ statesController.setAllAvailableToFalse();
146
+ }
147
+ this.setStateChangedAsync('info.connection', messageObj.payload.state == 'online', true);
150
148
  break;
151
149
  case 'bridge/devices':
152
- // As long as we are busy creating the devices, the states are written to the queue.
153
- createDevicesOrReady = false;
154
- await this.createDeviceDefinitions(deviceCache, messageObj.payload);
155
- await this.createOrUpdateDevices(deviceCache);
156
- this.subscribeWritableStates();
157
- createDevicesOrReady = true;
158
-
159
- // Now process all entries in the states queue
160
- while (incStatsQueue.length > 0) {
161
- this.processDeviceMessage(incStatsQueue.shift());
162
- }
150
+ await deviceController.createDeviceDefinitions(messageObj.payload);
151
+ await deviceController.createOrUpdateDevices();
152
+ await statesController.subscribeWritableStates();
153
+ statesController.processQueue();
163
154
  break;
164
155
  case 'bridge/groups':
165
- await this.createGroupDefinitions(groupCache, messageObj.payload);
166
- await this.createOrUpdateDevices(groupCache);
167
- this.subscribeWritableStates();
156
+ await deviceController.createGroupDefinitions(messageObj.payload);
157
+ await deviceController.createOrUpdateDevices();
158
+ await statesController.subscribeWritableStates();
159
+ statesController.processQueue();
168
160
  break;
169
161
  case 'bridge/event':
162
+ deviceController.processRemoveEvent(messageObj);
170
163
  break;
171
164
  case 'bridge/extensions':
172
165
  break;
173
166
  case 'bridge/logging':
174
- if (proxyZ2MLogsEnabled == true) {
175
- this.proxyZ2MLogs(messageObj);
167
+ if (this.config.proxyZ2MLogs == true) {
168
+ z2mController.proxyZ2MLogs(messageObj);
176
169
  }
177
170
  break;
171
+ case 'bridge/response/device/rename':
172
+ await deviceController.renameDeviceInCache(messageObj);
173
+ await deviceController.createOrUpdateDevices();
174
+ statesController.processQueue();
175
+ break;
178
176
  case 'bridge/response/networkmap':
179
177
  break;
180
178
  case 'bridge/response/touchlink/scan':
@@ -188,296 +186,34 @@ class Zigbee2mqtt extends core.Adapter {
188
186
  // {"payload":{"state":"online"},"topic":"FL.Licht.Links/availability"} ----> {"payload":{"available":true},"topic":"FL.Licht.Links"}
189
187
  if (messageObj.topic.endsWith('/availability')) {
190
188
  const topicSplit = messageObj.topic.split('/');
189
+
190
+ // If an availability message for an old device ID comes with a payload of NULL, this is the indicator that a device has been unnamed.
191
+ // If this is then still available in the cache, the messages must first be cached.
192
+ if (messageObj.payload == 'null') {
193
+ break;
194
+ }
195
+
191
196
  if (topicSplit.length == 2 && messageObj.payload && messageObj.payload.state) {
192
197
  const newMessage = {
193
198
  payload: { available: messageObj.payload.state == 'online' },
194
199
  topic: topicSplit[0]
195
200
  };
196
- // As long as we are busy creating the devices, the states are written to the queue.
197
- if (createDevicesOrReady == false) {
198
- incStatsQueue[incStatsQueue.length] = newMessage;
199
- break;
200
- }
201
- this.processDeviceMessage(newMessage);
201
+ statesController.processDeviceMessage(newMessage);
202
202
  }
203
203
  // States
204
204
  } else if (!messageObj.topic.includes('/')) {
205
- // As long as we are busy creating the devices, the states are written to the queue.
206
- if (createDevicesOrReady == false) {
207
- incStatsQueue[incStatsQueue.length] = messageObj;
208
- break;
209
- }
210
- this.processDeviceMessage(messageObj);
211
- }
212
- }
213
- break;
214
- }
215
- }
216
-
217
- async processDeviceMessage(messageObj) {
218
- this.logDebug(`processDeviceMessage -> messageObj: ${JSON.stringify(messageObj)}`);
219
- // Is payload present?
220
- if (messageObj.payload == '') {
221
- return;
222
- }
223
-
224
- const device = groupCache.concat(deviceCache).find(x => x.id == messageObj.topic);
225
- if (device) {
226
- this.logDebug(`processDeviceMessage -> device: ${JSON.stringify(device)}`);
227
- try {
228
- this.setDeviceState(messageObj, device);
229
- } catch (error) {
230
- adapter.log.error(error);
231
- }
232
- }
233
- else {
234
- adapter.log.warn(`Device: ${messageObj.topic} not found`);
235
- }
236
- }
237
-
238
- async setDeviceState(messageObj, device) {
239
-
240
- if (debugDevices.includes(device.ieee_address)) {
241
- this.log.warn(`--->>> fromZ2M -> ${device.ieee_address} states: ${JSON.stringify(messageObj)}`);
242
- }
243
-
244
- for (const [key, value] of Object.entries(messageObj.payload)) {
245
- this.logDebug(`setDeviceState -> key: ${key}`);
246
- this.logDebug(`setDeviceState -> value: ${JSON.stringify(value)}`);
247
-
248
- let states;
249
- if (key == 'action') {
250
- states = device.states.filter(x => (x.prop && x.prop == key) && x.id == value);
251
- } else {
252
- states = device.states.filter(x => (x.prop && x.prop == key) || x.id == key);
253
- }
254
- this.logDebug(`setDeviceState -> states: ${JSON.stringify(states)}`);
255
-
256
- for (const state of states) {
257
- if (!state) {
258
- continue;
259
- }
260
-
261
- const stateName = `${device.ieee_address}.${state.id}`;
262
-
263
- try {
264
- if (state.getter) {
265
- await this.setStateAsync(stateName, state.getter(messageObj.payload), true);
266
- }
267
- else {
268
- await this.setStateAsync(stateName, value, true);
205
+ statesController.processDeviceMessage(messageObj);
269
206
  }
270
- } catch (err) {
271
- this.log.warn(`Can not set ${stateName}`);
272
- }
273
- }
274
- }
275
- }
276
-
277
- async createDeviceDefinitions(cache, exposes) {
278
- clearArray(cache);
279
- for (const expose of exposes) {
280
- if (expose.definition != null) {
281
- // search for scenes in the endpoints and build them into an array
282
- let scenes = [];
283
- for (const key in expose.endpoints) {
284
- if (expose.endpoints[key].scenes) {
285
- scenes = scenes.concat(expose.endpoints[key].scenes);
286
- }
287
- }
288
-
289
- await defineDeviceFromExposes(cache, expose.friendly_name, expose.ieee_address, expose.definition, expose.power_source, scenes, useKelvin);
290
- }
291
- }
292
- }
293
-
294
- async createGroupDefinitions(cache, exposes) {
295
- clearArray(cache);
296
- for (const expose of exposes) {
297
- await defineGroupDevice(cache, expose.friendly_name, `group_${expose.id}`, expose.scenes, useKelvin);
298
- }
299
- }
300
-
301
- async createOrUpdateDevices(cache) {
302
- for (const device of cache) {
303
- const deviceName = device.id == device.ieee_address ? '' : device.id;
304
- if (!createCache[device.ieee_address] || createCache[device.ieee_address].common.name != deviceName) {
305
- const deviceObj = {
306
- type: 'device',
307
- common: {
308
- name: deviceName,
309
- },
310
-
311
- native: {}
312
- };
313
-
314
- if (!device.ieee_address.includes('group_')) {
315
- deviceObj.common.statusStates = {
316
- onlineId: `${this.name}.${this.instance}.${device.ieee_address}.available`
317
- };
318
207
  }
319
-
320
- //@ts-ignore
321
- await this.extendObjectAsync(device.ieee_address, deviceObj);
322
- createCache[device.ieee_address] = deviceObj;
323
- }
324
-
325
- // Here it is checked whether the scenes match the current data from z2m.
326
- // If necessary, scenes are automatically deleted from ioBroker.
327
- const sceneStates = await this.getStatesAsync(`${device.ieee_address}.scene_*`);
328
- const sceneIDs = Object.keys(sceneStates);
329
- for (const sceneID of sceneIDs) {
330
- const stateID = sceneID.split('.')[3];
331
- if (device.states.find(x => x.id == stateID) == null) {
332
- this.delObject(sceneID);
333
- }
334
- }
335
-
336
- for (const state of device.states) {
337
- if (!createCache[device.ieee_address][state.id] || createCache[device.ieee_address][state.id].name != state.name) {
338
- const iobState = await this.copyAndCleanStateObj(state);
339
- this.logDebug(`Orig. state: ${JSON.stringify(state)}`);
340
- this.logDebug(`Cleaned. state: ${JSON.stringify(iobState)}`);
341
-
342
- await this.extendObjectAsync(`${device.ieee_address}.${state.id}`, {
343
- type: 'state',
344
- common: iobState,
345
- native: {},
346
- });
347
- createCache[device.ieee_address][state.id] = state.name;
348
- }
349
- }
350
- }
351
- }
352
-
353
- async copyAndCleanStateObj(state) {
354
- const iobState = { ...state };
355
- const blacklistedKeys = [
356
- 'setter',
357
- 'setterOpt',
358
- 'getter',
359
- 'setattr',
360
- 'readable',
361
- 'writable',
362
- 'isOption',
363
- 'inOptions'
364
- ];
365
- for (const blacklistedKey of blacklistedKeys) {
366
- delete iobState[blacklistedKey];
367
- }
368
- return iobState;
369
- }
370
-
371
- async subscribeWritableStates() {
372
- await this.unsubscribeObjectsAsync('*');
373
-
374
- for (const device of groupCache.concat(deviceCache)) {
375
- for (const state of device.states) {
376
- if (state.write == true) {
377
- this.subscribeStatesAsync(`${device.ieee_address}.${state.id}`);
378
- }
379
- }
380
- }
381
- }
382
-
383
- async createZ2MMessage(id, state) {
384
-
385
- const splitedID = id.split('.');
386
-
387
- if (splitedID.length < 4) {
388
- this.log.warn(`state ${id} not valid`);
389
- return;
390
- }
391
-
392
- const ieee_address = splitedID[2];
393
- const stateName = splitedID[3];
394
-
395
- const device = groupCache.concat(deviceCache).find(d => d.ieee_address == ieee_address);
396
-
397
- if (!device) {
398
- return;
399
- }
400
-
401
- const deviceState = device.states.find(s => s.id == stateName);
402
-
403
- if (!deviceState) {
404
- return;
405
- }
406
-
407
- let stateVal = state.val;
408
- if (deviceState.setter) {
409
- stateVal = deviceState.setter(state.val);
410
- }
411
-
412
-
413
- let stateID = deviceState.id;
414
- if (deviceState.prop) {
415
- stateID = deviceState.prop;
416
- }
417
-
418
- let topic = `${device.ieee_address}/set`;
419
- if (device.ieee_address.includes('group_')) {
420
- topic = `${device.id}/set`;
421
- }
422
-
423
- const controlObj = {
424
- payload: {
425
- [stateID]: stateVal
426
- },
427
- topic: topic
428
- };
429
- // set stats with the mentioned role or ids always immediately to ack = true, because these are not reported back by Zigbee2MQTT
430
- if (isConnected == true && (['button'].includes(deviceState.role) || ['brightness_move', 'color_temp_move'].includes(stateID))) {
431
- this.setState(id, state, true);
432
- }
433
-
434
- return JSON.stringify(controlObj);
435
- }
436
-
437
- async proxyZ2MLogs(messageObj) {
438
- this.logDebug(`proxyZ2MLogs -> messageObj: ${JSON.stringify(messageObj)}`);
439
-
440
- const logMessage = messageObj.payload.message;
441
- if (logfilter.some(x => logMessage.includes(x))) {
442
- return;
443
- }
444
-
445
- const logLevel = messageObj.payload.level;
446
- switch (logLevel) {
447
- case 'debug':
448
- case 'info':
449
- case 'error':
450
- this.log[logLevel](logMessage);
451
- break;
452
- case 'warning':
453
- this.log.warn(logMessage);
454
208
  break;
455
209
  }
456
210
  }
457
211
 
458
- async logDebug(message) {
459
- if (debugLogEnabled == true) {
460
- this.log.debug(message);
461
- }
462
- }
463
-
464
- async setAllAvailableToFalse() {
465
- for (const device of deviceCache) {
466
- for (const state of device.states) {
467
- if (state.id == 'available') {
468
- await this.setStateAsync(`${device.ieee_address}.${state.id}`, false, true);
469
- }
470
- }
471
- }
472
- }
473
-
474
212
  async onUnload(callback) {
475
213
  try {
476
- await this.setAllAvailableToFalse();
477
- clearTimeout(ping);
478
- clearTimeout(pingTimeout);
479
- clearTimeout(autoRestartTimeout);
480
- clearTimeout(checkAvailableTimout);
214
+ await statesController.setAllAvailableToFalse();
215
+ await websocketController.allTimerClear();
216
+ await statesController.allTimerClear();
481
217
  callback();
482
218
  } catch (e) {
483
219
  callback();
@@ -486,16 +222,23 @@ class Zigbee2mqtt extends core.Adapter {
486
222
 
487
223
  async onStateChange(id, state) {
488
224
  if (state && state.ack == false) {
489
- const message = await this.createZ2MMessage(id, state);
490
- wsClient.send(message);
491
-
492
225
  if (id.includes('info.debugmessages')) {
493
- debugDevices = state.val;
226
+ logCustomizations.debugDevices = state.val;
494
227
  this.setState(id, state.val, true);
228
+ return;
495
229
  }
496
230
  if (id.includes('info.logfilter')) {
497
- logfilter = state.val.split(';').filter(x => x); // filter removes empty strings here
231
+ logCustomizations.logfilter = state.val.split(';').filter(x => x); // filter removes empty strings here
498
232
  this.setState(id, state.val, true);
233
+ return;
234
+ }
235
+
236
+ const message = await z2mController.createZ2MMessage(id, state) || { topic: '', payload: '' };
237
+
238
+ if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
239
+ mqttClient.publish(`zigbee2mqtt/${message.topic}`, JSON.stringify(message.payload));
240
+ } else if (this.config.connectionType == 'ws') {
241
+ websocketController.send(JSON.stringify(message));
499
242
  }
500
243
  }
501
244
  }
@@ -511,4 +254,4 @@ if (require.main !== module) {
511
254
  } else {
512
255
  // otherwise start the instance directly
513
256
  new Zigbee2mqtt();
514
- }
257
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zigbee2mqtt",
3
- "version": "0.2.0",
3
+ "version": "2.1.0",
4
4
  "description": "Zigbee2MQTT adapter for ioBroker",
5
5
  "author": {
6
6
  "name": "Dennis Rathjen",
@@ -19,12 +19,16 @@
19
19
  "url": "https://github.com/o0shojo0o/ioBroker.zigbee2mqtt.git"
20
20
  },
21
21
  "dependencies": {
22
- "@alcalzone/release-script-plugin-iobroker": "^3.5.9",
23
- "@alcalzone/release-script-plugin-license": "^3.5.9",
24
- "@iobroker/adapter-core": "^2.6.6",
22
+ "@iobroker/adapter-core": "^2.6.7",
23
+ "aedes": "^0.48.0",
24
+ "aedes-persistence-nedb": "^2.0.3",
25
+ "mqtt": "^4.3.7",
26
+ "net": "^1.0.2",
25
27
  "ws": "^8.9.0"
26
28
  },
27
29
  "devDependencies": {
30
+ "@alcalzone/release-script-plugin-iobroker": "^3.5.9",
31
+ "@alcalzone/release-script-plugin-license": "^3.5.9",
28
32
  "@alcalzone/release-script": "^3.5.9",
29
33
  "@iobroker/adapter-dev": "^1.1.0",
30
34
  "@iobroker/testing": "^4.1.0",
@@ -32,19 +36,19 @@
32
36
  "@types/chai": "^4.3.3",
33
37
  "@types/chai-as-promised": "^7.1.5",
34
38
  "@types/mocha": "^10.0.0",
35
- "@types/node": "^18.7.23",
39
+ "@types/node": "^18.8.3",
36
40
  "@types/proxyquire": "^1.3.28",
37
41
  "@types/sinon": "^10.0.13",
38
42
  "@types/sinon-chai": "^3.2.8",
39
43
  "chai": "^4.3.6",
40
44
  "chai-as-promised": "^7.1.1",
41
- "eslint": "^8.24.0",
45
+ "eslint": "^8.25.0",
42
46
  "eslint-config-prettier": "^8.5.0",
43
47
  "eslint-plugin-prettier": "^4.2.1",
44
48
  "mocha": "^10.0.0",
45
49
  "prettier": "^2.7.1",
46
50
  "proxyquire": "^2.1.3",
47
- "sinon": "^14.0.0",
51
+ "sinon": "^14.0.1",
48
52
  "sinon-chai": "^3.7.0",
49
53
  "typescript": "~4.8.4"
50
54
  },