iobroker.zigbee 1.8.12 → 1.8.14
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/i18n/pl/translations.json +2 -2
- package/admin/index_m.html +5 -5
- package/admin/tab_m.html +6 -6
- package/admin/words.js +2 -2
- package/io-package.json +37 -18
- package/lib/exposes.js +58 -18
- package/lib/ota.js +2 -2
- package/lib/statescontroller.js +5 -26
- package/main.js +133 -123
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -138,6 +138,15 @@ You can thank the authors by these links:
|
|
|
138
138
|
|
|
139
139
|
|
|
140
140
|
## Changelog
|
|
141
|
+
### 1.8.14 (2023-07-09)
|
|
142
|
+
* (arteck)
|
|
143
|
+
|
|
144
|
+
### 1.8.13 (2023-07-09)
|
|
145
|
+
* (arteck) ota corr
|
|
146
|
+
* (arteck) devices are wrong with enum exposes
|
|
147
|
+
* (arteck) select field for groups is larger
|
|
148
|
+
* (kirovilya) tuya.whitelabel corr
|
|
149
|
+
|
|
141
150
|
### 1.8.12 (2023-06-30)
|
|
142
151
|
* (arteck) new Documentation (thx Stefan)
|
|
143
152
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"Binding": "połączenie",
|
|
6
6
|
"Binding configuration": "Konfiguracja wiązania",
|
|
7
7
|
"COM port name": "Nazwa portu COM",
|
|
8
|
-
"Cancel": "
|
|
8
|
+
"Cancel": "Pomiń",
|
|
9
9
|
"Channel": "Kanał",
|
|
10
10
|
"ChannelChangeText": "Kanał ustawia używaną częstotliwość radiową. Można go zmienić, aby uniknąć konfliktów z istniejącymi sieciami Wi-Fi. <b>Podczas zmiany wszystkie urządzenia muszą zostać ponownie nauczone!</b>",
|
|
11
11
|
"Check firmware updates": "Sprawdź aktualizacje oprogramowania układowego",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"View config": "Wyświetl config",
|
|
89
89
|
"Waiting": "Czekaj",
|
|
90
90
|
"Write Attribute": "Napisz atrybut",
|
|
91
|
-
"Yes": "
|
|
91
|
+
"Yes": "Tak",
|
|
92
92
|
"You find good explanations what the settings mean": "Znajdziesz dobre wyjaśnienia, co oznaczają ustawienia",
|
|
93
93
|
"Zigbee adapter": "Adapter Zigbee",
|
|
94
94
|
"Zigbee-herdsman debug info": "Informacje debugowania Zigbee-Herdsman",
|
package/admin/index_m.html
CHANGED
|
@@ -985,10 +985,10 @@
|
|
|
985
985
|
<p class="translate device_with_endpoint">Main Endpoint</p>
|
|
986
986
|
</div>
|
|
987
987
|
</div>
|
|
988
|
-
<div class="
|
|
988
|
+
<div class="col1">
|
|
989
989
|
<div class="input-field groups">
|
|
990
990
|
<select id="d_groups_ep0" class="materialSelect" multiple>
|
|
991
|
-
<option value="1"
|
|
991
|
+
<option value="1">value</option>
|
|
992
992
|
</select>
|
|
993
993
|
<label for="d_groups_ep0" class="translate">Groups</label>
|
|
994
994
|
</div>
|
|
@@ -1003,7 +1003,7 @@
|
|
|
1003
1003
|
<div class="col">
|
|
1004
1004
|
<div class="input-field groups">
|
|
1005
1005
|
<select id="d_groups_ep1" class="materialSelect" multiple>
|
|
1006
|
-
<option value="1"
|
|
1006
|
+
<option value="1">value</option>
|
|
1007
1007
|
</select>
|
|
1008
1008
|
<label for="d_groups_ep1" class="translate">Groups</label>
|
|
1009
1009
|
</div>
|
|
@@ -1018,7 +1018,7 @@
|
|
|
1018
1018
|
<div class="col">
|
|
1019
1019
|
<div class="input-field groups">
|
|
1020
1020
|
<select id="d_groups_ep2" class="materialSelect" multiple>
|
|
1021
|
-
<option value="1"
|
|
1021
|
+
<option value="1">value</option>
|
|
1022
1022
|
</select>
|
|
1023
1023
|
<label for="d_groups_ep2" class="translate">Groups</label>
|
|
1024
1024
|
</div>
|
|
@@ -1033,7 +1033,7 @@
|
|
|
1033
1033
|
<div class="col">
|
|
1034
1034
|
<div class="input-field groups">
|
|
1035
1035
|
<select id="d_groups_ep3" class="materialSelect" multiple>
|
|
1036
|
-
<option value="1"
|
|
1036
|
+
<option value="1">value</option>
|
|
1037
1037
|
</select>
|
|
1038
1038
|
<label for="d_groups_ep3" class="translate">Groups</label>
|
|
1039
1039
|
</div>
|
package/admin/tab_m.html
CHANGED
|
@@ -683,9 +683,9 @@
|
|
|
683
683
|
<p class="translate device_with_endpoint">Main Endpoint</p>
|
|
684
684
|
</div>
|
|
685
685
|
</div>
|
|
686
|
-
<div class="
|
|
686
|
+
<div class="col1">
|
|
687
687
|
<div class="input-field groups">
|
|
688
|
-
<select id="d_groups_ep0" class="materialSelect" multiple><option value="1"
|
|
688
|
+
<select id="d_groups_ep0" class="materialSelect" multiple><option value="1">value</option></select>
|
|
689
689
|
<label for="d_groups_ep0" class="translate">Groups</label>
|
|
690
690
|
</div>
|
|
691
691
|
</div>
|
|
@@ -698,7 +698,7 @@
|
|
|
698
698
|
</div>
|
|
699
699
|
<div class="col">
|
|
700
700
|
<div class="input-field groups">
|
|
701
|
-
<select id="d_groups_ep1" class="materialSelect" multiple><option value="1"
|
|
701
|
+
<select id="d_groups_ep1" class="materialSelect" multiple><option value="1">value</option></select>
|
|
702
702
|
<label for="d_groups_ep1" class="translate">Groups</label>
|
|
703
703
|
</div>
|
|
704
704
|
</div>
|
|
@@ -711,7 +711,7 @@
|
|
|
711
711
|
</div>
|
|
712
712
|
<div class="col">
|
|
713
713
|
<div class="input-field groups">
|
|
714
|
-
<select id="d_groups_ep2" class="materialSelect" multiple><option value="1"
|
|
714
|
+
<select id="d_groups_ep2" class="materialSelect" multiple><option value="1">value</option></select>
|
|
715
715
|
<label for="d_groups_ep2" class="translate">Groups</label>
|
|
716
716
|
</div>
|
|
717
717
|
</div>
|
|
@@ -724,7 +724,7 @@
|
|
|
724
724
|
</div>
|
|
725
725
|
<div class="col">
|
|
726
726
|
<div class="input-field groups">
|
|
727
|
-
<select id="d_groups_ep3" class="materialSelect" multiple><option value="1"
|
|
727
|
+
<select id="d_groups_ep3" class="materialSelect" multiple><option value="1">value</option></select>
|
|
728
728
|
<label for="d_groups_ep3" class="translate">Groups</label>
|
|
729
729
|
</div>
|
|
730
730
|
</div>
|
|
@@ -777,7 +777,7 @@
|
|
|
777
777
|
<div class="col s12">
|
|
778
778
|
<div class="input-field members">
|
|
779
779
|
<label for="g_members" class="translate">Members</label>
|
|
780
|
-
<select id="g_members" class="materialSelect" multiple><option value="1"
|
|
780
|
+
<select id="g_members" class="materialSelect" multiple><option value="1">value</option></select>
|
|
781
781
|
</div>
|
|
782
782
|
</div>
|
|
783
783
|
</div>
|
package/admin/words.js
CHANGED
|
@@ -8,7 +8,7 @@ systemDictionary = {
|
|
|
8
8
|
"Binding": { "uk": "Прив'язка", "en": "Binding", "de": "Binding", "ru": "Привязка", "pt": "Ligação", "nl": "Verbindend", "fr": "Contraignant", "it": "Rilegatura", "es": "Unión", "pl": "połączenie", "zh-cn": "捆绑"},
|
|
9
9
|
"Binding configuration": { "uk": "Конфігурація привʼязки", "en": "Binding configuration", "de": "Binding konfiguration", "ru": "Конфигурация привязки", "pt": "Configuração de ligação", "nl": "Bindende configuratie", "fr": "Configuration de la liaison", "it": "Configurazione vincolante", "es": "Configuración de enlace", "pl": "Konfiguracja wiązania", "zh-cn": "绑定配置"},
|
|
10
10
|
"COM port name": { "uk": "Імʼя COM порта", "en": "COM port name", "de": "COM-Anschlussname", "ru": "Имя или адрес порта", "pt": "Nome da porta COM", "nl": "COM-poortnaam", "fr": "Nom du port COM", "it": "Nome della porta COM", "es": "Nombre del puerto COM", "pl": "Nazwa portu COM", "zh-cn": "设备端口"},
|
|
11
|
-
"Cancel": { "uk": "Скасувати", "en": "Cancel", "de": "Abbrechen", "ru": "Отмена", "pt": "Cancelar", "nl": "Annuleren", "fr": "Annuler", "it": "Annulla", "es": "Cancelar", "pl": "
|
|
11
|
+
"Cancel": { "uk": "Скасувати", "en": "Cancel", "de": "Abbrechen", "ru": "Отмена", "pt": "Cancelar", "nl": "Annuleren", "fr": "Annuler", "it": "Annulla", "es": "Cancelar", "pl": "Pomiń", "zh-cn": "取消"},
|
|
12
12
|
"Channel": { "uk": "Канал", "en": "Channel", "de": "Kanal", "ru": "Канал", "pt": "Canal", "nl": "Kanaal", "fr": "Canal", "it": "Canale", "es": "Canal", "pl": "Kanał", "zh-cn": "信道"},
|
|
13
13
|
"Check firmware updates": { "uk": "Перевірити оновлення прошивок пристроїв", "en": "Check firmware updates", "de": "Auf Firmware-Updates überprüfen", "ru": "Проверить обновления прошивки", "pt": "Verifique as atualizações de firmware", "nl": "Controleer firmware-updates", "fr": "Vérifier les mises à jour du firmware", "it": "Controlla gli aggiornamenti del firmware", "es": "Verifique las actualizaciones de firmware", "pl": "Sprawdź aktualizacje oprogramowania układowego", "zh-cn": "检查固件更新"},
|
|
14
14
|
"Choose channel": { "uk": "Виберіть канал", "en": "Choose channel", "de": "Kanal auswählen", "ru": "Выберите канал", "pt": "Escolha o canal", "nl": "Kies een kanaal", "fr": "Choisissez la chaîne", "it": "Scegli il canale", "es": "Elige canal", "pl": "Wybierz kanał", "zh-cn": "选择频道"},
|
|
@@ -84,7 +84,7 @@ systemDictionary = {
|
|
|
84
84
|
"View config": { "uk": "Переглянути конфігурацію", "en": "View config", "de": "Konfiguration anzeigen", "ru": "Посмотреть конфигурацию", "pt": "Ver configuração", "nl": "Bekijk configuratie", "fr": "Afficher la configuration", "it": "Visualizza config", "es": "Ver configuración", "pl": "Wyświetl config", "zh-cn": "查看配置"},
|
|
85
85
|
"Waiting": { "uk": "Очікування", "en": "Waiting", "de": "Warten", "ru": "Ожидание", "pt": "Esperando", "nl": "Wachtende", "fr": "Attendre", "it": "In attesa", "es": "Esperando", "pl": "Czekaj", "zh-cn": "等候"},
|
|
86
86
|
"Write Attribute": { "uk": "Записати атрибут", "en": "Write attribute", "de": "Attribut schreiben", "ru": "Запись атрибута", "pt": "Gravar Atributo", "nl": "Schrijf attribuut", "fr": "Ecrire attribut", "it": "Scrivi attributo", "es": "Escribir atributo", "pl": "Napisz atrybut", "zh-cn": "写属性"},
|
|
87
|
-
"Yes": { "uk": "Так", "en": "Yes", "de": "Ja", "ru": "Да", "pt": "sim", "nl": "Ja", "fr": "Oui", "it": "sì", "es": "Sí", "pl": "
|
|
87
|
+
"Yes": { "uk": "Так", "en": "Yes", "de": "Ja", "ru": "Да", "pt": "sim", "nl": "Ja", "fr": "Oui", "it": "sì", "es": "Sí", "pl": "Tak", "zh-cn": "是"},
|
|
88
88
|
"You find good explanations what the settings mean": {"uk": "Ви знайдете хороші пояснення значення налаштувань", "en": "You find good explanations what the settings mean", "de": "Sie finden gute Erklärungen, was die Einstellungen bedeuten", "ru": "Вы найдете хорошие объяснения, что означают настройки", "pt": "Você encontra boas explicações sobre o significado das configurações", "nl": "U vindt een goede uitleg wat de instellingen betekenen", "fr": "Vous trouvez de bonnes explications sur ce que signifient les paramètres", "it": "Trovi buone spiegazioni sul significato delle impostazioni", "es": "Encuentra buenas explicaciones de lo que significa la configuración", "pl": "Znajdziesz dobre wyjaśnienia, co oznaczają ustawienia", "zh-cn": "您会找到很好的解释,这些设置意味着什么"},
|
|
89
89
|
"Zigbee adapter": { "uk": "Адаптер Zigbee", "en": "Zigbee adapter", "de": "Zigbee-Adapter", "ru": "Zigbee адаптер", "pt": "Adaptador Zigbee", "nl": "Zigbee-adapter", "fr": "Adaptateur Zigbee", "it": "Adattatore Zigbee", "es": "Adaptador zigbee", "pl": "Adapter Zigbee", "zh-cn": "Zigbee适配器"},
|
|
90
90
|
"Zigbee-herdsman debug info": { "uk": "Інформація про налагодження Zigbee-herdsman", "en": "Zigbee-herdsman debug info", "de": "Zigbee-herdsman Debug-Info", "ru": "Отладочная информация Zigbee-herdsman", "pt": "Informações de depuração do pastor Zigbee", "nl": "Zigbee-herdsman debug informatie", "fr": "Informations de débogage de Zigbee-herdsman", "it": "Informazioni di debug di Zigbee-herdsman", "es": "Información de depuración de Zigbee-herdsman", "pl": "Informacje debugowania Zigbee-Herdsman", "zh-cn": "Zigbee-herdsman调试信息"},
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "zigbee",
|
|
4
|
-
"version": "1.8.
|
|
4
|
+
"version": "1.8.14",
|
|
5
5
|
"news": {
|
|
6
|
+
"1.8.14": {
|
|
7
|
+
"en": "",
|
|
8
|
+
"de": "",
|
|
9
|
+
"ru": "",
|
|
10
|
+
"pt": "",
|
|
11
|
+
"nl": "",
|
|
12
|
+
"fr": "",
|
|
13
|
+
"it": "",
|
|
14
|
+
"es": "",
|
|
15
|
+
"pl": "",
|
|
16
|
+
"uk": "",
|
|
17
|
+
"zh-cn": ""
|
|
18
|
+
},
|
|
19
|
+
"1.8.13": {
|
|
20
|
+
"en": "see Readme https://github.com/ioBroker/ioBroker.zigbee/blob/master/README.md",
|
|
21
|
+
"de": "see Readme https://github.com/ioBroker/ioBroker.zigbee/blob/master/README.md"
|
|
22
|
+
},
|
|
6
23
|
"1.8.12": {
|
|
7
24
|
"en": "new Documentation",
|
|
8
25
|
"de": "neue Dokumentation"
|
|
@@ -31,23 +48,6 @@
|
|
|
31
48
|
"1.8.8": {
|
|
32
49
|
"en": "fix lidl plug",
|
|
33
50
|
"de": "fix lidl plug"
|
|
34
|
-
},
|
|
35
|
-
"1.8.7": {
|
|
36
|
-
"en": "fix exposes",
|
|
37
|
-
"de": "belichtet fix",
|
|
38
|
-
"ru": "исправить экспозиции",
|
|
39
|
-
"pt": "corrigir expões",
|
|
40
|
-
"nl": "vertaling:",
|
|
41
|
-
"fr": "fix expose",
|
|
42
|
-
"it": "fix espone",
|
|
43
|
-
"es": "arreglar expone",
|
|
44
|
-
"pl": "naprawić",
|
|
45
|
-
"uk": "фіксувати висадки",
|
|
46
|
-
"zh-cn": "fix 暴露"
|
|
47
|
-
},
|
|
48
|
-
"1.8.6": {
|
|
49
|
-
"en": "fix exposes",
|
|
50
|
-
"de": "fix exposes"
|
|
51
51
|
}
|
|
52
52
|
},
|
|
53
53
|
"title": "Zigbee",
|
|
@@ -219,6 +219,7 @@
|
|
|
219
219
|
"_id": "exclude.all",
|
|
220
220
|
"type": "state",
|
|
221
221
|
"common": {
|
|
222
|
+
"role": "state",
|
|
222
223
|
"name": "all",
|
|
223
224
|
"type": "string",
|
|
224
225
|
"read": true,
|
|
@@ -252,6 +253,7 @@
|
|
|
252
253
|
"_id": "info.pairingMode",
|
|
253
254
|
"type": "state",
|
|
254
255
|
"common": {
|
|
256
|
+
"role": "indicator",
|
|
255
257
|
"name": "Pairing mode",
|
|
256
258
|
"type": "boolean",
|
|
257
259
|
"read": true,
|
|
@@ -264,6 +266,7 @@
|
|
|
264
266
|
"_id": "info.pairingCountdown",
|
|
265
267
|
"type": "state",
|
|
266
268
|
"common": {
|
|
269
|
+
"role": "indicator",
|
|
267
270
|
"name": "Pairing countdown",
|
|
268
271
|
"type": "number",
|
|
269
272
|
"read": true,
|
|
@@ -276,6 +279,7 @@
|
|
|
276
279
|
"_id": "info.pairingMessage",
|
|
277
280
|
"type": "state",
|
|
278
281
|
"common": {
|
|
282
|
+
"role": "indicator",
|
|
279
283
|
"name": "Pairing message",
|
|
280
284
|
"type": "string",
|
|
281
285
|
"read": true,
|
|
@@ -288,6 +292,7 @@
|
|
|
288
292
|
"_id": "info.groups",
|
|
289
293
|
"type": "state",
|
|
290
294
|
"common": {
|
|
295
|
+
"role": "state",
|
|
291
296
|
"name": "Groups",
|
|
292
297
|
"type": "string",
|
|
293
298
|
"read": true,
|
|
@@ -300,6 +305,7 @@
|
|
|
300
305
|
"_id": "info.undefinedDevices",
|
|
301
306
|
"type": "state",
|
|
302
307
|
"common": {
|
|
308
|
+
"role": "state",
|
|
303
309
|
"name": "Recorded undefined devices",
|
|
304
310
|
"type": "string",
|
|
305
311
|
"read": true,
|
|
@@ -307,6 +313,19 @@
|
|
|
307
313
|
"def": ""
|
|
308
314
|
},
|
|
309
315
|
"native": {}
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"_id": "info.debugmessages",
|
|
319
|
+
"type": "state",
|
|
320
|
+
"common": {
|
|
321
|
+
"role": "state",
|
|
322
|
+
"name": "Log changes as warnings for",
|
|
323
|
+
"type": "string",
|
|
324
|
+
"read": true,
|
|
325
|
+
"write": true,
|
|
326
|
+
"def": ""
|
|
327
|
+
},
|
|
328
|
+
"native": {}
|
|
310
329
|
}
|
|
311
330
|
]
|
|
312
331
|
}
|
package/lib/exposes.js
CHANGED
|
@@ -71,9 +71,35 @@ function genState(expose, role, name, desc) {
|
|
|
71
71
|
write: writable,
|
|
72
72
|
read: true,
|
|
73
73
|
type: 'string',
|
|
74
|
-
states:
|
|
74
|
+
states: {},
|
|
75
75
|
};
|
|
76
|
-
|
|
76
|
+
|
|
77
|
+
for (const val of expose.values) {
|
|
78
|
+
// if a definition of a enum states
|
|
79
|
+
if (val == '') {
|
|
80
|
+
state.states[propName] = propName;
|
|
81
|
+
} else {
|
|
82
|
+
state.states[val] = val;
|
|
83
|
+
}
|
|
84
|
+
state.type = typeof (val);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
switch (state.type) {
|
|
88
|
+
case 'boolean':
|
|
89
|
+
state.def = false;
|
|
90
|
+
break;
|
|
91
|
+
case 'number':
|
|
92
|
+
state.def = 0;
|
|
93
|
+
break;
|
|
94
|
+
case 'object':
|
|
95
|
+
state.def = {};
|
|
96
|
+
break;
|
|
97
|
+
case 'string':
|
|
98
|
+
state.def = '';
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// if a definition of a special button
|
|
77
103
|
if (state.states == ':') {
|
|
78
104
|
state.states = propName + ':' + propName;
|
|
79
105
|
state.type = 'object';
|
|
@@ -846,24 +872,38 @@ function applyExposes(mappedDevices, byModel, allExcludesObj) {
|
|
|
846
872
|
const allExcludesStr = JSON.stringify(allExcludesObj);
|
|
847
873
|
// create or update device from exposes
|
|
848
874
|
for (const deviceDef of zigbeeHerdsmanConverters.definitions) {
|
|
875
|
+
applyDeviceDef(mappedDevices, byModel, allExcludesStr, deviceDef);
|
|
876
|
+
|
|
877
|
+
if (deviceDef.hasOwnProperty('whiteLabel')) {
|
|
878
|
+
for (const deviceWhiteLabel of deviceDef.whiteLabel) {
|
|
879
|
+
applyDeviceDef(mappedDevices, byModel, allExcludesStr, {
|
|
880
|
+
...deviceDef,
|
|
881
|
+
model: deviceWhiteLabel.model,
|
|
882
|
+
vendor: deviceWhiteLabel.vendor,
|
|
883
|
+
description: deviceWhiteLabel.description || deviceDef.description,
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
849
889
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
} catch (e) {
|
|
865
|
-
console.log(`Wrong expose devicedefinition ${deviceDef.vendor} ${deviceDef.model}`);
|
|
890
|
+
function applyDeviceDef(mappedDevices, byModel, allExcludesStr, deviceDef) {
|
|
891
|
+
const stripModel = utils.getModelRegEx(deviceDef.model);
|
|
892
|
+
// check if device is mapped
|
|
893
|
+
const existsMap = byModel.get(stripModel);
|
|
894
|
+
|
|
895
|
+
if ((deviceDef.hasOwnProperty('exposes') && (!existsMap || !existsMap.hasOwnProperty('states'))) || allExcludesStr.indexOf(stripModel) > 0) {
|
|
896
|
+
try {
|
|
897
|
+
const newDevice = createFromExposes(stripModel, deviceDef);
|
|
898
|
+
if (!existsMap) {
|
|
899
|
+
mappedDevices.push(newDevice);
|
|
900
|
+
byModel.set(stripModel, newDevice);
|
|
901
|
+
} else {
|
|
902
|
+
existsMap.states = newDevice.states;
|
|
903
|
+
existsMap.exposed = true;
|
|
866
904
|
}
|
|
905
|
+
} catch (e) {
|
|
906
|
+
console.log(`Wrong expose devicedefinition ${deviceDef.vendor} ${stripModel}`);
|
|
867
907
|
}
|
|
868
908
|
}
|
|
869
909
|
}
|
package/lib/ota.js
CHANGED
|
@@ -97,7 +97,7 @@ class Ota {
|
|
|
97
97
|
const available = await device.mapped.ota.isUpdateAvailable(device.device, this);
|
|
98
98
|
result.status = available.available ? 'available' : 'not_available';
|
|
99
99
|
if (available.currentFileVersion !== available.otaFileVersion) {
|
|
100
|
-
this.
|
|
100
|
+
this.warn(`current Firmware for ${device.name} is ${available.currentFileVersion} new is ${available.otaFileVersion}`);
|
|
101
101
|
}
|
|
102
102
|
} else {
|
|
103
103
|
result.status = 'not_supported';
|
|
@@ -105,7 +105,7 @@ class Ota {
|
|
|
105
105
|
this.debug(`Firmware update for ${device.name} is ${result.status}`);
|
|
106
106
|
this.adapter.sendTo(obj.from, obj.command, result, obj.callback);
|
|
107
107
|
} catch (error) {
|
|
108
|
-
const message = `Failed to check if update available for '${device.name}'
|
|
108
|
+
const message = `Failed to check if update available for '${device.name}' ${error.message}`;
|
|
109
109
|
result.status = 'fail';
|
|
110
110
|
result.msg = message;
|
|
111
111
|
this.warn(message);
|
package/lib/statescontroller.js
CHANGED
|
@@ -72,31 +72,9 @@ class StatesController extends EventEmitter {
|
|
|
72
72
|
this.debugDevices = state.val.split(';');
|
|
73
73
|
}
|
|
74
74
|
this.info(`debug devices set to ${JSON.stringify(this.debugDevices)}`);
|
|
75
|
-
} else {
|
|
76
|
-
this.adapter.setObject('info.debugmessages', {
|
|
77
|
-
type: 'state',
|
|
78
|
-
common: {
|
|
79
|
-
name: 'Log changes as warnings for',
|
|
80
|
-
role: '',
|
|
81
|
-
type: 'string',
|
|
82
|
-
read: true,
|
|
83
|
-
write: true,
|
|
84
|
-
},
|
|
85
|
-
native: {},
|
|
86
|
-
});
|
|
87
75
|
}
|
|
88
76
|
});
|
|
89
|
-
|
|
90
|
-
type: 'state',
|
|
91
|
-
common: {
|
|
92
|
-
name: 'Recorded undefined devices',
|
|
93
|
-
role: '',
|
|
94
|
-
type: 'string',
|
|
95
|
-
read: true,
|
|
96
|
-
write: false,
|
|
97
|
-
},
|
|
98
|
-
native: {},
|
|
99
|
-
});
|
|
77
|
+
|
|
100
78
|
this.adapter.setStateAsync(`info.undefinedDevices`, JSON.stringify(knownUndefinedDevices), true);
|
|
101
79
|
}
|
|
102
80
|
|
|
@@ -160,12 +138,13 @@ class StatesController extends EventEmitter {
|
|
|
160
138
|
const result = {};
|
|
161
139
|
// find model states for options and get it values
|
|
162
140
|
const devStates = await this.getDevStates('0x' + devId, model);
|
|
163
|
-
if (
|
|
141
|
+
if (devStates == null || devStates == undefined) {
|
|
164
142
|
callback(result);
|
|
165
143
|
return;
|
|
166
144
|
}
|
|
167
|
-
|
|
168
|
-
|
|
145
|
+
|
|
146
|
+
const states = devStates.states.filter(statedesc => statedesc.isOption || statedesc.inOptions);
|
|
147
|
+
if (states == null || states == undefined) {
|
|
169
148
|
callback(result);
|
|
170
149
|
return;
|
|
171
150
|
}
|
package/main.js
CHANGED
|
@@ -516,7 +516,7 @@ class Zigbee extends utils.Adapter {
|
|
|
516
516
|
if (!converters.length) {
|
|
517
517
|
if (type !== 'readResponse') {
|
|
518
518
|
this.log.debug(
|
|
519
|
-
`No converter available for '${mappedModel.model}' with cluster '${cluster}' and type '${type}'`
|
|
519
|
+
`No converter available for '${mappedModel.model}' '${devId}' with cluster '${cluster}' and type '${type}'`
|
|
520
520
|
);
|
|
521
521
|
}
|
|
522
522
|
return;
|
|
@@ -562,144 +562,155 @@ class Zigbee extends utils.Adapter {
|
|
|
562
562
|
|
|
563
563
|
async publishFromState(deviceId, model, stateModel, stateList, options) {
|
|
564
564
|
let isGroup = false;
|
|
565
|
+
|
|
566
|
+
this.log.debug(`publishFromState : ${deviceId} ${model}`);
|
|
565
567
|
if (model === 'group') {
|
|
566
568
|
isGroup = true;
|
|
567
569
|
deviceId = parseInt(deviceId);
|
|
568
570
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
stateList.forEach(async changedState => {
|
|
579
|
-
const stateDesc = changedState.stateDesc;
|
|
580
|
-
const value = changedState.value;
|
|
581
|
-
|
|
582
|
-
if (stateDesc.id === 'send_payload') {
|
|
583
|
-
try {
|
|
584
|
-
const json_value = JSON.parse(value);
|
|
585
|
-
const payload = {device: deviceId.replace('0x', ''), payload: json_value};
|
|
586
|
-
const result = await this.sendPayload(payload);
|
|
587
|
-
if (result.hasOwnProperty('success') && result.success) {
|
|
588
|
-
this.acknowledgeState(deviceId, model, stateDesc, value);
|
|
589
|
-
}
|
|
590
|
-
} catch (error) {
|
|
591
|
-
this.log.warn(`send_payload: ${value} does not parse as JSON Object : ${error.message}`);
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
571
|
+
try {
|
|
572
|
+
const entity = await this.zbController.resolveEntity(deviceId);
|
|
573
|
+
|
|
574
|
+
this.log.debug(`entity: ${deviceId} ${model} ${safeJsonStringify(entity)}`);
|
|
575
|
+
|
|
576
|
+
const mappedModel = entity.mapped;
|
|
577
|
+
|
|
578
|
+
if (!mappedModel) {
|
|
579
|
+
this.log.debug(`No mapped model for ${model}`);
|
|
594
580
|
return;
|
|
595
581
|
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
582
|
+
|
|
583
|
+
stateList.forEach(async changedState => {
|
|
584
|
+
const stateDesc = changedState.stateDesc;
|
|
585
|
+
const value = changedState.value;
|
|
586
|
+
|
|
587
|
+
if (stateDesc.id === 'send_payload') {
|
|
588
|
+
try {
|
|
589
|
+
const json_value = JSON.parse(value);
|
|
590
|
+
const payload = {device: deviceId.replace('0x', ''), payload: json_value};
|
|
591
|
+
const result = await this.sendPayload(payload);
|
|
592
|
+
if (result.hasOwnProperty('success') && result.success) {
|
|
593
|
+
this.acknowledgeState(deviceId, model, stateDesc, value);
|
|
594
|
+
}
|
|
595
|
+
} catch (error) {
|
|
596
|
+
this.log.warn(`send_payload: ${value} does not parse as JSON Object : ${error.message}`);
|
|
608
597
|
return;
|
|
609
598
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
if (stateDesc.isOption) {
|
|
603
|
+
// acknowledge state with given value
|
|
604
|
+
this.acknowledgeState(deviceId, model, stateDesc, value);
|
|
605
|
+
// process sync state list
|
|
606
|
+
//this.processSyncStatesList(deviceId, modelId, syncStateList);
|
|
607
|
+
// if this is the device query state => trigger the device query
|
|
608
|
+
|
|
609
|
+
// on activation of the 'device_query' state trigger hardware query where possible
|
|
610
|
+
if (stateDesc.id === 'device_query') {
|
|
611
|
+
if (this.query_device_block.indexOf(deviceId) > -1) {
|
|
612
|
+
this.log.warn(`Device query for '${entity.device.ieeeAddr}' blocked`);
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
if (mappedModel) {
|
|
616
|
+
this.query_device_block.push(deviceId);
|
|
617
|
+
this.log.debug(`Device query for '${entity.device.ieeeAddr}' started`);
|
|
618
|
+
for (const converter of mappedModel.toZigbee) {
|
|
619
|
+
if (converter.hasOwnProperty('convertGet')) {
|
|
620
|
+
for (const ckey of converter.key) {
|
|
621
|
+
try {
|
|
622
|
+
await converter.convertGet(entity.device.endpoints[0], ckey, {});
|
|
623
|
+
} catch (error) {
|
|
624
|
+
this.log.warn(`Failed to read state '${JSON.stringify(ckey)}'of '${entity.device.ieeeAddr}' after query with '${JSON.stringify(error)}'`);
|
|
625
|
+
|
|
626
|
+
}
|
|
621
627
|
}
|
|
622
628
|
}
|
|
623
629
|
}
|
|
630
|
+
this.log.debug(`Device query for '${entity.device.ieeeAddr}' done`);
|
|
631
|
+
const idToRemove = deviceId;
|
|
632
|
+
setTimeout(() => {
|
|
633
|
+
const idx = this.query_device_block.indexOf(idToRemove);
|
|
634
|
+
if (idx > -1) {
|
|
635
|
+
this.query_device_block.splice(idx);
|
|
636
|
+
}
|
|
637
|
+
}, 10000);
|
|
624
638
|
}
|
|
625
|
-
|
|
626
|
-
const idToRemove = deviceId;
|
|
627
|
-
setTimeout(() => {
|
|
628
|
-
const idx = this.query_device_block.indexOf(idToRemove);
|
|
629
|
-
if (idx > -1) {
|
|
630
|
-
this.query_device_block.splice(idx);
|
|
631
|
-
}
|
|
632
|
-
}, 10000);
|
|
639
|
+
return;
|
|
633
640
|
}
|
|
634
641
|
return;
|
|
635
642
|
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
643
|
+
const converter = mappedModel.toZigbee.find(c => c && (c.key.includes(stateDesc.prop) || c.key.includes(stateDesc.setattr) || c.key.includes(stateDesc.id)));
|
|
644
|
+
if (!converter) {
|
|
645
|
+
this.log.error(`No converter available for '${model}' with key '${stateDesc.id}' `);
|
|
646
|
+
this.sendError(`No converter available for '${model}' with key '${stateDesc.id}' `);
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
const preparedValue = (stateDesc.setter) ? stateDesc.setter(value, options) : value;
|
|
651
|
+
const preparedOptions = (stateDesc.setterOpt) ? stateDesc.setterOpt(value, options) : {};
|
|
652
|
+
let syncStateList = [];
|
|
653
|
+
if (stateModel && stateModel.syncStates) {
|
|
654
|
+
stateModel.syncStates.forEach(syncFunct => {
|
|
655
|
+
const res = syncFunct(stateDesc, value, options);
|
|
656
|
+
if (res) {
|
|
657
|
+
syncStateList = syncStateList.concat(res);
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
const epName = stateDesc.epname !== undefined ? stateDesc.epname : (stateDesc.prop || stateDesc.id);
|
|
663
|
+
const key = stateDesc.setattr || stateDesc.prop || stateDesc.id;
|
|
664
|
+
this.log.debug(`convert ${key}, ${safeJsonStringify(preparedValue)}, ${safeJsonStringify(preparedOptions)}`);
|
|
665
|
+
|
|
666
|
+
let target;
|
|
667
|
+
if (model === 'group') {
|
|
668
|
+
target = entity.mapped;
|
|
669
|
+
} else {
|
|
670
|
+
target = await this.zbController.resolveEntity(deviceId, epName);
|
|
671
|
+
target = target.endpoint;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
this.log.debug(`target: ${safeJsonStringify(target)}`);
|
|
675
|
+
|
|
676
|
+
const meta = {
|
|
677
|
+
endpoint_name: epName,
|
|
678
|
+
options: preparedOptions,
|
|
679
|
+
device: entity.device,
|
|
680
|
+
mapped: model === 'group' ? [] : mappedModel,
|
|
681
|
+
message: {[key]: preparedValue},
|
|
682
|
+
logger: this.log,
|
|
683
|
+
state: {},
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
if (preparedOptions.hasOwnProperty('state')) {
|
|
687
|
+
meta.state = preparedOptions.state;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
try {
|
|
691
|
+
const result = await converter.convertSet(target, key, preparedValue, meta);
|
|
692
|
+
this.log.debug(`convert result ${safeJsonStringify(result)}`);
|
|
693
|
+
if (result !== undefined) {
|
|
694
|
+
if (stateModel && !isGroup) {
|
|
695
|
+
this.acknowledgeState(deviceId, model, stateDesc, value);
|
|
696
|
+
}
|
|
697
|
+
// process sync state list
|
|
698
|
+
this.processSyncStatesList(deviceId, model, syncStateList);
|
|
699
|
+
|
|
700
|
+
if (isGroup) {
|
|
701
|
+
await this.callPluginMethod('queryGroupMemberState', [deviceId, stateDesc]);
|
|
702
|
+
this.acknowledgeState(deviceId, model, stateDesc, value);
|
|
703
|
+
}
|
|
696
704
|
}
|
|
705
|
+
|
|
706
|
+
} catch (error) {
|
|
707
|
+
this.filterError(`Error ${error.code} on send command to ${deviceId}.` +
|
|
708
|
+
` Error: ${error.stack}`, `Send command to ${deviceId} failed with`, error);
|
|
697
709
|
}
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
});
|
|
710
|
+
});
|
|
711
|
+
} catch (err) {
|
|
712
|
+
this.log.error(`No entity for ${deviceId}`);
|
|
713
|
+
}
|
|
703
714
|
}
|
|
704
715
|
|
|
705
716
|
// This function is introduced to explicitly allow user level scripts to send Commands
|
|
@@ -917,7 +928,6 @@ class Zigbee extends utils.Adapter {
|
|
|
917
928
|
if (Number.isInteger(data)) {
|
|
918
929
|
_pairingMode = true;
|
|
919
930
|
this.setState('info.pairingCountdown', data, true);
|
|
920
|
-
_pairingMode = true;
|
|
921
931
|
}
|
|
922
932
|
if (data === 0) {
|
|
923
933
|
// set pairing mode off
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.zigbee",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.14",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Kirov Ilya",
|
|
6
6
|
"email": "kirovilya@gmail.com"
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@iobroker/adapter-core": "^2.6.8",
|
|
25
25
|
"tar": "^6.1.15",
|
|
26
|
-
"typescript": "^5.
|
|
26
|
+
"typescript": "^5.1.6",
|
|
27
27
|
"zigbee-herdsman": "0.16.0",
|
|
28
|
-
"zigbee-herdsman-converters": "15.
|
|
28
|
+
"zigbee-herdsman-converters": "15.35.1"
|
|
29
29
|
},
|
|
30
30
|
"description": "Zigbee devices",
|
|
31
31
|
"devDependencies": {
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"axios": "^1.3.4",
|
|
37
37
|
"chai": "^4.3.7",
|
|
38
38
|
"chai-as-promised": "^7.1.1",
|
|
39
|
-
"eslint": "^8.
|
|
39
|
+
"eslint": "^8.44.0",
|
|
40
40
|
"eslint-config-prettier": "^8.8.0",
|
|
41
41
|
"eslint-plugin-prettier": "^4.2.1",
|
|
42
42
|
"gulp": "^4.0.2",
|