iobroker.zigbee2mqtt 3.2.4 → 3.2.5
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 +3 -4
- package/admin/i18n/de/translations.json +5 -1
- package/admin/i18n/en/translations.json +5 -1
- package/admin/i18n/es/translations.json +7 -3
- package/admin/i18n/fr/translations.json +7 -3
- package/admin/i18n/it/translations.json +7 -3
- package/admin/i18n/nl/translations.json +7 -3
- package/admin/i18n/pl/translations.json +7 -3
- package/admin/i18n/pt/translations.json +7 -3
- package/admin/i18n/ru/translations.json +7 -3
- package/admin/i18n/uk/translations.json +7 -3
- package/admin/i18n/zh-cn/translations.json +5 -1
- package/admin/jsonConfig.json +34 -44
- package/io-package.json +14 -1
- package/lib/deviceController.js +19 -0
- package/lib/states.js +1 -1
- package/lib/statesController.js +153 -20
- package/lib/websocketController.js +5 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -30,9 +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.5 (2026-08-04)
|
|
34
|
+
* (arteck) State updates lag issue https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662
|
|
35
|
+
|
|
33
36
|
### 3.2.4 (2026-06-26)
|
|
34
37
|
* (arteck) Dependencies have been updated
|
|
35
|
-
*
|
|
36
38
|
|
|
37
39
|
### 3.2.3 (2026-06-25)
|
|
38
40
|
* (arteck) typo
|
|
@@ -49,9 +51,6 @@ check you VM Settings
|
|
|
49
51
|
* (arteck) fix aedes-persistence
|
|
50
52
|
* (arteck) fix illuminance
|
|
51
53
|
|
|
52
|
-
### 3.2.0 (2026-04-26)
|
|
53
|
-
* (arteck) del deprectated setStateAsync
|
|
54
|
-
|
|
55
54
|
## License
|
|
56
55
|
|
|
57
56
|
MIT License
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "Größe der Objekt-Symbole in Pixeln",
|
|
60
60
|
"Expert configurations": "Experteneinstellungen",
|
|
61
61
|
"coming soon": "kommt bald",
|
|
62
|
-
"Delete old / unused states": "Alte / ungenutzte Zustände löschen"
|
|
62
|
+
"Delete old / unused states": "Alte / ungenutzte Zustände löschen",
|
|
63
|
+
"Debug": "Debug",
|
|
64
|
+
"Info": "Info",
|
|
65
|
+
"Warning": "Warnung",
|
|
66
|
+
"Error": "Fehler"
|
|
63
67
|
}
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "Size of the object icons in pixels",
|
|
60
60
|
"Expert configurations": "Expert configurations",
|
|
61
61
|
"coming soon": "coming soon ",
|
|
62
|
-
"Delete old / unused states": "Delete old / unused states"
|
|
62
|
+
"Delete old / unused states": "Delete old / unused states",
|
|
63
|
+
"Debug": "Debug",
|
|
64
|
+
"Info": "Info",
|
|
65
|
+
"Warning": "Warning",
|
|
66
|
+
"Error": "Error"
|
|
63
67
|
}
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"With which log level should a negative search be logged?": "¿Con qué nivel de registro se debe registrar una búsqueda negativa?",
|
|
47
47
|
"Time of the automatic check": "Hora del control automático",
|
|
48
48
|
"More information": "Más información",
|
|
49
|
-
"Expert Settings. Please only use if you know what you're doing": "
|
|
50
|
-
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "
|
|
49
|
+
"Expert Settings. Please only use if you know what you're doing": "Configuración de expertos. Úselo solo si sabe lo que está haciendo",
|
|
50
|
+
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "Actualizar siempre el estado de ocupación cuando llega un mensaje del servidor zigbee2mqtt (solo para estado verdadero). Aumenta la carga en el sistema ioBroker",
|
|
51
51
|
"Always update available state when message included last_seen status": "Siempre actualizar el estado disponible cuando el mensaje incluya el estado last_seen",
|
|
52
52
|
"WS": "WS",
|
|
53
53
|
"WS (SSL)": "WS (SSL)",
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "Tamaño de los iconos de objetos en píxeles",
|
|
60
60
|
"Expert configurations": "Configuraciones avanzadas",
|
|
61
61
|
"coming soon": "próximamente",
|
|
62
|
-
"Delete old / unused states": "Eliminar estados antiguos / no utilizados"
|
|
62
|
+
"Delete old / unused states": "Eliminar estados antiguos / no utilizados",
|
|
63
|
+
"Debug": "Depuración",
|
|
64
|
+
"Info": "Información",
|
|
65
|
+
"Warning": "Advertencia",
|
|
66
|
+
"Error": "Error"
|
|
63
67
|
}
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"With which log level should a negative search be logged?": "Avec quel niveau de journalisation une recherche négative doit-elle être enregistrée ?",
|
|
47
47
|
"Time of the automatic check": "Heure du contrôle automatique",
|
|
48
48
|
"More information": "Plus d'information",
|
|
49
|
-
"Expert Settings. Please only use if you know what you're doing": "
|
|
50
|
-
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "
|
|
49
|
+
"Expert Settings. Please only use if you know what you're doing": "Paramètres d'expert. À utiliser uniquement si vous savez ce que vous faites",
|
|
50
|
+
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "Toujours mettre à jour l'état d'occupation lorsqu'un message arrive du serveur zigbee2mqtt (uniquement pour l'état vrai). Augmente la charge sur le système ioBroker",
|
|
51
51
|
"Always update available state when message included last_seen status": "Mettre à jour l'état disponible lorsque le message inclut le statut last_seen",
|
|
52
52
|
"WS": "WS",
|
|
53
53
|
"WS (SSL)": "WS (SSL)",
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "Taille des icônes d'objet en pixels",
|
|
60
60
|
"Expert configurations": "Configurations avancées",
|
|
61
61
|
"coming soon": "bientôt disponible",
|
|
62
|
-
"Delete old / unused states": "Supprimer les états anciens / inutilisés"
|
|
62
|
+
"Delete old / unused states": "Supprimer les états anciens / inutilisés",
|
|
63
|
+
"Debug": "Débogage",
|
|
64
|
+
"Info": "Info",
|
|
65
|
+
"Warning": "Avertissement",
|
|
66
|
+
"Error": "Erreur"
|
|
63
67
|
}
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"With which log level should a negative search be logged?": "Con quale livello di registro deve essere registrata una ricerca negativa?",
|
|
47
47
|
"Time of the automatic check": "Orario del controllo automatico",
|
|
48
48
|
"More information": "Maggiori informazioni",
|
|
49
|
-
"Expert Settings. Please only use if you know what you're doing": "
|
|
50
|
-
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "
|
|
49
|
+
"Expert Settings. Please only use if you know what you're doing": "Impostazioni avanzate. Da utilizzare solo se sai cosa stai facendo",
|
|
50
|
+
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "Aggiorna sempre lo stato di occupazione quando arriva un messaggio dal server zigbee2mqtt (solo per stato vero). Aumenta il carico sul sistema ioBroker",
|
|
51
51
|
"Always update available state when message included last_seen status": "Aggiorna sempre lo stato disponibile quando il messaggio include lo stato last_seen",
|
|
52
52
|
"WS": "WS",
|
|
53
53
|
"WS (SSL)": "WS (SSL)",
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "Dimensione delle icone degli oggetti in pixel",
|
|
60
60
|
"Expert configurations": "Configurazioni avanzate",
|
|
61
61
|
"coming soon": "prossimamente",
|
|
62
|
-
"Delete old / unused states": "Elimina stati vecchi / inutilizzati"
|
|
62
|
+
"Delete old / unused states": "Elimina stati vecchi / inutilizzati",
|
|
63
|
+
"Debug": "Debug",
|
|
64
|
+
"Info": "Info",
|
|
65
|
+
"Warning": "Avviso",
|
|
66
|
+
"Error": "Errore"
|
|
63
67
|
}
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"With which log level should a negative search be logged?": "Met welk logniveau moet een negatieve zoekopdracht worden geregistreerd?",
|
|
47
47
|
"Time of the automatic check": "Tijdstip van de automatische controle",
|
|
48
48
|
"More information": "Meer informatie",
|
|
49
|
-
"Expert Settings. Please only use if you know what you're doing": "
|
|
50
|
-
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "
|
|
49
|
+
"Expert Settings. Please only use if you know what you're doing": "Expertinstellingen. Gebruik dit alleen als u weet wat u doet",
|
|
50
|
+
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "Altijd de bezettingsstatus bijwerken wanneer een bericht van de zigbee2mqtt-server arriveert (alleen voor ware status). Verhoogt de belasting op het ioBroker-systeem",
|
|
51
51
|
"Always update available state when message included last_seen status": "Altijd de beschikbare status bijwerken wanneer het bericht de last_seen-status bevat",
|
|
52
52
|
"WS": "WS",
|
|
53
53
|
"WS (SSL)": "WS (SSL)",
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "Grootte van de objectpictogrammen in pixels",
|
|
60
60
|
"Expert configurations": "Geavanceerde configuraties",
|
|
61
61
|
"coming soon": "binnenkort beschikbaar",
|
|
62
|
-
"Delete old / unused states": "Oude / ongebruikte statussen verwijderen"
|
|
62
|
+
"Delete old / unused states": "Oude / ongebruikte statussen verwijderen",
|
|
63
|
+
"Debug": "Debug",
|
|
64
|
+
"Info": "Info",
|
|
65
|
+
"Warning": "Waarschuwing",
|
|
66
|
+
"Error": "Fout"
|
|
63
67
|
}
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"With which log level should a negative search be logged?": "Na jakim poziomie rejestrowania należy rejestrować wyszukiwanie wykluczające?",
|
|
47
47
|
"Time of the automatic check": "Czas automatycznego sprawdzenia",
|
|
48
48
|
"More information": "Więcej informacji",
|
|
49
|
-
"Expert Settings. Please only use if you know what you're doing": "
|
|
50
|
-
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "
|
|
49
|
+
"Expert Settings. Please only use if you know what you're doing": "Ustawienia eksperckie. Używaj tylko wtedy, gdy wiesz, co robisz",
|
|
50
|
+
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "Zawsze aktualizuj stan zajętości, gdy przychodzi wiadomość z serwera zigbee2mqtt (tylko dla stanu prawdziwego). Zwiększa obciążenie systemu ioBroker",
|
|
51
51
|
"Always update available state when message included last_seen status": "Zawsze aktualizuj available stan, gdy wiadomość zawiera status last_seen",
|
|
52
52
|
"WS": "WS",
|
|
53
53
|
"WS (SSL)": "WS (SSL)",
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "Rozmiar ikon obiektów w pikselach",
|
|
60
60
|
"Expert configurations": "Konfiguracje zaawansowane",
|
|
61
61
|
"coming soon": "wkrótce dostępne",
|
|
62
|
-
"Delete old / unused states": "Usuń stare / nieużywane stany"
|
|
62
|
+
"Delete old / unused states": "Usuń stare / nieużywane stany",
|
|
63
|
+
"Debug": "Debugowanie",
|
|
64
|
+
"Info": "Informacja",
|
|
65
|
+
"Warning": "Ostrzeżenie",
|
|
66
|
+
"Error": "Błąd"
|
|
63
67
|
}
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"With which log level should a negative search be logged?": "Com qual nível de log uma pesquisa negativa deve ser registrada?",
|
|
47
47
|
"Time of the automatic check": "Hora da verificação automática",
|
|
48
48
|
"More information": "Mais Informações",
|
|
49
|
-
"Expert Settings. Please only use if you know what you're doing": "
|
|
50
|
-
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "
|
|
49
|
+
"Expert Settings. Please only use if you know what you're doing": "Configurações de especialista. Use apenas se você souber o que está fazendo",
|
|
50
|
+
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "Sempre atualizar o estado de ocupação quando chega uma mensagem do servidor zigbee2mqtt (apenas para estado verdadeiro). Aumenta a carga no sistema ioBroker",
|
|
51
51
|
"Always update available state when message included last_seen status": "Sempre atualize o estado disponível quando a mensagem incluir o status last_seen",
|
|
52
52
|
"WS": "WS",
|
|
53
53
|
"WS (SSL)": "WS (SSL)",
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "Tamanho dos ícones dos objetos em pixels",
|
|
60
60
|
"Expert configurations": "Configurações avançadas",
|
|
61
61
|
"coming soon": "em breve",
|
|
62
|
-
"Delete old / unused states": "Excluir estados antigos / não utilizados"
|
|
62
|
+
"Delete old / unused states": "Excluir estados antigos / não utilizados",
|
|
63
|
+
"Debug": "Depuração",
|
|
64
|
+
"Info": "Info",
|
|
65
|
+
"Warning": "Aviso",
|
|
66
|
+
"Error": "Erro"
|
|
63
67
|
}
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"With which log level should a negative search be logged?": "На каком уровне журнала следует регистрировать отрицательный поиск?",
|
|
47
47
|
"Time of the automatic check": "Время автоматической проверки",
|
|
48
48
|
"More information": "Больше информации",
|
|
49
|
-
"Expert Settings. Please only use if you know what you're doing": "
|
|
50
|
-
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "
|
|
49
|
+
"Expert Settings. Please only use if you know what you're doing": "Экспертные настройки. Используйте только если вы знаете, что делаете",
|
|
50
|
+
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "Всегда обновлять состояние занятости при получении сообщения от сервера zigbee2mqtt (только для истинного состояния). Увеличивает нагрузку на систему ioBroker",
|
|
51
51
|
"Always update available state when message included last_seen status": "Всегда обновляйте доступное состояние, когда сообщение включает статус last_seen",
|
|
52
52
|
"WS": "WS",
|
|
53
53
|
"WS (SSL)": "WS (SSL)",
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "Размер значков объектов в пикселях",
|
|
60
60
|
"Expert configurations": "Расширенные настройки",
|
|
61
61
|
"coming soon": "скоро будет доступно",
|
|
62
|
-
"Delete old / unused states": "Удалить старые / неиспользуемые состояния"
|
|
62
|
+
"Delete old / unused states": "Удалить старые / неиспользуемые состояния",
|
|
63
|
+
"Debug": "Отладка",
|
|
64
|
+
"Info": "Информация",
|
|
65
|
+
"Warning": "Предупреждение",
|
|
66
|
+
"Error": "Ошибка"
|
|
63
67
|
}
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"With which log level should a negative search be logged?": "На якому рівні журналу слід реєструвати негативний пошук?",
|
|
47
47
|
"Time of the automatic check": "Час автоматичної перевірки",
|
|
48
48
|
"More information": "Більше інформації",
|
|
49
|
-
"Expert Settings. Please only use if you know what you're doing": "
|
|
50
|
-
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "
|
|
49
|
+
"Expert Settings. Please only use if you know what you're doing": "Експертні налаштування. Використовуйте лише якщо ви знаєте, що робите",
|
|
50
|
+
"Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System": "Завжди оновлювати стан зайнятості при надходженні повідомлення від сервера zigbee2mqtt (тільки для істинного стану). Збільшує навантаження на систему ioBroker",
|
|
51
51
|
"Always update available state when message included last_seen status": "Завжди оновлюйте доступний стан, коли повідомлення містить статус last_seen",
|
|
52
52
|
"WS": "WS",
|
|
53
53
|
"WS (SSL)": "WS (SSL)",
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "Розмір значків об'єктів у пікселях",
|
|
60
60
|
"Expert configurations": "Розширені налаштування",
|
|
61
61
|
"coming soon": "незабаром",
|
|
62
|
-
"Delete old / unused states": "Видалити старі / невикористовувані стани"
|
|
62
|
+
"Delete old / unused states": "Видалити старі / невикористовувані стани",
|
|
63
|
+
"Debug": "Налагодження",
|
|
64
|
+
"Info": "Інформація",
|
|
65
|
+
"Warning": "Попередження",
|
|
66
|
+
"Error": "Помилка"
|
|
63
67
|
}
|
|
@@ -59,5 +59,9 @@
|
|
|
59
59
|
"Size of the object icons in pixels": "对象图标大小(像素)",
|
|
60
60
|
"Expert configurations": "高级配置",
|
|
61
61
|
"coming soon": "即将推出",
|
|
62
|
-
"Delete old / unused states": "删除旧的/未使用的状态"
|
|
62
|
+
"Delete old / unused states": "删除旧的/未使用的状态",
|
|
63
|
+
"Debug": "调试",
|
|
64
|
+
"Info": "信息",
|
|
65
|
+
"Warning": "警告",
|
|
66
|
+
"Error": "错误"
|
|
63
67
|
}
|
package/admin/jsonConfig.json
CHANGED
|
@@ -10,37 +10,37 @@
|
|
|
10
10
|
"label": "Main Settings",
|
|
11
11
|
"items": {
|
|
12
12
|
"header_Start": {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
"type": "header",
|
|
14
|
+
"text": "Welcome to Zigbee2MQTT Adapter",
|
|
15
|
+
"size": 2
|
|
16
16
|
},
|
|
17
17
|
"_textStart": {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
"type": "staticText",
|
|
19
|
+
"text": "A detailed documentation with explanations and all further information can be found on this GitHub page",
|
|
20
|
+
"xs": 12,
|
|
21
|
+
"sm": 12,
|
|
22
|
+
"md": 6,
|
|
23
|
+
"lg": 4,
|
|
24
|
+
"xl": 4,
|
|
25
|
+
"style": {
|
|
26
|
+
"fontSize": 14,
|
|
27
|
+
"marginTop": 0
|
|
28
|
+
}
|
|
29
29
|
},
|
|
30
30
|
"_documentationLink": {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
"type": "staticLink",
|
|
32
|
+
"label": "click for Documentation",
|
|
33
|
+
"button": true,
|
|
34
|
+
"href": "https://github.com/arteck/ioBroker.zigbee2mqtt/blob/main/docs/wiki.md",
|
|
35
|
+
"xs": 12,
|
|
36
|
+
"sm": 12,
|
|
37
|
+
"md": 6,
|
|
38
|
+
"lg": 4,
|
|
39
|
+
"xl": 4,
|
|
40
|
+
"style": {
|
|
41
|
+
"fontSize": 18,
|
|
42
|
+
"marginTop": 0
|
|
43
|
+
}
|
|
44
44
|
},
|
|
45
45
|
"connectionHeader": {
|
|
46
46
|
"type": "header",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"md": 6,
|
|
81
81
|
"lg": 4,
|
|
82
82
|
"xl": 4,
|
|
83
|
-
"default": "zigbee2mqtt",
|
|
83
|
+
"default": "zigbee2mqtt",
|
|
84
84
|
"hidden": "data.connectionType != 'exmqtt'"
|
|
85
85
|
},
|
|
86
86
|
"spacer01": {
|
|
@@ -434,7 +434,6 @@
|
|
|
434
434
|
"type": "panel",
|
|
435
435
|
"label": "Other configurations",
|
|
436
436
|
"items": {
|
|
437
|
-
|
|
438
437
|
"proxyZ2MLogs": {
|
|
439
438
|
"type": "checkbox",
|
|
440
439
|
"label": "Proxy Zigbee2MQTT logs to ioBroker logs",
|
|
@@ -494,31 +493,23 @@
|
|
|
494
493
|
"label": "With which log level should a negative search be logged?",
|
|
495
494
|
"options": [
|
|
496
495
|
{
|
|
497
|
-
"label":
|
|
498
|
-
"en": "Debug"
|
|
499
|
-
},
|
|
496
|
+
"label": "Debug",
|
|
500
497
|
"value": "debug"
|
|
501
498
|
},
|
|
502
499
|
{
|
|
503
|
-
"label":
|
|
504
|
-
"en": "Info"
|
|
505
|
-
},
|
|
500
|
+
"label": "Info",
|
|
506
501
|
"value": "info"
|
|
507
502
|
},
|
|
508
503
|
{
|
|
509
|
-
"label":
|
|
510
|
-
"en": "Warning"
|
|
511
|
-
},
|
|
504
|
+
"label": "Warning",
|
|
512
505
|
"value": "warn"
|
|
513
506
|
},
|
|
514
507
|
{
|
|
515
|
-
"label":
|
|
516
|
-
"en": "Error"
|
|
517
|
-
},
|
|
508
|
+
"label": "Error",
|
|
518
509
|
"value": "error"
|
|
519
510
|
}
|
|
520
511
|
],
|
|
521
|
-
"newLine": true,
|
|
512
|
+
"newLine": true,
|
|
522
513
|
"hidden": "data.coordinatorCheck != true"
|
|
523
514
|
},
|
|
524
515
|
"coordinatorCheckCron": {
|
|
@@ -545,7 +536,6 @@
|
|
|
545
536
|
"newLine": true,
|
|
546
537
|
"hidden": "data.coordinatorCheck != true"
|
|
547
538
|
},
|
|
548
|
-
|
|
549
539
|
"alwaysUpdateOccupancyState": {
|
|
550
540
|
"type": "checkbox",
|
|
551
541
|
"label": "Always update state for occupancy when message arrives from zigbee2mqtt server (Only for true state). Increases load on ioBroker System",
|
|
@@ -600,7 +590,7 @@
|
|
|
600
590
|
"_deleteOldStatesResult": {
|
|
601
591
|
"type": "staticText",
|
|
602
592
|
"text": "",
|
|
603
|
-
|
|
593
|
+
"xs": 12,
|
|
604
594
|
"sm": 6,
|
|
605
595
|
"md": 4,
|
|
606
596
|
"lg": 3,
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "zigbee2mqtt",
|
|
4
|
-
"version": "3.2.
|
|
4
|
+
"version": "3.2.5",
|
|
5
5
|
"news": {
|
|
6
|
+
"3.2.5": {
|
|
7
|
+
"en": "State updates lag issue https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662",
|
|
8
|
+
"de": "Problem mit verzögerten Statusaktualisierungen https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662",
|
|
9
|
+
"ru": "Проблема задержки обновления состояния: https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662",
|
|
10
|
+
"pt": "Problema de atraso nas atualizações de estado https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662",
|
|
11
|
+
"nl": "Probleem met vertraging bij statusupdates: https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662",
|
|
12
|
+
"fr": "Problème de latence lors de la mise à jour de l'état : https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662",
|
|
13
|
+
"it": "Problema di ritardo nell'aggiornamento dello stato https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662",
|
|
14
|
+
"es": "Problema de retraso en las actualizaciones de estado https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662",
|
|
15
|
+
"pl": "Problem z opóźnieniem aktualizacji stanu https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662",
|
|
16
|
+
"uk": "Проблема із затримкою оновлення стану https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662",
|
|
17
|
+
"zh-cn": "状态更新延迟问题 https://github.com/arteck/ioBroker.zigbee2mqtt/issues/662"
|
|
18
|
+
},
|
|
6
19
|
"3.2.4": {
|
|
7
20
|
"en": "Dependencies have been updated\n",
|
|
8
21
|
"de": "Die Abhängigkeiten wurden aktualisiert.\n",
|
package/lib/deviceController.js
CHANGED
|
@@ -70,6 +70,9 @@ class DeviceController extends dmUtils.DeviceManagement {
|
|
|
70
70
|
return;
|
|
71
71
|
}
|
|
72
72
|
utils.clearArray(this.deviceCache);
|
|
73
|
+
// Topic->Device Map-Cache invalidieren, da deviceCache neu aufgebaut wird
|
|
74
|
+
// (verhindert veraltete Referenzen -> u.a. available-State bleibt sonst false)
|
|
75
|
+
this.invalidateStatesDeviceMap();
|
|
73
76
|
for (const devicesMessag of devicesMessage) {
|
|
74
77
|
if (!devicesMessag || !devicesMessag.ieee_address) {
|
|
75
78
|
continue;
|
|
@@ -308,6 +311,8 @@ class DeviceController extends dmUtils.DeviceManagement {
|
|
|
308
311
|
return;
|
|
309
312
|
}
|
|
310
313
|
utils.clearArray(this.groupCache);
|
|
314
|
+
// Topic->Device Map-Cache invalidieren, da groupCache neu aufgebaut wird
|
|
315
|
+
this.invalidateStatesDeviceMap();
|
|
311
316
|
for (const groupMessage of groupsMessage) {
|
|
312
317
|
// Fix 5: fehlende Pflichtfelder abfangen
|
|
313
318
|
if (!groupMessage || groupMessage.id == null || !groupMessage.friendly_name) {
|
|
@@ -485,6 +490,8 @@ class DeviceController extends dmUtils.DeviceManagement {
|
|
|
485
490
|
.find((x) => x.id === messageObj.payload.data.from);
|
|
486
491
|
if (renamedDevice) {
|
|
487
492
|
renamedDevice.id = messageObj.payload.data.to;
|
|
493
|
+
// Topic (device.id) hat sich geändert -> Map-Cache invalidieren
|
|
494
|
+
this.invalidateStatesDeviceMap();
|
|
488
495
|
}
|
|
489
496
|
}
|
|
490
497
|
|
|
@@ -501,6 +508,18 @@ class DeviceController extends dmUtils.DeviceManagement {
|
|
|
501
508
|
}
|
|
502
509
|
}
|
|
503
510
|
|
|
511
|
+
/**
|
|
512
|
+
* Invalidiert den Topic->Device Map-Cache des StatesController.
|
|
513
|
+
* Muss nach jedem Neuaufbau von deviceCache/groupCache aufgerufen werden,
|
|
514
|
+
* damit findDeviceByTopic() keine veralteten Geräteobjekte liefert
|
|
515
|
+
* (sonst bleibt z.B. das available-State neu angelernter Geräte auf false).
|
|
516
|
+
*/
|
|
517
|
+
invalidateStatesDeviceMap() {
|
|
518
|
+
if (this.adapter.statesController && typeof this.adapter.statesController.clearDeviceMap === 'function') {
|
|
519
|
+
this.adapter.statesController.clearDeviceMap();
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
504
523
|
/**
|
|
505
524
|
* Erstellt eine bereinigte Kopie eines State-Objekts ohne interne Laufzeit-Felder
|
|
506
525
|
* (getter, setter, prop, etc.) für die ioBroker-Objektdefinition.
|
package/lib/states.js
CHANGED
|
@@ -418,7 +418,7 @@ const states = {
|
|
|
418
418
|
unit: '',
|
|
419
419
|
getter: (payload) => {
|
|
420
420
|
// Wenn illuminance_raw bereits im Payload → illuminance_raw_direct setzt ihn direkt
|
|
421
|
-
if (payload.illuminance_raw != null) { return
|
|
421
|
+
if (payload.illuminance_raw != null) { return Number(payload.illuminance_raw); }
|
|
422
422
|
const lux = payload.illuminance;
|
|
423
423
|
if (lux == null) { return undefined; }
|
|
424
424
|
if (lux <= 0) { return 0; }
|
package/lib/statesController.js
CHANGED
|
@@ -28,6 +28,76 @@ class StatesController {
|
|
|
28
28
|
this._debugDeviceList = logCustomizations.debugDevices
|
|
29
29
|
? String(logCustomizations.debugDevices).split(',').map((s) => s.trim()).filter(Boolean)
|
|
30
30
|
: [];
|
|
31
|
+
|
|
32
|
+
// PERFORMANCE: Map-Cache für Topic->Device Lookup (vermeidet concat().find() pro Nachricht)
|
|
33
|
+
this.deviceMap = new Map();
|
|
34
|
+
|
|
35
|
+
// PERFORMANCE: Session-Cache für bereits per setObjectNotExistsAsync erstellte IDs
|
|
36
|
+
// Vermeidet wiederholte js-controller-Roundtrips
|
|
37
|
+
this.ensuredObjects = new Set();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Invalidiert den Topic->Device Map-Cache sowie den Session-Cache der
|
|
42
|
+
* bereits sichergestellten Objekte. Muss aufgerufen werden, wenn
|
|
43
|
+
* deviceCache/groupCache zur Laufzeit neu aufgebaut werden.
|
|
44
|
+
*/
|
|
45
|
+
clearDeviceMap() {
|
|
46
|
+
this.deviceMap.clear();
|
|
47
|
+
this.ensuredObjects.clear();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Findet ein Gerät oder eine Gruppe anhand des Topics.
|
|
52
|
+
* Nutzt einen Map-Cache und füllt diesen bei Bedarf über eine einmalige lineare Suche.
|
|
53
|
+
*
|
|
54
|
+
* @param {string} topic Das Topic (entspricht device.id)
|
|
55
|
+
* @returns {object|null} Das gefundene Geräte-/Gruppenobjekt oder null
|
|
56
|
+
*/
|
|
57
|
+
findDeviceByTopic(topic) { if (!topic) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const t = String(topic);
|
|
61
|
+
if (this.deviceMap.has(t)) {
|
|
62
|
+
return this.deviceMap.get(t);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Fallback: lineare Suche (einmalig) und Cache-Eintrag
|
|
66
|
+
for (const grp of this.groupCache || []) {
|
|
67
|
+
if (grp && grp.id === t) {
|
|
68
|
+
this.deviceMap.set(t, grp);
|
|
69
|
+
return grp;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
for (const dev of this.deviceCache || []) {
|
|
73
|
+
if (dev && dev.id === t) {
|
|
74
|
+
this.deviceMap.set(t, dev);
|
|
75
|
+
return dev;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Legt ein ioBroker-Objekt nur einmal pro Session an (reduziert setObjectNotExistsAsync-Roundtrips).
|
|
83
|
+
*
|
|
84
|
+
* @param {string} id Vollständige Objekt-ID
|
|
85
|
+
* @param {object} obj Objekt-Definition für setObjectNotExistsAsync
|
|
86
|
+
*/
|
|
87
|
+
async ensureObjectOnce(id, obj) {
|
|
88
|
+
if (!id) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (this.ensuredObjects.has(id)) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
await this.adapter.setObjectNotExistsAsync(id, obj);
|
|
96
|
+
this.ensuredObjects.add(id);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
// Loggen, aber nicht wiederholend blockieren
|
|
99
|
+
this.adapter.log.warn(`ensureObjectOnce: setObjectNotExistsAsync failed for ${id}: ${e}`);
|
|
100
|
+
}
|
|
31
101
|
}
|
|
32
102
|
|
|
33
103
|
/**
|
|
@@ -45,7 +115,8 @@ class StatesController {
|
|
|
45
115
|
return;
|
|
46
116
|
}
|
|
47
117
|
|
|
48
|
-
|
|
118
|
+
// PERFORMANCE: Map-basiertes Lookup statt concat().find()
|
|
119
|
+
const device = this.findDeviceByTopic(messageObj.topic);
|
|
49
120
|
if (device) {
|
|
50
121
|
try {
|
|
51
122
|
await this.setDeviceStateSafely(messageObj, device);
|
|
@@ -140,6 +211,11 @@ class StatesController {
|
|
|
140
211
|
return;
|
|
141
212
|
}
|
|
142
213
|
|
|
214
|
+
// COLLECTION: Alle non-action state write-Promises sammeln und dann parallel ausführen
|
|
215
|
+
const stateWrites = [];
|
|
216
|
+
// Flag für available-Update (wenn last_seen vorhanden und config aktiv)
|
|
217
|
+
let needSetAvailableTrue = false;
|
|
218
|
+
|
|
143
219
|
for (let [key, value] of Object.entries(messageObj.payload)) {
|
|
144
220
|
if (value === undefined || value === null) {
|
|
145
221
|
continue;
|
|
@@ -160,14 +236,15 @@ class StatesController {
|
|
|
160
236
|
// some devices has addition information in payload
|
|
161
237
|
const fullPath = `${device.ieee_address}.additional`;
|
|
162
238
|
|
|
163
|
-
|
|
239
|
+
// PERFORMANCE: ensure object only once per session
|
|
240
|
+
await this.ensureObjectOnce(fullPath, {
|
|
164
241
|
type: 'channel',
|
|
165
242
|
common: {
|
|
166
243
|
name: 'hidden channelstate',
|
|
167
244
|
},
|
|
168
245
|
native: {},
|
|
169
246
|
});
|
|
170
|
-
await this.
|
|
247
|
+
await this.ensureObjectOnce(`${fullPath}.${key}`, {
|
|
171
248
|
type: 'state',
|
|
172
249
|
common: {
|
|
173
250
|
name: key,
|
|
@@ -181,7 +258,14 @@ class StatesController {
|
|
|
181
258
|
if (typeof value === 'object') {
|
|
182
259
|
value = JSON.stringify(value);
|
|
183
260
|
}
|
|
184
|
-
|
|
261
|
+
// write additional state without awaiting
|
|
262
|
+
stateWrites.push((async () => {
|
|
263
|
+
try {
|
|
264
|
+
await this.adapter.setStateChangedAsync(`${fullPath}.${key}`, value, true);
|
|
265
|
+
} catch (e) {
|
|
266
|
+
this.adapter.log.warn(`Cannot set additional state ${fullPath}.${key}: ${e}`);
|
|
267
|
+
}
|
|
268
|
+
})());
|
|
185
269
|
}
|
|
186
270
|
continue;
|
|
187
271
|
}
|
|
@@ -191,7 +275,8 @@ class StatesController {
|
|
|
191
275
|
|
|
192
276
|
// set available status if last_seen is set
|
|
193
277
|
if (state.id === 'last_seen' && this.adapter.config.alwaysUpdateAvailableState === true) {
|
|
194
|
-
|
|
278
|
+
// mark flag to set available before other writes
|
|
279
|
+
needSetAvailableTrue = true;
|
|
195
280
|
}
|
|
196
281
|
|
|
197
282
|
// State noch nicht erstellt? → überspringen (Requeue erfolgt nur,
|
|
@@ -199,6 +284,7 @@ class StatesController {
|
|
|
199
284
|
if (!this.createCache[device.ieee_address]
|
|
200
285
|
|| !this.createCache[device.ieee_address][state.id]
|
|
201
286
|
|| this.createCache[device.ieee_address][state.id].created !== true) {
|
|
287
|
+
// If none created we already pushed to queue earlier
|
|
202
288
|
continue;
|
|
203
289
|
}
|
|
204
290
|
|
|
@@ -208,13 +294,33 @@ class StatesController {
|
|
|
208
294
|
actionStates.push(state);
|
|
209
295
|
}
|
|
210
296
|
else if (this.adapter.config.alwaysUpdateOccupancyState === true && state.id === 'occupancy' && value === true) {
|
|
211
|
-
|
|
297
|
+
// occupancy true: schedule write
|
|
298
|
+
stateWrites.push((async () => {
|
|
299
|
+
try {
|
|
300
|
+
await this.setStateSafelyAsync(stateName, value);
|
|
301
|
+
} catch (e) {
|
|
302
|
+
this.adapter.log.warn(`Cannot set occupancy ${stateName}: ${e}`);
|
|
303
|
+
}
|
|
304
|
+
})());
|
|
212
305
|
}
|
|
213
306
|
else {
|
|
214
307
|
if (state.getter) {
|
|
215
|
-
|
|
308
|
+
// schedule changed-safe write
|
|
309
|
+
stateWrites.push((async () => {
|
|
310
|
+
try {
|
|
311
|
+
await this.setStateChangedSafelyAsync(stateName, state.getter(messageObj.payload));
|
|
312
|
+
} catch (e) {
|
|
313
|
+
this.adapter.log.warn(`Cannot set state ${stateName}: ${e}`);
|
|
314
|
+
}
|
|
315
|
+
})());
|
|
216
316
|
} else {
|
|
217
|
-
|
|
317
|
+
stateWrites.push((async () => {
|
|
318
|
+
try {
|
|
319
|
+
await this.setStateChangedSafelyAsync(stateName, value);
|
|
320
|
+
} catch (e) {
|
|
321
|
+
this.adapter.log.warn(`Cannot set state ${stateName}: ${e}`);
|
|
322
|
+
}
|
|
323
|
+
})());
|
|
218
324
|
}
|
|
219
325
|
}
|
|
220
326
|
} catch (err) {
|
|
@@ -223,25 +329,52 @@ class StatesController {
|
|
|
223
329
|
}
|
|
224
330
|
}
|
|
225
331
|
|
|
332
|
+
// Wenn last_seen vorhanden: setze available zuerst (nicht parallelisiert)
|
|
333
|
+
if (needSetAvailableTrue) {
|
|
334
|
+
try {
|
|
335
|
+
await this.setStateSafelyAsync(`${device.ieee_address}.available`, true);
|
|
336
|
+
} catch (e) {
|
|
337
|
+
this.adapter.log.warn(`Cannot set available for ${device.ieee_address}: ${e}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Parallel ausführen: non-action states
|
|
342
|
+
try {
|
|
343
|
+
await Promise.all(stateWrites);
|
|
344
|
+
} catch (e) {
|
|
345
|
+
this.adapter.log.warn(`processDeviceMessage: parallel writes encountered error: ${e}`);
|
|
346
|
+
}
|
|
226
347
|
|
|
348
|
+
// ACTION states: auch parallel ausführen, berücksichtige setStateWithTimeoutAsync
|
|
349
|
+
const actionPromises = [];
|
|
227
350
|
for (const state of actionStates) {
|
|
228
351
|
const stateName = `${device.ieee_address}.${state.id}`;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
352
|
+
actionPromises.push((async () => {
|
|
353
|
+
try {
|
|
354
|
+
const getterPayload = state.getter(messageObj.payload);
|
|
355
|
+
if (getterPayload !== undefined) {
|
|
356
|
+
if (state.isEvent && state.isEvent === true) {
|
|
357
|
+
if (state.type === 'boolean') {
|
|
358
|
+
// setStateWithTimeoutAsync kümmert sich intern um Timer/Optimierung
|
|
359
|
+
await this.setStateWithTimeoutAsync(stateName, getterPayload, 250);
|
|
360
|
+
} else {
|
|
361
|
+
await this.setStateSafelyAsync(stateName, getterPayload);
|
|
362
|
+
}
|
|
236
363
|
} else {
|
|
237
|
-
await this.
|
|
364
|
+
await this.setStateChangedSafelyAsync(stateName, getterPayload);
|
|
238
365
|
}
|
|
239
|
-
} else {
|
|
240
|
-
await this.setStateChangedSafelyAsync(stateName, getterPayload);
|
|
241
366
|
}
|
|
367
|
+
} catch (err) {
|
|
368
|
+
this.adapter.log.warn(`Cannot set action state ${stateName}: ${err}`);
|
|
242
369
|
}
|
|
243
|
-
}
|
|
244
|
-
|
|
370
|
+
})());
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (actionPromises.length > 0) {
|
|
374
|
+
try {
|
|
375
|
+
await Promise.all(actionPromises);
|
|
376
|
+
} catch (e) {
|
|
377
|
+
this.adapter.log.warn(`processDeviceMessage: action state parallel writes error: ${e}`);
|
|
245
378
|
}
|
|
246
379
|
}
|
|
247
380
|
}
|
|
@@ -147,6 +147,11 @@ class WebsocketController {
|
|
|
147
147
|
for (const key of Object.keys(this.adapter.createCache)) {
|
|
148
148
|
delete this.adapter.createCache[key];
|
|
149
149
|
}
|
|
150
|
+
// Topic->Device Map-Cache des StatesController invalidieren, da deviceCache/groupCache
|
|
151
|
+
// neu aufgebaut werden (verhindert veraltete Referenzen auf alte Geräteobjekte)
|
|
152
|
+
if (this.adapter.statesController && typeof this.adapter.statesController.clearDeviceMap === 'function') {
|
|
153
|
+
this.adapter.statesController.clearDeviceMap();
|
|
154
|
+
}
|
|
150
155
|
|
|
151
156
|
// Nur reconnecten wenn kein intentionales Shutdown
|
|
152
157
|
if (!this._intentionalClose) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.zigbee2mqtt",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.5",
|
|
4
4
|
"description": "Zigbee2MQTT adapter for ioBroker",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Dennis Rathjen and Arthur Rupp",
|
|
@@ -25,11 +25,11 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@iobroker/adapter-core": "^3.4.1",
|
|
28
|
-
"@iobroker/dm-utils": "^3.
|
|
28
|
+
"@iobroker/dm-utils": "^3.1.3",
|
|
29
29
|
"aedes": "^0.51.3",
|
|
30
30
|
"aedes-persistence": "^9.1.2",
|
|
31
|
-
"axios": "^1.
|
|
32
|
-
"mqtt": "^5.15.
|
|
31
|
+
"axios": "^1.18.1",
|
|
32
|
+
"mqtt": "^5.15.2",
|
|
33
33
|
"net": "^1.0.2",
|
|
34
34
|
"node-schedule": "^2.1.1",
|
|
35
35
|
"sharp": "^0.34.5",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@iobroker/eslint-config": "^2.3.4",
|
|
45
45
|
"@iobroker/testing": "^5.2.2",
|
|
46
46
|
"@tsconfig/node22": "^22.0.5",
|
|
47
|
-
"@types/node": "^25.9.
|
|
47
|
+
"@types/node": "^25.9.5",
|
|
48
48
|
"@types/node-schedule": "^2.1.8",
|
|
49
49
|
"typescript": "~6.0.3"
|
|
50
50
|
},
|