iobroker.zwavews 0.0.17 → 0.1.0

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
@@ -35,6 +35,16 @@ Activate WS Server Settings in `zwave-js-ui` we use the Home Assistant Settings
35
35
 
36
36
 
37
37
  ## Changelog
38
+ ### 0.1.0 (2026-03-08)
39
+ * (arteck) BREAKING CHANGE - dp name is now with underline
40
+ * (arteck) add deviceManager
41
+ * (arteck) fix dp's with a space
42
+ * (arteck) fix dp's with special chars
43
+
44
+ ### 0.0.18 (2026-02-28)
45
+ * (arteck) add info.sendMessageAllowed object to allow sending the message to zwave-ui-js
46
+ * (arteck) add new checkbox to set info.sendMessageAllowed immediately after starting the adapter
47
+
38
48
  ### 0.0.17 (2026-02-20)
39
49
  * (arteck) fix adapter start
40
50
  * (arteck) Dependencies have been updated
@@ -31,5 +31,8 @@
31
31
  "Always refresh node infos": "Node-Informationen immer aktualisieren",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "Die Ereignisse wie 'Gerät entfernt' oder 'Deaktiviert' werden in der Beschreibung anstelle des Namens angezeigt",
33
33
  "Inform about wake up and sleep of battery devices in the log": "Über das Aufwachen und Schlafen von batteriebetriebenen Geräten im Protokoll informieren",
34
- "new Type event Warning in log": "neue Typ-Ereigniswarnung im Protokoll"
34
+ "new Type event Warning in log": "neue Typ-Ereigniswarnung im Protokoll",
35
+ "allow start send WS message directly after adapter start": "Erlaube das Senden von WS-Nachrichten direkt nach dem Adapterstart",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "damit kann man entscheiden ob die Nachrichten direkt nach adapter Start gesendet werden. Ist die checkbox false wird der letzte Status aus dem info.sendMessageAllowed DP genommen."
37
+
35
38
  }
@@ -31,6 +31,8 @@
31
31
  "Always refresh node infos": "Always refresh node infos",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name",
33
33
  "Inform about wake up and sleep of battery devices in the log": "Inform about wake up and sleep of battery devices in the log",
34
- "new Type event Warning in log": "new Type event Warning in log"
34
+ "new Type event Warning in log": "new Type event Warning in log",
35
+ "allow start send WS message directly after adapter start": "allow start send WS message directly after adapter start",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP."
35
37
 
36
38
  }
@@ -31,5 +31,7 @@
31
31
  "Always refresh node infos": "Actualizar siempre la información del nodo",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "Los eventos como 'Dispositivo eliminado' o 'Deshabilitado' se muestran en la descripción en lugar de en el nombre",
33
33
  "Inform about wake up and sleep of battery devices in the log": "Informar sobre el despertar y el sueño de los dispositivos de batería en el registro",
34
- "new Type event Warning in log": "nuevo evento de tipo Advertencia en el registro"
34
+ "new Type event Warning in log": "nuevo evento de tipo Advertencia en el registro",
35
+ "allow start send WS message directly after adapter start": "permitir el envío de mensajes WS directamente después del inicio del adaptador",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "Esto te permite decidir si los mensajes se envían inmediatamente después de que el adaptador se inicie. Si la casilla de verificación es falsa, el último estado se toma del DP info.sendMessageAllowed."
35
37
  }
@@ -31,5 +31,7 @@
31
31
  "Always refresh node infos": "Toujours actualiser les informations sur le nœud",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "Les événements tels que 'Appareil supprimé' ou 'Désactivé' sont affichés dans la description au lieu du nom",
33
33
  "Inform about wake up and sleep of battery devices in the log": "Informer sur le réveil et le sommeil des appareils alimentés par batterie dans le journal",
34
- "new Type event Warning in log": "nouvel avertissement d'événement de type dans le journal"
34
+ "new Type event Warning in log": "nouvel avertissement d'événement de type dans le journal",
35
+ "allow start send WS message directly after adapter start": "permettre l'envoi de messages WS directement après le démarrage de l'adaptateur",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "Cela vous permet de décider si les messages sont envoyés immédiatement après le démarrage de l'adaptateur. Si la case à cocher est fausse, le dernier statut est pris du DP info.sendMessageAllowed."
35
37
  }
@@ -31,5 +31,7 @@
31
31
  "Always refresh node infos": "Aggiorna sempre le informazioni sui nodi",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "Gli eventi come 'Dispositivo rimosso' o 'Disabilitato' vengono visualizzati nella descrizione anziché nel nome",
33
33
  "Inform about wake up and sleep of battery devices in the log": "Informazioni sul risveglio e sul sonno dei dispositivi a batteria nel registro",
34
- "new Type event Warning in log": "nuovo avviso di evento di tipo nel registro"
34
+ "new Type event Warning in log": "nuovo avviso di evento di tipo nel registro",
35
+ "allow start send WS message directly after adapter start": "consentire l'invio di messaggi WS direttamente dopo l'avvio dell'adattatore",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "Questo ti permette di decidere se i messaggi vengono inviati immediatamente dopo l'avvio dell'adattatore. Se la casella di controllo è falsa, l'ultimo stato viene preso dal DP info.sendMessageAllowed."
35
37
  }
@@ -31,5 +31,7 @@
31
31
  "Always refresh node infos": "Ververs node-informatie altijd",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "Evenementen zoals 'Apparaat verwijderd' of 'Uitgeschakeld' worden weergegeven in de beschrijving in plaats van in de naam",
33
33
  "Inform about wake up and sleep of battery devices in the log": "Informeer over het wakker worden en slapen van batterijapparaten in het logboek",
34
- "new Type event Warning in log": "nieuw Type gebeurtenis Waarschuwing in log"
34
+ "new Type event Warning in log": "nieuw Type gebeurtenis Waarschuwing in log",
35
+ "allow start send WS message directly after adapter start": "toestaan dat WS-berichten direct na het starten van de adapter worden verzonden",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "Hiermee kunt u beslissen of berichten onmiddellijk na het starten van de adapter worden verzonden. Als het selectievakje niet is geselecteerd, wordt de laatste status genomen van de info.sendMessageAllowed DP."
35
37
  }
@@ -31,6 +31,8 @@
31
31
  "Always refresh node infos": "Zawsze odświeżaj informacje o Node",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "Zdarzenia takie jak 'Urządzenie usunięte' lub 'Wyłączone' są wyświetlane w opisie zamiast w nazwie",
33
33
  "Inform about wake up and sleep of battery devices in the log": "Informuj o wybudzaniu i usypianiu urządzeń bateryjnych w Logu",
34
- "new Type event Warning in log": "nowe ostrzeżenie zdarzenia typu w Logu"
34
+ "new Type event Warning in log": "nowe ostrzeżenie zdarzenia typu w Logu",
35
+ "allow start send WS message directly after adapter start": "zezwól na wysyłanie wiadomości WS bezpośrednio po uruchomieniu adaptera",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "Dzięki temu możesz zdecydować, czy wiadomości są wysyłane bezpośrednio po uruchomieniu adaptera. Jeśli pole wyboru jest fałszywe, ostatni status jest pobierany z info.sendMessageAllowed DP."
35
37
 
36
38
  }
@@ -31,5 +31,7 @@
31
31
  "Always refresh node infos": "Sempre atualizar informações do nó",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "Os eventos como 'Dispositivo removido' ou 'Desativado' são exibidos na descrição em vez do nome",
33
33
  "Inform about wake up and sleep of battery devices in the log": "Informar sobre o despertar e o sono dos dispositivos de bateria no log",
34
- "new Type event Warning in log": "novo aviso de evento de tipo no log"
34
+ "new Type event Warning in log": "novo aviso de evento de tipo no log",
35
+ "allow start send WS message directly after adapter start": "permitir o envio de mensagens WS diretamente após o início do adaptador",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "Isso permite que você decida se as mensagens são enviadas imediatamente após o início do adaptador. Se a caixa de seleção for falsa, o último status é retirado do DP info.sendMessageAllowed."
35
37
  }
