iobroker.zigbee2mqtt 3.1.5 → 3.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 -80
- package/admin/jsonConfig.json +10 -1
- package/io-package.json +40 -79
- package/lib/deviceController.js +327 -4
- package/lib/exposes.js +1359 -1362
- package/lib/mqttServerController.js +28 -34
- package/lib/states.js +93 -19
- package/lib/statesController.js +4 -4
- package/lib/websocketController.js +1 -1
- package/lib/z2mController.js +3 -3
- package/main.js +26 -17
- package/package.json +7 -7
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const { Aedes } = require('aedes');
|
|
3
|
+
const Aedes = require('aedes');
|
|
5
4
|
const net = require('node:net');
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -51,40 +50,37 @@ class MqttServerController {
|
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
/**
|
|
54
|
-
* Startet den internen MQTT-Server mit
|
|
53
|
+
* Startet den internen MQTT-Server mit In-Memory-Persistenz (aedes + aedes-persistence-memory).
|
|
55
54
|
* Wartet auf den erfolgreichen listen()-Aufruf bevor die Methode zurückkehrt.
|
|
55
|
+
* Hinweis: aedes-persistence-nedb wurde entfernt, da es das veraltete nedb-Paket
|
|
56
|
+
* mit util.isDate verwendet (entfernt in Node.js v12+). In-Memory ist für einen
|
|
57
|
+
* internen Broker ausreichend – Clients subscriben sich bei Reconnect automatisch neu.
|
|
56
58
|
*/
|
|
57
59
|
async createMQTTServer() {
|
|
58
60
|
if (!this._checkConfig()) {
|
|
59
61
|
return;
|
|
60
62
|
}
|
|
61
63
|
try {
|
|
62
|
-
const
|
|
63
|
-
const db =
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// aedes-persistence-nedb does not implement the async setup() interface
|
|
68
|
-
// required by aedes v1.x → no-op shim
|
|
69
|
-
if (!db.setup) {
|
|
70
|
-
db.setup = async () => {};
|
|
71
|
-
}
|
|
72
|
-
this.aedesBroker = await Aedes.createBroker({ persistence: db });
|
|
73
|
-
this.mqttServer = net.createServer(this.aedesBroker.handle);
|
|
64
|
+
const MemoryPersistence = require('aedes-persistence');
|
|
65
|
+
const db = MemoryPersistence();
|
|
66
|
+
const aedes = Aedes({ persistence: db });
|
|
67
|
+
this.aedesBroker = aedes;
|
|
68
|
+
this.mqttServer = net.createServer(aedes.handle);
|
|
74
69
|
this._attachServerEvents('MQTT-Server');
|
|
75
70
|
|
|
76
71
|
await new Promise((resolve, reject) => {
|
|
72
|
+
this.mqttServer.once('error', reject);
|
|
77
73
|
this.mqttServer.listen(
|
|
78
74
|
this.adapter.config.mqttServerPort,
|
|
79
75
|
this.adapter.config.mqttServerIPBind,
|
|
80
76
|
() => {
|
|
77
|
+
this.mqttServer.removeListener('error', reject);
|
|
81
78
|
this.adapter.log.info(
|
|
82
79
|
`Starting MQTT-Server on IP ${this.adapter.config.mqttServerIPBind} and Port ${this.adapter.config.mqttServerPort}`
|
|
83
80
|
);
|
|
84
81
|
resolve();
|
|
85
82
|
}
|
|
86
83
|
);
|
|
87
|
-
this.mqttServer.once('error', reject);
|
|
88
84
|
});
|
|
89
85
|
} catch (err) {
|
|
90
86
|
this.adapter.log.error(`createMQTTServer error: ${err && err.message ? err.message : String(err)}`);
|
|
@@ -102,22 +98,24 @@ class MqttServerController {
|
|
|
102
98
|
return;
|
|
103
99
|
}
|
|
104
100
|
try {
|
|
105
|
-
|
|
106
|
-
this.
|
|
101
|
+
const aedes = Aedes();
|
|
102
|
+
this.aedesBroker = aedes;
|
|
103
|
+
this.mqttServer = net.createServer(aedes.handle);
|
|
107
104
|
this._attachServerEvents('DummyMQTT-Server');
|
|
108
105
|
|
|
109
106
|
await new Promise((resolve, reject) => {
|
|
107
|
+
this.mqttServer.once('error', reject);
|
|
110
108
|
this.mqttServer.listen(
|
|
111
109
|
this.adapter.config.mqttServerPort,
|
|
112
110
|
this.adapter.config.mqttServerIPBind,
|
|
113
111
|
() => {
|
|
112
|
+
this.mqttServer.removeListener('error', reject);
|
|
114
113
|
this.adapter.log.info(
|
|
115
114
|
`Starting DummyMQTT-Server on IP ${this.adapter.config.mqttServerIPBind} and Port ${this.adapter.config.mqttServerPort}`
|
|
116
115
|
);
|
|
117
116
|
resolve();
|
|
118
117
|
}
|
|
119
118
|
);
|
|
120
|
-
this.mqttServer.once('error', reject);
|
|
121
119
|
});
|
|
122
120
|
} catch (err) {
|
|
123
121
|
this.adapter.log.error(`createDummyMQTTServer error: ${err && err.message ? err.message : String(err)}`);
|
|
@@ -130,6 +128,17 @@ class MqttServerController {
|
|
|
130
128
|
* Wird beim Adapter-Stop oder nach einem Fehler beim Start aufgerufen.
|
|
131
129
|
*/
|
|
132
130
|
closeServer() {
|
|
131
|
+
if (this.aedesBroker) {
|
|
132
|
+
const broker = this.aedesBroker;
|
|
133
|
+
this.aedesBroker = null;
|
|
134
|
+
try {
|
|
135
|
+
broker.close(() => {
|
|
136
|
+
this.adapter.log.debug('Aedes broker closed.');
|
|
137
|
+
});
|
|
138
|
+
} catch (err) {
|
|
139
|
+
this.adapter.log.error(`closeServer aedesBroker.close() error: ${err}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
133
142
|
if (this.mqttServer) {
|
|
134
143
|
const server = this.mqttServer;
|
|
135
144
|
this.mqttServer = null;
|
|
@@ -143,21 +152,6 @@ class MqttServerController {
|
|
|
143
152
|
this.adapter.log.error(`closeServer mqttServer.close() error: ${err}`);
|
|
144
153
|
}
|
|
145
154
|
}
|
|
146
|
-
if (this.aedesBroker) {
|
|
147
|
-
const broker = this.aedesBroker;
|
|
148
|
-
this.aedesBroker = null;
|
|
149
|
-
try {
|
|
150
|
-
broker.close((err) => {
|
|
151
|
-
if (err) {
|
|
152
|
-
this.adapter.log.debug(`Aedes broker close callback error: ${err}`);
|
|
153
|
-
} else {
|
|
154
|
-
this.adapter.log.debug('Aedes broker closed.');
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
} catch (err) {
|
|
158
|
-
this.adapter.log.error(`closeServer aedesBroker.close() error: ${err}`);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
155
|
}
|
|
162
156
|
}
|
|
163
157
|
|
package/lib/states.js
CHANGED
|
@@ -347,12 +347,19 @@ const states = {
|
|
|
347
347
|
},
|
|
348
348
|
|
|
349
349
|
/**
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
350
|
+
* illuminance (Lux-State) – ausgelöst durch payload.illuminance.
|
|
351
|
+
*
|
|
352
|
+
* Fall 1 – beide Werte im Payload (illuminance + illuminance_raw):
|
|
353
|
+
* payload.illuminance wird direkt übernommen (neues Z2M sendet bereits Lux).
|
|
354
|
+
*
|
|
355
|
+
* Fall 2 – nur illuminance im Payload:
|
|
356
|
+
* payload.illuminance wird direkt übernommen.
|
|
357
|
+
*
|
|
358
|
+
* Fall 3 – nur illuminance_raw im Payload:
|
|
359
|
+
* Dieser State wird NICHT von diesem Eintrag gesetzt (prop='illuminance' nicht vorhanden).
|
|
360
|
+
* Stattdessen übernimmt illuminance_from_raw (prop='illuminance_raw') die Berechnung.
|
|
354
361
|
*/
|
|
355
|
-
|
|
362
|
+
illuminance_direct: {
|
|
356
363
|
id: 'illuminance',
|
|
357
364
|
prop: 'illuminance',
|
|
358
365
|
name: 'Illuminance',
|
|
@@ -363,13 +370,20 @@ const states = {
|
|
|
363
370
|
type: 'number',
|
|
364
371
|
def: 0,
|
|
365
372
|
unit: 'lux',
|
|
366
|
-
getter: (payload) => {
|
|
367
|
-
if (payload.illuminance == null) { return undefined; }
|
|
368
|
-
return Math.round(Math.pow(10, payload.illuminance / 10000));
|
|
369
|
-
},
|
|
370
373
|
},
|
|
371
374
|
|
|
372
|
-
|
|
375
|
+
/**
|
|
376
|
+
* illuminance_raw (Rohwert-State) – ausgelöst durch payload.illuminance.
|
|
377
|
+
*
|
|
378
|
+
* Fall 2 – nur illuminance im Payload:
|
|
379
|
+
* illuminance_raw wird aus dem Lux-Wert zurückgerechnet:
|
|
380
|
+
* raw = round(log10(lux) * 10000 + 1)
|
|
381
|
+
*
|
|
382
|
+
* Fall 1 – beide Werte im Payload:
|
|
383
|
+
* Getter gibt undefined zurück → dieser State wird NICHT gesetzt,
|
|
384
|
+
* stattdessen setzt illuminance_raw_direct (prop='illuminance_raw') den Rohwert direkt.
|
|
385
|
+
*/
|
|
386
|
+
illuminance_raw_from_lux: {
|
|
373
387
|
id: 'illuminance_raw',
|
|
374
388
|
prop: 'illuminance',
|
|
375
389
|
name: 'Illuminance raw',
|
|
@@ -380,11 +394,21 @@ const states = {
|
|
|
380
394
|
type: 'number',
|
|
381
395
|
def: 0,
|
|
382
396
|
unit: '',
|
|
397
|
+
getter: (payload) => {
|
|
398
|
+
// Wenn illuminance_raw bereits im Payload → illuminance_raw_direct setzt ihn direkt
|
|
399
|
+
if (payload.illuminance_raw != null) { return undefined; }
|
|
400
|
+
const lux = payload.illuminance;
|
|
401
|
+
if (lux == null) { return undefined; }
|
|
402
|
+
if (lux <= 0) { return 0; }
|
|
403
|
+
return Math.round(Math.log10(lux) * 10000 + 1);
|
|
404
|
+
},
|
|
383
405
|
},
|
|
384
406
|
|
|
385
407
|
/**
|
|
386
|
-
* Rohwert-State
|
|
387
|
-
*
|
|
408
|
+
* illuminance_raw (Rohwert-State) – ausgelöst durch payload.illuminance_raw.
|
|
409
|
+
*
|
|
410
|
+
* Fall 1 – beide Werte im Payload: direkt übernehmen.
|
|
411
|
+
* Fall 3 – nur illuminance_raw im Payload: direkt übernehmen.
|
|
388
412
|
*/
|
|
389
413
|
illuminance_raw_direct: {
|
|
390
414
|
id: 'illuminance_raw',
|
|
@@ -400,12 +424,15 @@ const states = {
|
|
|
400
424
|
},
|
|
401
425
|
|
|
402
426
|
/**
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
427
|
+
* illuminance (Lux-State) – ausgelöst durch payload.illuminance_raw.
|
|
428
|
+
*
|
|
429
|
+
* Fall 3 – nur illuminance_raw im Payload:
|
|
430
|
+
* Lux wird berechnet: lux = round(10^((raw - 1) / 10000))
|
|
431
|
+
*
|
|
432
|
+
* Fall 1 – beide Werte im Payload:
|
|
433
|
+
* Getter gibt undefined zurück → illuminance_direct (prop='illuminance') setzt Lux direkt.
|
|
407
434
|
*/
|
|
408
|
-
|
|
435
|
+
illuminance_from_raw: {
|
|
409
436
|
id: 'illuminance',
|
|
410
437
|
prop: 'illuminance_raw',
|
|
411
438
|
name: 'Illuminance',
|
|
@@ -417,8 +444,55 @@ const states = {
|
|
|
417
444
|
def: 0,
|
|
418
445
|
unit: 'lux',
|
|
419
446
|
getter: (payload) => {
|
|
420
|
-
|
|
421
|
-
|
|
447
|
+
// Wenn illuminance bereits im Payload → illuminance_direct setzt Lux direkt
|
|
448
|
+
if (payload.illuminance != null) { return undefined; }
|
|
449
|
+
const raw = payload.illuminance_raw;
|
|
450
|
+
if (raw == null) { return undefined; }
|
|
451
|
+
if (raw <= 0) { return 0; }
|
|
452
|
+
return Math.round(Math.pow(10, (raw - 1) / 10000));
|
|
453
|
+
},
|
|
454
|
+
},
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* illuminance (Lux-State) – ausgelöst durch payload.illuminance_lux.
|
|
458
|
+
* Geräte wie Philips HUE Motion, IKEA liefern illuminance_lux (bereits Lux).
|
|
459
|
+
* Wert wird direkt übernommen.
|
|
460
|
+
*/
|
|
461
|
+
illuminance_lux_direct: {
|
|
462
|
+
id: 'illuminance',
|
|
463
|
+
prop: 'illuminance_lux',
|
|
464
|
+
name: 'Illuminance',
|
|
465
|
+
icon: undefined,
|
|
466
|
+
role: 'value.brightness',
|
|
467
|
+
write: false,
|
|
468
|
+
read: true,
|
|
469
|
+
type: 'number',
|
|
470
|
+
def: 0,
|
|
471
|
+
unit: 'lux',
|
|
472
|
+
},
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* illuminance_raw (Rohwert-State) – ausgelöst durch payload.illuminance_lux.
|
|
476
|
+
* Berechnet: raw = round(log10(lux) * 10000 + 1)
|
|
477
|
+
* NUR wenn kein illuminance_raw im Payload – kein Überschreiben.
|
|
478
|
+
*/
|
|
479
|
+
illuminance_raw_from_lux2: {
|
|
480
|
+
id: 'illuminance_raw',
|
|
481
|
+
prop: 'illuminance_lux',
|
|
482
|
+
name: 'Illuminance raw',
|
|
483
|
+
icon: undefined,
|
|
484
|
+
role: 'value.brightness',
|
|
485
|
+
write: false,
|
|
486
|
+
read: true,
|
|
487
|
+
type: 'number',
|
|
488
|
+
def: 0,
|
|
489
|
+
unit: '',
|
|
490
|
+
getter: (payload) => {
|
|
491
|
+
if (payload.illuminance_raw != null) { return undefined; }
|
|
492
|
+
const lux = payload.illuminance_lux;
|
|
493
|
+
if (lux == null) { return undefined; }
|
|
494
|
+
if (lux <= 0) { return 0; }
|
|
495
|
+
return Math.round(Math.log10(lux) * 10000 + 1);
|
|
422
496
|
},
|
|
423
497
|
},
|
|
424
498
|
|
package/lib/statesController.js
CHANGED
|
@@ -157,7 +157,7 @@ class StatesController {
|
|
|
157
157
|
if (typeof value === 'object') {
|
|
158
158
|
value = JSON.stringify(value);
|
|
159
159
|
}
|
|
160
|
-
|
|
160
|
+
this.adapter.setState(`${fullPath}.${key}`, value, true);
|
|
161
161
|
}
|
|
162
162
|
continue;
|
|
163
163
|
}
|
|
@@ -233,7 +233,7 @@ class StatesController {
|
|
|
233
233
|
if (value === undefined || value === null) {
|
|
234
234
|
return;
|
|
235
235
|
}
|
|
236
|
-
|
|
236
|
+
this.adapter.setState(stateName, value, true);
|
|
237
237
|
}
|
|
238
238
|
|
|
239
239
|
/**
|
|
@@ -264,7 +264,7 @@ class StatesController {
|
|
|
264
264
|
return;
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
this.adapter.setState(stateName, value, true);
|
|
268
268
|
|
|
269
269
|
// Auto-Reset (false → nichts tun, true → nach timeout zurücksetzen)
|
|
270
270
|
// Wenn value=false (z.B. Stop-Aktion im simpleMoveStopState-Modus),
|
|
@@ -276,7 +276,7 @@ class StatesController {
|
|
|
276
276
|
if (value === true) {
|
|
277
277
|
this.timeOutCache[stateName] = this.adapter.setTimeout(() => {
|
|
278
278
|
delete this.timeOutCache[stateName];
|
|
279
|
-
this.adapter.
|
|
279
|
+
this.adapter.setState(stateName, false, true).catch((err) => {
|
|
280
280
|
this.adapter.log.debug(`setStateWithTimeout reset error for ${stateName}: ${err}`);
|
|
281
281
|
});
|
|
282
282
|
}, timeout);
|
|
@@ -133,8 +133,8 @@ class WebsocketController {
|
|
|
133
133
|
this.adapter.log.debug(`WebSocket closed – code: ${code}, reason: ${reason ? reason.toString() : 'none'}`);
|
|
134
134
|
|
|
135
135
|
try {
|
|
136
|
+
await this.adapter.setStateChangedAsync('info.connection', false, true);
|
|
136
137
|
if (this.adapter.statesController) {
|
|
137
|
-
this.adapter.setStateChanged('info.connection', false, true);
|
|
138
138
|
await this.adapter.statesController.setAllAvailableToFalse();
|
|
139
139
|
}
|
|
140
140
|
} catch (err) {
|
package/lib/z2mController.js
CHANGED
|
@@ -87,7 +87,7 @@ class Z2mController {
|
|
|
87
87
|
if (stateID === 'send_payload') {
|
|
88
88
|
try {
|
|
89
89
|
controlObj.payload = JSON.parse(stateVal);
|
|
90
|
-
|
|
90
|
+
this.adapter.setState(id, state.val, true);
|
|
91
91
|
} catch (error) {
|
|
92
92
|
// Fix 9: rawStr als String direkt als payload – wird in main.js via
|
|
93
93
|
// JSON.stringify() nochmals gewrappt → würde doppelt quoten.
|
|
@@ -122,7 +122,7 @@ class Z2mController {
|
|
|
122
122
|
if (deviceState.isOption) {
|
|
123
123
|
// set optionsValues 'Cache'
|
|
124
124
|
device.optionsValues[stateName] = state.val;
|
|
125
|
-
|
|
125
|
+
this.adapter.setState(id, state.val, true);
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -130,7 +130,7 @@ class Z2mController {
|
|
|
130
130
|
const immediateAckRole = ['button'].includes(deviceState.role);
|
|
131
131
|
const immediateAckId = ['brightness_move', 'colortemp_move', 'brightness_step', 'effect'].includes(deviceState.id);
|
|
132
132
|
if (immediateAckRole || immediateAckId) {
|
|
133
|
-
|
|
133
|
+
this.adapter.setState(id, state.val, true);
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
if (this.logCustomizations.debugDevices) {
|
package/main.js
CHANGED
|
@@ -71,7 +71,7 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
71
71
|
|
|
72
72
|
adapterInfo(this.config, this.log);
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
this.setState('info.connection', false, true);
|
|
75
75
|
|
|
76
76
|
const debugDevicesState = await this.getStateAsync('info.debugmessages');
|
|
77
77
|
if (debugDevicesState && debugDevicesState.val) {
|
|
@@ -109,6 +109,7 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
109
109
|
clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`,
|
|
110
110
|
clean: true,
|
|
111
111
|
reconnectPeriod: 500,
|
|
112
|
+
connectTimeout: 10000,
|
|
112
113
|
};
|
|
113
114
|
|
|
114
115
|
if (this.config.externalMqttServerCredentials === true) {
|
|
@@ -130,6 +131,7 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
130
131
|
clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`,
|
|
131
132
|
clean: true,
|
|
132
133
|
reconnectPeriod: 500,
|
|
134
|
+
connectTimeout: 10000,
|
|
133
135
|
});
|
|
134
136
|
}
|
|
135
137
|
|
|
@@ -156,18 +158,25 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
156
158
|
this.log.info('MQTT client reconnecting to Zigbee2MQTT...');
|
|
157
159
|
});
|
|
158
160
|
|
|
159
|
-
this.mqttClient.on('offline', () => {
|
|
160
|
-
(
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
} catch (e) {
|
|
168
|
-
this.log.error(`MQTT offline setAllAvailableToFalse error: ${e}`);
|
|
161
|
+
this.mqttClient.on('offline', async () => {
|
|
162
|
+
this.log.warn('MQTT client offline – connection to Zigbee2MQTT lost.');
|
|
163
|
+
await this.setStateChangedAsync('info.connection', false, true).catch((e) =>
|
|
164
|
+
this.log.error(`MQTT offline setStateChangedAsync error: ${e}`)
|
|
165
|
+
);
|
|
166
|
+
try {
|
|
167
|
+
if (this.statesController) {
|
|
168
|
+
await this.statesController.setAllAvailableToFalse();
|
|
169
169
|
}
|
|
170
|
-
}
|
|
170
|
+
} catch (e) {
|
|
171
|
+
this.log.error(`MQTT offline setAllAvailableToFalse error: ${e}`);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
this.mqttClient.on('close', async () => {
|
|
176
|
+
this.log.debug('MQTT client connection closed.');
|
|
177
|
+
await this.setStateChangedAsync('info.connection', false, true).catch((e) =>
|
|
178
|
+
this.log.error(`MQTT close setStateChangedAsync error: ${e}`)
|
|
179
|
+
);
|
|
171
180
|
});
|
|
172
181
|
|
|
173
182
|
this.mqttClient.on('error', (err) => {
|
|
@@ -513,7 +522,7 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
513
522
|
async onUnload(callback) {
|
|
514
523
|
try {
|
|
515
524
|
if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
|
|
516
|
-
if (this.mqttClient &&
|
|
525
|
+
if (this.mqttClient && this.mqttClient.connected) {
|
|
517
526
|
try {
|
|
518
527
|
this.mqttClient.removeAllListeners();
|
|
519
528
|
this.mqttClient.end(true);
|
|
@@ -561,7 +570,7 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
561
570
|
this.log.error(e);
|
|
562
571
|
}
|
|
563
572
|
|
|
564
|
-
|
|
573
|
+
this.setState('info.connection', false, true);
|
|
565
574
|
|
|
566
575
|
// Schedule-Job beenden
|
|
567
576
|
const job = schedule.scheduledJobs['coordinatorCheck'];
|
|
@@ -586,14 +595,14 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
586
595
|
if (state && state.ack === false) {
|
|
587
596
|
if (id.endsWith('info.debugmessages')) {
|
|
588
597
|
this.logCustomizations.debugDevices = state.val != null ? String(state.val) : '';
|
|
589
|
-
|
|
598
|
+
this.setState(id, state.val, true);
|
|
590
599
|
return;
|
|
591
600
|
}
|
|
592
601
|
if (id.endsWith('info.logfilter')) {
|
|
593
602
|
this.logCustomizations.logfilter = state.val != null
|
|
594
603
|
? String(state.val).split(';').filter((x) => x)
|
|
595
604
|
: [];
|
|
596
|
-
|
|
605
|
+
this.setState(id, state.val, true);
|
|
597
606
|
return;
|
|
598
607
|
}
|
|
599
608
|
|
|
@@ -608,7 +617,7 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
608
617
|
}
|
|
609
618
|
|
|
610
619
|
if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
|
|
611
|
-
if (!this.mqttClient || this.mqttClient.
|
|
620
|
+
if (!this.mqttClient || !this.mqttClient.connected) {
|
|
612
621
|
this.log.warn(`Cannot publish state, MQTT client not connected. (${id})`);
|
|
613
622
|
return;
|
|
614
623
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.zigbee2mqtt",
|
|
3
|
-
"version": "3.1
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"description": "Zigbee2MQTT adapter for ioBroker",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Dennis Rathjen and Arthur Rupp",
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
"url": "https://github.com/arteck/ioBroker.zigbee2mqtt.git"
|
|
22
22
|
},
|
|
23
23
|
"engines": {
|
|
24
|
-
"node": ">=
|
|
24
|
+
"node": ">= 22"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@iobroker/adapter-core": "^3.3.2",
|
|
28
28
|
"@iobroker/dm-utils": "^3.0.17",
|
|
29
|
-
"aedes": "^
|
|
30
|
-
"aedes-persistence
|
|
29
|
+
"aedes": "^0.51.3",
|
|
30
|
+
"aedes-persistence": "^9.1.2",
|
|
31
|
+
"axios": "^1.15.2",
|
|
31
32
|
"mqtt": "^5.15.1",
|
|
32
|
-
"axios": "^1.14.0",
|
|
33
33
|
"net": "^1.0.2",
|
|
34
34
|
"node-schedule": "^2.1.1",
|
|
35
35
|
"sharp": "^0.34.5",
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
"@alcalzone/release-script-plugin-license": "^5.1.1",
|
|
42
42
|
"@alcalzone/release-script-plugin-manual-review": "^5.1.1",
|
|
43
43
|
"@iobroker/adapter-dev": "^1.5.0",
|
|
44
|
-
"@iobroker/testing": "^5.2.2",
|
|
45
44
|
"@iobroker/eslint-config": "^2.1.0",
|
|
45
|
+
"@iobroker/testing": "^5.2.2",
|
|
46
46
|
"@tsconfig/node14": "^14.1.8",
|
|
47
47
|
"@types/node": "^25.5.2",
|
|
48
48
|
"@types/node-schedule": "^2.1.8",
|
|
49
|
-
"typescript": "~6.0.
|
|
49
|
+
"typescript": "~6.0.3"
|
|
50
50
|
},
|
|
51
51
|
"main": "main.js",
|
|
52
52
|
"files": [
|