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 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": "Anuluj",
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": "tak",
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",
@@ -985,10 +985,10 @@
985
985
  <p class="translate device_with_endpoint">Main Endpoint</p>
986
986
  </div>
987
987
  </div>
988
- <div class="col">
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">Значение</option>
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">Значение</option>
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">Значение</option>
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">Значение</option>
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="col">
686
+ <div class="col1">
687
687
  <div class="input-field groups">
688
- <select id="d_groups_ep0" class="materialSelect" multiple><option value="1">Значение</option></select>
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">Значение</option></select>
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">Значение</option></select>
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">Значение</option></select>
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">Значение</option></select>
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": "Anuluj", "zh-cn": "取消"},
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": "tak", "zh-cn": "是"},
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.12",
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: expose.values.map(item => `${item}:${item}`).join(';'),
74
+ states: {},
75
75
  };
76
- // if a definition of a button
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
- const stripModel = utils.getModelRegEx(deviceDef.model);
851
- // check if device is mapped
852
- const existsMap = byModel.get(stripModel);
853
-
854
- if ((deviceDef.hasOwnProperty('exposes') && (!existsMap || !existsMap.hasOwnProperty('states'))) || allExcludesStr.indexOf(stripModel) > 0) {
855
- try {
856
- const newDevice = createFromExposes(stripModel, deviceDef);
857
- if (!existsMap) {
858
- mappedDevices.push(newDevice);
859
- byModel.set(stripModel, newDevice);
860
- } else {
861
- existsMap.states = newDevice.states;
862
- existsMap.exposed = true;
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.warning(`current Firmware for ${device.name} is ${available.currentFileVersion} new is ${available.otaFileVersion}`);
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}' (${error.message})`;
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);
@@ -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
- this.adapter.setObject('info.undefinedDevices', {
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 (!devStates) {
141
+ if (devStates == null || devStates == undefined) {
164
142
  callback(result);
165
143
  return;
166
144
  }
167
- const states = devStates.states.filter(statedesc => statedesc.isOption || statedesc.inOptions);
168
- if (!states) {
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
- const entity = await this.zbController.resolveEntity(deviceId);
570
- this.log.debug(`entity: ${deviceId} ${model} ${safeJsonStringify(entity)}`);
571
- const mappedModel = entity.mapped;
572
- if (!mappedModel) {
573
- this.log.debug(`No mapped model for ${model}`);
574
- return;
575
- }
576
- this.log.debug(`Mapped Model: ${JSON.stringify(mappedModel)}`);
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
- if (stateDesc.isOption) {
598
- // acknowledge state with given value
599
- this.acknowledgeState(deviceId, model, stateDesc, value);
600
- // process sync state list
601
- //this.processSyncStatesList(deviceId, modelId, syncStateList);
602
- // if this is the device query state => trigger the device query
603
-
604
- // on activation of the 'device_query' state trigger hardware query where possible
605
- if (stateDesc.id === 'device_query') {
606
- if (this.query_device_block.indexOf(deviceId) > -1) {
607
- this.log.warn(`Device query for '${entity.device.ieeeAddr}' blocked`);
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
- if (mappedModel) {
611
- this.query_device_block.push(deviceId);
612
- this.log.debug(`Device query for '${entity.device.ieeeAddr}' started`);
613
- for (const converter of mappedModel.toZigbee) {
614
- if (converter.hasOwnProperty('convertGet')) {
615
- for (const ckey of converter.key) {
616
- try {
617
- await converter.convertGet(entity.device.endpoints[0], ckey, {});
618
- } catch (error) {
619
- this.log.warn(`Failed to read state '${JSON.stringify(ckey)}'of '${entity.device.ieeeAddr}' after query with '${JSON.stringify(error)}'`);
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
- this.log.debug(`Device query for '${entity.device.ieeeAddr}' done`);
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
- return;
637
- }
638
- const converter = mappedModel.toZigbee.find(c => c && (c.key.includes(stateDesc.prop) || c.key.includes(stateDesc.setattr) || c.key.includes(stateDesc.id)));
639
- if (!converter) {
640
- this.log.error(`No converter available for '${model}' with key '${stateDesc.id}' `);
641
- this.sendError(`No converter available for '${model}' with key '${stateDesc.id}' `);
642
- return;
643
- }
644
-
645
- const preparedValue = (stateDesc.setter) ? stateDesc.setter(value, options) : value;
646
- const preparedOptions = (stateDesc.setterOpt) ? stateDesc.setterOpt(value, options) : {};
647
- let syncStateList = [];
648
- if (stateModel && stateModel.syncStates) {
649
- stateModel.syncStates.forEach(syncFunct => {
650
- const res = syncFunct(stateDesc, value, options);
651
- if (res) {
652
- syncStateList = syncStateList.concat(res);
653
- }
654
- });
655
- }
656
-
657
- const epName = stateDesc.epname !== undefined ? stateDesc.epname : (stateDesc.prop || stateDesc.id);
658
- const key = stateDesc.setattr || stateDesc.prop || stateDesc.id;
659
- this.log.debug(`convert ${key}, ${safeJsonStringify(preparedValue)}, ${safeJsonStringify(preparedOptions)}`);
660
-
661
- let target;
662
- if (model === 'group') {
663
- target = entity.mapped;
664
- } else {
665
- target = await this.zbController.resolveEntity(deviceId, epName);
666
- target = target.endpoint;
667
- }
668
-
669
- this.log.debug(`target: ${safeJsonStringify(target)}`);
670
-
671
- const meta = {
672
- endpoint_name: epName,
673
- options: preparedOptions,
674
- device: entity.device,
675
- mapped: model === 'group' ? [] : mappedModel,
676
- message: {[key]: preparedValue},
677
- logger: this.log,
678
- state: {},
679
- };
680
- if (preparedOptions.hasOwnProperty('state')) {
681
- meta.state = preparedOptions.state;
682
- }
683
- try {
684
- const result = await converter.convertSet(target, key, preparedValue, meta);
685
- this.log.debug(`convert result ${safeJsonStringify(result)}`);
686
- if (result !== undefined) {
687
- if (stateModel && !isGroup) {
688
- this.acknowledgeState(deviceId, model, stateDesc, value);
689
- }
690
- // process sync state list
691
- this.processSyncStatesList(deviceId, model, syncStateList);
692
-
693
- if (isGroup) {
694
- await this.callPluginMethod('queryGroupMemberState', [deviceId, stateDesc]);
695
- this.acknowledgeState(deviceId, model, stateDesc, value);
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
- } catch (error) {
699
- this.filterError(`Error ${error.code} on send command to ${deviceId}.` +
700
- ` Error: ${error.stack}`, `Send command to ${deviceId} failed with`, error);
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.12",
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.0.4",
26
+ "typescript": "^5.1.6",
27
27
  "zigbee-herdsman": "0.16.0",
28
- "zigbee-herdsman-converters": "15.32.0"
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.41.0",
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",