@@ -31,5 +31,7 @@
31
31
  "Always refresh node infos": "Всегда обновлять информацию о узлах",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "События, такие как 'Устройство удалено' или 'Отключено', отображаются в описании, а не в имени",
33
33
  "Inform about wake up and sleep of battery devices in the log": "Информация о пробуждении и сне устройств на батарейках в журнале",
34
- "new Type event Warning in log": "новое предупреждение о событии типа в журнале"
34
+ "new Type event Warning in log": "новое предупреждение о событии типа в журнале",
35
+ "allow start send WS message directly after adapter start": "разрешить отправку WS-сообщения непосредственно после запуска адаптера",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "Это позволяет вам решить, отправляются ли сообщения сразу после запуска адаптера. Если флажок не установлен, последний статус берется из info.sendMessageAllowed DP."
35
37
  }
@@ -31,5 +31,7 @@
31
31
  "Always refresh node infos": "Завжди оновлювати інформацію про вузли",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "Події, такі як 'Пристрій видалено' або 'Вимкнено', відображаються в описі, а не в імені",
33
33
  "Inform about wake up and sleep of battery devices in the log": "Інформація про пробудження та сон пристроїв на батарейках у журналі",
34
- "new Type event Warning in log": "нове попередження про подію типу в журналі"
34
+ "new Type event Warning in log": "нове попередження про подію типу в журналі",
35
+ "allow start send WS message directly after adapter start": "дозволить отправлять WS-сообщение непосредственно после запуска адаптера",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "Это позволяет вам решить, отправляются ли сообщения сразу после запуска адаптера. Если флажок не установлен, последний статус берется из info.sendMessageAllowed DP."
35
37
  }
@@ -31,5 +31,7 @@
31
31
  "Always refresh node infos": "始终刷新节点信息",
32
32
  "The events such as 'Device removed' or 'Disabled' are displayed in the description instead of in the name": "诸如“设备已移除”或“已禁用”等事件显示在描述中,而不是名称中",
33
33
  "Inform about wake up and sleep of battery devices in the log": "在日志中通知电池设备的唤醒和休眠情况",
34
- "new Type event Warning in log": "日志中新类型事件警告"
34
+ "new Type event Warning in log": "日志中新类型事件警告",
35
+ "allow start send WS message directly after adapter start": "允许在适配器启动后直接发送 WS 消息",
36
+ "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.": "这允许您决定是否在适配器启动后立即发送消息。如果复选框为 false,则最后的状态将从 info.sendMessageAllowed DP 中获取。"
35
37
  }
@@ -5,6 +5,31 @@
5
5
  "width": "calc(100% - 100px)"
6
6
  },
