iobroker.zigbee2mqtt 2.1.1 → 2.2.1
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/README.md +12 -0
- package/admin/i18n/de/translations.json +1 -1
- package/io-package.json +27 -25
- package/lib/check.js +30 -30
- package/lib/colors.js +442 -443
- package/lib/deviceController.js +239 -233
- package/lib/exposes.js +901 -859
- package/lib/messages.js +31 -31
- package/lib/mqttServerController.js +30 -30
- package/lib/nonGenericDevicesExtension.js +47 -0
- package/lib/rgb.js +227 -203
- package/lib/states.js +6375 -6374
- package/lib/statesController.js +137 -129
- package/lib/utils.js +82 -82
- package/lib/websocketController.js +58 -58
- package/lib/z2mController.js +64 -64
- package/main.js +202 -201
- package/package.json +3 -3
package/lib/z2mController.js
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
1
|
class Z2mController {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
constructor(adapter, deviceCache, groupCache, logCustomizations) {
|
|
3
|
+
this.adapter = adapter;
|
|
4
|
+
this.groupCache = groupCache;
|
|
5
|
+
this.deviceCache = deviceCache;
|
|
6
|
+
this.logCustomizations = logCustomizations;
|
|
7
|
+
}
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
async createZ2MMessage(id, state) {
|
|
10
|
+
const splitedID = id.split('.');
|
|
11
|
+
if (splitedID.length < 4) {
|
|
12
|
+
this.adapter.log.warn(`state ${id} not valid`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const ieee_address = splitedID[2];
|
|
17
|
+
const stateName = splitedID[3];
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
const device = this.groupCache.concat(this.deviceCache).find(d => d.ieee_address == ieee_address);
|
|
20
|
+
if (!device) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
const deviceState = device.states.find(s => s.id == stateName);
|
|
25
|
+
if (!deviceState) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
let stateVal = state.val;
|
|
30
|
+
if (deviceState.setter) {
|
|
31
|
+
stateVal = deviceState.setter(state.val);
|
|
32
|
+
}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
let stateID = deviceState.id;
|
|
35
|
+
if (deviceState.prop) {
|
|
36
|
+
stateID = deviceState.prop;
|
|
37
|
+
}
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
const controlObj = {
|
|
40
|
+
payload: {
|
|
41
|
+
[stateID]: stateVal
|
|
42
|
+
},
|
|
43
|
+
topic: `${device.id}/set`
|
|
44
|
+
};
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
topic: topic
|
|
49
|
-
};
|
|
50
|
-
// set stats with the mentioned role or ids always immediately to ack = true, because these are not reported back by Zigbee2MQTT
|
|
51
|
-
if (['button'].includes(deviceState.role) || ['brightness_move', 'color_temp_move'].includes(stateID)) {
|
|
52
|
-
this.adapter.setState(id, state, true);
|
|
53
|
-
}
|
|
46
|
+
// set stats with the mentioned role or ids always immediately to ack = true, because these are not reported back by Zigbee2MQTT
|
|
47
|
+
if (['button'].includes(deviceState.role) || ['brightness_move', 'color_temp_move'].includes(stateID)) {
|
|
48
|
+
this.adapter.setState(id, state, true);
|
|
49
|
+
}
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
if (this.logCustomizations.debugDevices.includes(device.ieee_address)) {
|
|
52
|
+
this.adapter.log.warn(`<<<--- toZ2M -> ${device.ieee_address} states: ${JSON.stringify(controlObj)}`);
|
|
53
|
+
}
|
|
57
54
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (this.logCustomizations.logfilter.some(x => logMessage.includes(x))) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
55
|
+
return controlObj;
|
|
56
|
+
}
|
|
63
57
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
58
|
+
async proxyZ2MLogs(messageObj) {
|
|
59
|
+
const logMessage = messageObj.payload.message;
|
|
60
|
+
if (this.logCustomizations.logfilter.some(x => logMessage.includes(x))) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const logLevel = messageObj.payload.level;
|
|
65
|
+
switch (logLevel) {
|
|
66
|
+
case 'debug':
|
|
67
|
+
case 'info':
|
|
68
|
+
case 'error':
|
|
69
|
+
this.adapter.log[logLevel](logMessage);
|
|
70
|
+
break;
|
|
71
|
+
case 'warning':
|
|
72
|
+
this.adapter.log.warn(logMessage);
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
module.exports = {
|
|
79
|
-
|
|
79
|
+
Z2mController: Z2mController
|
|
80
80
|
};
|
package/main.js
CHANGED
|
@@ -23,6 +23,7 @@ let mqttClient;
|
|
|
23
23
|
let deviceCache = [];
|
|
24
24
|
// eslint-disable-next-line prefer-const
|
|
25
25
|
let groupCache = [];
|
|
26
|
+
const createCache = {};
|
|
26
27
|
const logCustomizations = { debugDevices: '', logfilter: [] };
|
|
27
28
|
let showInfo = true;
|
|
28
29
|
let statesController;
|
|
@@ -33,233 +34,233 @@ let mqttServerController;
|
|
|
33
34
|
|
|
34
35
|
class Zigbee2mqtt extends core.Adapter {
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
constructor(options) {
|
|
38
|
+
super({
|
|
39
|
+
...options,
|
|
40
|
+
name: 'zigbee2mqtt',
|
|
41
|
+
});
|
|
42
|
+
this.on('ready', this.onReady.bind(this));
|
|
43
|
+
this.on('stateChange', this.onStateChange.bind(this));
|
|
44
|
+
this.on('unload', this.onUnload.bind(this));
|
|
45
|
+
}
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
async onReady() {
|
|
48
|
+
statesController = new StatesController(this, deviceCache, groupCache, logCustomizations, createCache);
|
|
49
|
+
deviceController = new DeviceController(this, deviceCache, groupCache, this.config, createCache);
|
|
50
|
+
z2mController = new Z2mController(this, deviceCache, groupCache, logCustomizations);
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
// Initialize your adapter here
|
|
53
|
+
adapterInfo(this.config, this.log);
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
this.setStateAsync('info.connection', false, true);
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
const debugDevicesState = await this.getStateAsync('info.debugmessages');
|
|
58
|
+
if (debugDevicesState && debugDevicesState.val) {
|
|
59
|
+
logCustomizations.debugDevices = String(debugDevicesState.val);
|
|
60
|
+
}
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
62
|
+
const logfilterState = await this.getStateAsync('info.logfilter');
|
|
63
|
+
if (logfilterState && logfilterState.val) {
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
logCustomizations.logfilter = String(logfilterState.val).split(';').filter(x => x); // filter removes empty strings here
|
|
66
|
+
}
|
|
67
|
+
// MQTT
|
|
68
|
+
if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
|
|
69
|
+
// External MQTT-Server
|
|
70
|
+
if (this.config.connectionType == 'exmqtt') {
|
|
71
|
+
if (this.config.externalMqttServerIP == '') {
|
|
72
|
+
this.log.warn('Please configure the External MQTT-Server connection!');
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
mqttClient = mqtt.connect(`mqtt://${this.config.externalMqttServerIP}:${this.config.externalMqttServerPort}`, { clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`, clean: true, reconnectPeriod: 500 });
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
}
|
|
78
|
+
// Internal MQTT-Server
|
|
79
|
+
else {
|
|
80
|
+
mqttServerController = new MqttServerController(this);
|
|
81
|
+
await mqttServerController.createMQTTServer();
|
|
82
|
+
await this.delay(1500);
|
|
83
|
+
mqttClient = mqtt.connect(`mqtt://${this.config.mqttServerIPBind}:${this.config.mqttServerPort}`, { clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`, clean: true, reconnectPeriod: 500 });
|
|
84
|
+
}
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
// MQTT Client
|
|
87
|
+
mqttClient.on('connect', () => {
|
|
88
|
+
this.log.info(`Connect to Zigbee2MQTT over ${this.config.connectionType == 'exmqtt' ? 'external mqtt' : 'internal mqtt'} connection.`);
|
|
89
|
+
});
|
|
89
90
|
|
|
90
|
-
|
|
91
|
+
mqttClient.subscribe('zigbee2mqtt/#');
|
|
91
92
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
93
|
+
mqttClient.on('message', (topic, payload) => {
|
|
94
|
+
const newMessage = `{"payload":${payload.toString() == '' ? '"null"' : payload.toString()},"topic":"${topic.slice(topic.search('/') + 1)}"}`;
|
|
95
|
+
this.messageParse(newMessage);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
// Websocket
|
|
99
|
+
else if (this.config.connectionType == 'ws') {
|
|
100
|
+
if (this.config.wsServerIP == '') {
|
|
101
|
+
this.log.warn('Please configure the Websoket connection!');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
103
104
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
// Dummy MQTT-Server
|
|
106
|
+
if (this.config.dummyMqtt == true) {
|
|
107
|
+
mqttServerController = new MqttServerController(this);
|
|
108
|
+
await mqttServerController.createDummyMQTTServer();
|
|
109
|
+
await this.delay(1500);
|
|
110
|
+
}
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
this.startWebsocket();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
startWebsocket() {
|
|
117
|
+
websocketController = new WebsocketController(this);
|
|
118
|
+
const wsClient = websocketController.initWsClient();
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
wsClient.on('open', () => {
|
|
121
|
+
this.log.info('Connect to Zigbee2MQTT over websocket connection.');
|
|
122
|
+
});
|
|
122
123
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
wsClient.on('message', (message) => {
|
|
125
|
+
this.messageParse(message);
|
|
126
|
+
});
|
|
126
127
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
128
|
+
wsClient.on('close', async () => {
|
|
129
|
+
this.setStateChangedAsync('info.connection', false, true);
|
|
130
|
+
await statesController.setAllAvailableToFalse();
|
|
131
|
+
this.log.warn('Websocket disconnectet');
|
|
132
|
+
});
|
|
133
|
+
}
|
|
133
134
|
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
async messageParse(message) {
|
|
136
|
+
const messageObj = JSON.parse(message);
|
|
136
137
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
const topicSplit = messageObj.topic.split('/');
|
|
138
|
+
switch (messageObj.topic) {
|
|
139
|
+
case 'bridge/config':
|
|
140
|
+
break;
|
|
141
|
+
case 'bridge/info':
|
|
142
|
+
if (showInfo) {
|
|
143
|
+
zigbee2mqttInfo(messageObj.payload, this.log);
|
|
144
|
+
checkConfig(messageObj.payload.config, this.log);
|
|
145
|
+
showInfo = false;
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
case 'bridge/state':
|
|
149
|
+
if (messageObj.payload.state != 'online') {
|
|
150
|
+
statesController.setAllAvailableToFalse();
|
|
151
|
+
}
|
|
152
|
+
this.setStateChangedAsync('info.connection', messageObj.payload.state == 'online', true);
|
|
153
|
+
break;
|
|
154
|
+
case 'bridge/devices':
|
|
155
|
+
await deviceController.createDeviceDefinitions(messageObj.payload);
|
|
156
|
+
await deviceController.createOrUpdateDevices();
|
|
157
|
+
await statesController.subscribeWritableStates();
|
|
158
|
+
statesController.processQueue();
|
|
159
|
+
break;
|
|
160
|
+
case 'bridge/groups':
|
|
161
|
+
await deviceController.createGroupDefinitions(messageObj.payload);
|
|
162
|
+
await deviceController.createOrUpdateDevices();
|
|
163
|
+
await statesController.subscribeWritableStates();
|
|
164
|
+
statesController.processQueue();
|
|
165
|
+
break;
|
|
166
|
+
case 'bridge/event':
|
|
167
|
+
deviceController.processRemoveEvent(messageObj);
|
|
168
|
+
break;
|
|
169
|
+
case 'bridge/response/device/remove':
|
|
170
|
+
deviceController.processRemoveEvent(messageObj);
|
|
171
|
+
break;
|
|
172
|
+
case 'bridge/extensions':
|
|
173
|
+
break;
|
|
174
|
+
case 'bridge/logging':
|
|
175
|
+
if (this.config.proxyZ2MLogs == true) {
|
|
176
|
+
z2mController.proxyZ2MLogs(messageObj);
|
|
177
|
+
}
|
|
178
|
+
break;
|
|
179
|
+
case 'bridge/response/device/rename':
|
|
180
|
+
await deviceController.renameDeviceInCache(messageObj);
|
|
181
|
+
await deviceController.createOrUpdateDevices();
|
|
182
|
+
statesController.processQueue();
|
|
183
|
+
break;
|
|
184
|
+
case 'bridge/response/networkmap':
|
|
185
|
+
break;
|
|
186
|
+
case 'bridge/response/touchlink/scan':
|
|
187
|
+
break;
|
|
188
|
+
case 'bridge/response/touchlink/identify':
|
|
189
|
+
break;
|
|
190
|
+
case 'bridge/response/touchlink/factory_reset':
|
|
191
|
+
break;
|
|
192
|
+
default:
|
|
193
|
+
{
|
|
194
|
+
// {"payload":{"state":"online"},"topic":"FL.Licht.Links/availability"} ----> {"payload":{"available":true},"topic":"FL.Licht.Links"}
|
|
195
|
+
if (messageObj.topic.endsWith('/availability')) {
|
|
196
|
+
const topicSplit = messageObj.topic.split('/');
|
|
197
197
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
198
|
+
// 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.
|
|
199
|
+
// If this is then still available in the cache, the messages must first be cached.
|
|
200
|
+
if (messageObj.payload == 'null') {
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
203
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
204
|
+
if (topicSplit.length == 2 && messageObj.payload && messageObj.payload.state) {
|
|
205
|
+
const newMessage = {
|
|
206
|
+
payload: { available: messageObj.payload.state == 'online' },
|
|
207
|
+
topic: topicSplit[0]
|
|
208
|
+
};
|
|
209
|
+
statesController.processDeviceMessage(newMessage);
|
|
210
|
+
}
|
|
211
|
+
// States
|
|
212
|
+
} else if (!messageObj.topic.includes('/')) {
|
|
213
|
+
statesController.processDeviceMessage(messageObj);
|
|
214
|
+
//console.log(JSON.stringify(messageObj));
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
219
220
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
221
|
+
async onUnload(callback) {
|
|
222
|
+
try {
|
|
223
|
+
await statesController.setAllAvailableToFalse();
|
|
224
|
+
await websocketController.allTimerClear();
|
|
225
|
+
await statesController.allTimerClear();
|
|
226
|
+
callback();
|
|
227
|
+
} catch (e) {
|
|
228
|
+
callback();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
230
231
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
232
|
+
async onStateChange(id, state) {
|
|
233
|
+
if (state && state.ack == false) {
|
|
234
|
+
if (id.includes('info.debugmessages')) {
|
|
235
|
+
logCustomizations.debugDevices = state.val;
|
|
236
|
+
this.setState(id, state.val, true);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (id.includes('info.logfilter')) {
|
|
240
|
+
logCustomizations.logfilter = state.val.split(';').filter(x => x); // filter removes empty strings here
|
|
241
|
+
this.setState(id, state.val, true);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
243
244
|
|
|
244
|
-
|
|
245
|
+
const message = await z2mController.createZ2MMessage(id, state) || { topic: '', payload: '' };
|
|
245
246
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
247
|
+
if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
|
|
248
|
+
mqttClient.publish(`zigbee2mqtt/${message.topic}`, JSON.stringify(message.payload));
|
|
249
|
+
} else if (this.config.connectionType == 'ws') {
|
|
250
|
+
websocketController.send(JSON.stringify(message));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
253
254
|
}
|
|
254
255
|
|
|
255
256
|
|
|
256
257
|
if (require.main !== module) {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
258
|
+
// Export the constructor in compact mode
|
|
259
|
+
/**
|
|
260
|
+
* @param {Partial<core.AdapterOptions>} [options={}]
|
|
261
|
+
*/
|
|
262
|
+
module.exports = (options) => new Zigbee2mqtt(options);
|
|
262
263
|
} else {
|
|
263
|
-
|
|
264
|
-
|
|
264
|
+
// otherwise start the instance directly
|
|
265
|
+
new Zigbee2mqtt();
|
|
265
266
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.zigbee2mqtt",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Zigbee2MQTT adapter for ioBroker",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Dennis Rathjen",
|
|
@@ -36,13 +36,13 @@
|
|
|
36
36
|
"@types/chai": "^4.3.3",
|
|
37
37
|
"@types/chai-as-promised": "^7.1.5",
|
|
38
38
|
"@types/mocha": "^10.0.0",
|
|
39
|
-
"@types/node": "^18.11.
|
|
39
|
+
"@types/node": "^18.11.3",
|
|
40
40
|
"@types/proxyquire": "^1.3.28",
|
|
41
41
|
"@types/sinon": "^10.0.13",
|
|
42
42
|
"@types/sinon-chai": "^3.2.8",
|
|
43
43
|
"chai": "^4.3.6",
|
|
44
44
|
"chai-as-promised": "^7.1.1",
|
|
45
|
-
"eslint": "^8.
|
|
45
|
+
"eslint": "^8.26.0",
|
|
46
46
|
"eslint-config-prettier": "^8.5.0",
|
|
47
47
|
"eslint-plugin-prettier": "^4.2.1",
|
|
48
48
|
"mocha": "^10.1.0",
|