iobroker.zigbee2mqtt 2.3.0 → 2.4.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 CHANGED
@@ -30,6 +30,17 @@ This adapter allows to control the data points of the devices of a Zigbee2MQTT i
30
30
  Placeholder for the next version (at the beginning of the line):
31
31
  ### **WORK IN PROGRESS**
32
32
  -->
33
+ ### 2.4.1 (2022-11-16)
34
+
35
+ - (o0shojo0o) fix based on [review](https://github.com/ioBroker/ioBroker.repositories/pull/1976#issuecomment-1316656378)
36
+
37
+ ### 2.4.0 (2022-11-08)
38
+
39
+ - (o0shojo0o) fix for devices with multiple endpoints ([#57](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/57)).
40
+ - (o0shojo0o) added option `Brightness move should also turn the light on or off`
41
+ - (o0shojo0o) added state toggle for groups
42
+ - (o0shojo0o) more dynamic during data point creation ([#48](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/48)).
43
+
33
44
  ### 2.3.0 (2022-10-30)
34
45
 
35
46
  - (o0shojo0o) added support for the `toggle` of states that support this.
@@ -20,5 +20,6 @@
20
20
  "Color temperature sync with color": "Farbtemperatur mit Farbe synchronisieren",
21
21
  "Use Kelvin instead of mired for the color temps": "Kelvin anstelle von Mired für die Farbtemperaturen verwenden",
22
22
  "Other configurations": "Andere Konfigurationen",
23
- "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT Protokolle zu ioBroker Protokollen"
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT Protokolle zu ioBroker Protokollen",
24
+ "Brightness move should also turn the light on or off": "Brightness move soll auch das Licht ein- oder ausschalten"
24
25
  }
@@ -20,5 +20,6 @@
20
20
  "Color temperature sync with color": "Color temperature sync with color",
21
21
  "Use Kelvin instead of mired for the color temps": "Use Kelvin instead of mired for the color temps",
22
22
  "Other configurations": "Other configurations",
23
- "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT logs to ioBroker logs"
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT logs to ioBroker logs",
24
+ "Brightness move should also turn the light on or off": "Brightness move should also turn the light on or off"
24
25
  }
@@ -20,5 +20,6 @@
20
20
  "Color temperature sync with color": "Sincronización de la temperatura del color con el color",
21
21
  "Use Kelvin instead of mired for the color temps": "Use Kelvin en lugar de mired para las temperaturas de color",
22
22
  "Other configurations": "Otras configuraciones",
23
- "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy de registros Zigbee2MQTT a registros de ioBroker"
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy de registros Zigbee2MQTT a registros de ioBroker",
24
+ "Brightness move should also turn the light on or off": "El movimiento de brillo también debe encender o apagar la luz"
24
25
  }
@@ -20,5 +20,6 @@
20
20
  "Color temperature sync with color": "Synchronisation de la température de couleur avec la couleur",
21
21
  "Use Kelvin instead of mired for the color temps": "Utilisez Kelvin au lieu de embourbé pour les températures de couleur",
22
22
  "Other configurations": "Autres configurations",
23
- "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT se connecte aux journaux ioBroker"
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT se connecte aux journaux ioBroker",
24
+ "Brightness move should also turn the light on or off": "Le mouvement de luminosité devrait également allumer ou éteindre la lumière"
24
25
  }
@@ -20,5 +20,6 @@
20
20
  "Color temperature sync with color": "Sincronizzazione della temperatura del colore con il colore",
21
21
  "Use Kelvin instead of mired for the color temps": "Usa Kelvin invece di mired per le temperature di colore",
22
22
  "Other configurations": "Altre configurazioni",
23
- "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT registra nei registri di ioBroker"
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT registra nei registri di ioBroker",
24
+ "Brightness move should also turn the light on or off": "Il movimento della luminosità dovrebbe anche accendere o spegnere la luce"
24
25
  }
@@ -20,5 +20,6 @@
20
20
  "Color temperature sync with color": "Synchronisatie van kleurtemperatuur met kleur",
21
21
  "Use Kelvin instead of mired for the color temps": "Gebruik Kelvin in plaats van mired voor de kleurtemperaturen",
22
22
  "Other configurations": "Andere configuraties",
23
- "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT logt in op ioBroker logs"
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT logt in op ioBroker logs",
24
+ "Brightness move should also turn the light on or off": "Helderheidsbeweging moet ook het licht aan- of uitzetten"
24
25
  }
@@ -20,5 +20,6 @@
20
20
  "Color temperature sync with color": "Synchronizacja temperatury barwowej z kolorem",
21
21
  "Use Kelvin instead of mired for the color temps": "Użyj Kelvina zamiast mired dla temperatury kolorów",
22
22
  "Other configurations": "Inne konfiguracje",
23
- "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT loguje do logów ioBroker"
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT loguje do logów ioBroker",
24
+ "Brightness move should also turn the light on or off": "Ruch jasności powinien również włączać lub wyłączać światło"
24
25
  }
@@ -20,5 +20,6 @@
20
20
  "Color temperature sync with color": "Sincronização da temperatura de cor com a cor",
21
21
  "Use Kelvin instead of mired for the color temps": "Use Kelvin em vez de atolado para as temperaturas de cor",
22
22
  "Other configurations": "Outras configurações",
23
- "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT logs para logs ioBroker"
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "Proxy Zigbee2MQTT logs para logs ioBroker",
24
+ "Brightness move should also turn the light on or off": "O movimento de brilho também deve ligar ou desligar a luz"
24
25
  }
@@ -20,5 +20,6 @@
20
20
  "Color temperature sync with color": "Синхронизация цветовой температуры с цветом",
21
21
  "Use Kelvin instead of mired for the color temps": "Используйте шкалу Кельвина вместо майреда для цветовой температуры.",
22
22
  "Other configurations": "Другие конфигурации",
23
- "Proxy Zigbee2MQTT logs to ioBroker logs": "Проксировать журналы Zigbee2MQTT в журналы ioBroker"
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "Проксировать журналы Zigbee2MQTT в журналы ioBroker",
24
+ "Brightness move should also turn the light on or off": "Изменение яркости также должно включать или выключать свет."
24
25
  }
@@ -0,0 +1,25 @@
1
+ {
2
+ "zigbee2mqtt adapter settings": "Налаштування адаптера для zigbee2mqtt",
3
+ "Select and configure your Zigbee2MQTT connection": "Виберіть і налаштуйте підключення Zigbee2MQTT",
4
+ "Select connection to Zigbee2MQTT": "Виберіть підключення до Zigbee2MQTT",
5
+ "Websocket": "Websocket",
6
+ "External MQTT-Server (Experimental)": "Зовнішній MQTT-сервер (експериментальний)",
7
+ "Internal MQTT-Server (Experimental)": "Внутрішній MQTT-сервер (експериментальний)",
8
+ "Configure your Zigbee2MQTT connection": "Налаштуйте підключення Zigbee2MQTT",
9
+ "Websocket IP-Address": "IP-адреса Websocket",
10
+ "Websocket Port": "Порт Websocket",
11
+ "Create a dummy MQTT-Server for Zigbee2MQTT": "Створіть фіктивний MQTT-сервер для Zigbee2MQTT",
12
+ "External MQTT-Server IP-Address": "IP-адреса зовнішнього MQTT-сервера",
13
+ "External MQTT-Server Port": "Зовнішній порт MQTT-сервера",
14
+ "MQTT-Server IP-Address bind": "Прив’язка IP-адреси MQTT-сервера",
15
+ "MQTT-Server Port": "Порт MQTT-сервера",
16
+ "Configure your Zigbee2MQTT WebUi connection": "Налаштуйте підключення Zigbee2MQTT WebUi",
17
+ "WebUi Address": "Адреса WebUI",
18
+ "WebUi Port": "Порт WebUi",
19
+ "Color configurations": "Кольорові конфігурації",
20
+ "Color temperature sync with color": "Синхронізація колірної температури з кольором",
21
+ "Use Kelvin instead of mired for the color temps": "Використовуйте для колірних температур замість Кельвіна",
22
+ "Other configurations": "Інші конфігурації",
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "Журнали проксі Zigbee2MQTT до журналів ioBroker",
24
+ "Brightness move should also turn the light on or off": "Переміщення яскравості також повинно вмикати або вимикати світло"
25
+ }
@@ -20,5 +20,6 @@
20
20
  "Color temperature sync with color": "色温与颜色同步",