7
7
  "items": {
8
+ "_deviceManager": {
9
+ "type": "panel",
10
+ "label": "devices",
11
+ "items": {
12
+ "_devMng": {
13
+ "type": "deviceManager",
14
+ "sm": 12,
15
+ "style": {
16
+ "width": "100%",
17
+ "height": "100%",
18
+ "overflow": "hidden"
19
+ }
20
+ }
21
+ },
22
+ "style": {
23
+ "width": "100%",
24
+ "height": "100%",
25
+ "overflow": "hidden"
26
+ },
27
+ "innerStyle": {
28
+ "width": "100%",
29
+ "height": "100%",
30
+ "overflow": "hidden"
31
+ }
32
+ },
8
33
  "_tab_Start": {
9
34
  "type": "panel",
10
35
  "label": "Main Settings",
@@ -305,6 +330,18 @@
305
330
  "type": "panel",
306
331
  "label": "Other configurations",
307
332
  "items": {
333
+ "wsOnStart": {
334
+ "type": "checkbox",
335
+ "label": "allow start send WS message directly after adapter start",
336
+ "default": true,
337
+ "help": "This allows you to decide whether messages are sent immediately after the adapter starts. If the checkbox is false, the last status is taken from the info.sendMessageAllowed DP.",
338
+ "xs": 12,
339
+ "sm": 12,
340
+ "md": 12,
341
+ "lg": 12,
342
+ "xl": 12,
343
+ "newLine": true
344
+ },
308
345
  "showNodeInfoMessage": {
309
346
  "type": "checkbox",
310
347
  "label": "Show Node Info messages to ioBroker log",
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "zwavews",
4
- "version": "0.0.17",
4
+ "version": "0.1.0",
5
5
  "news": {
6
+ "0.1.0": {
7
+ "en": "BREAKING CHANGE - dp name is now with underline\nadd deviceManager\nfix dp's with a space\nfix dp's with special chars",
8
+ "de": "BREAKING CHANGE - dp name ist jetzt mit unterstreichen\nadd-Gerät Manager\ndp's mit einem raum reparieren\nfix dp's with special chars",
9
+ "ru": "BREAKING CHANGE - название dp теперь с подчеркиванием\nдобавить устройство Менеджер\nустановить dp в пространстве\nобсуждение dp's with special chars",
10
+ "pt": "MUDANÇA DE INÍCIO - nome dp está agora com sublinhado\nadicionar dispositivo Gestor\ncorrigir dp's com um espaço\ncorrigir dp's com caracteres especiais",
11
+ "nl": "BREAKING VERANDERING - dp naam is nu met benadrukken\napparaat toevoegen Beheerder\nfix dp's met een spatie\nfix dp's met speciale tekens",
12
+ "fr": "CHANGEMENT DE BREAKING - DP nom est maintenant avec le soulignement\najouter un périphérique Gestionnaire\nréparer dp's avec un espace\nfixer dp's avec des caractères spéciaux",
13
+ "it": "BREAKING CHANGE - il nome dp è ora in linea\naggiungere dispositivo Manager\nfix dp's con uno spazio\nsistemare dp's con beneficenza speciali",
14
+ "es": "CAMBIO DE BREAKING - nombre dp ahora es con subrayado\nañadir dispositivo Manager\narreglar dp con un espacio\narreglar dp con chars especiales",
15
+ "pl": "ZMIANA BREAKING - nazwa dp jest teraz z podkreśleniem\ndodaj urządzenie Kierownik\nfix dp 's z przestrzenią\nfix dp 's ze specjalnymi znakami",
16
+ "uk": "BREAKING CHANGE - ім'я dp тепер з онлайн\nдодати пристрій Менеджер\nзакріпити dp's з космосом\nфіксувати dp з особливими chars",
17
+ "zh-cn": "断裂变换 - dp 名称现在是下划线\n添加设备 经理\n修补 dp 的空格\n修复 dp 与特殊字符"
18
+ },
19
+ "0.0.18": {
20
+ "en": "add info.sendMessageAllowed object to allow sending the message to zwave-ui-js\nadd new checkbox to set info.sendMessageAllowed immediately after starting the adapter",
21
+ "de": "add info.sendMessageAllowed object to let send the message to zwave-ui-js\nneue Checkbox hinzufügen, um info.sendMessage einzustellen Sofort nach dem Start des Adapters zugelassen",
22
+ "ru": "добавить info.sendMessageРазрешенный объект для отправки сообщения на zwave-ui-js\nдобавить новый флажок для установки info.sendMessage Допускается сразу после запуска адаптера",
23
+ "pt": "add info.sendMessagePermitido objeto para permitir o envio da mensagem para zwave-ui-js\nadicionar nova caixa de seleção para definir info.sendMessage Permitido imediatamente após iniciar o adaptador",
24
+ "nl": "info.sendMessageToegewezen object om het bericht naar zwave-ui-js te versturen\nnieuwe selectievakje toevoegen om info.sendMessage in te stellen Onmiddellijk na het starten van de adapter toegestaan",
25
+ "fr": "ajouter info.sendMessageObjet autorisé pour permettre l'envoi du message à zwave-ui-js\najouter une nouvelle case à cocher pour définir info.sendMessage Autorisé immédiatement après le démarrage de l'adaptateur",
26
+ "it": "aggiungere info.sendMessageAllowed oggetto per consentire l'invio del messaggio a zwave-ui-js\naggiungere nuova casella di controllo per impostare info.sendMessage Consentito subito dopo l'avvio dell'adattatore",
27
+ "es": "añadir info.sendMessagePropósito permitido enviar el mensaje a zwave-ui-js\nañadir nueva casilla para configurar información.sendMessage Permitido inmediatamente después de iniciar el adaptador",
28
+ "pl": "dodaj info.sendMessageDopuszczalny obiekt, aby umożliwić wysyłanie wiadomości do zwave- ui- js\ndodaj nową opcję do ustawienia info.sendMessage Dozwolone bezpośrednio po uruchomieniu adaptera",
29
+ "uk": "додайте інформацію.sendMessageВсього об'єкту, щоб дозволити надсилати повідомлення на zwave-ui-js\nдодати нову прапорець, щоб встановити інформацію.sendMessage Допускається відразу після запуску адаптера",
30
+ "zh-cn": "添加信息. sendMessage Allowed 对象允许将消息发送到 zwave- ui- js\n添加新复选框以设置信息. sendMessage 启动适配器后立即允许"
31
+ },
6
32
  "0.0.17": {
7
33
  "en": "fix adapter start\nDependencies have been updated",
8
34
  "de": "befestigungsadapter start\nAbhängigkeiten wurden aktualisiert",
@@ -67,35 +93,8 @@
67
93
  "pl": "dodaj typ zdarzenia \"powiadomienie o wartości\"",
68
94
  "uk": "додати тип події \"значення повідомлення\"",
69
95
  "zh-cn": "添加事件类型“ 值通知”"
70
- },
71
- "0.0.12": {
72
- "en": "typo\nfix dp channel name\nadd endpoint > 0 to value if exists",
73
- "de": "typo\ndp kanal name\nendpunkt hinzufügen > 0 auf wert, falls vorhanden",
74
- "ru": "опечатка\nустановить имя канала dp\nдобавить конечную точку 0, если существует",
75
- "pt": "erro de digitação\ncorrigir o nome do canal dp\nadicionar endpoint > 0 a valor se existir",
76
- "nl": "type\nfix dp kanaalnaam\neindpunt toevoegen > 0 naar waarde indien aanwezig",
77
- "fr": "typo\ncorriger le nom du canal dp\najouter le paramètre > 0 à valeur s'il existe",
78
- "it": "tipo\ncorretto nome del canale dp\naggiungere il punto finale 0 a valore se esiste",
79
- "es": "typo\nfijar nombre del canal dp\nañadir endpoint √ 0 a valor si existe",
80
- "pl": "typo\nfix dp nazwa kanału\ndodać punkt końcowy > 0 do wartości, jeśli istnieje",
81
- "uk": "типи\nзафіксувати ім'я каналів dp\nдодати кінцеву точку > 0 до значення, якщо існує",
82
- "zh-cn": "类型\n修复 dp 频道名称\n添加终点 > 0 到数值( 如果存在)"
83
- },
84
- "0.0.11": {
85
- "en": "fix dp types",
86
- "de": "dp-typen",
87
- "ru": "фиксировать типы dp",
88
- "pt": "corrigir tipos dp",
89
- "nl": "fix dp types",
90
- "fr": "correction des types dp",
91
- "it": "corretti i tipi dp",
92
- "es": "arreglos tipo dp",
93
- "pl": "fix dp types",
94
- "uk": "фіксувати типи dp",
95
- "zh-cn": "固定 dp 类型"
96
96
  }
97
97
  },
98
- "messages": [],
99
98
  "titleLang": {
100
99
  "en": "Z-Wave WS",
101
100
  "de": "Z-Wave WS",
@@ -183,6 +182,60 @@
183
182
  {
184
183
  "admin": ">=7.6.17"
185
184
  }
185
+ ],
186
+ "messages": [
187
+ {
188
+ "condition": {
189
+ "operand": "and",
190
+ "rules": [
191
+ "oldVersion<0.0.18",
192
+ "newVersion>=0.1.0"
193
+ ]
194
+ },
195
+ "title": {
196
+ "en": "Important notice!",
197
+ "de": "Wichtiger Hinweis!",
198
+ "ru": "Важное замечание!",
199
+ "pt": "Notícia importante!",
200
+ "nl": "Belangrijke mededeling!",
201
+ "fr": "Avis important!",
202
+ "it": "Avviso IMPORTANTE!",
203
+ "es": "Noticia importante!",
204
+ "pl": "Ważna uwaga!",
205
+ "zh-cn": "重要通知!"
206
+ },
207
+ "text": {
208
+ "en": "\"BREAKING CHANGE. <br> Adapter version 0.1.0 use now a underline on Object. check you alias or visu and corr this mistake. example: Manufacturer Specific is now Manufacturer_Specific",
209
+ "de": "\"BREAKING CHANGE. <br> Die Adapterversion 0.1.0 verwendet jetzt eine Unterstreichung bei Objekten. Überprüfe deinen Alias oder Visu und korrigiere es. Beispiel: Manufacturer Specific lautet jetzt Manufacturer_Specific.",
210
+ "ru": "\"BREAKING CHANGE. <br> В версии адаптера 0.1.0 теперь используется подчеркивание объекта. Проверьте свой псевдоним или визуализацию и исправьте эту ошибку. Например: Manufacturer Specific теперь Manufacturer_Specific",
211
+ "pt": "\"BREAKING CHANGE. <br> A versão 0.1.0 do adaptador agora usa um sublinhado em Objetos. Verifique seu alias ou visualizador e corrija esse erro. Exemplo: Manufacturer Specific agora é Manufacturer_Specific.",
212
+ "nl": "\"BREAKING CHANGE. <br> Adapterversie 0.1.0 gebruikt nu een onderstreping bij Object. Controleer je alias of visualisatie en corrigeer deze fout. Bijvoorbeeld: Manufacturer Specific is nu Manufacturer_Specific.",
213
+ "fr": "\"BREAKING CHANGE. <br> L'adaptateur version 0.1.0 utilise désormais un trait de soulignement sur les objets. Vérifiez votre alias ou visualisez l'interface et corrigez cette erreur. Exemple : Manufacturer Specific devient Manufacturer_Specific.",
214
+ "it": "\"BREAKING CHANGE. <br> La versione 0.1.0 dell'adattatore ora utilizza una sottolineatura sull'oggetto. Controlla il tuo alias o visu e correggi questo errore. Esempio: Manufacturer Specific ora è Manufacturer_Specific",
215
+ "es": "\"BREAKING CHANGE. <br> La versión 0.1.0 del adaptador ahora usa un subrayado en el objeto. Verifique su alias o visu y corrija este error. Ejemplo: Manufacturer Specific ahora es Manufacturer_Specific",
216
+ "pl": "\"BREAKING CHANGE. <br> Wersja adaptera 0.1.0 używa teraz podkreślenia na obiekcie. Sprawdź alias lub wizualizację i popraw ten błąd. Przykład: Manufacturer Specific to teraz Manufacturer_Specific",
217
+ "uk": "\"BREAKING CHANGE. <br> Версія адаптера 0.1.0 тепер використовує підкреслення на об'єкті. Перевірте свій псевдонім або візуалізацію та виправте цю помилку. Приклад: Manufacturer Specific тепер Manufacturer_Specific.",
218
+ "zh-cn": "\"BREAKING CHANGE. <br> 适配器版本 0.1.0 现在在对象名称前使用下划线。请检查您的别名或视觉设置,并更正此错误。例如:Manufacturer Specific 现在是 Manufacturer_Specific。"
219
+ },
220
+ "link": "https://github.com/arteck/ioBroker.zwavews/wiki/DP's-with-space-blank-in-Name",
221
+ "level": "warn",
222
+ "linkText": {
223
+ "en": "Readme",
224
+ "de": "Liesmich",
225
+ "ru": "Прочти меня",
226
+ "pt": "Leia-me",
227
+ "nl": "Leesmij",
228
+ "fr": "Lisez-moi",
229
+ "it": "Leggimi",
230
+ "es": "Léame",
231
+ "pl": "Readme",
232
+ "zh-cn": "自述文件"
233
+ },
234
+ "buttons": [
235
+ "agree",
236
+ "cancel"
237
+ ]
238
+ }
186
239
  ]
187
240
  },
188
241
  "native": {
@@ -207,7 +260,8 @@
207
260
  "showNodeInfoMessage": true,
208
261
  "useEventInDesc": false,
209
262
  "wakeUpInfo": false,
210
- "newTypeEvent": true
263
+ "newTypeEvent": true,
264
+ "wsOnStart": true
211
265
  },
212
266
  "protectedNative": [
213
267
  "externalMqttServerPassword",
@@ -291,6 +345,19 @@
291
345
  "def": ""
292
346
  },
293
347
  "native": {}
348
+ },
349
+ {
350
+ "_id": "info.sendMessageAllowed",
351
+ "type": "state",
352
+ "common": {
353
+ "role": "state",
354
+ "name": "send message is allowed",
355
+ "type": "boolean",
356
+ "read": true,
357
+ "write": true,
358
+ "def": true
359
+ },
360
+ "native": {}
294
361
  }
295
362
  ]
296
363
  }
