iobroker.zwavews 0.0.18 → 0.1.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 +9 -0
- package/admin/jsonConfig.json +25 -0
- package/io-package.json +88 -29
- package/lib/devicemgmt.js +404 -0
- package/lib/helper.js +5 -3
- package/lib/utils.js +13 -0
- package/lib/websocketController.js +1 -1
- package/main.js +16 -5
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -35,6 +35,15 @@ Activate WS Server Settings in `zwave-js-ui` we use the Home Assistant Settings
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
## Changelog
|
|
38
|
+
### 0.1.1 (2026-03-15)
|
|
39
|
+
* (arteck) add debug information
|
|
40
|
+
|
|
41
|
+
### 0.1.0 (2026-03-08)
|
|
42
|
+
* (arteck) BREAKING CHANGE - dp name is now with underline
|
|
43
|
+
* (arteck) add deviceManager
|
|
44
|
+
* (arteck) fix dp's with a space
|
|
45
|
+
* (arteck) fix dp's with special chars
|
|
46
|
+
|
|
38
47
|
### 0.0.18 (2026-02-28)
|
|
39
48
|
* (arteck) add info.sendMessageAllowed object to allow sending the message to zwave-ui-js
|
|
40
49
|
* (arteck) add new checkbox to set info.sendMessageAllowed immediately after starting the adapter
|
package/admin/jsonConfig.json
CHANGED
|
@@ -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",
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "zwavews",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.1.1",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.1.1": {
|
|
7
|
+
"en": "add debug information",
|
|
8
|
+
"de": "debug information",
|
|
9
|
+
"ru": "добавить информацию об отладке",
|
|
10
|
+
"pt": "adicionar informações de depuração",
|
|
11
|
+
"nl": "debug-informatie toevoegen",
|
|
12
|
+
"fr": "ajouter des informations de débogage",
|
|
13
|
+
"it": "aggiungere informazioni debug",
|
|
14
|
+
"es": "añadir información de depuración",
|
|
15
|
+
"pl": "dodaj informacje o debugowaniu",
|
|
16
|
+
"uk": "додати інформацію debug",
|
|
17
|
+
"zh-cn": "添加调试信息"
|
|
18
|
+
},
|
|
19
|
+
"0.1.0": {
|
|
20
|
+
"en": "BREAKING CHANGE - dp name is now with underline\nadd deviceManager\nfix dp's with a space\nfix dp's with special chars",
|
|
21
|
+
"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",
|
|
22
|
+
"ru": "BREAKING CHANGE - название dp теперь с подчеркиванием\nдобавить устройство Менеджер\nустановить dp в пространстве\nобсуждение dp's with special chars",
|
|
23
|
+
"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",
|
|
24
|
+
"nl": "BREAKING VERANDERING - dp naam is nu met benadrukken\napparaat toevoegen Beheerder\nfix dp's met een spatie\nfix dp's met speciale tekens",
|
|
25
|
+
"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",
|
|
26
|
+
"it": "BREAKING CHANGE - il nome dp è ora in linea\naggiungere dispositivo Manager\nfix dp's con uno spazio\nsistemare dp's con beneficenza speciali",
|
|
27
|
+
"es": "CAMBIO DE BREAKING - nombre dp ahora es con subrayado\nañadir dispositivo Manager\narreglar dp con un espacio\narreglar dp con chars especiales",
|
|
28
|
+
"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",
|
|
29
|
+
"uk": "BREAKING CHANGE - ім'я dp тепер з онлайн\nдодати пристрій Менеджер\nзакріпити dp's з космосом\nфіксувати dp з особливими chars",
|
|
30
|
+
"zh-cn": "断裂变换 - dp 名称现在是下划线\n添加设备 经理\n修补 dp 的空格\n修复 dp 与特殊字符"
|
|
31
|
+
},
|
|
6
32
|
"0.0.18": {
|
|
7
33
|
"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",
|
|
8
34
|
"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",
|
|
@@ -67,35 +93,8 @@
|
|
|
67
93
|
"pl": "dodaj zdarzenie gotowe",
|
|
68
94
|
"uk": "додати захід готовий",
|
|
69
95
|
"zh-cn": "添加已准备的事件"
|
|
70
|
-
},
|
|
71
|
-
"0.0.13": {
|
|
72
|
-
"en": "add event type \"value notification\"",
|
|
73
|
-
"de": "ereignistyp hinzufügen \"wert-benachrichtigung\"",
|
|
74
|
-
"ru": "добавить событие типа «уведомление о ценности»",
|
|
75
|
-
"pt": "adicionar tipo de evento \"notificação de valor\"",
|
|
76
|
-
"nl": "gebeurtenistype \"waarde notificatie\" toevoegen",
|
|
77
|
-
"fr": "ajouter le type d'événement \"avis de valeur\"",
|
|
78
|
-
"it": "aggiungere tipo di evento \"notifica valore\"",
|
|
79
|
-
"es": "añadir tipo de evento \"notificación de valor\"",
|
|
80
|
-
"pl": "dodaj typ zdarzenia \"powiadomienie o wartości\"",
|
|
81
|
-
"uk": "додати тип події \"значення повідомлення\"",
|
|
82
|
-
"zh-cn": "添加事件类型“ 值通知”"
|
|
83
|
-
},
|
|
84
|
-
"0.0.12": {
|
|
85
|
-
"en": "typo\nfix dp channel name\nadd endpoint > 0 to value if exists",
|
|
86
|
-
"de": "typo\ndp kanal name\nendpunkt hinzufügen > 0 auf wert, falls vorhanden",
|
|
87
|
-
"ru": "опечатка\nустановить имя канала dp\nдобавить конечную точку 0, если существует",
|
|
88
|
-
"pt": "erro de digitação\ncorrigir o nome do canal dp\nadicionar endpoint > 0 a valor se existir",
|
|
89
|
-
"nl": "type\nfix dp kanaalnaam\neindpunt toevoegen > 0 naar waarde indien aanwezig",
|
|
90
|
-
"fr": "typo\ncorriger le nom du canal dp\najouter le paramètre > 0 à valeur s'il existe",
|
|
91
|
-
"it": "tipo\ncorretto nome del canale dp\naggiungere il punto finale 0 a valore se esiste",
|
|
92
|
-
"es": "typo\nfijar nombre del canal dp\nañadir endpoint √ 0 a valor si existe",
|
|
93
|
-
"pl": "typo\nfix dp nazwa kanału\ndodać punkt końcowy > 0 do wartości, jeśli istnieje",
|
|
94
|
-
"uk": "типи\nзафіксувати ім'я каналів dp\nдодати кінцеву точку > 0 до значення, якщо існує",
|
|
95
|
-
"zh-cn": "类型\n修复 dp 频道名称\n添加终点 > 0 到数值( 如果存在)"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
|
-
"messages": [],
|
|
99
98
|
"titleLang": {
|
|
100
99
|
"en": "Z-Wave WS",
|
|
101
100
|
"de": "Z-Wave WS",
|
|
@@ -184,7 +183,67 @@
|
|
|
184
183
|
"admin": ">=7.6.17"
|
|
185
184
|
}
|
|
186
185
|
],
|
|
187
|
-
"
|
|
186
|
+
"plugins": {
|
|
187
|
+
"docker": {
|
|
188
|
+
"iobDockerComposeFiles": [
|
|
189
|
+
"https://github.com/zwave-js/zwave-js-ui/blob/master/docker/docker-compose.yml"
|
|
190
|
+
]
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
"messages": [
|
|
194
|
+
{
|
|
195
|
+
"condition": {
|
|
196
|
+
"operand": "and",
|
|
197
|
+
"rules": [
|
|
198
|
+
"oldVersion<0.0.18",
|
|
199
|
+
"newVersion>=0.1.0"
|
|
200
|
+
]
|
|
201
|
+
},
|
|
202
|
+
"title": {
|
|
203
|
+
"en": "Important notice!",
|
|
204
|
+
"de": "Wichtiger Hinweis!",
|
|
205
|
+
"ru": "Важное замечание!",
|
|
206
|
+
"pt": "Notícia importante!",
|
|
207
|
+
"nl": "Belangrijke mededeling!",
|
|
208
|
+
"fr": "Avis important!",
|
|
209
|
+
"it": "Avviso IMPORTANTE!",
|
|
210
|
+
"es": "Noticia importante!",
|
|
211
|
+
"pl": "Ważna uwaga!",
|
|
212
|
+
"zh-cn": "重要通知!"
|
|
213
|
+
},
|
|
214
|
+
"text": {
|
|
215
|
+
"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",
|
|
216
|
+
"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.",
|
|
217
|
+
"ru": "\"BREAKING CHANGE. <br> В версии адаптера 0.1.0 теперь используется подчеркивание объекта. Проверьте свой псевдоним или визуализацию и исправьте эту ошибку. Например: Manufacturer Specific теперь Manufacturer_Specific",
|
|
218
|
+
"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.",
|
|
219
|
+
"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.",
|
|
220
|
+
"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.",
|
|
221
|
+
"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",
|
|
222
|
+
"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",
|
|
223
|
+
"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",
|
|
224
|
+
"uk": "\"BREAKING CHANGE. <br> Версія адаптера 0.1.0 тепер використовує підкреслення на об'єкті. Перевірте свій псевдонім або візуалізацію та виправте цю помилку. Приклад: Manufacturer Specific тепер Manufacturer_Specific.",
|
|
225
|
+
"zh-cn": "\"BREAKING CHANGE. <br> 适配器版本 0.1.0 现在在对象名称前使用下划线。请检查您的别名或视觉设置,并更正此错误。例如:Manufacturer Specific 现在是 Manufacturer_Specific。"
|
|
226
|
+
},
|
|
227
|
+
"link": "https://github.com/arteck/ioBroker.zwavews/wiki/DP's-with-space-blank-in-Name",
|
|
228
|
+
"level": "warn",
|
|
229
|
+
"linkText": {
|
|
230
|
+
"en": "Readme",
|
|
231
|
+
"de": "Liesmich",
|
|
232
|
+
"ru": "Прочти меня",
|
|
233
|
+
"pt": "Leia-me",
|
|
234
|
+
"nl": "Leesmij",
|
|
235
|
+
"fr": "Lisez-moi",
|
|
236
|
+
"it": "Leggimi",
|
|
237
|
+
"es": "Léame",
|
|
238
|
+
"pl": "Readme",
|
|
239
|
+
"zh-cn": "自述文件"
|
|
240
|
+
},
|
|
241
|
+
"buttons": [
|
|
242
|
+
"agree",
|
|
243
|
+
"cancel"
|
|
244
|
+
]
|
|
245
|
+
}
|
|
246
|
+
]
|
|
188
247
|
},
|
|
189
248
|
"native": {
|
|
190
249
|
"connectionType": "ws",
|
|
@@ -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,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';
|
|
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
|
@@ -68,7 +68,7 @@ class Helper {
|
|
|
68
68
|
|
|
69
69
|
if (valuesOnly != null && typeof valuesOnly === "object" && valuesOnly.length > 0) {
|
|
70
70
|
for (const v of valuesOnly) {
|
|
71
|
-
let parsePath = `${nodeId}.${v.commandClassName}
|
|
71
|
+
let parsePath = utils.formatObject(`${nodeId}.${v.commandClassName}`);
|
|
72
72
|
let metadata = v.metadata || {};
|
|
73
73
|
|
|
74
74
|
if (constant.noInfoDP.includes(v.commandClassName)) {
|
|
@@ -115,6 +115,8 @@ class Helper {
|
|
|
115
115
|
parsePath = `${parsePath}_${v.endpoint}`;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
parsePath = utils.formatObject(parsePath); // entferne sonderzeichen und blanke aus dem namen
|
|
119
|
+
|
|
118
120
|
const nam_id = v.label ?? v.propertyName;
|
|
119
121
|
|
|
120
122
|
metadata.value = v.value; // add value for resolution
|
|
@@ -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}`);
|
|
@@ -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)) {
|
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
|
|
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
|
@@ -4,6 +4,7 @@ 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;
|
|
@@ -55,11 +56,11 @@ class zwavews extends core.Adapter {
|
|
|
55
56
|
|
|
56
57
|
const debugDevicesState = await this.getStateAsync("info.debugId");
|
|
57
58
|
if (debugDevicesState && debugDevicesState.val) {
|
|
58
|
-
logCustomizations.debugDevices = String(
|
|
59
|
-
debugDevicesState.val.toLowerCase(),
|
|
60
|
-
);
|
|
59
|
+
logCustomizations.debugDevices = String(debugDevicesState.val.toLowerCase());
|
|
61
60
|
}
|
|
62
61
|
|
|
62
|
+
this.deviceManagement = new dmZwave(this);
|
|
63
|
+
|
|
63
64
|
if (this.config.wsOnStart) {
|
|
64
65
|
this.setStateChanged("info.sendMessageAllowed", true, true);
|
|
65
66
|
}
|
|
@@ -67,6 +68,7 @@ class zwavews extends core.Adapter {
|
|
|
67
68
|
this.nodeCache = {};
|
|
68
69
|
this.setStateChanged("info.debugmessages", "", true);
|
|
69
70
|
|
|
71
|
+
|
|
70
72
|
// MQTT
|
|
71
73
|
if (["exmqtt", "intmqtt"].includes(this.config.connectionType)) {
|
|
72
74
|
// External MQTT-Server
|
|
@@ -183,10 +185,13 @@ class zwavews extends core.Adapter {
|
|
|
183
185
|
try {
|
|
184
186
|
const messageObj = JSON.parse(message);
|
|
185
187
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
+
const debugDevicesState = await this.getStateAsync("info.debugId");
|
|
189
|
+
if (debugDevicesState && debugDevicesState.val) {
|
|
190
|
+
logCustomizations.debugDevices = String(debugDevicesState.val.toLowerCase());
|
|
188
191
|
}
|
|
189
192
|
|
|
193
|
+
this.log.debug(`--->>> fromZ2W_RAW1 -> ${JSON.stringify(messageObj)}`);
|
|
194
|
+
|
|
190
195
|
const type = messageObj?.type;
|
|
191
196
|
|
|
192
197
|
if (this.config.connectionType === 'ws') {
|
|
@@ -248,6 +253,10 @@ class zwavews extends core.Adapter {
|
|
|
248
253
|
const nodeArg = eventTyp.args;
|
|
249
254
|
const nodeId = utils.formatNodeId(eventTyp.nodeId);
|
|
250
255
|
|
|
256
|
+
if (logCustomizations.debugDevices.includes(nodeId.toLowerCase())) {
|
|
257
|
+
this.log.warn(`--->>> fromZ2W_RAW2-> ${JSON.stringify(eventTyp)}` );
|
|
258
|
+
}
|
|
259
|
+
|
|
251
260
|
let parsePath = `${nodeId}.${nodeArg.commandClassName}.${nodeArg.propertyName
|
|
252
261
|
.replace(/[^\p{L}\p{N}\s]/gu, "")
|
|
253
262
|
.replace(/\s+/g, " ")
|
|
@@ -264,6 +273,8 @@ class zwavews extends core.Adapter {
|
|
|
264
273
|
}
|
|
265
274
|
}
|
|
266
275
|
|
|
276
|
+
parsePath = utils.formatObject(parsePath);
|
|
277
|
+
|
|
267
278
|
if (nodeArg.commandClass === 119) { // sonderlocke für node naming
|
|
268
279
|
switch (nodeArg.property) {
|
|
269
280
|
case 'name':
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.zwavews",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
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",
|