iobroker.zigbee2mqtt 3.2.8 → 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,8 +30,11 @@ 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
+
33
36
  ### 3.2.8 (2026-09-19)
34
- * (arteck) fix also fpor dummy mqtt if ws selected
37
+ * (arteck) fix also for dummy mqtt if ws selected
35
38
 
36
39
  ### 3.2.7 (2026-09-19)
37
40
  * (arteck) fix available status direct after new device is paired
@@ -43,9 +46,6 @@ check you VM Settings
43
46
  ### 3.2.5 (2026-08-04)
44
47
  * (arteck) State updates lag issue https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662
45
48
 
46
- ### 3.2.4 (2026-06-26)
47
- * (arteck) Dependencies have been updated
48
-
49
49
  ## License
50
50
 
51
51
  MIT License
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "zigbee2mqtt",
4
- "version": "3.2.8",
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
+ },
6
19
  "3.2.8": {
7
20
  "en": "fix also fpor dummy mqtt if ws selected",
8
21
  "de": "Fix auch für Dummy-MQT, falls gewählt",
@@ -80,19 +93,6 @@
80
93
  "pl": "literówka\nnapraw niektóre ostrzeżenia\nnapraw wewnętrzny MQTT\nnaprawić języki",
81
94
  "uk": "друкарська помилка\nвиправити деякі попередження\nвиправити внутрішній mqtt\nвиправити мови",
82
95
  "zh-cn": "拼写错误\n修复一些警告\n修复内部 MQTT\n修复语言"
83
- },
84
- "3.2.2": {
85
- "en": "Dependencies have been updated",
86
- "de": "Abhängigkeiten wurden aktualisiert",
87
- "ru": "Зависимости были обновлены",
88
- "pt": "As dependências foram atualizadas",
89
- "nl": "Afhankelijkheden zijn bijgewerkt",
90
- "fr": "Les dépendances ont été actualisées",
91
- "it": "Le dipendenze sono state aggiornate",
92
- "es": "Se han actualizado las dependencias",
93
- "pl": "Zaktualizowano zależności",
94
- "uk": "Залежність було оновлено",
95
- "zh-cn": "依赖关系已更新"
96
96
  }
97
97
  },
98
98
  "messages": [
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,13 +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 Verbindungsaufbau (MQTT-connect ODER WebSocket-open) innerhalb von 5s kein
294
- * bridge/devices empfangen wurde. Wird u.a. benötigt, wenn bei "intmqtt" der interne
295
- * Broker (In-Memory-Persistenz) neu erzeugt wurde und Zigbee2MQTT die Retained-
296
- * Nachrichten nicht von sich aus erneut published, oder wenn bei "ws" (inkl.
297
- * dummyMqtt) Z2M nach einem Verbindungsabbruch nicht sofort den vollständigen
298
- * State über die WebSocket-API nachsendet.
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.
299
304
  */
300
305
  async tryFallbackDeviceReload() {
301
306
  if (this.deviceCache.length > 0) {
@@ -306,35 +311,95 @@ class Zigbee2mqtt extends core.Adapter {
306
311
  this.log.debug('Fallback device reload skipped – WebUI address/port not configured.');
307
312
  return;
308
313
  }
314
+ if (!this.deviceController || !this.statesController) {
315
+ this.log.debug('Fallback device reload: controllers not yet initialized, aborting.');
316
+ return;
317
+ }
309
318
  this.log.warn(
310
- 'No bridge/devices received from Zigbee2MQTT within 5s – trying fallback via WebUI REST API. ' +
311
- '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.'
312
322
  );
313
- try {
314
- const scheme = this.config.webUIScheme || 'http';
315
- const url = `${scheme}://${this.config.webUIServer}:${this.config.webUIPort}/api/devices`;
316
- const response = await axios.get(url, { timeout: 5000 });
317
- const devices = response && response.data;
318
- if (!Array.isArray(devices) || devices.length === 0) {
319
- this.log.warn('Fallback device reload: WebUI API returned no devices.');
320
- return;
321
- }
322
- if (!this.deviceController || !this.statesController) {
323
- 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));
324
364
  return;
325
365
  }
326
- await this.deviceController.createDeviceDefinitions(devices);
327
- await this.deviceController.createOrUpdateDevices();
328
- await this.statesController.subscribeWritableStates();
329
- await this.statesController.processQueue();
330
- this.log.info(`Fallback device reload completed – ${devices.length} device(s) imported via WebUI API.`);
331
- } catch (e) {
332
- this.log.error(
333
- `Fallback device reload via WebUI API failed: ${e && e.message ? e.message : String(e)}. ` +
334
- 'Please verify that the Zigbee2MQTT frontend is enabled and reachable, or restart Zigbee2MQTT once ' +
335
- 'to force it to re-publish bridge/devices.'
336
- );
337
- }
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
+ });
338
403
  }
339
404
 
340
405
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zigbee2mqtt",
3
- "version": "3.2.8",
3
+ "version": "3.2.9",
4
4
  "description": "Zigbee2MQTT adapter for ioBroker",
5
5
  "author": {
6
6
  "name": "Dennis Rathjen and Arthur Rupp",