iobroker.zigbee2mqtt 3.2.7 → 3.2.9

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 CHANGED
@@ -30,6 +30,12 @@ check you VM Settings
30
30
  [Adapter Documentation](https://github.com/arteck/ioBroker.zigbee2mqtt/blob/main/docs/wiki.md)
31
31
 
32
32
  ## Changelog
33
+ ### 3.2.9 (2026-09-19)
34
+ * (arteck) url fix
35
+
36
+ ### 3.2.8 (2026-09-19)
37
+ * (arteck) fix also for dummy mqtt if ws selected
38
+
33
39
  ### 3.2.7 (2026-09-19)
34
40
  * (arteck) fix available status direct after new device is paired
35
41
  * (arteck) fix internal mqtt handling
@@ -40,15 +46,6 @@ check you VM Settings
40
46
  ### 3.2.5 (2026-08-04)
41
47
  * (arteck) State updates lag issue https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662
42
48
 
43
- ### 3.2.4 (2026-06-26)
44
- * (arteck) Dependencies have been updated
45
-
46
- ### 3.2.3 (2026-06-25)
47
- * (arteck) typo
48
- * (arteck) fix some warnings
49
- * (arteck) fix internal mqtt
50
- * (arteck) fix languages
51
-
52
49
  ## License
53
50
 
54
51
  MIT License
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "zigbee2mqtt",
4
- "version": "3.2.7",
4
+ "version": "3.2.9",
5
5
  "news": {
6
+ "3.2.9": {
7
+ "en": "url fix",
8
+ "de": "URL-Fix",
9
+ "ru": "исправление URL-адреса",
10
+ "pt": "url fix",
11
+ "nl": "URL-correctie",
12
+ "fr": "url fix",
13
+ "it": "url fix",
14
+ "es": "url fix",
15
+ "pl": "poprawka adresu URL",
16
+ "uk": "виправлення URL-адреси",
17
+ "zh-cn": "网址修复"
18
+ },
19
+ "3.2.8": {
20
+ "en": "fix also fpor dummy mqtt if ws selected",
21
+ "de": "Fix auch für Dummy-MQT, falls gewählt",
22
+ "ru": "исправить также фиктивный matt, если мы выбрали",
23
+ "pt": "fixe também para dummy matt se eu escolher",
24
+ "nl": "ook opgelost voor dummy-mqt, indien geselecteerd",
25
+ "fr": "fix aussi pour le faux MQT si sélectionné",
26
+ "it": "fix anche per dummy mtt se scelto",
27
+ "es": "corregir también para MQT ficticio si lo elegí",
28
+ "pl": "napraw również fpor dummy mqtt, jeśli wybrano ws",
29
+ "uk": "Виправте також фпор фіктивний mqtt, якщо вибрано WS",
30
+ "zh-cn": "如果我们选择了,还修复了虚拟 mqtt 的问题"
31
+ },
6
32
  "3.2.7": {
7
33
  "en": "fix available status direct after new device is paired\nfix internal mqtt handling",
8
34
  "de": "Verfügbarkeit direkt nach Kopplung korrigieren\nFix internes MQTT-Handling",
@@ -67,32 +93,6 @@
67
93
  "pl": "literówka\nnapraw niektóre ostrzeżenia\nnapraw wewnętrzny MQTT\nnaprawić języki",
68
94
  "uk": "друкарська помилка\nвиправити деякі попередження\nвиправити внутрішній mqtt\nвиправити мови",
69
95
  "zh-cn": "拼写错误\n修复一些警告\n修复内部 MQTT\n修复语言"
70
- },
71
- "3.2.2": {
72
- "en": "Dependencies have been updated",
73
- "de": "Abhängigkeiten wurden aktualisiert",
74
- "ru": "Зависимости были обновлены",
75
- "pt": "As dependências foram atualizadas",
76
- "nl": "Afhankelijkheden zijn bijgewerkt",
77
- "fr": "Les dépendances ont été actualisées",
78
- "it": "Le dipendenze sono state aggiornate",
79
- "es": "Se han actualizado las dependencias",
80
- "pl": "Zaktualizowano zależności",
81
- "uk": "Залежність було оновлено",
82
- "zh-cn": "依赖关系已更新"
83
- },
84
- "3.2.1": {
85
- "en": "Adapter requires node.js >= 22 now\nupd device manager\nfix aedes-persistence\nfix illuminance",
86
- "de": "Adapter benötigt node.js >= 22 jetzt\nupd device manager\naedes-persistence reparieren\nbefestigungsleuchten",
87
- "ru": "Адаптер требует node.js >= 22 сейчас\nобновленный device manager\nфиксировать стойкость\nфиксировать освещенность",
88
- "pt": "Adaptador requer nod.js >= 22 agora\ngerenciador de dispositivos upd\ncorrigir aedes-persistência\nfixar a iluminação",
89
- "nl": "Voor de adapter zijn node.js < 22 nu nodig\nupd apparaatbeheer\nfix aedes-persistence\nfix verlichtingssterkte",
90
- "fr": "Adaptateur nécessite node.js >= 22 maintenant\ngestionnaire de périphérique mis à jour\nfixer la persistance des aedes\nfixer l'éclairage",
91
- "it": "Adattatore richiede node.js >= 22 ora\nupd device manager\nfissare aedes-persistenza\nilluminazione di correzione",
92
- "es": "Adaptador requiere node.js ю= 22 ahora\nupd device manager\narreglar aedes-persistence\niluminación de fijación",
93
- "pl": "Adapter wymaga node.js > = 22\nmenedżer urządzenia upd\nfix aedes- trwałość\npodświetlenie",
94
- "uk": "Адаптер вимагає node.js >= 22 тепер\nдиспетчер пристроїв\nфіксувати адисистентність\nфіксувати ілюмінанс",
95
- "zh-cn": "适配器需要节点.js 现在22\n上调设备管理器\n固定死因-持久性\n修补灯光"
96
96
  }
97
97
  },
98
98
  "messages": [
@@ -77,6 +77,15 @@ class WebsocketController {
77
77
  this.adapter.log.info('Connect to Zigbee2MQTT over websocket connection.');
78
78
  this.sendPingToServer();
79
79
  this.wsHeartbeat();
80
+ // Einmaliger Fallback-Check: kommt innerhalb von 5s kein bridge/devices
81
+ // (z.B. weil Z2M nach einem dummyMqtt-Neuaufbau noch nicht "bereit" ist),
82
+ // versuche die Geräteliste über die Z2M-WebUI-REST-API nachzuladen.
83
+ // Nur relevant, wenn der Adapter selbst einen (dummy) MQTT-Broker verwaltet –
84
+ // bei rein externem MQTT-Server (dummyMqtt=false) bleibt dieser über einen
85
+ // Adapter-Neustart hinweg unberührt, ein Fallback ist dort nicht nötig.
86
+ if (this.adapter.config.dummyMqtt === true && typeof this.adapter.scheduleDeviceReloadFallback === 'function') {
87
+ this.adapter.scheduleDeviceReloadFallback();
88
+ }
80
89
  });
81
90
 
82
91
  this.wsClient.on('pong', () => {
package/main.js CHANGED
@@ -4,7 +4,6 @@
4
4
  // you need to create an adapter
5
5
  const core = require('@iobroker/adapter-core');
6
6
  const mqtt = require('mqtt');
7
- const axios = require('axios');
8
7
  const utils = require('./lib/utils');
9
8
  const schedule = require('node-schedule');
10
9
  const checkConfig = require('./lib/check').checkConfig;
@@ -275,8 +274,11 @@ class Zigbee2mqtt extends core.Adapter {
275
274
  /**
276
275
  * Plant einen einmaligen Fallback-Timer: Kommt innerhalb von 5 Sekunden kein
277
276
  * bridge/devices von Zigbee2MQTT an (deviceCache bleibt leer), wird versucht,
278
- * die Geräteliste über die Z2M-WebUI-REST-API (`/api/devices`) nachzuladen.
279
- * Wird KEIN neuer MQTT-Client / Broker erzeugt – nur ein einmaliger HTTP-Call.
277
+ * die Geräteliste über einen kurzlebigen WebSocket-Request gegen die Z2M-WebUI
278
+ * nachzuladen (Zigbee2MQTT bietet dort KEINE REST-API – nur den WebSocket unter
279
+ * `/api`, denselben, den auch connectionType "ws" nutzt).
280
+ * Wird KEIN neuer MQTT-Client / Broker erzeugt – nur eine einmalige, kurzlebige
281
+ * zusätzliche WS-Verbindung.
280
282
  */
281
283
  scheduleDeviceReloadFallback() {
282
284
  if (this.deviceReloadTimer) {
@@ -289,11 +291,16 @@ class Zigbee2mqtt extends core.Adapter {
289
291
  }
290
292
 
291
293
  /**
292
- * Lädt die Geräteliste einmalig über die Z2M-WebUI-REST-API nach, falls nach
293
- * dem MQTT-Connect innerhalb von 5s kein bridge/devices empfangen wurde.
294
- * Wird u.a. benötigt, wenn bei "intmqtt" der interne Broker (In-Memory-Persistenz)
295
- * neu erzeugt wurde und Zigbee2MQTT die Retained-Nachrichten nicht von sich aus
296
- * erneut published (Z2M selbst läuft weiter, ohne eigenen Neustart).
294
+ * Lädt die Geräteliste einmalig nach, falls nach dem Verbindungsaufbau
295
+ * (MQTT-connect ODER WebSocket-open) innerhalb von 5s kein bridge/devices
296
+ * empfangen wurde. Wird u.a. benötigt, wenn bei "intmqtt"/"ws"+dummyMqtt der
297
+ * interne Broker neu erzeugt wurde und Zigbee2MQTT die Retained-Nachrichten
298
+ * nicht von sich aus erneut published.
299
+ *
300
+ * Zigbee2MQTT hat keine REST-API für Geräte – daher wird hierfür kurzzeitig
301
+ * (max. 8s) eine zusätzliche WebSocket-Verbindung zur Z2M-WebUI (`/api`)
302
+ * aufgebaut, auf die erste `bridge/devices`-Nachricht gewartet und die
303
+ * Verbindung danach sofort wieder geschlossen.
297
304
  */
298
305
  async tryFallbackDeviceReload() {
299
306
  if (this.deviceCache.length > 0) {
@@ -304,35 +311,95 @@ class Zigbee2mqtt extends core.Adapter {
304
311
  this.log.debug('Fallback device reload skipped – WebUI address/port not configured.');
305
312
  return;
306
313
  }
314
+ if (!this.deviceController || !this.statesController) {
315
+ this.log.debug('Fallback device reload: controllers not yet initialized, aborting.');
316
+ return;
317
+ }
307
318
  this.log.warn(
308
- 'No bridge/devices received from Zigbee2MQTT within 5s – trying fallback via WebUI REST API. ' +
309
- 'This can happen if the internal MQTT broker was recreated (adapter restart) while Zigbee2MQTT itself keeps running.'
319
+ 'No bridge/devices received from Zigbee2MQTT within 5s – trying fallback via a temporary WebSocket ' +
320
+ 'request to the Zigbee2MQTT WebUI. This can happen if the internal/dummy MQTT broker was recreated ' +
321
+ '(adapter restart) while Zigbee2MQTT itself keeps running.'
310
322
  );
311
- try {
312
- const scheme = this.config.webUIScheme || 'http';
313
- const url = `${scheme}://${this.config.webUIServer}:${this.config.webUIPort}/api/devices`;
314
- const response = await axios.get(url, { timeout: 5000 });
315
- const devices = response && response.data;
316
- if (!Array.isArray(devices) || devices.length === 0) {
317
- this.log.warn('Fallback device reload: WebUI API returned no devices.');
318
- return;
319
- }
320
- if (!this.deviceController || !this.statesController) {
321
- this.log.debug('Fallback device reload: controllers not yet initialized, aborting.');
323
+
324
+ const WebSocketClient = require('ws');
325
+ const wsScheme = this.config.webUIScheme === 'https' ? 'wss' : 'ws';
326
+ const url = `${wsScheme}://${this.config.webUIServer}:${this.config.webUIPort}/api`;
327
+ const FALLBACK_TIMEOUT_MS = 8000;
328
+
329
+ await new Promise((resolvePromise) => {
330
+ let settled = false;
331
+ let fallbackWs = null;
332
+ let timeoutHandle = null;
333
+
334
+ const finish = (errorMessage) => {
335
+ if (settled) {
336
+ return;
337
+ }
338
+ settled = true;
339
+ if (timeoutHandle) {
340
+ clearTimeout(timeoutHandle);
341
+ }
342
+ if (fallbackWs) {
343
+ try {
344
+ fallbackWs.removeAllListeners();
345
+ fallbackWs.terminate();
346
+ } catch {
347
+ // ignore cleanup errors
348
+ }
349
+ }
350
+ if (errorMessage) {
351
+ this.log.error(
352
+ `Fallback device reload via WebUI WebSocket failed: ${errorMessage}. ` +
353
+ 'Please verify that the Zigbee2MQTT frontend is enabled and reachable, or restart ' +
354
+ 'Zigbee2MQTT once to force it to re-publish bridge/devices.'
355
+ );
356
+ }
357
+ resolvePromise();
358
+ };
359
+
360
+ try {
361
+ fallbackWs = new WebSocketClient(url, { rejectUnauthorized: false });
362
+ } catch (e) {
363
+ finish(e && e.message ? e.message : String(e));
322
364
  return;
323
365
  }
324
- await this.deviceController.createDeviceDefinitions(devices);
325
- await this.deviceController.createOrUpdateDevices();
326
- await this.statesController.subscribeWritableStates();
327
- await this.statesController.processQueue();
328
- this.log.info(`Fallback device reload completed – ${devices.length} device(s) imported via WebUI API.`);
329
- } catch (e) {
330
- this.log.error(
331
- `Fallback device reload via WebUI API failed: ${e && e.message ? e.message : String(e)}. ` +
332
- 'Please verify that the Zigbee2MQTT frontend is enabled and reachable, or restart Zigbee2MQTT once ' +
333
- 'to force it to re-publish bridge/devices.'
334
- );
335
- }
366
+
367
+ timeoutHandle = setTimeout(() => finish('timeout waiting for bridge/devices'), FALLBACK_TIMEOUT_MS);
368
+
369
+ fallbackWs.on('message', (data) => {
370
+ let msg;
371
+ try {
372
+ msg = JSON.parse(data.toString());
373
+ } catch {
374
+ return;
375
+ }
376
+ if (!msg || msg.topic !== 'bridge/devices' || !Array.isArray(msg.payload)) {
377
+ return;
378
+ }
379
+ (async () => {
380
+ try {
381
+ await this.deviceController.createDeviceDefinitions(msg.payload);
382
+ await this.deviceController.createOrUpdateDevices();
383
+ await this.statesController.subscribeWritableStates();
384
+ await this.statesController.processQueue();
385
+ this.log.info(
386
+ `Fallback device reload completed – ${msg.payload.length} device(s) imported via WebUI WebSocket.`
387
+ );
388
+ finish();
389
+ } catch (e) {
390
+ finish(e && e.message ? e.message : String(e));
391
+ }
392
+ })();
393
+ });
394
+
395
+ fallbackWs.on('error', (err) => {
396
+ finish(err && err.message ? err.message : String(err));
397
+ });
398
+
399
+ fallbackWs.on('close', () => {
400
+ finish('WebSocket closed before bridge/devices arrived');
401
+ });
402
+ });
336
403
  }
337
404
 
338
405
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zigbee2mqtt",
3
- "version": "3.2.7",
3
+ "version": "3.2.9",
4
4
  "description": "Zigbee2MQTT adapter for ioBroker",
5
5
  "author": {
6
6
  "name": "Dennis Rathjen and Arthur Rupp",