21
21
  "Use Kelvin instead of mired for the color temps": "使用 Kelvin 而不是 mired 作为色温",
22
22
  "Other configurations": "其他配置",
23
- "Proxy Zigbee2MQTT logs to ioBroker logs": "代理 Zigbee2MQTT 日志到 ioBroker 日志"
23
+ "Proxy Zigbee2MQTT logs to ioBroker logs": "代理 Zigbee2MQTT 日志到 ioBroker 日志",
24
+ "Brightness move should also turn the light on or off": "亮度移动也应该打开或关闭灯"
24
25
  }
@@ -144,6 +144,11 @@
144
144
  "size": 2,
145
145
  "newLine": true
146
146
  },
147
+ "brightnessMoveOnOff": {
148
+ "type": "checkbox",
149
+ "label": "Brightness move should also turn the light on or off",
150
+ "newLine": true
151
+ },
147
152
  "proxyZ2MLogs": {
148
153
  "type": "checkbox",
149
154
  "label": "Proxy Zigbee2MQTT logs to ioBroker logs",
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "zigbee2mqtt",
4
- "version": "2.3.0",
4
+ "version": "2.4.1",
5
5
  "news": {
6
+ "2.4.1": {
7
+ "en": "fix based on [review](https://github.com/ioBroker/ioBroker.repositories/pull/1976#issuecomment-1316656378)",
8
+ "de": "(https://github.com/ioBroker/ioBroker.repositories/pull/1976#issuecomment-1316656378)",
9
+ "ru": "исправить на [review](https://github.com/ioBroker/ioBroker.repositories/pull/1976#issuecomment-1316656378)",
10
+ "pt": "correção com base em [review](https://github.com/ioBroker/ioBroker.repositories/pull/1976#comment-1316656378)",
11
+ "nl": "quality over Quantity Releases Vertaling:",
12
+ "fr": "fix based on [review](https://github.com/ioBroker/ioBroker.repositories/pull/1976#issuecomment-1316656378)",
13
+ "it": "fix based on [review](https://github.com/ioBroker/ioBroker.repositories/pull/1976#issuecomment-1316656378)",
14
+ "es": "fijado basado en [review](https://github.com/ioBroker/ioBroker.repositories/pull/1976#issuecomment-1316656378)",
15
+ "pl": "recenzent oparty na przeglądzie (https:/github.com/ioBroker/ioBroker.repositories/pull/1976#issuecomment-1316656363636378)",
16
+ "uk": "javaScript licenses API Веб-сайт Go1.13.8",
17
+ "zh-cn": "fix 基于[审查](http://github.com/ioBroker/ioBroker.reories/pull/1976#issuement-1316656378)"
18
+ },
19
+ "2.4.0": {
20
+ "en": "fix for devices with multiple endpoints ([#57](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/57)).\nadded option `Brightness move should also turn the light on or off`\nadded state toggle for groups \nmore dynamic during data point creation ([#48](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/48)).",
21
+ "de": "fix für Geräte mit mehreren Endpunkten [#57](https://github.com/o0shojo0o/ioBroker.zigbee2mqt/issues/57).\nzusätzliche Option `Brightness move sollte auch das Licht ein- oder ausschalten `\nzusatzzustandswinkel für gruppen\nmehr Dynamik bei der Erstellung von Datenpunkten [#48](https://github.com/o0shojo0o/ioBroker.zigbee2mqt/issues/48).",
22
+ "ru": "исправить для устройств с несколькими точками [#57](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/57).\nдобавленная опция `Перемещение яркости должно также повернуть свет на или вне`\nдобавлена государственная очка для групп\nболее динамично во время создания данных [#48](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/48).",
23
+ "pt": "correção para dispositivos com múltiplos endpoints [#57](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/57).\nopção adicionada `Brightness move também deve ligar ou desligar a luz`\nadicionado conjunto de estado para grupos\nmais dinâmico durante a criação do ponto de dados [#48](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/48).",
24
+ "nl": "vertaling:.\nvoegde optie 'Brightness zet ook het licht aan of uit'\nvertaling:\ndynamischer tijdens datapunt 48: github.com/oshojoo/ioBroker.",
25
+ "fr": "correction des dispositifs comportant plusieurs paramètres [#57](https://github.com/o0shojo0o/ioBroker.zigbee2mqt/issues/57).\noption ajoutée `Brightness move should also turn the light on or off`\nla lutte de l'état pour les groupes\nplus dynamique lors de la création de points de données [#48](https://github.com/o0shojo0o/ioBroker.zigbee2mqt/issues/48).",
26
+ "it": "fix per dispositivi con più endpoint [#57](https://github.com/o0shojo0o/ioBroker.zigbee2mqt/issues/57).\nopzione aggiunta `Brightness movimento dovrebbe anche accendere o spegnere la luce `\ntoggle di stato aggiunto per gruppi\npiù dinamica durante la creazione di data point [#48](https://github.com/o0shojo0o/ioBroker.zigbee2mqt/issues/48).",
27
+ "es": "fix for devices with multiple endpoints [#57](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/57).\nopción agregada `El movimiento de la rectitud también debe encender o apagar la luz &apos\nañadido a la lucha estatal para grupos\nmás dinámica durante la creación de puntos de datos [#48](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/48).",
28
+ "pl": "urządzenia z wieloma punktami końcowymi (#57(https:/github.com/o0shojo0/ioBroker.zigbee2mqtt/issues/57).\ndodano również możliwość wykonania ruchu `Brightness'\ndodać stan dla grup\ndynamiczny w czasie tworzenia danych (#48)(https:/github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/48).",
29
+ "uk": "виправлення для пристроїв з декількома кінцевими точками [#57](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/57).\nдоданий варіант `Брайтний рух також повинен перетворювати світло або вимкнути`\nдодано державний контроль за групами\nбільш динамічний при створенні точки даних [#48](https://github.com/o0shojo0o/ioBroker.zigbee2mqtt/issues/48).",
30
+ "zh-cn": "fix 有多个最终用户的装置[第57号](http://github.com/o0shojo0o/ioBroker.zigbee2mqt/issues/57).\n增加“权利流动”的选择,也应该改变“或”以外的照明。\n加入集团的州\n在数据点创建期间,增加活力[第48](http://github.com/oshojo0o/ioBroker.zigbee2mqt/issues/48)."
31
+ },
6
32
  "2.3.0": {
7
33
  "en": "added support for the `toggle` of states that support this.\nadded correct handling of `color_move` and `color_temperature_move`",
8
34
  "de": "zusätzliche unterstützung für den kippen von staaten, die dies unterstützen.\nkorrekte handhabung von color_move und color_temperature_move",
@@ -67,31 +93,6 @@
67
93
  "pl": "dodano możliwość synchronizacji kolorowej synchronizacji z kolorami\nnaprawić filtry i debugDevices\nwiele błędów\nteraz ustalono odpowiednie min/max w kolorowym tempie\nlepsza obsługa błędów dla połączeń powiązań",
68
94
  "uk": "додано варіант синхронізації кольору з кольором\nвиправити logfilter і debugDevices\nбагато помилок\nтепер встановлюємо правильний хв/макс за кольором\nкраща обробка помилок для підключення",
69
95
  "zh-cn": "添加了用颜色的气温合办法\nfix 木图和溶剂\n批发\n现将正确的分钟/升值确定为色色彩。\na. 处理联系的错误"
70
- },
71
- "2.0.0": {
72
- "en": "*!!!BREAKING CHANGE!!!**\n\nadded configurable connection to Zigbee2MQTT (Settings must be renewed)\nWebsocket\nExternal MQTT-Server\nInternal MQTT-Server\noptimized state writing performance in ioBroker\nfixed the correct set of the connection status",
73
- "de": "*! BREAKING CHANGE*\n\nzusätzliche konfigurierbare Verbindung zu Zigbee2MQTT (Einstellungen müssen erneuert werden)\nWebsocket\nExterner MQTT-Server\nInterner MQTT-Server\noptimierte Zustandsschreibleistung in ioBroker\nden korrekten satz des verbindungsstatus festlegt",
74
- "ru": "*! ИЗМЕНЕНИЕ ЗАВТРА*\n\nдобавлена настраиваемая связь с Zigbee2MQTT (Настройки должны быть обновлены)\nWebsocket\nВнешний MQTT-Server\nВнутренний MQTT-Server\nоптимизированное представление государственной записи в ioBroker\nисправил правильный набор состояния соединения",
75
- "pt": "*! QUE GRANDE MUDANÇA\n\nconexão configurável adicionada ao Zigbee2MQTT (As inscrições devem ser renovadas)\nWebsocket\nMQTT externo-Server\nMQTT interno-Server\ndesempenho de escrita de estado otimizado no ioBroker\nfixou o conjunto correto do status da conexão",
76
- "nl": "♪ \n\nvoegde connectie toe aan Zigbee2MQT (Settings moet vernieuwd)\nWebsocket\nExterne MQTT-Server\nInterne MQTT-Server\noptimaal staatsschrijving in ioBroker\nde correcte set van de connectie status",
77
- "fr": "*! CHANGE DE BREAKING*\n\nconnexion configurable ajoutée à Zigbee2MQTT (Les paramètres doivent être renouvelés)\nWebsocket\nMQTT-Serveur externe\nInterne MQTT-Serveur\nperformance d'écriture d'état optimisée en ioBroker\nfixe l'ensemble correct du statut de connexion",
78
- "it": "# CAMBIAMENTO\n\naggiunta di connessione configurabile a Zigbee2MQTT (I posti devono essere rinnovati)\nWebsocket\nMQTT-Server esterno\nInterno MQTT-Server\nprestazioni di scrittura dello stato ottimizzate in ioBroker\nfisso l'insieme corretto dello stato di connessione",
79
- "es": "*! ¡CAMBIANDO\n\nconexión configurable agregada a Zigbee2MQTT (Se debe renovar la configuración)\nWebsocket\nMQTT externo-Server\nInterno MQTT-Server\nrendimiento de escritura de estado optimizado en ioBroker\nfija el conjunto correcto del estado de conexión",
80
- "pl": "! BREAKING CHANGE! (ANG.)\n\nzigbee2MQTT dodano połączenie konfigurowalne. (Odrodzenie się)\nStrona internetowa\nOficjalna strona MQTT-Server\nOficjalna strona MQTT\nzoptymalizowany stan pisania w ioBrokerze\nustalono poprawny zbiór statusu związku",
81
- "uk": "* БРЕАКІНГ ЧАНГ*\n\nдодано налаштування підключення до Zigbee2MQTT (Налаштування повинні бути відновлені)\nВеб-сайт\nЗовнішній MQTT-Server\nВнутрішній MQTT-Server\nоптимізоване державне письмо продуктивність в ioBroker\nвиправлено правильний набір статусу підключення",
82
- "zh-cn": "页:1 BREAKREANGE*\n\n兹格贝雷2 MQTT的可图联系 (必须重启)\n网站\n外贸总协定\n内贸总协定\n最佳国家书面表现\na. 固定的联络点地位"
83
- },
84
- "1.0.0": {
85
- "en": "*!!!BREAKING CHANGE!!!**\n\nadded options for external MQTT-Server\nconnection to zigbe2mqtt completely reworked and changed to MQTT\nlots of bugfixes\nautomatically set button actions back to false\nadded support for Zigbee2MQTT feature simulated_brightness\nadded config check\nadded log output about coordinator details",
86
- "de": "*! BREAKING CHANGE*\n\nweitere Optionen für externen MQTT-Server\nanschluss an Zickbe2mqt komplett überarbeitet und in MQTT geändert\nviele bugfixes\nautomatisch schaltfläche aktionen wieder auf false setzen\nunterstützung für Zigbee2MQTT Funktion simuliert_brightness\nzusatzprüfung\nlog ausgabe von koordinatordaten hinzugefügt",
87
- "ru": "*! ИЗМЕНЕНИЕ ЗАВТРА*\n\nдобавлены опции для внешнего MQTT-Server\nподключение к zigbe2mqtt полностью переработано и изменено в MQTT\nмного багфиксов\nавтоматически установите кнопки действия назад к ложному\nдобавлена поддержка функции Zigbee2MQTT simulated_brightness\nдобавлено config check\nдобавил выход журнала о деталях координатора",
88
- "pt": "*! QUE GRANDE MUDANÇA\n\nopções adicionadas para MQTT-Server externo\nconexão com zigbe2mqtt completamente retrabalhado e alterado para MQTT\nlotes de correções de bugs\nautomaticamente definir as ações do botão de volta ao falso\nsuporte adicionado para recurso Zigbee2MQTT simulado_brightness\nverificação de configuração adicionada\nadicionado saída de log sobre detalhes do coordenador",
89
- "nl": "♪ \n\nvoegde opties toe voor externe MQT-Server\nverbinding met Zigbe2mqt volledig herwerkt en veranderd in MQT\nveel insectenfixen\nautomatisch de knoppen opzetten naar valse\nsteun toegevoegd voor Zigbee2MQT\nvoegde config check toe\nvertaling:",
90
- "fr": "*! CHANGE DE BREAKING*\n\noptions supplémentaires pour MQTT-Server externe\nconnexion à zigbe2mqtt complètement retravaillé et changé à MQTT\nbeaucoup de bugfixes\ndéfinir automatiquement les actions de bouton retour à false\nsupport ajouté pour la fonction Zigbee2MQTT simulée_brightness\nconfig check ajouté\nproduit log ajouté sur les coordonnées des coordonnateurs",
91
- "it": "# CAMBIAMENTO\n\nopzioni aggiuntive per MQTT-Server esterno\nconnessione a zigbe2mqt completamente rielaborato e cambiato in MQTT\nmolti bugfix\nautomaticamente impostare le azioni del pulsante indietro a false\nsupporto aggiunto per Zigbee2MQTT funzione simulated_brightness\ncontrollo configurazione aggiunto\nuscita di log aggiunto sui dettagli del coordinatore",
92
- "es": "*! ¡CAMBIANDO\n\nopciones adicionales para MQTT-Server externo\nconexión a zigbe2mqtt completamente rediseñado y cambiado a MQTT\nmuchos bugfixes\nautomáticamente poner las acciones del botón de nuevo a falso\nsoporte añadido para función Zigbee2MQTT simulado_brightness\ncontrol de configuración añadido\nproducción de registro agregada sobre detalles de coordinadores",
93
- "pl": "! BREAKING CHANGE! (ANG.)\n\nobsługa MQTT-Server\nzigbe2mqtt całkowicie przerobił i zmienił MQTT\nwiele błędów\nautomatycznie ustawione akcje przycisku\ndodano obsługę Zigbee2MQTT\nsprawdzać\ndokładna produkcja logów na temat szczegółów koordynacji",
94
- "zh-cn": "页:1 BREAKREANGE*\n\n外贸总协定\n与zigbe2mqt完全重新工作,并改装到外贸总协定\n批发\n自动建立但顿行动回到虚假的行动\n对Zigbee2MQTT特征的增援\n增幅检查\n协调员的产出"
95
96
  }
96
97
  },
97
98
  "titleLang": {
@@ -104,7 +105,8 @@
104
105
  "it": "zigbee2mqtt",
105
106
  "es": "zigbee2mqtt",
106
107
  "pl": "zigbee2mqtt",
107
- "zh-cn": "zigbee2mqtt"
108
+ "zh-cn": "zigbee2mqtt",
109
+ "uk": "zigbee2mqtt"
108
110
  },
109
111
  "desc": {
110
112
  "en": "Zigbee2MQTT adapter for ioBroker",
@@ -116,7 +118,8 @@
116
118
  "it": "Adattatore Zigbee2MQTT per ioBroker",
117
119
  "es": "Adaptador Zigbee2MQTT para ioBroker",
118
120
  "pl": "Adapter Zigbee2MQTT do ioBroker",
119
- "zh-cn": "用于 ioBroker 的 Zigbee2MQTT 适配器"
121
+ "zh-cn": "用于 ioBroker 的 Zigbee2MQTT 适配器",
122
+ "uk": "Адаптер Zigbee2MQTT для ioBroker"
120
123
  },
121
124
  "authors": [
122
125
  "Dennis Rathjen <dennis.rathjen@outlook.de>"
@@ -192,7 +195,8 @@
192
195
  "debugLogEnabled": false,
193
196
  "proxyZ2MLogs": true,
194
197
  "useKelvin": false,
195
- "colorTempSyncColor": false
198
+ "colorTempSyncColor": false,
199
+ "brightnessMoveOnOff": false
196
200
  },
197
201
  "objects": [],
198
202
  "instanceObjects": [
@@ -38,6 +38,7 @@ class DeviceController {
38
38
 
39
39
 
40
40
  async defineGroupDevice(groupID, ieee_address, scenes) {
41
+ const propName = this.adapter.config.brightnessMoveOnOff == true ? 'brightness_move_onoff' : 'brightness_move';
41
42
  const newDevice = {
42
43
  id: groupID,
43
44
  ieee_address: ieee_address,
@@ -45,76 +46,93 @@ class DeviceController {
45
46
  states: [
46
47
  states.state,
47
48
  states.brightness,
48
- //states.color,
49
- states.brightness_move,
50
49
  states.colortemp_move,
51
- ],
52
- };
53
-
54
- const color = {
55
- id: 'color',
56
- prop: 'color',
57
- name: 'Color',
58
- icon: undefined,
59
- role: 'level.color.rgb',
60
- write: true,
61
- read: true,
62
- type: 'string',
63
- setter: (value) => {
64
- let xy = [0, 0];
65
- const rgbcolor = colors.ParseColor(value);
66
- xy = rgb.rgb_to_cie(rgbcolor.r, rgbcolor.g, rgbcolor.b);
67
- return {
68
- x: xy[0],
69
- y: xy[1]
70
- };
71
- },
72
- getter: payload => {
73
- if (payload.color_mode != 'xy' && this.config.colorTempSyncColor == false) {
74
- return undefined;
75
- }
76
- if (payload.color && payload.color.x && payload.color.y) {
77
- const colorval = rgb.cie_to_rgb(payload.color.x, payload.color.y);
78
- return '#' + utils.decimalToHex(colorval[0]) + utils.decimalToHex(colorval[1]) + utils.decimalToHex(colorval[2]);
79
- } else {
80
- return undefined;
81
- }
82
- },
83
- };
84
-
85
- // @ts-ignore
86
- newDevice.states.push(color);
87
-
88
- const colortemp = {
89
- id: 'colortemp',
90
- prop: 'color_temp',
91
- name: 'Color temperature',
92
- icon: undefined,
93
- role: 'level.color.temperature',
94
- write: true,
95
- read: true,
96
- type: 'number',
97
- min: this.config.useKelvin == true ? utils.miredKelvinConversion(500) : 150,
98
- max: this.config.useKelvin == true ? utils.miredKelvinConversion(150) : 500,
99
- unit: this.config.useKelvin == true ? 'K' : 'mired',
100
- setter: (value) => {
101
- return utils.toMired(value);
102
- },
103
- getter: (payload) => {
104
- if (payload.color_mode != 'color_temp') {
105
- return undefined;
106
- }
107
- if (this.config.useKelvin == true) {
108
- return utils.miredKelvinConversion(payload.color_temp);
109
- } else {
110
- return payload.color_temp;
50
+ {
51
+ id: 'brightness_move',
52
+ prop: propName,
53
+ name: 'Dimming',
54
+ icon: undefined,
55
+ role: 'state',
56
+ write: true,
57
+ read: false,
58
+ type: 'number',
59
+ min: -50,
60
+ max: 50,
61
+ def: 0
62
+ },
63
+ {
64
+ id: 'color',
65
+ prop: 'color',
66
+ name: 'Color',
67
+ icon: undefined,
68
+ role: 'level.color.rgb',
69
+ write: true,
70
+ read: true,
71
+ type: 'string',
72
+ def: '#ff00ff',
73
+ setter: (value) => {
74
+ let xy = [0, 0];
75
+ const rgbcolor = colors.ParseColor(value);
76
+ xy = rgb.rgb_to_cie(rgbcolor.r, rgbcolor.g, rgbcolor.b);
77
+ return {
78
+ x: xy[0],
79
+ y: xy[1]
80
+ };
81
+ },
82
+ getter: payload => {
83
+ if (payload.color_mode != 'xy' && this.config.colorTempSyncColor == false) {
84
+ return undefined;
85
+ }
86
+ if (payload.color && payload.color.x && payload.color.y) {
87
+ const colorval = rgb.cie_to_rgb(payload.color.x, payload.color.y);
88
+ return '#' + utils.decimalToHex(colorval[0]) + utils.decimalToHex(colorval[1]) + utils.decimalToHex(colorval[2]);
89
+ } else {
90
+ return undefined;
91
+ }
92
+ },
93
+ },
94
+ {
95
+ id: 'colortemp',
96
+ prop: 'color_temp',
97
+ name: 'Color temperature',
98
+ icon: undefined,
99
+ role: 'level.color.temperature',
100
+ write: true,
101
+ read: true,
102
+ type: 'number',
103
+ min: this.config.useKelvin == true ? utils.miredKelvinConversion(500) : 150,
104
+ max: this.config.useKelvin == true ? utils.miredKelvinConversion(150) : 500,
105
+ def: this.config.useKelvin == true ? utils.miredKelvinConversion(150) : 500,
106
+ unit: this.config.useKelvin == true ? 'K' : 'mired',
107
+ setter: (value) => {
108
+ return utils.toMired(value);
109
+ },
110
+ getter: (payload) => {
111
+ if (payload.color_mode != 'color_temp') {
112
+ return undefined;
113
+ }
114
+ if (this.config.useKelvin == true) {
115
+ return utils.miredKelvinConversion(payload.color_temp);
116
+ } else {
117
+ return payload.color_temp;
118
+ }
119
+ },
120
+ },
121
+ {
122
+ id: 'state_toggle',
123
+ name: 'Toggle the state',
124
+ icon: undefined,
125
+ role: 'button',
126
+ write: true,
127
+ read: true,
128
+ type: 'boolean',
129
+ setattr: 'state',
130
+ def: true,
131
+ setter: (value) => (value) ? 'TOGGLE' : undefined
111
132
  }
112
- },
133
+ ],
113
134
  };
114
135
 
115
- // @ts-ignore
116
- newDevice.states.push(colortemp);
117
-
118
136
  // Create buttons for scenes
119
137
  for (const scene of scenes) {
120
138
  const sceneSate = {
@@ -125,6 +143,7 @@ class DeviceController {
125
143
  role: 'button',
126
144
  write: true,
127
145
  read: true,
146
+ def: true,
128
147
  type: 'boolean',
129
148
  setter: (value) => (value) ? scene.id : undefined
130
149
  };
@@ -216,7 +235,7 @@ class DeviceController {
216
235
  }
217
236
 
218
237
  if (ieee_address != undefined) {
219
- this.adapter.setStateAsync(`${ieee_address}.available`, false, true);
238
+ this.adapter.setState(`${ieee_address}.available`, false, true);
220
239
  this.adapter.extendObject(`${ieee_address}`, { common: { name: 'Device removed!', } });
221
240
  delete this.createCache[ieee_address];
222
241
  }
package/lib/exposes.js CHANGED
@@ -71,7 +71,7 @@ function genState(expose, role, name, desc) {
71
71
 
72
72
  if (writable) {
73
73
  state.setter = (payload) => (payload) ? (expose.value_on || 'ON') : ((expose.value_off != undefined) ? expose.value_off : 'OFF');
74
- state.setattr = expose.name;
74
+ state.setattr = expose.property;
75
75
  }
76
76
 
77
77
  if (expose.endpoint) {
@@ -109,7 +109,6 @@ function genState(expose, role, name, desc) {
109
109
  role: role || 'state',
110
110
  write: writable,
111
111
  read: true,
112
- type: 'string',
113
112
  states: {}
114
113
  };
115
114
 
@@ -118,6 +117,21 @@ function genState(expose, role, name, desc) {
118
117
  state.type = typeof (val);
119
118
  }
120
119
 
120
+ switch (state.type) {
121
+ case 'boolean':
122
+ state.def = false;
123
+ break;
124
+ case 'number':
125
+ state.def = 0;
126
+ break;
127
+ case 'object':
128
+ state.def = {};
129
+ break;
130
+ case 'string':
131
+ state.def = '';
132
+ break;
133
+ }
134
+
121
135
  if (expose.endpoint) {
122
136
  state.epname = expose.endpoint;
123
137
  state.setattr = expose.name;
@@ -269,41 +283,42 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
269
283
  for (const prop of expose.features) {
270
284
  switch (prop.name) {
271
285
  case 'state': {
272
- const stateNameS = expose.endpoint ? `state_${expose.endpoint}` : 'state';
286
+ const stateName = expose.endpoint ? `state_${expose.endpoint}` : 'state';
273
287
  pushToStates({
274
- id: stateNameS,
288
+ id: stateName,
275
289
  name: `Switch state ${expose.endpoint ? expose.endpoint : ''}`.trim(),
276
290
  icon: undefined,
277
291
  role: 'switch',
278
292
  write: true,
279
293
  read: true,
280
294
  type: 'boolean',
281
- getter: (payload) => (payload[stateNameS] === (prop.value_on || 'ON')),
295
+ getter: (payload) => (payload[stateName] === (prop.value_on || 'ON')),
282
296
  setter: (value) => (value) ? prop.value_on || 'ON' : ((prop.value_off != undefined) ? prop.value_off : 'OFF'),
283
297
  epname: expose.endpoint,
284
- setattr: 'state',
298
+ //setattr: stateName,
285
299
  }, prop.access);
286
300
  // features contains TOGGLE?
287
301
  if (prop.value_toggle) {
288
302
  pushToStates({
289
- id: `${prop.property}_toggle`,
290
- prop: `${prop.property}_toggle`,
291
- name: `Toggle state of the ${prop.property}`,
303
+ id: `${stateName}_toggle`,
304
+ prop: `${stateName}_toggle`,
305
+ name: `Toggle state of the ${stateName}`,
292
306
  icon: undefined,
293
307
  role: 'button',
294
308
  write: true,
295
309
  read: true,
296
310
  type: 'boolean',
297
- setattr: prop.property,
311
+ def: true,
312
+ setattr: stateName,
298
313
  setter: (value) => (value) ? prop.value_toggle : undefined
299
314
  });
300
315
  }
301
316
  break;
302
317
  }
303
318
  case 'brightness': {
304
- const stateNameB = expose.endpoint ? `brightness_${expose.endpoint}` : 'brightness';
319
+ const stateName = expose.endpoint ? `brightness_${expose.endpoint}` : 'brightness';
305
320
  pushToStates({
306
- id: stateNameB,
321
+ id: stateName,
307
322
  name: `Brightness ${expose.endpoint ? expose.endpoint : ''}`.trim(),
308
323
  icon: undefined,
309
324
  role: 'level.dimmer',
@@ -312,38 +327,40 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
312
327
  type: 'number',
313
328
  min: 0, // ignore expose.value_min
314
329
  max: 100, // ignore expose.value_max
330
+ def: 100,
315
331
  inOptions: true,
316
332
  unit: '%',
317
333
  getter: (value) => {
318
- return utils.bulbLevelToAdapterLevel(value[stateNameB]);
334
+ return utils.bulbLevelToAdapterLevel(value[stateName]);
319
335
  },
320
336
  setter: (value) => {
321
337
  return utils.adapterLevelToBulbLevel(value);
322
338
  },
323
- setterOpt: (value, options) => {
324
- const hasTransitionTime = options && options.hasOwnProperty('transition_time');
325
- const transitionTime = hasTransitionTime ? options.transition_time : 0;
326
- const preparedOptions = { ...options, transition: transitionTime };
327
- preparedOptions.brightness = utils.adapterLevelToBulbLevel(value);
328
- return preparedOptions;
329
- },
330
- readResponse: (resp) => {
331
- const respObj = resp[0];
332
- if (respObj.status === 0 && respObj.attrData != undefined) {
333
- return utils.bulbLevelToAdapterLevel(respObj.attrData);
334
- }
335
- },
336
- epname: expose.endpoint,
337
- setattr: 'brightness',
338
339
  }, prop.access);
339
- pushToStates(statesDefs.brightness_move, prop.access);
340
+ // brightnessMoveOnOff
341
+ const propName = config.brightnessMoveOnOff == true ? `${stateName}_move_onoff` : `${stateName}_move`;
342
+ pushToStates({
343
+ id: `${stateName}_move`,
344
+ prop: propName,
345
+ name: 'Dimming',
346
+ icon: undefined,
347
+ role: 'state',
348
+ write: true,
349
+ read: false,
350
+ type: 'number',
351
+ min: -50,
352
+ max: 50,
353
+ def: 0
354
+ }, prop.access);
340
355
  break;
341
356
  }
342
357
  case 'color_temp': {
343
- const stateNameT = expose.endpoint ? `colortemp_${expose.endpoint}` : 'colortemp';
358
+ const stateName = expose.endpoint ? `colortemp_${expose.endpoint}` : 'colortemp';
359
+ const propName = expose.endpoint ? `color_temp_${expose.endpoint}` : 'color_temp';
360
+ const colorMode = expose.endpoint ? `color_mode_${expose.endpoint}` : 'color_mode';
344
361
  pushToStates({
345
- id: stateNameT,
346
- prop: expose.endpoint ? `color_temp_${expose.endpoint}` : 'color_temp',
362
+ id: stateName,
363
+ prop: propName,
347
364
  name: `Color temperature ${expose.endpoint ? expose.endpoint : ''}`.trim(),
348
365
  icon: undefined,
349
366
  role: 'level.color.temperature',
@@ -352,42 +369,50 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
352
369
  type: 'number',
353
370
  min: config.useKelvin == true ? utils.miredKelvinConversion(prop.value_max) : prop.value_min,
354
371
  max: config.useKelvin == true ? utils.miredKelvinConversion(prop.value_min) : prop.value_max,
372
+ def: config.useKelvin == true ? utils.miredKelvinConversion(prop.value_min) : prop.value_max,
355
373
  unit: config.useKelvin == true ? 'K' : 'mired',
356
374
  setter: (value) => {
357
375
  return utils.toMired(value);
358
376
  },
359
- // setterOpt: (_value, options) => {
360
- // const hasTransitionTime = options && options.hasOwnProperty('transition_time');
361
- // const transitionTime = hasTransitionTime ? options.transition_time : 0;
362
- // return { ...options, transition: transitionTime };
363
- // },
364
377
  getter: (payload) => {
365
- if (payload.color_mode != 'color_temp') {
378
+ if (payload[colorMode] != 'color_temp') {
366
379
  return undefined;
367
380
  }
368
381
  if (config.useKelvin == true) {
369
- return utils.miredKelvinConversion(payload.color_temp);
382
+ return utils.miredKelvinConversion(payload[propName]);
370
383
  } else {
371
- return payload.color_temp;
384
+ return payload[propName];
372
385
  }
373
386
  },
374
- epname: expose.endpoint,
375
- setattr: 'color_temp',
376
387
  }, prop.access);
377
- pushToStates(statesDefs.colortemp_move, prop.access);
388
+ // Colortemp
389
+ pushToStates({
390
+ id: `${stateName}_move`,
391
+ prop: `${propName}_move`,
392
+ name: 'Colortemp change',
393
+ icon: undefined,
394
+ role: 'state',
395
+ write: true,
396
+ read: false,
397
+ type: 'number',
398
+ min: -50,
399
+ max: 50,
400
+ def: 0
401
+ }, prop.access);
378
402
  break;
379
403
  }
380
404
  case 'color_xy': {
381
- const stateNameC = expose.endpoint ? `color_${expose.endpoint}` : 'color';
405
+ const stateName = expose.endpoint ? `color_${expose.endpoint}` : 'color';
406
+ const colorMode = expose.endpoint ? `color_mode_${expose.endpoint}` : 'color_mode';
382
407
  pushToStates({
383
- id: stateNameC,
384
- prop: expose.endpoint ? `color_${expose.endpoint}` : 'color',
408
+ id: stateName,
385
409
  name: `Color ${expose.endpoint ? expose.endpoint : ''}`.trim(),
386
410
  icon: undefined,
387
411
  role: 'level.color.rgb',
388
412
  write: true,
389
413
  read: true,
390
414
  type: 'string',
415
+ def: '#ff00ff',
391
416
  setter: (value) => {
392
417
 
393
418
  let xy = [0, 0];
@@ -401,32 +426,32 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
401
426
 
402
427
  },
403
428
  getter: payload => {
404
- if (payload.color_mode != 'xy' && config.colorTempSyncColor == false) {
429
+ if (payload[colorMode] != 'xy' && config.colorTempSyncColor == false) {
405
430
  return undefined;
406
431
  }
407
- if (payload.color && payload.color.hasOwnProperty('x') && payload.color.hasOwnProperty('y')) {
408
- const colorval = rgb.cie_to_rgb(payload.color.x, payload.color.y);
432
+ if (payload[stateName] && payload[stateName].hasOwnProperty('x') && payload[stateName].hasOwnProperty('y')) {
433
+ const colorval = rgb.cie_to_rgb(payload[stateName].x, payload[stateName].y);
409
434
  return '#' + utils.decimalToHex(colorval[0]) + utils.decimalToHex(colorval[1]) + utils.decimalToHex(colorval[2]);
410
435
  } else {
411
436
  return undefined;
412
437
  }
413
438
  },
414
439
  epname: expose.endpoint,
415
- setattr: 'color',
416
440
  }, prop.access);
417
441
  break;
418
442
  }
419
443
  case 'color_hs': {
420
- const stateNameH = expose.endpoint ? `color_${expose.endpoint}` : 'color';
444
+ const stateName = expose.endpoint ? `color_${expose.endpoint}` : 'color';
445
+ const colorMode = expose.endpoint ? `color_mode_${expose.endpoint}` : 'color_mode';
421
446
  pushToStates({
422
- id: stateNameH,
423
- prop: expose.endpoint ? `color_${expose.endpoint}` : 'color',
447
+ id: stateName,
424
448
  name: `Color ${expose.endpoint ? expose.endpoint : ''}`.trim(),
425
449
  icon: undefined,
426
450
  role: 'level.color.rgb',
427
451
  write: true,
428
452
  read: true,
429
453
  type: 'string',
454
+ def: '#ff00ff',
430
455
  setter: (value) => {
431
456
  const _rgb = colors.ParseColor(value);
432
457
  const hsv = rgb.rgbToHSV(_rgb.r, _rgb.g, _rgb.b, true);
@@ -438,138 +463,22 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
438
463
  };
439
464
  },
440
465
  getter: payload => {
441
- if (payload.color_mode != 'hs') {
466
+ if (!['hs', 'xy'].includes(payload[colorMode]) && config.colorTempSyncColor == false) {
442
467
  return undefined;
443
468
  }
444
- if (payload.color && payload.color.hasOwnProperty('h') && payload.color.hasOwnProperty('s') & payload.color.hasOwnProperty('b')) {
445
- return rgb.hsvToRGBString(payload.color.h, payload.color.s, Math.round(payload.color.b / 2.55));
446
- } else {
447
- return undefined;
469
+
470
+ if (payload[stateName] && payload[stateName].hasOwnProperty('h') && payload[stateName].hasOwnProperty('s') & payload[stateName].hasOwnProperty('b')) {
471
+ return rgb.hsvToRGBString(payload[stateName].h, payload[stateName].s, Math.round(payload[stateName].b / 2.55));
472
+ }
473
+
474
+ if (payload[stateName] && payload[stateName].hasOwnProperty('x') && payload[stateName].hasOwnProperty('y')) {
475
+ const colorval = rgb.cie_to_rgb(payload[stateName].x, payload[stateName].y);
476
+ return '#' + utils.decimalToHex(colorval[0]) + utils.decimalToHex(colorval[1]) + utils.decimalToHex(colorval[2]);
448
477
  }
478
+ return undefined;
479
+
449
480
  },
450
- epname: expose.endpoint,
451
- setattr: 'color',
452
481
  }, prop.access);
453
- // pushToStates({
454
- // id: expose.endpoint ? `hue_${expose.endpoint}` : 'hue',
455
- // prop: expose.endpoint ? `color_${expose.endpoint}` : 'color',
456
- // name: `Hue ${expose.endpoint ? expose.endpoint : ''}`.trim(),
457
- // icon: undefined,
458
- // role: 'level.color.hue',
459
- // write: true,
460
- // read: false,
461
- // type: 'number',
462
- // min: 0,
463
- // max: 360,
464
- // inOptions: true,
465
- // setter: (value, options) => {
466
- // return {
467
- // hue: value,
468
- // saturation: options.saturation,
469
- // };
470
- // },
471
- // setterOpt: (_value, options) => {
472
- // const hasTransitionTime = options && options.hasOwnProperty('transition_time');
473
- // const transitionTime = hasTransitionTime ? options.transition_time : 0;
474
- // const hasHueCalibrationTable = options && options.hasOwnProperty('hue_calibration');
475
- // if (hasHueCalibrationTable)
476
- // try {
477
- // return { ...options, transition: transitionTime, hue_correction: JSON.parse(options.hue_calibration) };
478
- // }
479
- // catch (err) {
480
- // const hue_correction_table = [];
481
- // options.hue_calibration.split(',').forEach(element => {
482
- // const match = /([0-9]+):([0-9]+)/.exec(element);
483
- // if (match && match.length == 3)
484
- // hue_correction_table.push({ in: Number(match[1]), out: Number(match[2]) });
485
- // });
486
- // if (hue_correction_table.length > 0)
487
- // return { ...options, transition: transitionTime, hue_correction: hue_correction_table };
488
- // }
489
- // return { ...options, transition: transitionTime };
490
- // },
491
-
492
- // }, prop.access);
493
- // pushToStates({
494
- // id: expose.endpoint ? `saturation_${expose.endpoint}` : 'saturation',
495
- // prop: expose.endpoint ? `color_${expose.endpoint}` : 'color',
496
- // name: `Saturation ${expose.endpoint ? expose.endpoint : ''}`.trim(),
497
- // icon: undefined,
498
- // role: 'level.color.saturation',
499
- // write: true,
500
- // read: false,
501
- // type: 'number',
502
- // min: 0,
503
- // max: 100,
504
- // inOptions: true,
505
- // setter: (value, options) => {
506
- // return {
507
- // hue: options.hue,
508
- // saturation: value,
509
- // };
510
- // },
511
- // setterOpt: (_value, options) => {
512
- // const hasTransitionTime = options && options.hasOwnProperty('transition_time');
513
- // const transitionTime = hasTransitionTime ? options.transition_time : 0;
514
- // const hasHueCalibrationTable = options && options.hasOwnProperty('hue_calibration');
515
- // if (hasHueCalibrationTable)
516
- // try {
517
- // return { ...options, transition: transitionTime, hue_correction: JSON.parse(options.hue_calibration) };
518
- // }
519
- // catch (err) {
520
- // const hue_correction_table = [];
521
- // options.hue_calibration.split(',').forEach(element => {
522
- // const match = /([0-9]+):([0-9]+)/.exec(element);
523
- // if (match && match.length == 3)
524
- // hue_correction_table.push({ in: Number(match[1]), out: Number(match[2]) });
525
- // });
526
- // if (hue_correction_table.length > 0)
527
- // return { ...options, transition: transitionTime, hue_correction: hue_correction_table };
528
- // }
529
- // return { ...options, transition: transitionTime };
530
- // },
531
-
532
- // }, 2);
533
- // pushToStates(statesDefs.hue_move, 2);
534
- // pushToStates(statesDefs.saturation_move, 2);
535
- // pushToStates({
536
- // id: 'hue_calibration',
537
- // prop: 'color',
538
- // name: 'Hue color calibration table',
539
- // icon: undefined,
540
- // role: 'table',
541
- // write: true,
542
- // read: false,
543
- // type: 'string',
544
- // inOptions: true,
545
- // setter: (_value, options) => {
546
- // return {
547
- // hue: options.hue,
548
- // saturation: options.saturation,
549
- // };
550
- // },
551
- // setterOpt: (_value, options) => {
552
- // const hasTransitionTime = options && options.hasOwnProperty('transition_time');
553
- // const transitionTime = hasTransitionTime ? options.transition_time : 0;
554
- // const hasHueCalibrationTable = options && options.hasOwnProperty('hue_calibration');
555
- // if (hasHueCalibrationTable)
556
- // try {
557
- // return { ...options, transition: transitionTime, hue_correction: JSON.parse(options.hue_calibration) };
558
- // }
559
- // catch (err) {
560
- // const hue_correction_table = [];
561
- // options.hue_calibration.split(',').forEach(element => {
562
- // const match = /([0-9]+):([0-9]+)/.exec(element);
563
- // if (match && match.length == 3)
564
- // hue_correction_table.push({ in: Number(match[1]), out: Number(match[2]) });
565
- // });
566
- // if (hue_correction_table.length > 0)
567
- // return { ...options, transition: transitionTime, hue_correction: hue_correction_table };
568
- // }
569
- // return { ...options, transition: transitionTime };
570
- // },
571
-
572
- // }, prop.access);
573
482
  break;
574
483
  }
575
484
  default:
@@ -597,6 +506,7 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
597
506
  write: true,
598
507
  read: true,
599
508
  type: 'boolean',
509
+ def: true,
600
510
  setattr: prop.property,
601
511
  setter: (value) => (value) ? prop.value_toggle : undefined
602
512
  });
@@ -733,6 +643,7 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
733
643
  min: config.useKelvin == true ? utils.miredKelvinConversion(500) : 150,
734
644
  max: config.useKelvin == true ? utils.miredKelvinConversion(150) : 500,
735
645
  unit: config.useKelvin == true ? 'K' : 'mired',
646
+ isEvent: true,
736
647
  getter: (payload) => {
737
648
  if (payload.action != 'color_temperature_move') {
738
649
  return undefined;
@@ -761,6 +672,7 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
761
672
  read: true,
762
673
  type: 'string',
763
674
  def: '#ffffff',
675
+ isEvent: true,
764
676
  getter: (payload) => {
765
677
  if (payload.action != 'color_move') {
766
678
  return undefined;
@@ -866,6 +778,7 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
866
778
  role: 'button',
867
779
  write: true,
868
780
  read: true,
781
+ def: true,
869
782
  type: 'boolean',
870
783
  setattr: prop.property,
871
784
  setter: (value) => (value) ? prop.value_toggle : undefined
@@ -971,6 +884,7 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
971
884
  role: 'button',
972
885
  write: true,
973
886
  read: true,
887
+ def: true,
974
888
  type: 'boolean',
975
889
  setter: (value) => (value) ? scene.id : undefined
976
890
  });
@@ -1,7 +1,7 @@
1
1
  const core = require('@iobroker/adapter-core');
2
2
  const Aedes = require('aedes');
3
3
  const net = require('net');
4
-
4
+ let mqttServer;
5
5
 
6
6
  class MqttServerController {
7
7
  constructor(adapter) {
@@ -14,7 +14,7 @@ class MqttServerController {
14
14
  const db = new NedbPersistence({ path: `${core.getAbsoluteInstanceDataDir(this.adapter)}/mqttData`, prefix: '' });
15
15
  // @ts-ignore
16
16
  const aedes = Aedes({ persistence: db });
17
- const mqttServer = net.createServer(aedes.handle);
17
+ mqttServer = net.createServer(aedes.handle);
18
18
  mqttServer.listen(this.adapter.config.mqttServerPort, this.adapter.config.mqttServerIPBind, () => {
19
19
  this.adapter.log.info(`Statring MQTT-Server on IP ${this.adapter.config.mqttServerIPBind} and Port ${this.adapter.config.mqttServerPort}`);
20
20
  });
@@ -27,7 +27,7 @@ class MqttServerController {
27
27
  try {
28
28
  // @ts-ignore
29
29
  const aedes = Aedes();
30
- const mqttServer = net.createServer(aedes.handle);
30
+ mqttServer = net.createServer(aedes.handle);
31
31
  mqttServer.listen(this.adapter.config.mqttServerPort, this.adapter.config.mqttServerIPBind, () => {
32
32
  this.adapter.log.info(`Statring DummyMQTT-Server on IP ${this.adapter.config.mqttServerIPBind} and Port ${this.adapter.config.mqttServerPort}`);
33
33
  });
@@ -35,6 +35,12 @@ class MqttServerController {
35
35
  this.adapter.log.error(err);
36
36
  }
37
37
  }
38
+
39
+ closeServer() {
40
+ if (mqttServer && !mqttServer.closed()) {
41
+ mqttServer.close();
42
+ }
43
+ }
38
44
  }
39
45
 
40
46
  module.exports = {
package/lib/states.js CHANGED
@@ -136,6 +136,7 @@ const states = {
136
136
  write: true,
137
137
  read: true,
138
138
  type: 'boolean',
139
+ def: false,
139
140
  getter: payload => (payload.state === 'ON'),
140
141
  setter: (value) => (value) ? 'ON' : 'OFF',
141
142
  },
@@ -151,6 +152,7 @@ const states = {
151
152
  unit: '%',
152
153
  min: 0,
153
154
  max: 100,
155
+ def: 100,
154
156
  getter: payload => {
155
157
  return utils.bulbLevelToAdapterLevel(payload.brightness);
156
158
  },
@@ -35,15 +35,47 @@ class StatesController {
35
35
  this.adapter.log.warn(`--->>> fromZ2M -> ${device.ieee_address} states: ${JSON.stringify(messageObj)}`);
36
36
  }
37
37
 
38
- for (const [key, value] of Object.entries(messageObj.payload)) {
39
- let states;
40
- if (key == 'action') {
41
- states = device.states.filter(x => (x.prop && x.prop == key));
42
- } else {
43
- states = device.states.filter(x => (x.prop && x.prop == key) || x.id == key);
44
- }
38
+ // Is an action
39
+ if (Object.keys(messageObj.payload).includes('action')) {
40
+ const states = device.states.filter(x => (x.prop && x.prop == 'action'));
45
41
 
46
42
  for (const state of states) {
43
+ const stateName = `${device.ieee_address}.${state.id}`;
44
+
45
+ // It may be that the state has not yet been created!
46
+ if (!this.createCache[device.ieee_address] || !this.createCache[device.ieee_address][state.id] || !this.createCache[device.ieee_address][state.id].created) {
47
+ incStatsQueue[incStatsQueue.length] = messageObj;
48
+ continue;
49
+ }
50
+
51
+ if (!state.getter) {
52
+ this.adapter.log.error(`Action ${stateName} has no getter, this must not be!`);
53
+ continue;
54
+ }
55
+
56
+ try {
57
+ if (state.isEvent && state.isEvent == true) {
58
+ if (state.type == 'boolean') {
59
+ await this.setStateWithTimeoutAsync(stateName, state.getter(messageObj.payload), 300);
60
+ }
61
+ else {
62
+ await this.setStateSafelyAsync(stateName, state.getter(messageObj.payload));
63
+ }
64
+ }
65
+ else {
66
+ await this.setStateChangedSafelyAsync(stateName, state.getter(messageObj.payload));
67
+ }
68
+ } catch (err) {
69
+ incStatsQueue[incStatsQueue.length] = messageObj;
70
+ this.adapter.log.debug(`Can not set ${stateName}, queue state in incStatsQueue!`);
71
+ }
72
+ }
73
+ }
74
+ // Is not an action
75
+ else {
76
+ for (const [key, value] of Object.entries(messageObj.payload)) {
77
+ const state = device.states.find(x => (x.prop && x.prop == key) || x.id == key);
78
+
47
79
  if (!state) {
48
80
  continue;
49
81
  }
@@ -53,28 +85,20 @@ class StatesController {
53
85
  // It may be that the state has not yet been created!
54
86
  if (!this.createCache[device.ieee_address] || !this.createCache[device.ieee_address][state.id] || !this.createCache[device.ieee_address][state.id].created) {
55
87
  incStatsQueue[incStatsQueue.length] = messageObj;
56
- //this.adapter.log.debug(`State ${stateName} is not yet created, queue state in incStatsQueue!`);
57
88
  continue;
58
89
  }
59
90
 
60
91
  try {
61
- if (state.isEvent) {
62
- if (state.getter) {
63
- await this.setStateWithTimeoutAsync(stateName, state.getter(messageObj.payload), 300);
64
- } else {
65
- await this.setStateWithTimeoutAsync(stateName, value, 300);
66
- }
92
+ if (state.getter) {
93
+ await this.setStateChangedSafelyAsync(stateName, state.getter(messageObj.payload));
67
94
  } else {
68
- if (state.getter) {
69
- await this.setStateChangedSafelyAsync(stateName, state.getter(messageObj.payload));
70
- } else {
71
- await this.setStateChangedSafelyAsync(stateName, value);
72
- }
95
+ await this.setStateChangedSafelyAsync(stateName, value);
73
96
  }
74
97
  } catch (err) {
75
98
  incStatsQueue[incStatsQueue.length] = messageObj;
76
99
  this.adapter.log.debug(`Can not set ${stateName}, queue state in incStatsQueue!`);
77
100
  }
101
+
78
102
  }
79
103
  }
80
104
  }
@@ -116,12 +140,12 @@ class StatesController {
116
140
  for (const device of this.groupCache.concat(this.deviceCache)) {
117
141
  for (const state of device.states) {
118
142
  if (state.write == true) {
119
- this.adapter.subscribeStatesAsync(`${device.ieee_address}.${state.id}`);
143
+ this.adapter.subscribeStates(`${device.ieee_address}.${state.id}`);
120
144
  }
121
145
  }
122
146
  }
123
- this.adapter.subscribeStatesAsync('info.debugmessages');
124
- this.adapter.subscribeStatesAsync('info.logfilter');
147
+ this.adapter.subscribeStates('info.debugmessages');
148
+ this.adapter.subscribeStates('info.logfilter');
125
149
  }
126
150
 
127
151
  async setAllAvailableToFalse() {
@@ -72,6 +72,12 @@ class WebsocketController {
72
72
  }, restartTimeout);
73
73
  }
74
74
 
75
+ closeConnection() {
76
+ if (wsClient && wsClient.readyState !== WebSocket.CLOSED) {
77
+ wsClient.close();
78
+ }
79
+ }
80
+
75
81
  async allTimerClear() {
76
82
  clearTimeout(pingTimeout);
77
83
  clearTimeout(ping);
@@ -49,7 +49,7 @@ class Z2mController {
49
49
  };
50
50
 
51
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)) {
52
+ if (['button'].includes(deviceState.role) || ['brightness_move', 'colortemp_move', 'brightness_move', 'effect'].includes(deviceState.id)) {
53
53
  this.adapter.setState(id, state, true);
54
54
  }
55
55
 
package/main.js CHANGED
@@ -52,7 +52,7 @@ class Zigbee2mqtt extends core.Adapter {
52
52
  // Initialize your adapter here
53
53
  adapterInfo(this.config, this.log);
54
54
 
55
- this.setStateAsync('info.connection', false, true);
55
+ this.setState('info.connection', false, true);
56
56
 
57
57
  const debugDevicesState = await this.getStateAsync('info.debugmessages');
58
58
  if (debugDevicesState && debugDevicesState.val) {
@@ -126,9 +126,9 @@ class Zigbee2mqtt extends core.Adapter {
126
126
  });
127
127
 
128
128
  wsClient.on('close', async () => {
129
- this.setStateChangedAsync('info.connection', false, true);
129
+ this.setStateChanged('info.connection', false, true);
130
130
  await statesController.setAllAvailableToFalse();
131
- this.log.warn('Websocket disconnectet');
131
+ this.log.warn('Websocket disconnected');
132
132
  });
133
133
  }
134
134
 
@@ -149,7 +149,7 @@ class Zigbee2mqtt extends core.Adapter {
149
149
  if (messageObj.payload.state != 'online') {
150
150
  statesController.setAllAvailableToFalse();
151
151
  }
152
- this.setStateChangedAsync('info.connection', messageObj.payload.state == 'online', true);
152
+ this.setStateChanged('info.connection', messageObj.payload.state == 'online', true);
153
153
  break;
154
154
  case 'bridge/devices':
155
155
  await deviceController.createDeviceDefinitions(messageObj.payload);
@@ -220,6 +220,11 @@ class Zigbee2mqtt extends core.Adapter {
220
220
 
221
221
  async onUnload(callback) {
222
222
  try {
223
+ if (mqttClient && !mqttClient.closed) {
224
+ mqttClient.close();
225
+ }
226
+ mqttServerController.closeServer();
227
+ websocketController.closeConnection();
223
228
  await statesController.setAllAvailableToFalse();
224
229
  await websocketController.allTimerClear();
225
230
  await statesController.allTimerClear();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zigbee2mqtt",
3
- "version": "2.3.0",
3
+ "version": "2.4.1",
4
4
  "description": "Zigbee2MQTT adapter for ioBroker",
5
5
  "author": {
6
6
  "name": "Dennis Rathjen",
@@ -24,7 +24,7 @@
24
24
  "aedes-persistence-nedb": "^2.0.3",
25
25
  "mqtt": "^4.3.7",
26
26
  "net": "^1.0.2",
27
- "ws": "^8.10.0"
27
+ "ws": "^8.11.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@alcalzone/release-script-plugin-iobroker": "^3.5.9",
@@ -33,22 +33,22 @@
33
33
  "@iobroker/adapter-dev": "^1.2.0",
34
34
  "@iobroker/testing": "^4.1.0",
35
35
  "@tsconfig/node14": "^1.0.3",
36
- "@types/chai": "^4.3.3",
36
+ "@types/chai": "^4.3.4",
37
37
  "@types/chai-as-promised": "^7.1.5",
38
38
  "@types/mocha": "^10.0.0",
39
- "@types/node": "^18.11.7",
39
+ "@types/node": "^18.11.9",
40
40
  "@types/proxyquire": "^1.3.28",
41
41
  "@types/sinon": "^10.0.13",
42
- "@types/sinon-chai": "^3.2.8",
43
- "chai": "^4.3.6",
42
+ "@types/sinon-chai": "^3.2.9",
43
+ "chai": "^4.3.7",
44
44
  "chai-as-promised": "^7.1.1",
45
- "eslint": "^8.26.0",
45
+ "eslint": "^8.27.0",
46
46
  "eslint-config-prettier": "^8.5.0",
47
47
  "eslint-plugin-prettier": "^4.2.1",
48
48
  "mocha": "^10.1.0",
49
49
  "prettier": "^2.7.1",
50
50
  "proxyquire": "^2.1.3",
51
- "sinon": "^14.0.1",
51
+ "sinon": "^14.0.2",
52
52
  "sinon-chai": "^3.7.0",
53
53
  "typescript": "~4.8.4"
54
54
  },