package/lib/constants.js CHANGED
@@ -10,6 +10,7 @@ const noInfoDP = [
10
10
  "rfRegions",
11
11
  "Scene Actuator Configuration",
12
12
  "dimmingDuration",
13
+ "paramInformation",
13
14
  ];
14
15
  const mixedType = [
15
16
  "interviewStage",
@@ -0,0 +1,404 @@
1
+ 'use strict';
2
+ const dmUtils = require('@iobroker/dm-utils');
3
+ const humanizeDuration = require('humanize-duration');
4
+
5
+ /**
6
+ *
7
+ */
8
+ class dmZwave extends dmUtils.DeviceManagement {
9
+ /**
10
+ *
11
+ * @param adapter
12
+ */
13
+ constructor(adapter) {
14
+ super(adapter);
15
+ this.adapter = adapter;
16
+ }
17
+
18
+ /**
19
+ *
20
+ */
21
+ async listDevices() {
22
+ const devices = await this.adapter.getDevicesAsync();
23
+ const arrDevices = [];
24
+ for (const i in devices) {
25
+ const status = {};
26
+
27
+ const nodeId = this.stripIobPrefix(devices[i]._id);
28
+
29
+ const device = this.adapter.nodeCache[nodeId].nodeData;
30
+
31
+ if (device.ready) {
32
+ status.connection = device.ready ? 'connected' : 'disconnected';
33
+ }
34
+
35
+ //const link_quality = await this.adapter.getStateAsync(`${theDevice._id}.status`);
36
+ //status.rssi = link_quality.val == 'alive' ? '100' : '0';
37
+
38
+ const battery = await this.adapter.getStateAsync(`${devices[i]._id}.Battery.level`);
39
+ if (battery) {
40
+ status.battery = battery.val;
41
+ }
42
+
43
+ let devStatus;
44
+
45
+ switch (device.status) {
46
+ case 1:
47
+ devStatus = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAbCAYAAABvCO8sAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuMTGKCBbOAAAAuGVYSWZJSSoACAAAAAUAGgEFAAEAAABKAAAAGwEFAAEAAABSAAAAKAEDAAEAAAADAAAAMQECABEAAABaAAAAaYcEAAEAAABsAAAAAAAAAKOTAADoAwAAo5MAAOgDAABQYWludC5ORVQgNS4xLjExAAADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlgAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAADY5TB4zfSjcAAAB4ZJREFUSEuNlmuMlsUVx38zz3Xfdy/sRdldZBERCgjGIshFKgi2tR80ptp7bLVgqVorNGmatB/az/WDUVOjBUWTJpqITW9pbMXWoKCJyqWLglFkQVnZXZZd2Pd9bvPMnH54d40upuk/+edJJpnzmznnPDOj+D/00+3/mIMO12olK7XSlyroEBQC4wLHReRN58yrj2z+8rHpc6dLTR/4tLbt/NcapcOfOeGrRZE1m6RGkdSwpsCJ4IcxYVOVsNKKF0aJOPuSlObB323Z+O/psab0ucD7n3yx3en4Aa30pmziHEPHj3L62FHGhgc5N36ewFMEPogTgiimpaub7ssWc9HchTTP6EIp94y22baH7vrK0PTYFwDv27F7EUFllymKxaeOHuD4/r2MDI0wkRkWz5vFpXMvYWR4hMGPz6CV4MqSsigo8oymljYuX7mROVdcQxDHA8bktz2+ZcNbn47/GeD9T768SPym3cnEWO87e/7Gx+8dIcmF629Yy5qNG7hs3nw6Ojp4e/8b/GjLVhb0duJsiXMWQYEo8nqN7gVLWbrx61RmdI4i5sZHN6178wLg1if3tFs/3pvWzi069MKzDJ0coKv7Yr5112aWrlhFFEVoEbAlu3Y8znPPPseM5hhnDNZZEFDaQ3seJstouaiH5bdsptrRddIra6sf3rRhEEBPAUsveKAoikVHXvk7Zz4a4JJ5c9n0q1+zePV6SuWT5CUGxeFDB9m+4w+0t1YRW+KsgdIgtmFXGvwwYmLkFP27n6NIsz7nNT80xdEA9z716mqn1KZT7x7g9HuHaeno4uZ7tjGjbz4TqSEvBSOaelaw96UX6e5oRsTirEVsibhyElgik/Agihl+7wAn+1/DKe+2e3bu+9onQKeD+9JajYEDr2JLYc03b6dl9hc4lxgSC6lVFKIYGTnLkQOHqFQriAjiGvVzziLWNqCuBFci1hJWWnn/9X+SjI8iOtwGoLdsf7nHib7xzIfHqI+eoXfRFfRcuYpaVpKWQmohKR1Z6RgdHaV27jxKKZQTcALONSyNrziHOIs4iwKK2hhDH7wNIut+vGPPQm1VcI0xtn3kxPuItcy+ei0SNZMVJVnpSEtHaoW0hLQwKAVaq8l2kwZIpGEaYHGNMRFHEMYMH+vHmjxUnn+dVtq70pqc5OwQYRxT6Z1HPRcSI2SloygdeSlk1qGiClFTjFJ60grUVN8J4qbAAmLBObTvUxs5hclqoPQyjdJ9tsgps4SweQY0tZLmjswIaQFpAXnpyIwjbOtkRu8snHMoz0d7Plo3wA2MILhGfSfBCrB5Sp4mCKpXa6WqjYKX6DDEOI/MODJDAzoJzgqHipqZu/xainqC9gNUEKKDEOUFKO2B8oDGApRWkxlQiLPY0qGUDrU4SZTSKM9HXElWWNLCkeSOtGg4KYSkgKyAvmXr6Zw7D2cdXhg3HEV4QYQXhI2FeD5KeZPp1qB9tOdhHblGGPTCiCCu4NIa6fkJslKRGksyBc6FpHBMZBaqXaz4zt1E1SrOCl5UxYsqeHEVL2rCC2O0H4IXgPZBKfy4gh/G4NygFif9XhRTab8IV2RMDA5gjCYvNGkBSS6kn0ChlhqaZy1i7d2/oWvBEopkAhGFDhq71WGMDqJGqv0AJ0K1cyZBUzNOpN+7+qY769pv2myKLDx78l2cdcRzV+EIESdYcYgo7NQvJ1AaR9jaRc8VK+mcMx/tacqiTmmyRqMomTxXfUyaMPuqL9Het7DEyS8VwOadB/+cTozdfPBPj4FNabv+PpouX4uyBZ7n8D3B9zW+pwi0JvQEXzkCTxGFPtqV2PQ8Jqk1YMpj/65HGT3+DiLCNd/7OdX2mXu333HVWg1grXs4au1k1pVrKAtL7Y1nSEdOkruAPIM8gywV0kxIckc9h1qumMgcY7WCidxRBG3ottn4HZdhdBWTZ5R5Rt/yDTS1d+OcfQTAAzj4l8ePf/GWe5ZUOnsWTwyfpDg7iB0dQHVcjsTtuNLiBKwVrAVnwTpFKR6l1VgLZQmleNRHhzjy18cYH+inddY85q+7FS/wdz9x57JffHJ4A0iRbvXD6kfz1t1K1HYx5cgx0j0PUpx4A1M6jPUwRlEYISuENBeyTMgKRVoG1HPFmff7OfL8bxn74C3i9m4W3vBt/ErrWay5d4rzmRv/zicOrSaIXqiPnW49/srz1IdO4IUhXs9y/Dkr0TNm48fN+L6PVqCUBVPHnfuI7IPXSY69RpFnVGfOYf76b1Dp6MmcSW9+etPVL34uEOAHOw6tdjrcVRa13uF39nH68D5cUcfzNbqpC908Ex23ohRIXsPWTuNqI5TG4EUVepZcS8/Sa/Gi6oiz5Xef/uFVuz8d/wIgwO2P7e9TUfwQyC3p+DDjA4cZ//Ao6fgwziSNF6nSgEIFMXHbxXTMXkDH3CVU2meikBdcUf/JzrtWXfBO/VzglL6/4z83ob2tWnGdNalvkvPktfPYvN64ivyYqNpCpbUTP6o462Qftnjwqc3L/jg91pT+J3BKd/z+rSXKCzag1AqQSxFpQSzWUROlTmil3lSYl5/avOLA9LnT9V/RtStc6hwLfgAAAABJRU5ErkJggg==';
48
+ break;
49
+ case 2:
50
+ devStatus = 'data:image/png;base64,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';
51
+ break;
52
+ case 3:
53
+ devStatus = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAbCAYAAABvCO8sAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCA1LjEuMTGKCBbOAAAAuGVYSWZJSSoACAAAAAUAGgEFAAEAAABKAAAAGwEFAAEAAABSAAAAKAEDAAEAAAADAAAAMQECABEAAABaAAAAaYcEAAEAAABsAAAAAAAAAKOTAADoAwAAo5MAAOgDAABQYWludC5ORVQgNS4xLjExAAADAACQBwAEAAAAMDIzMAGgAwABAAAAAQAAAAWgBAABAAAAlgAAAAAAAAACAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAAAAADY5TB4zfSjcAAABx5JREFUSEuFlmuMlOUVx3/nPO87OzN7Y91dFhRZlssK2rIwVNOmmlSNqWlsaNpPjdZYG1Cp1lglog1eUdtqWipUwVZs6CX9JAlNDNqLJtbU6y6XXtJlEVZhWXZZEHZ3dnfmfZ7TD+/MgmjjmTxfJm/OL/9z/uc5j/AZsXnzCxrFfFFErlahgEi7itaZmfkQxlS1X0TetRD+EjPwzk2r7rNzc5wdcu4f1Xhiw8M6o3nOjS5yd1iwwsTkJGNjo4yPFymXSwBEUUR9XT2NjQ3UZLMI8lbik0233nLz78/NV41PBT675fnPORc960O4/PjwML29vbx/8CAnPzpNqVTCzFADUaEmk+G88xrp6OhgUWcnLS0tiOjfRp27/e6bb/jPubk/AXzuuW3XqXO/Gx0rNr77Xjc9PbvxPpCJI1QEw8AMAURBVSEY5VKZOI7o6urikkKBOXF08qp9/7hh5rPbXjo7/8eAW7duu865aMexoaFo1yuvMDg4RC6XBQMLHjPDLICBCIgITpXIOSIVFKGvOMHK+e08NHcWDeWp5PWFF3/za/eu/dMngFu3PH+JOvfG0PBw44s7djJeLJKJIywEQghYMMw8ZgCGiCBA5Byxc8ROGTLhy7kMD7fPpMUJr827mIH2jtOWhC/ddtvN/wZQgI0bf63i3JbR0bHGXbteZqJYJBM5fJKQJAk+KeN9Ge89IXjMAhYCmEEIEAIflj1XZGMenT+L1nye3xw7xfo332ZyfLwhcrJl66ZHdBqYy0fXh2CXd/d0Mzg4RBy5NLlPMJ+cpbKiNBhgKIYD+r3nmnyGRxfMpiWTZdsHQ6wf/ggZOEpPdzcGV0jN3BsBdP36n4qK3DEyMsLu3fvI5XP4EFIlIVT6lhoFQCQ1jCI4Uf4bAivrczzS2U5TTY5f9Q+w9ugwS1TI5rLs7tnDyMgJVPXOp3/2TKTnn9/8hWB2aV9fH6VyGaaNcQZWYSGVnwo4gT3ec31Dng0XtdNUE7P14GHuOnKcLhVCMIJBkiQc6NsPFpbV5GsuVXV6Zak0RX9/P5lMTComLZuZUb02RFKQCkSi7Es8qxprefSieTRkYp7p+4B7Dg9ScBAskFjAh0CcyXDg/feZmJwE0atURLqKxSIjIydxohVDpKqqpUxBgqqkMB9Y3VTHI4s7qMtk2dR3mHsPD9HlHN6McjB8SIEicOLER4wXiyCyTA1mT0xMUi6VEEktXz0iUjmpMifCPm+saapjw5IOauMMP99/iHUfDrLUOXwwkgoo+ErvgVKpTLFYxMxmK5APwU+XDioQ1VQVgorgEPYlgdvPq+WhJR3k4wwb9x9k/cAxlsYRHvAYwSoHS28lUhHeexBiFSiqKioK031KIdUyOoR9PnBncz0PLp5HJop4an8/DwyOsDSK8AZhuu/VKqXGNgwRxTkHZiUVOJrL5chk4ooDqycFR5LC1rbO4IHFHUQu4qnefh46ejwtYwWWqkoBVVcjKTqOY3LZLMCAmtme2lyOpqZGsICKpuZQR6TK3mCsm9nEjxa3E7mIJ3v72TB4nKVO8QbeQqruLErqBUCE4KGpqZF8Pg+wRy2EV2tqssxrb6dcLqOqROpwIuwOcH9LI/d1zkVE+XHvIR4/doLPuwhvUulTqmq69yKIKNU2lUoJ7fPmkc3lAF5TylPvqdP3FixaiFPFqRCp0mPCAzMbWbtwLmUTHuvt54nhk3TFMQYE0sFOhcn0GhCRdGVpeh+5yNHZuQhR7SkWS2/pLXesCT6Eza0trSwvLKM8OUUvwoOt9dwz/wISER7vO8IvToxSiGOCgOmZrXZGlaCiFYcLqo6JiUmWL19Ka2sLFsKmH951q1eAIwOD253TvxdWrCCcP5t7ZtRy9/w5TIry2IEjbD89xtIoxtIlWClfZWw0VaTOoS51ozqHTzwz21pYsaIAyJuTk5O/rdQijee2vnCJRdEbzf2HGr/at4diJsfjB4/y4qlR5qiQhHBmqD9mkkpFq31TJUkCuXyOb6z8OjPb2kaTJLn8tlu/t/djQICdT2287sr9/9wxpS76yeEhnuk7yLLaWgKGNyPxnhDOHujU9qlwBVGKxQlmzWrj2muvoa2tLfHef2v1qu/urH7/iTfNyJrVK19dsnz7IW8N/+rpZu+evfjE4+IYUUnVka6oFJtuhtJUGRc5VhS6WF4oUF9fd8r78J3Vq26afl6kX39KPPn89oubQvilD+Erw8ePc6Cvj/5Dhzhx8hSlcpIOQmWTxFFM04wZLFjYQWdnJ83NzajqqyGE769eddNnv9qqsWb9Oum6YNG3Uf2BmV1WKpVkfGyM8fFxpkpTAGQyGWrztdTW1ZHLZhHVt733T+98ufsPL724+awmn4n/C6zG/Xetkws7Fxacc1er6mUiXGjQUCnpaTM+8N53e+//+vqf977zxx2bPhVUjf8BEOqFeSvUAvAAAAAASUVORK5CYII=';
54
+ break;
55
+ case 4:
56
+ devStatus = 'data:image/png;base64,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';
57
+ break;
58
+ default:
59
+ devStatus = 'unknown';
60
+ }
61
+
62
+ const res = {
63
+ id: nodeId,
64
+ name: device.name || device.label,
65
+ icon: devStatus,
66
+ manufacturer: device.deviceConfig.manufacturer,
67
+ model: `${device.deviceConfig.label } ${ device.deviceConfig.description}`,
68
+ status: status,
69
+ hasDetails: true,
70
+ actions: [
71
+ {
72
+ id: 'doc',
73
+ icon: 'lines',
74
+ description: 'Documentation',
75
+ handler: async (_id, context) => this.openPDF(context, device),
76
+ },
77
+ ],
78
+ };
79
+
80
+
81
+ arrDevices.push(res);
82
+ }
83
+
84
+ // nach id sortieren (z.B. nodeID_2 vor nodeID_10)
85
+ arrDevices.sort((a, b) => String(a?.id ?? '').localeCompare(String(b?.id ?? ''), undefined, {
86
+ numeric: true,
87
+ sensitivity: 'base',
88
+ }));
89
+
90
+ return arrDevices;
91
+ }
92
+
93
+ /**
94
+ *
95
+ * @param context
96
+ * @param device
97
+ */
98
+ async openPDF(context, device) {
99
+ const manual = device?.deviceConfig?.metadata?.manual;
100
+ const urls = Array.isArray(manual)
101
+ ? manual
102
+ : (typeof manual === 'string' && manual.trim())
103
+ ? [manual]
104
+ : [];
105
+
106
+ const items = {};
107
+
108
+ if (!urls.length) {
109
+ items._no_manual = {
110
+ type: 'staticText',
111
+ text: this.adapter.i18nTranslation?.['No documentation link found'] || 'No documentation link found',
112
+ newLine: true,
113
+ };
114
+ } else {
115
+ urls
116
+ .filter(u => typeof u === 'string' && u.trim())
117
+ .forEach((u, idx) => {
118
+ const href = /^https?:\/\//i.test(u) ? u : `https://${u}`;
119
+ items[`_manual_${idx}`] = {
120
+ type: 'staticLink',
121
+ label: urls.length === 1 ? 'Dokumentation' : `Dokumentation ${idx + 1}`,
122
+ href,
123
+ button: true,
124
+ newLine: true,
125
+ };
126
+ });
127
+ }
128
+
129
+ await context.showForm(
130
+ {
131
+ type: 'panel',
132
+ items,
133
+ },
134
+ {
135
+ title: this.adapter.i18nTranslation?.['DeviceDocumentation'] || 'Device documentation',
136
+ },
137
+ );
138
+
139
+ return { refresh: true };
140
+ }
141
+
142
+ /**
143
+ *
144
+ * @param id
145
+ * @param action
146
+ * @param context
147
+ */
148
+ async getDeviceDetails(id, action, context) {
149
+ this.adapter.log.debug('getDeviceDetails');
150
+
151
+ const device = this.adapter.nodeCache[id]?.nodeData;
152
+
153
+ if (!device) {
154
+ return null;
155
+ }
156
+
157
+ const items = {
158
+ nodeId: {
159
+ type: 'staticText',
160
+ text: `Node ID: ${device.nodeId ?? '—'}`,
161
+ newLine: true,
162
+ },
163
+ manufacturerId: {
164
+ type: 'staticText',
165
+ text: `Manufacturer ID: ${device.manufacturerId ?? device.deviceConfig?.manufacturerId ?? '—'}`,
166
+ newLine: true,
167
+ },
168
+ productId: {
169
+ type: 'staticText',
170
+ text: `Product ID: ${device.productId ?? '—'}`,
171
+ newLine: true,
172
+ },
173
+ productType: {
174
+ type: 'staticText',
175
+ text: `Product Type: ${device.productType ?? '—'}`,
176
+ newLine: true,
177
+ },
178
+ protocolVersion: {
179
+ type: 'staticText',
180
+ text: `Protocol Version: ${device.protocolVersion ?? '—'}`,
181
+ newLine: true,
182
+ },
183
+ sdkVersion: {
184
+ type: 'staticText',
185
+ text: `SDK Version: ${device.sdkVersion ?? '—'}`,
186
+ newLine: true,
187
+ },
188
+ interviewStage: {
189
+ type: 'staticText',
190
+ text: `Interview Stage: ${device.interviewStage ?? '—'}`,
191
+ newLine: true,
192
+ },
193
+ lastActive: {
194
+ type: 'staticText',
195
+ text: `Last Active: ${device.lastActive ?? '—'}`,
196
+ newLine: true,
197
+ },
198
+ endpointsCount: {
199
+ type: 'staticText',
200
+ text: `Endpoints Count: ${device.endpointsCount ?? '—'}`,
201
+ newLine: true,
202
+ },
203
+ deviceClassBasic: {
204
+ type: 'staticText',
205
+ text: `Device Class Basic: ${device.deviceClass?.basic ?? '—'}`,
206
+ newLine: true,
207
+ },
208
+ deviceClassGeneric: {
209
+ type: 'staticText',
210
+ text: `Device Class Generic: ${device.deviceClass?.generic ?? '—'}`,
211
+ newLine: true,
212
+ },
213
+ deviceClassSpecific: {
214
+ type: 'staticText',
215
+ text: `Device Class Specific: ${device.deviceClass?.specific ?? '—'}`,
216
+ newLine: true,
217
+ },
218
+ supportsSecurity: {
219
+ type: 'checkbox',
220
+ label: 'Supports Security',
221
+ readOnly: true,
222
+ checked: !!device.supportsSecurity,
223
+ newLine: true,
224
+ },
225
+ supportsBeaming: {
226
+ type: 'checkbox',
227
+ label: 'Supports Beaming',
228
+ readOnly: true,
229
+ checked: !!device.supportsBeaming,
230
+ },
231
+ isFrequentListening: {
232
+ type: 'checkbox',
233
+ label: 'Frequent Listening',
234
+ readOnly: true,
235
+ checked: !!device.isFrequentListening,
236
+ },
237
+ isControllerNode: {
238
+ type: 'checkbox',
239
+ label: 'Controller Node',
240
+ readOnly: true,
241
+ checked: !!device.isControllerNode,
242
+ },
243
+ keepAwake: {
244
+ type: 'checkbox',
245
+ label: 'Keep Awake',
246
+ readOnly: true,
247
+ checked: !!device.keepAwake,
248
+ },
249
+ };
250
+
251
+ let devStatus;
252
+ switch (device.status) {
253
+ case 1:
254
+ devStatus = 'asleep';
255
+ break;
256
+ case 2:
257
+ devStatus = 'awake';
258
+ break;
259
+ case 3:
260
+ devStatus = 'dead';
261
+ break;
262
+ case 4:
263
+ devStatus = 'alive';
264
+ break;
265
+ default:
266
+ devStatus = 'unknown';
267
+ }
268
+
269
+ return {
270
+ id: String(device.nodeId),
271
+ schema: {
272
+ type: 'tabs',
273
+ items: {
274
+ _tab_Start: {
275
+ type: 'panel',
276
+ label: 'Main',
277
+ items: {
278
+ header_Start: {
279
+ type: 'header',
280
+ text: `${id} - ${device.label} ${device?.deviceClass?.basic || ''}`.trim(),
281
+ size: 3,
282
+ },
283
+ nameDevice: {
284
+ type: 'text',
285
+ label: 'Device Name',
286
+ readOnly: true,
287
+ },
288
+ manufacturer: {
289
+ type: 'text',
290
+ label: 'Manufacturer',
291
+ readOnly: true,
292
+ },
293
+ firmwareVersion: {
294
+ type: 'text',
295
+ label: 'Firmware Version',
296
+ readOnly: true,
297
+ },
298
+ statusText: {
299
+ type: 'text',
300
+ label: 'Status',
301
+ readOnly: true,
302
+ },
303
+ zwavePlusVersion: {
304
+ type: 'text',
305
+ label: 'Zwave Plus Version',
306
+ readOnly: true,
307
+ },
308
+ _divider2: {
309
+ type: 'divider',
310
+ color: 'primary',
311
+ },
312
+ ready: {
313
+ type: 'checkbox',
314
+ label: 'is Ready',
315
+ readOnly: true,
316
+ },
317
+ isListening: {
318
+ type: 'checkbox',
319
+ label: 'is Listening',
320
+ readOnly: true,
321
+ },
322
+ isRouting: {
323
+ type: 'checkbox',
324
+ label: 'is Routing',
325
+ readOnly: true,
326
+ },
327
+ isSecure: {
328
+ type: 'checkbox',
329
+ label: 'is Secure',
330
+ readOnly: true,
331
+ newLine: true,
332
+ },
333
+ maxBaudRate: {
334
+ type: 'text',
335
+ label: 'Max Baud Rate',
336
+ readOnly: true,
337
+ },
338
+ },
339
+ },
340
+ _tab_Details: {
341
+ type: 'panel',
342
+ label: 'Details',
343
+ items,
344
+ },
345
+ },
346
+ },
347
+ data: {
348
+ nameDevice: device.name || '',
349
+ manufacturer: device.deviceConfig?.manufacturer || '',
350
+ firmwareVersion: device.firmwareVersion || '',
351
+ statusText: devStatus,
352
+ zwavePlusVersion: device.zwavePlusVersion || '',
353
+ ready: !!device.ready,
354
+ isListening: !!device.isListening,
355
+ isRouting: !!device.isRouting,
356
+ isSecure: !!device.isSecure,
357
+ maxBaudRate: device.maxBaudRate ? `${device.maxBaudRate} kBaud/s` : '',
358
+ },
359
+ };
360
+ }
361
+
362
+
363
+
364
+ /**
365
+ *
366
+ * @param time
367
+ * @param type
368
+ */
369
+ async formatDate(time, type) { //'ISO_8601' | 'ISO_8601_local' | 'epoch' | 'relative'
370
+ if (type === 'ISO_8601') {
371
+ return new Date(time).toISOString();
372
+ } else if (type === 'ISO_8601_local') {
373
+ return this.toLocalISOString(new Date(time));
374
+ } else if (type === 'epoch') {
375
+ return time;
376
+ }
377
+ // relative
378
+ const ago = `${humanizeDuration(Date.now() - time, {language: 'en', largest: 2, round: true}) } ago`;
379
+ return ago;
380
+
381
+ }
382
+
383
+ /**
384
+ *
385
+ * @param d
386
+ */
387
+ toLocalISOString(d) {
388
+ const off = d.getTimezoneOffset();
389
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes() - off, d.getSeconds(), d.getMilliseconds()).toISOString();
390
+ }
391
+ // Entfernt den ioBroker-Prefix am Anfang, z.B.
392
+ // "zwavews.0.nodeID_1.info.name" -> "nodeID_1.info.name"
393
+ /**
394
+ *
395
+ * @param id
396
+ */
397
+ stripIobPrefix(id) {
398
+ const s = String(id ?? '');
399
+ return s.replace(/^[^.]+\.[^.]+\./, '');
400
+ }
401
+
402
+ }
403
+
404
+ module.exports = dmZwave;
package/lib/helper.js CHANGED
@@ -63,11 +63,12 @@ class Helper {
63
63
 
64
64
  const valuesOnly = element.values ?? null;
65
65
  delete element.values;
66
+
66
67
  await this.parse(`${nodeId}.info`, element);
67
68
 
68
69
  if (valuesOnly != null && typeof valuesOnly === "object" && valuesOnly.length > 0) {
69
70
  for (const v of valuesOnly) {
70
- let parsePath = `${nodeId}.${v.commandClassName}`;
71
+ let parsePath = utils.formatObject(`${nodeId}.${v.commandClassName}`);
71
72
  let metadata = v.metadata || {};
72
73
 
73
74
  if (constant.noInfoDP.includes(v.commandClassName)) {
@@ -114,6 +115,8 @@ class Helper {
114
115
  parsePath = `${parsePath}_${v.endpoint}`;
115
116
  }
116
117
 
118
+ parsePath = utils.formatObject(parsePath); // entferne sonderzeichen und blanke aus dem namen
119
+
117
120
  const nam_id = v.label ?? v.propertyName;
118
121
 
119
122
  metadata.value = v.value; // add value for resolution
@@ -158,15 +161,14 @@ class Helper {
158
161
  common,
159
162
  native,
160
163
  });
161
-
164
+
162
165
  if (common.write === true) {
163
166
  this.adapter.subscribeStates(parsePath);
164
167
  }
165
168
 
166
- this.alreadyCreatedObjects[parsePath] = { };
167
-
168
- this.adapter.setState(parsePath, valDp, true);
169
+ this.adapter.setStateChanged(parsePath, valDp, true);
169
170
 
171
+ this.alreadyCreatedObjects[parsePath] = {};
170
172
  }
171
173
  }
172
174
  } catch (error) {
@@ -181,7 +183,7 @@ class Helper {
181
183
  * @param options
182
184
  */
183
185
  async parse(path, element, options = { write: false }) {
184
- let parsePath = path;
186
+ let parsePath = utils.formatObject(path);
185
187
 
186
188
  if (element == null) {
187
189
  this.adapter.log.debug(`Cannot extract empty: ${parsePath}`);
@@ -222,7 +224,7 @@ class Helper {
222
224
  }
223
225
  }
224
226
 
225
- this.adapter.setState(parsePath, valDp, true);
227
+ this.adapter.setStateChanged(parsePath, valDp, true);
226
228
  return;
227
229
  }
228
230
  options.channelName = utils.getLastSegment(parsePath);
@@ -257,7 +259,7 @@ class Helper {
257
259
  }
258
260
 
259
261
  for (const key of Object.keys(element)) {
260
- let fullPath = `${parsePath}.${key}`;
262
+ let fullPath = utils.formatObject(`${parsePath}.${key}`);
261
263
  let valDP = element[key];
262
264
 
263
265
  if (Array.isArray(valDP)) {
@@ -271,6 +273,11 @@ class Helper {
271
273
  continue;
272
274
  }
273
275
 
276
+ // überspringe bestimmte DP Namen
277
+ if (constant.noInfoDP.includes(key)) {
278
+ continue;
279
+ }
280
+
274
281
  const isObj = this.isObject(valDP);
275
282
 
276
283
  if (isObj) {
@@ -327,13 +334,13 @@ class Helper {
327
334
 
328
335
  try {
329
336
  if (valDP !== undefined) {
330
- this.adapter.setState(fullPath, valDP, true);
337
+ this.adapter.setStateChanged(fullPath, valDP, true);
331
338
 
332
339
  if (fullPath.endsWith('ready') ) {
333
340
  valDP = element['status'];
334
341
  if (utils.isNumeric(valDP) && valDP == 3) {
335
342
  fullPath = fullPath.replace(".status", ".ready");
336
- this.adapter.setState(fullPath, false, true);
343
+ this.adapter.setStateChanged(fullPath, false, true);
337
344
  }
338
345
  }
339
346
  }
package/lib/utils.js CHANGED
@@ -137,6 +137,18 @@ function replaceLastDot(str) {
137
137
  const idx = str.lastIndexOf(".");
138
138
  return idx >= 0 ? `${str.slice(0, idx)}_${str.slice(idx + 1)}` : str;
139
139
  }
140
+
141
+ /**
142
+ *
143
+ * @param str
144
+ */
145
+ function formatObject(str) {
146
+ if (typeof str !== "string") {
147
+ return "";
148
+ }
149
+ return str.trim().replace(/₂/g, "2").replace(/\s+/g, "_");
150
+ }
151
+
140
152
  /**
141
153
  *
142
154
  * @param input
@@ -202,4 +214,5 @@ module.exports = {
202
214
  formatMQTT,
203
215
  padNodeId,
204
216
  getStatusText,
217
+ formatObject,
205
218
  };
@@ -69,7 +69,7 @@ class WebsocketController {
69
69
  */
70
70
  send(message) {
71
71
  if (wsClient.readyState !== WebSocket.OPEN) {
72
- this.adapter.log.warn('Cannot set State, no websocket connection to Zigbee2MQTT!');
72
+ this.adapter.log.warn('Cannot set State, no websocket connection to zwave-js-ui');
73
73
  return;
74
74
  }
75
75
  wsClient.send(message);
package/main.js CHANGED
@@ -1,9 +1,10 @@
1
- "use strict";
1
+ 'use strict';
2
2
 
3
3
  const core = require("@iobroker/adapter-core");
4
4
  const mqtt = require("mqtt");
5
5
  const utils = require("./lib/utils");
6
6
  const constant = require("./lib/constants");
7
+ const dmZwave = require('./lib/devicemgmt.js');
7
8
 
8
9
  const adapterInfo = require("./lib/messages").adapterInfo;
9
10
  const StatesController = require("./lib/statesController").StatesController;
@@ -14,7 +15,6 @@ const MqttServerController = require("./lib/mqttServerController").MqttServerCon
14
15
 
15
16
  let mqttClient;
16
17
  let deviceCache = {};
17
- let nodeCache = {};
18
18
  const logCustomizations = { debugDevices: "", logfilter: [] };
19
19
 
20
20
  let websocketController;
@@ -49,7 +49,7 @@ class zwavews extends core.Adapter {
49
49
  // Initialize your adapter here
50
50
  adapterInfo(this.config, this.log);
51
51
 
52
- this.setState("info.connection", false, true);
52
+ this.setStateChanged("info.connection", false, true);
53
53
  await statesController.setAllAvailableToFalse();
54
54
 
55
55
  helper = new Helper(this, deviceCache);
@@ -60,7 +60,16 @@ class zwavews extends core.Adapter {
60
60
  debugDevicesState.val.toLowerCase(),
61
61
  );
62
62
  }
63
- this.setState("info.debugmessages", "", true);
63
+
64
+ this.deviceManagement = new dmZwave(this);
65
+
66
+ if (this.config.wsOnStart) {
67
+ this.setStateChanged("info.sendMessageAllowed", true, true);
68
+ }
69
+
70
+ this.nodeCache = {};
71
+ this.setStateChanged("info.debugmessages", "", true);
72
+
64
73
 
65
74
  // MQTT
66
75
  if (["exmqtt", "intmqtt"].includes(this.config.connectionType)) {
@@ -113,7 +122,7 @@ class zwavews extends core.Adapter {
113
122
  // MQTT Client
114
123
  mqttClient.on("connect", () => {
115
124
  this.log.info(`Connect to zwavews over ${this.config.connectionType == "exmqtt" ? "external mqtt" : "internal mqtt"} connection.`);
116
- this.setState("info.connection", true, true);
125
+ this.setStateChanged("info.connection", true, true);
117
126
  });
118
127
 
119
128
  mqttClient.subscribe(`${this.config.baseTopic}/#`);
@@ -133,7 +142,7 @@ class zwavews extends core.Adapter {
133
142
  if (this.config.dummyMqtt == true) {
134
143
  mqttServerController = new MqttServerController(this);
135
144
  await mqttServerController.createDummyMQTTServer();
136
- this.setState("info.connection", true, true);
145
+ this.setStateChanged("info.connection", true, true);
137
146
  await this.delay(1500);
138
147
  }
139
148
 
@@ -161,7 +170,7 @@ class zwavews extends core.Adapter {
161
170
  await statesController.setAllAvailableToFalse();
162
171
  startListening = false;
163
172
  deviceCache = [];
164
- nodeCache = [];
173
+ this.nodeCache = [];
165
174
  this.log.info('Websocket connection closed. Attempting to reconnect...');
166
175
  });
167
176
  }
@@ -198,6 +207,10 @@ class zwavews extends core.Adapter {
198
207
  break;
199
208
  }
200
209
 
210
+ if (allNodesCreated) { // wird manchmal doppelt geschickt
211
+ break;
212
+ }
213
+
201
214
  driver = messageObj.result.state.driver;
202
215
  controller = messageObj.result.state.controller;
203
216
  allNodes = messageObj.result.state.nodes;
@@ -209,13 +222,13 @@ class zwavews extends core.Adapter {
209
222
  this.log.warn(`--->>> fromZ2W_RAW2-> ${JSON.stringify(nodeData)}` );
210
223
  }
211
224
 
212
- if (!nodeCache[nodeId]) {
225
+ if (!this.nodeCache[nodeId]) {
213
226
  if (this.config.showNodeInfoMessage) {
214
227
  this.log.info(`Node Info Update for ${nodeId}`);
215
228
  }
216
- nodeCache[nodeId] = {nodeId: nodeId};
229
+ this.nodeCache[nodeId] = {nodeData};
217
230
  }
218
- await helper.createNode(`${nodeId}`, nodeData, options);
231
+ await helper.createNode(nodeId, nodeData, options);
219
232
  }
220
233
 
221
234
  allNodesCreated = true;
@@ -255,6 +268,8 @@ class zwavews extends core.Adapter {
255
268
  }
256
269
  }
257
270
 
271
+ parsePath = utils.formatObject(parsePath);
272
+
258
273
  if (nodeArg.commandClass === 119) { // sonderlocke für node naming
259
274
  switch (nodeArg.property) {
260
275
  case 'name':
@@ -398,7 +413,7 @@ class zwavews extends core.Adapter {
398
413
  this.log.error(e);
399
414
  }
400
415
 
401
- this.setState("info.connection", false, true);
416
+ this.setStateChanged("info.connection", false, true);
402
417
 
403
418
  callback();
404
419
  }
@@ -407,11 +422,11 @@ class zwavews extends core.Adapter {
407
422
  if (!allNodesCreated) { // wenn alle nodes angelegt sind, erst dann horchen auf target
408
423
  return;
409
424
  }
410
-
425
+
411
426
  if (state && state.ack == false) {
412
427
  if (id.endsWith("info.debugId")) {
413
428
  logCustomizations.debugDevices = state.val.toLowerCase();
414
- this.setState(id, state.val, true);
429
+ this.setStateChanged(id, state.val, true);
415
430
  return;
416
431
  }
417
432
 
@@ -429,13 +444,17 @@ class zwavews extends core.Adapter {
429
444
  nodeId: nodeId,
430
445
  valueId: nativeObj.valueId,
431
446
  value: state.val
432
- }
433
- }
434
- this.setStateChanged('info.debugmessages', JSON.stringify(message), true);
447
+ };
448
+
449
+ const sendMessageAllowed = await this.getStateAsync("info.sendMessageAllowed");
435
450
 
436
- this.log.debug(`<zwavews> error message ${message}`);
451
+ if (sendMessageAllowed.val) {
452
+ websocketController.send(JSON.stringify(message));
453
+ }
437
454
 
438
- websocketController.send(JSON.stringify(message));
455
+ this.setStateChanged('info.debugmessages', JSON.stringify(message), true);
456
+ this.log.debug(`<zwavews> message onStateChange ${message}`);
457
+ }
439
458
  }
440
459
  }
441
460
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zwavews",
3
- "version": "0.0.17",
3
+ "version": "0.1.0",
4
4
  "description": "zwavews adapter for ioBroker",
5
5
  "author": {
6
6
  "name": "Dennis Rathjen and Arthur Rupp",
@@ -27,6 +27,7 @@
27
27
  "dependencies": {
28
28
  "@iobroker/adapter-core": "^3.3.2",
29
29
  "@iobroker/dm-utils": "^2.0.1",
30
+ "humanize-duration": "^3.33.2",
30
31
  "aedes": "^0.51.3",
31
32
  "aedes-persistence-nedb": "^2.0.3",
32
33
  "mqtt": "^5.15.0",