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