iobroker.zigbee 2.0.3 → 2.0.5
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 +34 -20
- package/admin/admin.js +9 -3
- package/io-package.json +27 -27
- package/lib/DeviceDebug.js +4 -2
- package/lib/commands.js +6 -2
- package/lib/exposes.js +7 -2
- package/lib/localConfig.js +3 -3
- package/lib/statescontroller.js +6 -4
- package/lib/zbDeviceConfigure.js +83 -56
- package/lib/zigbeecontroller.js +31 -40
- package/main.js +16 -28
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -152,30 +152,44 @@ You can thank the authors by these links:
|
|
|
152
152
|
|
|
153
153
|
-----------------------------------------------------------------------------------------------------
|
|
154
154
|
## Changelog
|
|
155
|
+
### 2.0.5 (2025-03-25)
|
|
156
|
+
* (asgothian) ZHC 23.6.0
|
|
157
|
+
* (asgothian) ZH 3.3.x
|
|
158
|
+
* (asgothian) removed extra logging
|
|
159
|
+
* (asgothian) fixed memory issue.
|
|
160
|
+
* (asgothian) Configure on Message - 5 attempts.
|
|
161
|
+
* (arteck) update transmitPower
|
|
162
|
+
* (asgothian) fix crash in ZigbeeController.ByteArrayToString
|
|
163
|
+
* (AlexHaxe) device designation for devices without mapped model (allows use in groups and bindings)
|
|
164
|
+
*
|
|
165
|
+
|
|
166
|
+
### 2.0.4 (2025-03-09)
|
|
167
|
+
* (arteck) back to 2.0.2
|
|
168
|
+
|
|
155
169
|
### 2.0.3 (2025-03-07)
|
|
156
|
-
* fix configured info
|
|
157
|
-
* fix battery voltage (V -> mV)
|
|
158
|
-
* enable debug interface v1.0
|
|
159
|
-
* Push Zigbee-Herdsman to
|
|
160
|
-
* Push Zigbee-Herdsman-Converters to 23.1.1
|
|
161
|
-
* fix configure on message
|
|
162
|
-
* remove extra warning messages
|
|
163
|
-
* fix Adapter-Checker notes
|
|
164
|
-
* improve base64 image detection
|
|
165
|
-
* removed unused adaptert objects (info.groups, excludes) from adapter config
|
|
170
|
+
* (asgothian) fix configured info
|
|
171
|
+
* (asgothian) fix battery voltage (V -> mV)
|
|
172
|
+
* (asgothian) enable debug interface v1.0
|
|
173
|
+
* (asgothian) Push Zigbee-Herdsman to 2.5.7
|
|
174
|
+
* (asgothian) Push Zigbee-Herdsman-Converters to 23.1.1
|
|
175
|
+
* (asgothian) fix configure on message
|
|
176
|
+
* (asgothian) remove extra warning messages
|
|
177
|
+
* (asgothian) fix Adapter-Checker notes
|
|
178
|
+
* (asgothian) improve base64 image detection
|
|
179
|
+
* (asgothian) removed unused adaptert objects (info.groups, excludes) from adapter config
|
|
166
180
|
*
|
|
167
181
|
|
|
168
182
|
### 2.0.2 (2025-03-02)
|
|
169
|
-
*
|
|
170
|
-
* fix failure to configure for devices needing multiple configurations (Issue #2375)
|
|
171
|
-
* fix hold/release and press/release action handling (Issue #2387)
|
|
172
|
-
* fix lib/legacy requirement for external converters (Issue #2376)
|
|
173
|
-
* improved external converter handling
|
|
174
|
-
* fix OTA bug
|
|
175
|
-
* improved message handling for devices which report values outside their defined ranges
|
|
176
|
-
* preparation for ZHC 22.x (model definition loaded on demand
|
|
177
|
-
* fix legacy definition for devices
|
|
178
|
-
* added action state for remotes.
|
|
183
|
+
* (asgothian) expose generation with expose function requiring a device. (Issue #1842)
|
|
184
|
+
* (asgothian) fix failure to configure for devices needing multiple configurations (Issue #2375)
|
|
185
|
+
* (asgothian) fix hold/release and press/release action handling (Issue #2387)
|
|
186
|
+
* (asgothian) fix lib/legacy requirement for external converters (Issue #2376)
|
|
187
|
+
* (asgothian) improved external converter handling
|
|
188
|
+
* (asgothian) fix OTA bug
|
|
189
|
+
* (asgothian) improved message handling for devices which report values outside their defined ranges
|
|
190
|
+
* (asgothian) preparation for ZHC 22.x (model definition loaded on demand
|
|
191
|
+
* (asgothian) fix legacy definition for devices
|
|
192
|
+
* (asgothian) added action state for remotes.
|
|
179
193
|
*
|
|
180
194
|
|
|
181
195
|
### 2.0.1 (2025-02-25)
|
package/admin/admin.js
CHANGED
|
@@ -31,7 +31,8 @@ let devices = [],
|
|
|
31
31
|
cidList,
|
|
32
32
|
shuffleInstance,
|
|
33
33
|
errorData = [],
|
|
34
|
-
debugMessages = {}
|
|
34
|
+
debugMessages = {},
|
|
35
|
+
debugInLog = true;
|
|
35
36
|
const dbgMsgfilter = new Set();
|
|
36
37
|
const dbgMsghide = new Set();
|
|
37
38
|
const updateCardInterval = setInterval(updateCardTimer, 6000);
|
|
@@ -974,7 +975,8 @@ function displayDebugMessages(msg) {
|
|
|
974
975
|
const button = `<a id="e_all" class="btn-floating waves-effect waves-light green tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">sync_problem</i></a>`;
|
|
975
976
|
const fbutton = `<a id="f_all" class="btn-floating waves-effect waves-light blue tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">${dbgMsgfilter.size != 0 ? 'filter_list' : 'format_align_justify' }</i></a>`;
|
|
976
977
|
const hbutton = `<a id="h_all" class="btn-floating waves-effect waves-light blue tooltipped center-align hoverable translateT" title="Update debug messages"><i class="material-icons large">${dbgMsghide.size != 0 ? 'unfold_more' : 'unfold_less'}</i></a>`;
|
|
977
|
-
|
|
978
|
+
const logbutton = `<a id="l_all" class="btn-floating waves-effect waves-light ${debugInLog ? 'green' : 'red'} tooltipped center-align hoverable translateT" title="Log messages"><i class="material-icons large">${debugInLog ? 'speaker_notes' : 'speaker_notes_off'}</i></a>`;
|
|
979
|
+
Html.push(`<li><table><thead id="dbgtable"><tr><td>${logbutton}</td><td colspan="3">Debug information by device</td><td>${fbutton}</td><td>${hbutton}</td><td>${button}</td></tr></thead><tbody>`);
|
|
978
980
|
if (!keylength) {
|
|
979
981
|
Html.push('<tr><td></td><td>No debug data loaded - press reload to refresh</td><td></td><td> </td><td> </td><td> </td><td> </td><td> </td></tr></tbody></table></li>')
|
|
980
982
|
$('#dbg_data_list').html(Html.join(''));
|
|
@@ -1003,6 +1005,10 @@ function displayDebugMessages(msg) {
|
|
|
1003
1005
|
$(`#e_all`).click(function () {
|
|
1004
1006
|
getDebugMessages();
|
|
1005
1007
|
});
|
|
1008
|
+
$(`#l_all`).click(function () {
|
|
1009
|
+
debugInLog = !debugInLog;
|
|
1010
|
+
getDebugMessages();
|
|
1011
|
+
});
|
|
1006
1012
|
$(`#f_all`).click(function () {
|
|
1007
1013
|
if (dbgMsgfilter.size > 0) {
|
|
1008
1014
|
dbgMsgfilter.clear();
|
|
@@ -1052,7 +1058,7 @@ function displayDebugMessages(msg) {
|
|
|
1052
1058
|
}
|
|
1053
1059
|
|
|
1054
1060
|
function getDebugMessages() {
|
|
1055
|
-
sendTo(namespace, 'getDebugMessages', {}, function(msg) {
|
|
1061
|
+
sendTo(namespace, 'getDebugMessages', { inlog: debugInLog }, function(msg) {
|
|
1056
1062
|
debugMessages = msg;
|
|
1057
1063
|
if (msg) displayDebugMessages(debugMessages)
|
|
1058
1064
|
})
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "zigbee",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.5",
|
|
5
5
|
"news": {
|
|
6
|
+
"2.0.5": {
|
|
7
|
+
"en": "ZHC 23.6.0\nZH 3.3.x\nremoved extra logging\nfixed memory issue.\nConfigure on Message - 5 attempts.\nupdate transmitPower\nfix crash in ZigbeeController.ByteArrayToString\ndevice designation for devices without mapped model (allows use in groups and bindings)\n",
|
|
8
|
+
"de": "ZHC 23.6.0\nZH 3.3.x\nentfernte zusätzliche protokollierung\nfeste speicherausgabe.\nKonfigurieren auf Nachricht - 5 Versuche.\nupdate sendPower\ncrash in ZigbeeController beheben. ByteArrayToString\ngerätebezeichnung für geräte ohne abgebildetes modell (ermöglicht die verwendung in gruppen und bindungen)\n",
|
|
9
|
+
"ru": "ZHC 23.6.0\nZH 3.3.x\nудаленный дополнительный лес\nпроблемы с памятью.\nНастройка на сообщение - 5 попыток.\nобновление передатчика\nкрушение в ZigbeeController. Разработчик:teArrayToString\nобозначение устройства для устройств без картографической модели (позволяет использовать в группах и привязках)\n",
|
|
10
|
+
"pt": "ZHC 23.6.0\nZH 3.3.x\nretirada extra\nproblema de memória fixa.\nConfigurar na Mensagem - 5 tentativas.\natualização de energia\ncorrigir acidente em ZigbeeController. Linha de produção\ndesignação do dispositivo para dispositivos sem modelo mapeado (permite o uso em grupos e encadernações)\n",
|
|
11
|
+
"nl": "ZHC 23.6.0\nZH 3.3.x\nextra loggen verwijderd\nvast geheugen probleem.\nConfigureren op Bericht - 5 pogingen.\nupdate transmitPower\nherstel crash in ZigbeeController. ByteArrayToString\napparaataanduiding voor apparaten zonder in kaart gebracht model (kan worden gebruikt in groepen en bindingen)\n",
|
|
12
|
+
"fr": "ZHC 23.6.0\nZH 3.3.x\nretrait de l'exploitation supplémentaire\nproblème de mémoire fixe.\nConfigurer sur Message - 5 tentatives.\nmise à jour de transmissionPower\nréparer l'accident dans ZigbeeController. ByteArrayToString\ndésignation de l'appareil pour les dispositifs sans modèle cartographié (permet d'utiliser en groupes et de fixations)\n",
|
|
13
|
+
"it": "ZHC 23.6.0\nZH 3.3.x\nrimosso extra logging\nproblema di memoria fisso.\nConfigurare su Messaggio - 5 tentativi.\naggiornamento trasmetterePower\nfissare l'incidente a ZigbeeController. ByteArrayToString\ndesignazione del dispositivo per dispositivi senza modello mappato (permette l'uso in gruppi e binding)\n",
|
|
14
|
+
"es": "ZHC 23.6.0\nZH 3.3.x\nextra de registro\nproblema de memoria fijo.\nConfigurar en el Mensaje - 5 intentos.\ntransmisión de actualizaciónPower\narregla el accidente en ZigbeeController. ByteArrayToString\ndesignación de dispositivos para dispositivos sin modelo mapeado (permite el uso en grupos y encuadernaciones)\n",
|
|
15
|
+
"pl": "ZHC 23.6.0\nZH 3.3.x\nusunięte dodatkowe logowanie\nproblemy z pamięcią stałą.\nKonfiguracja wiadomości - 5 prób.\ntransmiter aktualizacji Power\nnaprawić wypadek w ZigbeeController. ByteArrayToString\noznaczenie urządzenia dla urządzeń bez mapowanego modelu (pozwala na stosowanie w grupach i wiązaniach)\n",
|
|
16
|
+
"uk": "ЗХК 23.6.0\nZH 3.3.x\nвидалення додаткового входу\nвиправлено проблему пам'яті.\nНастроювання повідомлення - 5 спроб.\nоновлення трансмісії\nфіксувати аварійну аварійну аварійність в ZigbeeController. ByteArrayToString\nпозначення пристрою для пристроїв без картографічної моделі ( дозволяє використовувати в групах і зв'язках)\n",
|
|
17
|
+
"zh-cn": "ZHC 23.6.0\nZH 3.3.x 电话\n已删除的额外日志\n固定记忆问题.\n配置信件 - 5 个尝试 .\n更新传输\n修复Zigbee控制器的崩溃。 字节箭头结构\n没有绘图模型的设备指定(分组和捆绑中的允许使用)\n"
|
|
18
|
+
},
|
|
19
|
+
"2.0.4": {
|
|
20
|
+
"en": "back to 2.0.2",
|
|
21
|
+
"de": "zurück zu 2.0.2",
|
|
22
|
+
"ru": "вернуться в 2.0.2",
|
|
23
|
+
"pt": "voltar para 2.0.2",
|
|
24
|
+
"nl": "terug naar 2.0.2",
|
|
25
|
+
"fr": "retour à 2.0.2",
|
|
26
|
+
"it": "torna a 2.0.2",
|
|
27
|
+
"es": "volver a 2.0.2",
|
|
28
|
+
"pl": "powrót do 2.0.2",
|
|
29
|
+
"uk": "до 2.0.2",
|
|
30
|
+
"zh-cn": "返回到2.0.2"
|
|
31
|
+
},
|
|
6
32
|
"2.0.3": {
|
|
7
33
|
"en": "fix configured info\nfix battery voltage (V -> mV)\nenable debug interface v1.0\nPush Zigbee-Herdsman to 3.5.7\nPush Zigbee-Herdsman-Converters to 23.1.1\nfix configure on message\nremove extra warning messages\nfix Adapter-Checker notes\nimprove base64 image detection\nremoved unused adaptert objects (info.groups, excludes) from adapter config\n",
|
|
8
34
|
"de": "die konfigurierten informationen\nbatteriespannung fixieren (V -> mV)\ndebug interface v1.0\nPush Zigbee-Herdsman auf 3.5.7\nPush Zigbee-Herdsman-Konverter auf 23.1.1\nkonfigurieren der nachricht\nzusätzliche warnmeldungen entfernen\nfix Adapter-Checker-Noten\nverbesserung der bilderkennung von base64\nentfernte ungenutzte adapterobjekte (info.groups, ausgenommen) von adapter config\n",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "corr ikona pobierz błąd (axios)",
|
|
68
94
|
"uk": "корр іконки завантажити помилку (axios)",
|
|
69
95
|
"zh-cn": "corr 图标下载错误( axios)"
|
|
70
|
-
},
|
|
71
|
-
"1.10.12": {
|
|
72
|
-
"en": "corr Channel Scan",
|
|
73
|
-
"de": "corr Channel Scan",
|
|
74
|
-
"ru": "корректор канала",
|
|
75
|
-
"pt": "escaneamento do canal de cortiça",
|
|
76
|
-
"nl": "corr kanaalscan",
|
|
77
|
-
"fr": "balayage du canal corr",
|
|
78
|
-
"it": "corr Channel Scansione",
|
|
79
|
-
"es": "corr Channel Scan",
|
|
80
|
-
"pl": "corr Channel Scan",
|
|
81
|
-
"uk": "сканування каналу",
|
|
82
|
-
"zh-cn": "频道扫描"
|
|
83
|
-
},
|
|
84
|
-
"1.10.11": {
|
|
85
|
-
"en": "BREAKING CHANGE\n\nbugs : ChannelScan is currently not available\n\n\nfix linter errors\ndisable map display for deactivated devices\nnew option on map: disable physics interaction\nnew zigbee-herdsman-converters 20.28.0\nnew zigbee-herdsman 2.1.1\nAllow use of keyless converters (used for TuYa and compatible devices in zigbee-herdsman-converters\nswap from request to axios\ndelete groups works again",
|
|
86
|
-
"de": "VERWENDUNGSBEREICH\n\nbugs : ChannelScan ist derzeit nicht verfügbar\n\n\nlinterfehler beheben\nkartenanzeige für deaktivierte geräte deaktivieren\nneue option auf der karte: physik-interaktion deaktivieren\nneue zickbee-herdsman-konverter 20.28.0\nneuer zickbee-herdsman 2.1.1\nVerwenden von schlüssellosen Wandlern (für TuYa und kompatible Geräte in Zickbee-herdsman-Konverter verwendet)\nswap von anfrage an axios\nlöschen von gruppen funktioniert wieder",
|
|
87
|
-
"ru": "ОБМЕН\n\nжуки: ChannelScan в настоящее время не доступен\n\n\nисправление ошибок\nотключить отображение карты для деактивированных устройств\nновый вариант на карте: отключить взаимодействие физики\n20.28.0\n2.1.1\nПозволить использовать бесключевые конвертеры (используемые для TuYa и совместимые устройства в zigbee-herdsman-конвертерах\nсвопа от запроса к axios\nудалить группы снова",
|
|
88
|
-
"pt": "ALTERAÇÕES DE TRABALHO\n\nbugs : ChannelScan não está disponível\n\n\ncorrigir erros do linter\ndesativar a exibição do mapa para dispositivos desativados\nnova opção no mapa: desativar a interação física\nnovos conversores de zigbee-herdsman 20.28.0\nnovo zigbee-herdsman 2.1.1\nPermitir o uso de conversores sem chave (usado para TuYa e dispositivos compatíveis em conversores de zigbee-herdsman\nswap de pedido para axios\nexcluir grupos funciona novamente",
|
|
89
|
-
"nl": "BREAKING VERANDERING\n\nbugs: ChannelScan is momenteel niet beschikbaar\n\n\nrepareren linter fouten\nkaartweergave voor gedeactiveerde apparaten uitschakelen\nnieuwe optie op de kaart: interactie natuurkunde uitschakelen\nnieuwe zigbee-herdsman-converters 20.28.0\nnieuwe zigbee-herdsman 2.1.1\nGebruik van sleutelloze converters toestaan (gebruikt voor TuYa en compatibele apparaten in zigbee-herdsman-converters\nruil van verzoek naar axios\ngroepen opnieuw verwijderen",
|
|
90
|
-
"fr": "CHANGEMENT DE BREAING\n\nbugs : ChannelScan n'est actuellement pas disponible\n\n\ncorrection des erreurs linter\ndésactiver l'affichage de la carte pour les appareils désactivés\nnouvelle option sur la carte: désactiver l'interaction physique\nnouveaux convertisseurs zigbee-herdsman 20.28.0\nnouveau zigbee-herdsman 2.1.1\nPermettre l'utilisation de convertisseurs sans clé (utilisés pour TuYa et appareils compatibles dans les convertisseurs zigbee-herdsman-converters\néchange de la demande à l'axios\nsupprimer les groupes fonctionne à nouveau",
|
|
91
|
-
"it": "CAPITOLO DI RICERCA\n\nbugs: ChannelScan non è attualmente disponibile\n\n\ncorreggere gli errori di linter\ndisabilitare la visualizzazione della mappa per i dispositivi disattivati\nnuova opzione sulla mappa: disabilitare l'interazione fisica\nnuovo zigbee-herdsman-converters 20.28.0\nnuovo zigbee-herdsman 2.1.1\nConsentire l'uso di convertitori senza chiave (utilizzati per TuYa e dispositivi compatibili in zigbee-herdsman-converter\nswap da richiesta a assios\ncancellare i gruppi funziona di nuovo",
|
|
92
|
-
"es": "BREAKING CHANGE\n\nbugs : ChannelScan actualmente no está disponible\n\n\ncorrige errores de invierno\npantalla de mapa deshabilitado para dispositivos desactivados\nnueva opción en el mapa: la interacción física deshabilitada\nnuevos zigbee-herdsman-converters 20.28.0\nnuevo zigbee-herdsman 2.1.1\nPermitir el uso de convertidores sin llave (utilizados para TuYa y dispositivos compatibles en zigbee-herdsman-converters\nswap from request to axios\neliminar grupos funciona de nuevo",
|
|
93
|
-
"pl": "ZMIANA ZBIORCZA\n\nbłędy: ChannelScan jest obecnie niedostępny\n\n\nnaprawić błędy lintera\nwyłączyć wyświetlacz mapy dla wyłączonych urządzeń\nnowa opcja na mapie: wyłączenie interakcji fizyki\nnowe konwertery zigbee- herdsman- 20.28.0\nnowy zigbee-herdsman 2.1.1\nZezwalaj na stosowanie konwerterów bezklawiszowych (używanych dla TuYa i kompatybilnych urządzeń w konwerterach zigbee- herdsman-\nzamiana z wniosku na aksjos\nusuń grupy działa ponownie",
|
|
94
|
-
"uk": "БРЕАКІНГ ЗМІН\n\nпомилки : CanalScan наразі немає\n\n\nвиправлено помилки linter\nвідключення відображення карти для деактивованих пристроїв\nновий варіант на карті: відключена фізика взаємодія\nнові zigbee-herdsman-converters 20.28.0\nновий zigbee-herdsman 2.1.1\nДозволити використання без ключів конвертерів (використовується для TuYa та сумісних пристроїв в zigbee-herdsman-converters\nковтання від запиту в осях\nвидалити групи знову",
|
|
95
|
-
"zh-cn": "破坏变化\n\n错误 : 频道扫描目前不可用\n\n\n修正线性错误\n禁用已停用设备的地图显示\n地图上的新选项: 禁用物理交互\n新齐格比-牧民-转换器 20.28.0\n新齐格比牧民 2.1.1\n允许使用无密钥转换器( 用于 TuYa 和 Zigbee- herdsman- 转换器中的兼容设备)\n从请求转换为轴\n再次删除组工作"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
package/lib/DeviceDebug.js
CHANGED
|
@@ -6,6 +6,7 @@ class DeviceDebug extends EventEmitter {
|
|
|
6
6
|
this.adapter = adapter;
|
|
7
7
|
this.dataByID = { };
|
|
8
8
|
this.dataByDevice = { };
|
|
9
|
+
this.logStatus = true;
|
|
9
10
|
|
|
10
11
|
}
|
|
11
12
|
|
|
@@ -65,14 +66,15 @@ class DeviceDebug extends EventEmitter {
|
|
|
65
66
|
target.push(item);
|
|
66
67
|
this.dataByDevice[item.deviceID] = DevData;
|
|
67
68
|
}
|
|
68
|
-
if (message.hasOwnProperty('message')) {
|
|
69
|
+
if (message.hasOwnProperty('message') && this.logStatus) {
|
|
69
70
|
this.warn(`ELEVATED:${flag} (${dataId.toString(16).slice(-4)}) ${message.message}`)
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
collectDebugData() {
|
|
76
|
+
collectDebugData(logStatus) {
|
|
77
|
+
this.logStatus = logStatus;
|
|
76
78
|
return this.dataByDevice;
|
|
77
79
|
}
|
|
78
80
|
}
|
package/lib/commands.js
CHANGED
|
@@ -156,7 +156,7 @@ class Commands {
|
|
|
156
156
|
}
|
|
157
157
|
case 'getDebugMessages':
|
|
158
158
|
if (obj) {
|
|
159
|
-
this.adapter.sendTo(obj.from, obj.command, {byId:this.adapter.deviceDebug.collectDebugData()},obj.callback);
|
|
159
|
+
this.adapter.sendTo(obj.from, obj.command, {byId:this.adapter.deviceDebug.collectDebugData( obj.message.inlog)},obj.callback);
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
}
|
|
@@ -604,7 +604,7 @@ class Commands {
|
|
|
604
604
|
async getLocalImages(from, command, msg, callback) {
|
|
605
605
|
if (this.stController) {
|
|
606
606
|
const id = msg.id;
|
|
607
|
-
const result = await this.stController.localConfig.enumerateImages(utils.getAbsoluteInstanceDataDir(this.adapter).replace('.','
|
|
607
|
+
const result = await this.stController.localConfig.enumerateImages(utils.getAbsoluteInstanceDataDir(this.adapter).replace('zigbee.','zigbee_'));
|
|
608
608
|
this.adapter.sendTo(from, command, {imageData:result}, callback)
|
|
609
609
|
}
|
|
610
610
|
}
|
|
@@ -639,6 +639,10 @@ class Commands {
|
|
|
639
639
|
const target = msg.target.replace(`${this.adapter.namespace}.`, '');
|
|
640
640
|
const entity = await this.zbController.resolveEntity(target);
|
|
641
641
|
//this.warn('entity for ' + target + ' is '+ JSON.stringify(entity))
|
|
642
|
+
if (entity && !entity.mapped) {
|
|
643
|
+
this.warn('unable to set local Override for device whithout mapped model');
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
642
646
|
if (msg.data)
|
|
643
647
|
{
|
|
644
648
|
for (const prop in msg.data) {
|
package/lib/exposes.js
CHANGED
|
@@ -885,9 +885,14 @@ function applyExposes(mappedDevices, byModel) {
|
|
|
885
885
|
}
|
|
886
886
|
}
|
|
887
887
|
|
|
888
|
-
async function applyExposeForDevice(mappedDevices, byModel, device) {
|
|
888
|
+
async function applyExposeForDevice(mappedDevices, byModel, device, logger) {
|
|
889
|
+
const t = Date.now();
|
|
889
890
|
const deviceDef = await zigbeeHerdsmanConverters.findByDevice(device);
|
|
890
|
-
if (!deviceDef)
|
|
891
|
+
if (!deviceDef) {
|
|
892
|
+
//logger.warn(`ZHC02,${Date.now()},${Date.now()-t},${device && device.ieeeAddr ? device.ieeeAddr : '0x0'}, failed`);
|
|
893
|
+
return false;
|
|
894
|
+
}
|
|
895
|
+
//logger.warn(`ZHC02,${Date.now()},${Date.now()-t},${device && device.ieeeAddr ? device.ieeeAddr : '0x0'}, passed`);
|
|
891
896
|
applyDeviceDef(mappedDevices, byModel, deviceDef, device);
|
|
892
897
|
return true;
|
|
893
898
|
}
|
package/lib/localConfig.js
CHANGED
|
@@ -138,7 +138,7 @@ class localConfig extends EventEmitter {
|
|
|
138
138
|
try {
|
|
139
139
|
this.adapter.fileExists(namespace, rv, (err, result) => {
|
|
140
140
|
if (result) return;
|
|
141
|
-
const src = this.adapter.expandFileName(iconPath).replace('.','
|
|
141
|
+
const src = this.adapter.expandFileName(iconPath).replace('zigbee.','zigbee_');
|
|
142
142
|
fs.readFile(src, (err, data) => {
|
|
143
143
|
if (err) {
|
|
144
144
|
this.error('unable to read ' + src + ' : '+ (err && err.message? err.message:' no message given'))
|
|
@@ -220,7 +220,7 @@ class localConfig extends EventEmitter {
|
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
async updateFromDeviceNames() {
|
|
223
|
-
const fn = this.adapter.expandFileName('dev_names').replace('.', '
|
|
223
|
+
const fn = this.adapter.expandFileName('dev_names').replace('zigbee.', 'zigbee_').concat('.json');
|
|
224
224
|
fs.readFile(fn, (err, content) => {
|
|
225
225
|
if (!err) {
|
|
226
226
|
let data_js = {};
|
|
@@ -249,7 +249,7 @@ class localConfig extends EventEmitter {
|
|
|
249
249
|
|
|
250
250
|
async init() {
|
|
251
251
|
this.info('init localConfig');
|
|
252
|
-
const fn = this.adapter.expandFileName('LocalOverrides').replace('.','
|
|
252
|
+
const fn = this.adapter.expandFileName('LocalOverrides').replace('zigbee.','zigbee_').concat('.json');
|
|
253
253
|
this.filename = fn;
|
|
254
254
|
this.basefolder = path.dirname(fn);
|
|
255
255
|
|
package/lib/statescontroller.js
CHANGED
|
@@ -466,8 +466,10 @@ class StatesController extends EventEmitter {
|
|
|
466
466
|
}
|
|
467
467
|
}
|
|
468
468
|
} else {
|
|
469
|
-
|
|
470
|
-
|
|
469
|
+
if (!markOnly) {
|
|
470
|
+
this.debug(`keeping connected state ${JSON.stringify(statename)} of ${devId} `);
|
|
471
|
+
messages.push(`keeping connecte state ${JSON.stringify(statename)} of ${devId} `);
|
|
472
|
+
}
|
|
471
473
|
}
|
|
472
474
|
});
|
|
473
475
|
}
|
|
@@ -578,7 +580,7 @@ class StatesController extends EventEmitter {
|
|
|
578
580
|
value = minval
|
|
579
581
|
if (!this.stashedErrors.hasOwnProperty(`${stateId}.min`))
|
|
580
582
|
{
|
|
581
|
-
this.
|
|
583
|
+
this.warn(`State value for ${stateId} has value "${nval}" less than min "${minval}". - this eror is recorded and not repeated`);
|
|
582
584
|
this.stashedErrors[`${stateId}.min`] = `State value for ${stateId} has value "${nval}." less than min "${minval}"`;
|
|
583
585
|
}
|
|
584
586
|
}
|
|
@@ -589,7 +591,7 @@ class StatesController extends EventEmitter {
|
|
|
589
591
|
value = maxval;
|
|
590
592
|
if (!this.stashedErrors.hasOwnProperty(`${stateId}.max`))
|
|
591
593
|
{
|
|
592
|
-
this.
|
|
594
|
+
this.warn(`State value for ${stateId} has value "${nval}" more than max "${maxval}". - this eror is recorded and not repeated`);
|
|
593
595
|
this.stashedErrors[`${stateId}.max`] = `State value for ${stateId} has value "${nval}" more than max "${maxval}".`;
|
|
594
596
|
}
|
|
595
597
|
}
|
package/lib/zbDeviceConfigure.js
CHANGED
|
@@ -12,75 +12,75 @@ class DeviceConfigure extends BaseExtension {
|
|
|
12
12
|
this.delayedConfigure = {};
|
|
13
13
|
|
|
14
14
|
this.configuring = new Set();
|
|
15
|
-
this.
|
|
15
|
+
this.configureOnMessage = new Set();
|
|
16
|
+
this.configureOnMessageAttempts = {};
|
|
16
17
|
this.name = 'DeviceConfigure';
|
|
17
18
|
|
|
18
|
-
this.
|
|
19
|
+
this.MessageStash = [];
|
|
20
|
+
this.deviceConfigureQueue = [];
|
|
21
|
+
this.configureIntervall = null;
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
setOptions(options) {
|
|
22
25
|
return typeof options === 'object';
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return
|
|
28
|
+
async handleConfigureQueue() {
|
|
29
|
+
if (this.deviceConfigureQueue.length < 1) {
|
|
30
|
+
this.info('Handled all devices Queued for configuration.')
|
|
31
|
+
clearInterval(this.configureIntervall);
|
|
32
|
+
this.configureIntervall == null;
|
|
33
|
+
return;
|
|
31
34
|
}
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (device.meta.hasOwnProperty('configured') && device.meta.configured !== this.configureKeys[device.ieeeAddr]) return true;
|
|
36
|
-
return (device.interviewing !== true && this.checkDelayedConfigure(device)>0);
|
|
35
|
+
const configureItem = this.deviceConfigureQueue.shift();
|
|
36
|
+
this.info(`DeviceConfigureQueue configuring ${configureItem.dev.ieeeAddr} ${configureItem.dev.modelID}`)
|
|
37
|
+
this.doConfigure(configureItem.dev, configureItem.mapped);
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.
|
|
44
|
-
return
|
|
40
|
+
PushDeviceToQueue(device, mappedDevice) {
|
|
41
|
+
const id = device.ieeeAddr;
|
|
42
|
+
for (const candidate of this.deviceConfigureQueue) {
|
|
43
|
+
if (candidate.id == id) {
|
|
44
|
+
this.debug('no duplicate entry in queue');
|
|
45
|
+
return;
|
|
45
46
|
}
|
|
46
|
-
return 0;
|
|
47
|
-
}
|
|
48
|
-
const dc = this.delayedConfigure[device.ieeeAddr];
|
|
49
|
-
// this.warn('checkDelayedConfigure for ' + device.ieeeAddr + ' with ' + JSON.stringify(dc));
|
|
50
|
-
dc.maxAttempts--;
|
|
51
|
-
if (dc.maxAttempts > 0) return dc.maxAttempts;
|
|
52
|
-
if (num && num > 0) {
|
|
53
|
-
dc.maxAttempts = num;
|
|
54
|
-
return num;
|
|
55
47
|
}
|
|
56
|
-
|
|
48
|
+
this.deviceConfigureQueue.push({ id: device.ieeeAddr, dev:device, mapped:mappedDevice });
|
|
49
|
+
if (this.configureIntervall) return;
|
|
50
|
+
this.configureIntervall = setInterval(async () => await this.handleConfigureQueue(), 5000);
|
|
57
51
|
}
|
|
58
52
|
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
return 0;
|
|
53
|
+
shouldConfigure(device, mappedDevice) {
|
|
54
|
+
if (!device || !mappedDevice) {
|
|
55
|
+
return false;
|
|
63
56
|
}
|
|
64
|
-
|
|
57
|
+
if (!mappedDevice || !mappedDevice.configure) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
// no configuration if we are interviewing or configuring
|
|
61
|
+
if (this.configuring.has(device.ieeeAddr) || device.interviewing) return false;
|
|
62
|
+
const t = Date.now();
|
|
63
|
+
const cfgkey = zigbeeHerdsmanConverters.getConfigureKey(mappedDevice);
|
|
64
|
+
const result = device.meta.hasOwnProperty('configured') && device.meta.configured !== cfgkey;
|
|
65
|
+
this.debug(`should configure for device ${device.ieeeAddr} (${mappedDevice.model}: ${device.meta.hasOwnProperty('configured') ? device.meta.configured: 'none'} - ${cfgkey} (query took ${Date.now()- t} ms)`);
|
|
66
|
+
return result;
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
|
|
68
69
|
async onZigbeeStarted() {
|
|
69
70
|
try {
|
|
70
71
|
this.coordinatorEndpoint = await this.zigbee.getDevicesByType('Coordinator')[0].endpoints[0];
|
|
71
72
|
|
|
72
73
|
for (const device of await this.zigbee.getClients()) {
|
|
73
74
|
const mappedDevice = await zigbeeHerdsmanConverters.findByDevice(device);
|
|
74
|
-
|
|
75
75
|
if (forcedConfigureOnEachStart.find((d) => d && d.hasOwnProperty('zigbeeModel') && d.zigbeeModel.includes(device.modelID))) {
|
|
76
|
-
this.debug(`DeviceConfigure ${device.ieeeAddr} ${device.modelID} forced by adapter config`);
|
|
76
|
+
this.debug(`DeviceConfigure ${device.ieeeAddr} ${mappedDevice ? mappedDevice.model : device.modelID} forced by adapter config`);
|
|
77
77
|
device.meta.configured = -1; // Force a reconfiguration for this device
|
|
78
78
|
}
|
|
79
79
|
if (this.shouldConfigure(device, mappedDevice)) {
|
|
80
|
-
this.
|
|
81
|
-
await this.
|
|
80
|
+
this.info(`DeviceConfigure ${device.ieeeAddr} ${mappedDevice ? mappedDevice.model : device.modelID} needed - Device added to Configuration Queue`);
|
|
81
|
+
await this.PushDeviceToQueue(device, mappedDevice);
|
|
82
82
|
} else {
|
|
83
|
-
this.debug(`DeviceConfigure ${device.ieeeAddr} ${device.modelID} not needed`);
|
|
83
|
+
this.debug(`DeviceConfigure ${device.ieeeAddr} ${mappedDevice ? mappedDevice.model : device.modelID} not needed`);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
} catch (error) {
|
|
@@ -92,9 +92,14 @@ class DeviceConfigure extends BaseExtension {
|
|
|
92
92
|
onZigbeeEvent(data, mappedDevice) {
|
|
93
93
|
try {
|
|
94
94
|
const device = data.device;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
this.configure(
|
|
95
|
+
const com = this.configureOnMessageAttempts[device.ieeeAddr];
|
|
96
|
+
if (com) {
|
|
97
|
+
this.info(`checking configure on message : next attempt in ${30000 - (Date.now() - com.timestamp)} seconds`);
|
|
98
|
+
if (Date.now() - com.timestamp > 30000 && !this.configuring.has(device.ieeeAddr)) {
|
|
99
|
+
com.timestamp = Date.now();
|
|
100
|
+
this.info('Configure on Message for ' + device.ieeeAddr);
|
|
101
|
+
this.doConfigure(device, mappedDevice);
|
|
102
|
+
}
|
|
98
103
|
}
|
|
99
104
|
} catch (error) {
|
|
100
105
|
this.sendError(error);
|
|
@@ -109,8 +114,8 @@ class DeviceConfigure extends BaseExtension {
|
|
|
109
114
|
this.configuring.delete(device.ieeeAddr);
|
|
110
115
|
}
|
|
111
116
|
|
|
112
|
-
if (this.
|
|
113
|
-
delete this.
|
|
117
|
+
if (this.configureOnMessageAttempts && this.configureOnMessageAttempts.hasOwnProperty(device.ieeeAddr)) {
|
|
118
|
+
delete this.configureOnMessageAttempts[device.ieeeAddr];
|
|
114
119
|
}
|
|
115
120
|
} catch (error) {
|
|
116
121
|
this.sendError(error);
|
|
@@ -129,16 +134,17 @@ class DeviceConfigure extends BaseExtension {
|
|
|
129
134
|
async configure(device, mappedDevice) {
|
|
130
135
|
try {
|
|
131
136
|
if (mappedDevice !== undefined && device !== undefined) {
|
|
137
|
+
|
|
132
138
|
try {
|
|
133
139
|
await this.doConfigure(device, mappedDevice)
|
|
134
140
|
} catch (error) {
|
|
135
141
|
this.sendError(error);
|
|
136
|
-
this.warn(`DeviceConfigure failed ${device.ieeeAddr} ${
|
|
142
|
+
this.warn(`DeviceConfigure failed ${device.ieeeAddr} ${mappedDevice.model}`);
|
|
137
143
|
}
|
|
138
144
|
}
|
|
139
145
|
} catch (error) {
|
|
140
146
|
this.sendError(error);
|
|
141
|
-
this.error(`Failed to DeviceConfigure.configure ${device.ieeeAddr} ${
|
|
147
|
+
this.error(`Failed to DeviceConfigure.configure ${device.ieeeAddr} ${mappedDevice.model}: ${error && error.message ? error.message : 'no error message'})`);
|
|
142
148
|
}
|
|
143
149
|
}
|
|
144
150
|
|
|
@@ -146,8 +152,9 @@ class DeviceConfigure extends BaseExtension {
|
|
|
146
152
|
const coordinatorEndpoint = await this.zigbee.getDevicesByType('Coordinator')[0].endpoints[0];
|
|
147
153
|
try {
|
|
148
154
|
if (mappedDevice) {
|
|
149
|
-
if (mappedDevice.configure === undefined) return `No configure available for ${device.ieeeAddr} ${
|
|
150
|
-
this.info(`Configuring ${device.ieeeAddr} ${
|
|
155
|
+
if (mappedDevice.configure === undefined) return `No configure available for ${device.ieeeAddr} ${mappedDevice.model}.`;
|
|
156
|
+
this.info(`Configuring ${device.ieeeAddr} ${mappedDevice.model}`);
|
|
157
|
+
this.configuring.add(device.ieeeAddr);
|
|
151
158
|
if (typeof mappedDevice.configure === 'function') await mappedDevice.configure(device, coordinatorEndpoint, this);
|
|
152
159
|
else {
|
|
153
160
|
const promises = [];
|
|
@@ -155,26 +162,41 @@ class DeviceConfigure extends BaseExtension {
|
|
|
155
162
|
await Promise.all(promises.map(callback => callback(device, coordinatorEndpoint, mappedDevice)))
|
|
156
163
|
}
|
|
157
164
|
device.meta.configured = zigbeeHerdsmanConverters.getConfigureKey(mappedDevice);
|
|
158
|
-
this.
|
|
165
|
+
this.configuring.delete(device.ieeeAddr);
|
|
166
|
+
delete this.configureOnMessageAttempts[device.ieeeAddr];
|
|
159
167
|
device.save();
|
|
160
|
-
this.info(`DeviceConfigure successful ${device.ieeeAddr} ${
|
|
161
|
-
this.delayedConfigureAttempt(device, true);
|
|
168
|
+
this.info(`DeviceConfigure successful ${device.ieeeAddr} ${mappedDevice.model}`);
|
|
162
169
|
return '';
|
|
163
170
|
}
|
|
164
171
|
} catch (error) {
|
|
172
|
+
this.configuring.delete(device.ieeeAddr);
|
|
165
173
|
// https://github.com/Koenkk/zigbee2mqtt/issues/14857
|
|
166
174
|
if (error.stack.includes('UNSUPPORTED_ATTRIBUTE')) {
|
|
175
|
+
this.debug(`Configuration attempt on ${device.ieeeAddr} ${mappedDevice.model} with unsupported Attribute(s) : ${error.message}`)
|
|
167
176
|
// do nothing
|
|
168
177
|
} else {
|
|
169
178
|
if (error && error.message && error.message.match(/(\d+)ms/gm)) {
|
|
170
179
|
// timeout message - we do want to start the configure chain
|
|
171
|
-
|
|
172
|
-
|
|
180
|
+
if (this.configureOnMessageAttempts.hasOwnProperty(device.ieeeAddr)) {
|
|
181
|
+
const com = this.configureOnMessageAttempts[device.ieeeAddr];
|
|
182
|
+
com.count--;
|
|
183
|
+
com.timestamp = Date.now();
|
|
184
|
+
this.info(`Timeout trying to configure ${device.ieeeAddr} ${mappedDevice.model} (${com.count}).`)
|
|
185
|
+
if ( com.count < 0) delete this.configureOnMessage[device.ieeeAddr];
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
this.info(`Timeout trying to configure ${device.ieeeAddr} ${mappedDevice.model} (starting CoM).`)
|
|
189
|
+
this.configureOnMessageAttempts[device.ieeeAddr] = {
|
|
190
|
+
count: 5,
|
|
191
|
+
timestamp: 0,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
173
194
|
return `Configuration timed out ${device.ieeeAddr} ${device.modelID}. The device did not repond in time to the configuration request. Another attempt will be made when the device is awake.`;
|
|
174
195
|
} else {
|
|
175
196
|
this.sendError(error);
|
|
176
|
-
|
|
177
|
-
|
|
197
|
+
const msg = `${device.ieeeAddr} ${device.modelID} Failed to configure. --> ${error && error.message ? error.message : ' no error message given'}`
|
|
198
|
+
this.warn(msg);
|
|
199
|
+
return msg;
|
|
178
200
|
}
|
|
179
201
|
|
|
180
202
|
|
|
@@ -182,6 +204,11 @@ class DeviceConfigure extends BaseExtension {
|
|
|
182
204
|
}
|
|
183
205
|
return 'no return value specified';
|
|
184
206
|
}
|
|
207
|
+
|
|
208
|
+
async stop() {
|
|
209
|
+
clearInterval(this.configureIntervall);
|
|
210
|
+
this.configureOnMessageAttempts = {};
|
|
211
|
+
}
|
|
185
212
|
}
|
|
186
213
|
|
|
187
214
|
module.exports = DeviceConfigure;
|
package/lib/zigbeecontroller.js
CHANGED
|
@@ -65,6 +65,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
65
65
|
super();
|
|
66
66
|
this.adapter = adapter;
|
|
67
67
|
this._permitJoinTime = 0;
|
|
68
|
+
this.transmitPower = 0;
|
|
68
69
|
this.herdsmanStarted = false;
|
|
69
70
|
this.extensions = [
|
|
70
71
|
new DeviceAvailabilityExt(this, {}),
|
|
@@ -74,19 +75,41 @@ class ZigbeeController extends EventEmitter {
|
|
|
74
75
|
];
|
|
75
76
|
this.herdsmanTimeoutRegexp = new RegExp(/(\d+)ms/);
|
|
76
77
|
this.herdsmanLogSettings = {}
|
|
78
|
+
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
|
|
80
82
|
ByteArrayToString(data) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
if (data) {
|
|
84
|
+
return data.map(function (x) {
|
|
85
|
+
x = x + 0x100 + 1; // twos complement
|
|
86
|
+
x = x.toString(16); // to hex
|
|
87
|
+
x = ('00'+x).substr(-2); // zero-pad to 8-digits
|
|
88
|
+
return x
|
|
89
|
+
}).join('');
|
|
90
|
+
}
|
|
91
|
+
else return '';
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
configure(options) {
|
|
95
|
+
|
|
96
|
+
if (options.transmitPower != undefined) {
|
|
97
|
+
this.transmitPower = options.transmitPower;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.powerText = '';
|
|
101
|
+
if (this.transmitPower !== '0') {
|
|
102
|
+
const powerLevels = {
|
|
103
|
+
'-22': 'low',
|
|
104
|
+
'19': 'high',
|
|
105
|
+
'20': 'high+'
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
this.powerText = powerLevels[this.transmitPower] || 'normal';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
this.info(` --> transmitPower : ${this.powerText}`);
|
|
112
|
+
|
|
90
113
|
const herdsmanSettings = {
|
|
91
114
|
network: {
|
|
92
115
|
panID: options.net.panId,
|
|
@@ -102,6 +125,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
102
125
|
path: options.sp.port,
|
|
103
126
|
adapter: options.sp.adapter,
|
|
104
127
|
},
|
|
128
|
+
transmitpower: this.transmitPower,
|
|
105
129
|
adapter: {
|
|
106
130
|
forceStartWithInconsistentAdapterConfiguration: options.startWithInconsistent
|
|
107
131
|
},
|
|
@@ -114,11 +138,6 @@ class ZigbeeController extends EventEmitter {
|
|
|
114
138
|
herdsmanSettings.network.extenedPanID = options.net.extPanId;
|
|
115
139
|
}
|
|
116
140
|
|
|
117
|
-
if (options.transmitPower == undefined) {
|
|
118
|
-
this.transmitPower = 0;
|
|
119
|
-
} else {
|
|
120
|
-
this.transmitPower = options.transmitPower;
|
|
121
|
-
}
|
|
122
141
|
this.disableLed = options.disableLed;
|
|
123
142
|
this.warnOnDeviceAnnouncement = options.warnOnDeviceAnnouncement;
|
|
124
143
|
this.herdsmanLogSettings.panID = herdsmanSettings.network.panID;
|
|
@@ -204,35 +223,6 @@ class ZigbeeController extends EventEmitter {
|
|
|
204
223
|
this.sendError(e);
|
|
205
224
|
}
|
|
206
225
|
|
|
207
|
-
// only for CC1352P and CC26X2R1 transmit power
|
|
208
|
-
let powerText = 'normal';
|
|
209
|
-
|
|
210
|
-
if (this.transmitPower != '0') {
|
|
211
|
-
switch (this.transmitPower) {
|
|
212
|
-
case '-22':
|
|
213
|
-
powerText = 'low';
|
|
214
|
-
break;
|
|
215
|
-
case '19':
|
|
216
|
-
powerText = 'high';
|
|
217
|
-
break;
|
|
218
|
-
case '20':
|
|
219
|
-
powerText = 'high+';
|
|
220
|
-
break;
|
|
221
|
-
default:
|
|
222
|
-
powerText = 'normal';
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
this.info(` --> transmitPower : ${powerText}`);
|
|
228
|
-
try {
|
|
229
|
-
await this.herdsman.setTransmitPower(this.transmitPower);
|
|
230
|
-
} catch (e) {
|
|
231
|
-
this.sendError(e);
|
|
232
|
-
this.info('Unable to set transmit power, unsupported function.');
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// Call extensions
|
|
236
226
|
|
|
237
227
|
const deviceIterator = this.getClientIterator();
|
|
238
228
|
let deviceCount = 0;
|
|
@@ -575,6 +565,7 @@ class ZigbeeController extends EventEmitter {
|
|
|
575
565
|
if (_key.kind === 'ieee') _key.key = await this.herdsman.getDeviceByIeeeAddr(_key.key);
|
|
576
566
|
const device = _key.key;
|
|
577
567
|
if (device) {
|
|
568
|
+
const t = Date.now();
|
|
578
569
|
const mapped = await zigbeeHerdsmanConverters.findByDevice(device);
|
|
579
570
|
const endpoints = mapped && mapped.endpoint ? mapped.endpoint(device) : null;
|
|
580
571
|
let endpoint;
|
package/main.js
CHANGED
|
@@ -307,7 +307,7 @@ class Zigbee extends utils.Adapter {
|
|
|
307
307
|
require,
|
|
308
308
|
module: {},
|
|
309
309
|
};
|
|
310
|
-
const mN = (fs.existsSync(moduleName) ? moduleName : this.expandFileName(moduleName).replace('.', '
|
|
310
|
+
const mN = (fs.existsSync(moduleName) ? moduleName : this.expandFileName(moduleName).replace('zigbee.', 'zigbee_'));
|
|
311
311
|
if (!fs.existsSync(mN)) {
|
|
312
312
|
this.log.warn(`External converter not loaded - neither ${moduleName} nor ${mN} exist.`);
|
|
313
313
|
}
|
|
@@ -373,25 +373,15 @@ class Zigbee extends utils.Adapter {
|
|
|
373
373
|
const toAdd = {...definition};
|
|
374
374
|
delete toAdd['homeassistant'];
|
|
375
375
|
try {
|
|
376
|
+
const t = Date.now();
|
|
376
377
|
if (zigbeeHerdsmanConverters.hasOwnProperty('addExternalDefinition')) {
|
|
377
378
|
zigbeeHerdsmanConverters.addExternalDefinition(toAdd);
|
|
378
|
-
this.log.info(
|
|
379
|
+
this.log.info(`added external converter using addExternalDefinition (${Date.now()-t} ms)`)
|
|
379
380
|
}
|
|
380
381
|
else if (zigbeeHerdsmanConverters.hasOwnProperty('addDefinition')) {
|
|
381
382
|
zigbeeHerdsmanConverters.addDefinition(toAdd);
|
|
382
|
-
this.log.info(
|
|
383
|
+
this.log.info(`added external converter using addDefinition (${Date.now()-t} ms)`);
|
|
383
384
|
}
|
|
384
|
-
|
|
385
|
-
/*
|
|
386
|
-
for (const zigbeeModel of toAdd.zigbeeModel)
|
|
387
|
-
{
|
|
388
|
-
try {
|
|
389
|
-
zigbeeHerdsmanConverters.addToExternalDefinitionsLookup(zigbeeModel, toAdd.toAdd);
|
|
390
|
-
} catch (e) {
|
|
391
|
-
this.log.error(`unable to apply external converter ${JSON.stringify(toAdd)} for device ${zigbeeModel}: ${e && e.message ? e.message : 'no error message available'}`);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
*/
|
|
395
385
|
} catch (e) {
|
|
396
386
|
this.log.error(`unable to apply external converter for ${JSON.stringify(toAdd.model)}: ${e && e.message ? e.message : 'no error message available'}`);
|
|
397
387
|
}
|
|
@@ -660,8 +650,8 @@ class Zigbee extends utils.Adapter {
|
|
|
660
650
|
if (stateDesc.isOption || stateDesc.compositeState) {
|
|
661
651
|
// acknowledge state with given value
|
|
662
652
|
if (has_elevated_debug) {
|
|
663
|
-
|
|
664
|
-
this.emit('device_debug', { ID:debugID, data: { flag: 'cc', states:[{id:stateDesc.id, value:value, payload:'none (OC State)'}] , IO:false }});
|
|
653
|
+
const message = 'changed state: ' + JSON.stringify(changedState);
|
|
654
|
+
this.emit('device_debug', { ID:debugID, data: { flag: 'cc', states:[{id:stateDesc.id, value:value, payload:'none (OC State)'}] , IO:false }, message:message});
|
|
665
655
|
}
|
|
666
656
|
else
|
|
667
657
|
this.log.debug('changed composite state: ' + JSON.stringify(changedState));
|
|
@@ -670,21 +660,16 @@ class Zigbee extends utils.Adapter {
|
|
|
670
660
|
if (stateDesc.compositeState && stateDesc.compositeTimeout) {
|
|
671
661
|
this.stController.triggerComposite(deviceId, model, stateDesc, changedState.source.includes('.admin.'));
|
|
672
662
|
}
|
|
673
|
-
// process sync state list
|
|
674
|
-
//this.processSyncStatesList(deviceId, modelId, syncStateList);
|
|
675
|
-
// if this is the device query state => trigger the device query
|
|
676
|
-
|
|
677
663
|
// on activation of the 'device_query' state trigger hardware query where possible
|
|
678
664
|
if (stateDesc.id === 'device_query') {
|
|
679
665
|
if (this.query_device_block.indexOf(deviceId) > -1) {
|
|
680
|
-
this.log.
|
|
666
|
+
this.log.info(`Device query for '${entity.device.ieeeAddr}' blocked`);
|
|
681
667
|
return;
|
|
682
668
|
}
|
|
683
669
|
if (mappedModel) {
|
|
684
670
|
this.query_device_block.push(deviceId);
|
|
685
671
|
if (has_elevated_debug) {
|
|
686
672
|
const message = `Device query for '${entity.device.ieeeAddr}/${entity.device.endpoints[0].ID}' triggered`;
|
|
687
|
-
//this.log.warn(`ELEVATED O06: ${message}`);
|
|
688
673
|
this.emit('device_debug', { ID:debugID, data: { flag: 'qs' ,states:[{id:stateDesc.id, value:value, payload:'none for device query'}], IO:false }, message:message});
|
|
689
674
|
}
|
|
690
675
|
else
|
|
@@ -708,7 +693,6 @@ class Zigbee extends utils.Adapter {
|
|
|
708
693
|
}
|
|
709
694
|
if (has_elevated_debug) {
|
|
710
695
|
const message = `ELEVATED O07: Device query for '${entity.device.ieeeAddr}/${entity.device.endpoints[0].ID}' complete`;
|
|
711
|
-
//this.log.warn(`ELEVATED O07: ${message}`);
|
|
712
696
|
this.emit('device_debug', { ID:debugID, data: { flag: 'qe' , IO:false }, message:message});
|
|
713
697
|
}
|
|
714
698
|
else
|
|
@@ -833,7 +817,6 @@ class Zigbee extends utils.Adapter {
|
|
|
833
817
|
}
|
|
834
818
|
}
|
|
835
819
|
if (has_elevated_debug) {
|
|
836
|
-
//this.log.warn('epname is ' + epName + ' or ' + stateDesc.epname);
|
|
837
820
|
this.emit('device_debug', { ID:debugID, data: { states:[{id:stateDesc.id, value:value, payload:preparedValue, ep:stateDesc.epname}] , IO:false }});
|
|
838
821
|
}
|
|
839
822
|
|
|
@@ -986,13 +969,18 @@ class Zigbee extends utils.Adapter {
|
|
|
986
969
|
|
|
987
970
|
|
|
988
971
|
newDevice(entity) {
|
|
989
|
-
this.log.debug(`New device event: ${safeJsonStringify(entity)}`);
|
|
990
|
-
this.stController.AddModelFromHerdsman(entity.device, entity.mapped.model)
|
|
991
972
|
const dev = entity.device;
|
|
973
|
+
const model = (entity.mapped) ? entity.mapped.model : dev.modelID;
|
|
974
|
+
this.log.debug(`New device event: ${safeJsonStringify(entity)}`);
|
|
975
|
+
if (!entity.mapped && !entity.device.interviewing) {
|
|
976
|
+
const msg = `New device: '${dev.ieeeAddr}' does not have a known model. please provide an external converter for '${dev.modelID}'.`;
|
|
977
|
+
this.log.warn(msg);
|
|
978
|
+
this.logToPairing(msg, true);
|
|
979
|
+
}
|
|
980
|
+
this.stController.AddModelFromHerdsman(entity.device, model)
|
|
992
981
|
if (dev) {
|
|
993
982
|
this.getObject(dev.ieeeAddr.substr(2), (err, obj) => {
|
|
994
983
|
if (!obj) {
|
|
995
|
-
const model = (entity.mapped) ? entity.mapped.model : entity.device.modelID;
|
|
996
984
|
this.log.debug(`new device ${dev.ieeeAddr} ${dev.networkAddress} ${model} `);
|
|
997
985
|
this.logToPairing(`New device joined '${dev.ieeeAddr}' model ${model}`, true);
|
|
998
986
|
this.stController.updateDev(dev.ieeeAddr.substr(2), model, model, () =>
|
|
@@ -1061,7 +1049,7 @@ class Zigbee extends utils.Adapter {
|
|
|
1061
1049
|
getZigbeeOptions() {
|
|
1062
1050
|
// file path for db
|
|
1063
1051
|
let dbDir = path.join(utils.getAbsoluteInstanceDataDir(this), '');
|
|
1064
|
-
dbDir = dbDir.replace('.', '
|
|
1052
|
+
dbDir = dbDir.replace('zigbee.', 'zigbee_');
|
|
1065
1053
|
|
|
1066
1054
|
if (this.systemConfig && !fs.existsSync(dbDir)) {
|
|
1067
1055
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.zigbee",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.5",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Kirov Ilya",
|
|
6
6
|
"email": "kirovilya@gmail.com"
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"ajv": "^8.17.1",
|
|
29
29
|
"uri-js": "^4.4.1",
|
|
30
30
|
"typescript": "^5.6.3",
|
|
31
|
-
"zigbee-herdsman": "3.
|
|
32
|
-
"zigbee-herdsman-converters": "23.
|
|
31
|
+
"zigbee-herdsman": "^3.3.0",
|
|
32
|
+
"zigbee-herdsman-converters": "23.6.0"
|
|
33
33
|
},
|
|
34
34
|
"description": "Zigbee devices",
|
|
35
35
|
"devDependencies": {
|
|
@@ -47,7 +47,8 @@
|
|
|
47
47
|
"gulp-jsdoc3": "^3.0.0",
|
|
48
48
|
"gulp-replace": "^1.1.4",
|
|
49
49
|
"mixin-deep": "^2.0.1",
|
|
50
|
-
"mocha": "^11.1.0"
|
|
50
|
+
"mocha": "^11.1.0",
|
|
51
|
+
"@iobroker/dev-server": "^0.7.8"
|
|
51
52
|
},
|
|
52
53
|
"homepage": "https://github.com/ioBroker/ioBroker.zigbee",
|
|
53
54
|
"keywords": [
|
|
@@ -85,7 +86,6 @@
|
|
|
85
86
|
"test:package": "mocha test/package --exit",
|
|
86
87
|
"test:unit": "mocha test/unit --exit",
|
|
87
88
|
"test:integration": "mocha test/integration --exit",
|
|
88
|
-
"watch:parcel": "parcel admin/src/index.tsx -d admin/build --hmr-port 1235",
|
|
89
89
|
"test:js": "mocha --opts test/mocha.custom.opts",
|
|
90
90
|
"lint": "eslint .",
|
|
91
91
|
"release": "release-script",
|