iobroker.zigbee 3.3.2 → 3.3.3
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 +6 -0
- package/io-package.json +14 -14
- package/lib/exposes.js +32 -13
- package/lib/statescontroller.js +6 -1
- package/lib/zigbeecontroller.js +11 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -141,6 +141,12 @@ You can thank the authors by these links:
|
|
|
141
141
|
|
|
142
142
|
-----------------------------------------------------------------------------------------------------
|
|
143
143
|
## Changelog
|
|
144
|
+
### 3.3.3 (2026-01-11)
|
|
145
|
+
* Fix crash bug
|
|
146
|
+
* getter for composite states V1
|
|
147
|
+
* zhc
|
|
148
|
+
*
|
|
149
|
+
|
|
144
150
|
### 3.3.2 (2026-01-04)
|
|
145
151
|
* Fix sync brightness / state
|
|
146
152
|
* Fix bug in expose
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "zigbee",
|
|
4
|
-
"version": "3.3.
|
|
4
|
+
"version": "3.3.3",
|
|
5
5
|
"news": {
|
|
6
|
+
"3.3.3": {
|
|
7
|
+
"en": "Fix crash bug\ngetter for composite states V1\nzhc\n",
|
|
8
|
+
"de": "Fehler behoben\ngetter für zusammengesetzte Zustände V1\nzh\n",
|
|
9
|
+
"ru": "Исправить ошибку crash bug\nгеттер для композитных состояний V1\nджк\n",
|
|
10
|
+
"pt": "Corrigir erro de falha\ngetter para estados compostos V1\nzhc\n",
|
|
11
|
+
"nl": "Fix crash bug\ngetter voor samengestelde toestanden V1\nzhc\n",
|
|
12
|
+
"fr": "Correction d'un bug de plantage\ngetter pour les états composites V1\nzhc\n",
|
|
13
|
+
"it": "Correre bug crash\ngetter per stati compositi V1\nzhc\n",
|
|
14
|
+
"es": "Corrección de fallo\ngetter para estados compuestos V1\nzhc\n",
|
|
15
|
+
"pl": "Napraw błąd awarii\ngetter for composite states V1\nzhc\n",
|
|
16
|
+
"uk": "Виправлення помилки збою\nоберт для композитних станів V1\nжк\n",
|
|
17
|
+
"zh-cn": "修复崩溃错误\nv1 复合状态获取器\n日语\n"
|
|
18
|
+
},
|
|
6
19
|
"3.3.2": {
|
|
7
20
|
"en": "Fix sync brightness / state\nFix bug in expose\nFix rewrite state config\n",
|
|
8
21
|
"de": "Synchronisierhelligkeit / Zustand\nFehler behoben in exponieren\nRewriting State config\n",
|
|
@@ -80,19 +93,6 @@
|
|
|
80
93
|
"pl": "Ulepszenia dotyczące debugowania interfejsu użytkownika\nOpcja \"resend _ states\" do publikowania wartości stanu dla urządzenia przy ponownym połączeniu\nUlepszona karta grupowa\nUlepszone informacje grupowe\nZmodyfikowana karta koordynatora (2 strony)\nponowna próba błędu 25\njasne komunikaty błędów ukryte\nZHC 25.50.0 lub nowsze",
|
|
81
94
|
"uk": "Удосконалення на дебурзі UI\nВаріант 'resend_states' для публікації державних значень для пристрою на відключенні\nПокращена групова карта\nПокращена інформація групи\nЗмінена карта координатора (2 сторони)\nптиця по помилки 25\nчіткі повідомлення про помилку\nZHC 25.50.0 або новачок",
|
|
82
95
|
"zh-cn": "调试 UI 的改进\n选项“ resend_ states ” 以在重新连接时发布状态值以设备\n改进组卡\n改进组信息\n修改的协调员卡(2面)\n重试错误 25\n清除隐藏的错误消息\nZHC 25.50.0或更新"
|
|
83
|
-
},
|
|
84
|
-
"3.2.2": {
|
|
85
|
-
"en": "Bugfix on delete object.\nimproved device query.\nfixed delete device with local overrides.\n",
|
|
86
|
-
"de": "Bugfix auf Löschobjekt.\nverbesserte geräteabfrage.\nfeste löschvorrichtung mit lokalen overrides.\n",
|
|
87
|
-
"ru": "Bugfix для удаления объекта.\nулучшенный запрос устройства.\nфиксированное устройство удаления с локальными переопределениями.\n",
|
|
88
|
-
"pt": "Correcção de erros ao apagar o objecto.\npesquisa de dispositivos melhorada.\ndispositivo de exclusão fixo com substituições locais.\n",
|
|
89
|
-
"nl": "Bugfix bij verwijderen van object.\nverbeterde apparaatquery.\nvast delete apparaat met lokale overrides.\n",
|
|
90
|
-
"fr": "Correction sur objet de suppression.\nrequête de périphérique améliorée.\ndispositif de suppression fixe avec redéfinitions locales.\n",
|
|
91
|
-
"it": "Bugfix su delete object.\nmigliore query del dispositivo.\ndispositivo di cancellazione fisso con override locali.\n",
|
|
92
|
-
"es": "Bugfix en el objeto borrado.\nmejorada consulta de dispositivos.\ndispositivo de eliminación fijo con anulas locales.\n",
|
|
93
|
-
"pl": "Bugfix na usunąć obiekt.\nulepszone zapytanie urządzenia.\nnaprawione urządzenie usuwające z lokalnymi przekroczeniami.\n",
|
|
94
|
-
"uk": "Виправлення помилок при видаленні об'єкта.\nпокращений пристрій запиту.\nфіксований пристрій видалення з локальними перенаряддями.\n",
|
|
95
|
-
"zh-cn": "删除对象上的错误修正 .\n改进设备查询 .\n有本地覆盖的固定删除设备 .\n"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
package/lib/exposes.js
CHANGED
|
@@ -180,15 +180,32 @@ function genState(expose, overrides) {
|
|
|
180
180
|
|
|
181
181
|
function generateCompositeStates(expose, _channelID, options)
|
|
182
182
|
{
|
|
183
|
-
const states = [];
|
|
184
183
|
const stname = `${_channelID}${expose.property}`;
|
|
185
184
|
const stateId = stname.replace(/\*/g, '');
|
|
186
185
|
const stateName = (expose.description || expose.name);
|
|
187
186
|
const channelID = options.newCompositeMethod ? `c_${stateId}.` : '';
|
|
187
|
+
const stateData = {
|
|
188
|
+
states: [],
|
|
189
|
+
keys:[]
|
|
190
|
+
};
|
|
191
|
+
if (expose?.features?.[Symbol.iterator]) for (const prop of expose.features) {
|
|
192
|
+
if (prop.type === 'composite' || prop.type === 'list') {
|
|
193
|
+
const subStateData = generateCompositeStates(prop, channelID, options);
|
|
194
|
+
if (options.newCompositeMethod)
|
|
195
|
+
stateData.keys.push(prop.property);
|
|
196
|
+
else
|
|
197
|
+
stateData.keys.push(...subStateData.keys);
|
|
198
|
+
stateData.states.push(...subStateData.states);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
stateData.states.push(genState(prop, options.newCompositeMethod ? { fromComposite: true, name: `${channelID}${prop.property}` , channelID: stateId }: { fromComposite: true }))
|
|
202
|
+
stateData.keys.push(prop.property)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
188
205
|
if (options.newCompositeMethod) {
|
|
189
|
-
|
|
190
206
|
if (typeof stname !== 'string') return undefined;;
|
|
191
|
-
|
|
207
|
+
const KeysToUpdate = stateData.keys;
|
|
208
|
+
stateData.states.push({
|
|
192
209
|
id: stateId,
|
|
193
210
|
name: stateName,
|
|
194
211
|
icon: undefined,
|
|
@@ -196,11 +213,17 @@ function generateCompositeStates(expose, _channelID, options)
|
|
|
196
213
|
write: Boolean (expose.access & ea.SET),
|
|
197
214
|
read: Boolean(expose.access & ea.GET),
|
|
198
215
|
type: 'string',
|
|
216
|
+
subkeys : stateData.keys,
|
|
199
217
|
getter: (value) => {
|
|
200
218
|
const myval = value[stateId];
|
|
201
219
|
if (myval != undefined && typeof myval === 'object') return JSON.stringify(myval);
|
|
202
220
|
return myval;
|
|
203
221
|
},
|
|
222
|
+
compositeGetter: (value) => {
|
|
223
|
+
const myval = value[stateId];
|
|
224
|
+
if (typeof myval === 'object') return myval;
|
|
225
|
+
return undefined;
|
|
226
|
+
},
|
|
204
227
|
setter: (value) => {
|
|
205
228
|
try {
|
|
206
229
|
return JSON.parse(value);
|
|
@@ -212,15 +235,8 @@ function generateCompositeStates(expose, _channelID, options)
|
|
|
212
235
|
})
|
|
213
236
|
|
|
214
237
|
}
|
|
215
|
-
if (expose?.features?.[Symbol.iterator]) for (const prop of expose.features) {
|
|
216
|
-
if (prop.type === 'composite' || prop.type === 'list') {
|
|
217
|
-
states.push(...generateCompositeStates(prop, channelID, options))
|
|
218
|
-
}
|
|
219
|
-
else
|
|
220
|
-
states.push(genState(prop, options.newCompositeMethod ? { fromComposite: true, name: `${channelID}${prop.name}` , channelID: stateId }: { fromComposite: true }))
|
|
221
|
-
}
|
|
222
238
|
|
|
223
|
-
return
|
|
239
|
+
return stateData;
|
|
224
240
|
|
|
225
241
|
}
|
|
226
242
|
function createFromExposes(model, def, device, options, log) {
|
|
@@ -982,8 +998,11 @@ function createFromExposes(model, def, device, options, log) {
|
|
|
982
998
|
case 'composite':
|
|
983
999
|
{
|
|
984
1000
|
const cStates = generateCompositeStates(expose, '', options);
|
|
985
|
-
for (const state of cStates)
|
|
986
|
-
|
|
1001
|
+
for (const state of cStates.states)
|
|
1002
|
+
if (options.newCompositeMethod)
|
|
1003
|
+
pushToStates(state, expose.access);
|
|
1004
|
+
else
|
|
1005
|
+
pushToStates(modifyState(state, { pairedkeys: cStates.keys } , false), expose.access);
|
|
987
1006
|
break;
|
|
988
1007
|
}
|
|
989
1008
|
case 'list':
|
package/lib/statescontroller.js
CHANGED
|
@@ -1173,6 +1173,11 @@ class StatesController extends EventEmitter {
|
|
|
1173
1173
|
|
|
1174
1174
|
let stateID = statedesc.id;
|
|
1175
1175
|
|
|
1176
|
+
if (statedesc.compositeGetter) {
|
|
1177
|
+
const compositePayload = statedesc.compositeGetter(payload);
|
|
1178
|
+
if (compositePayload) await this.publishToState(devId, model, compositePayload, debugId);
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1176
1181
|
// checking value
|
|
1177
1182
|
if (value === undefined || value === null) {
|
|
1178
1183
|
const message = `value '${JSON.stringify(value)}' from device ${devId} via ${mode} for '${statedesc.name} (ID ${statedesc.id} ${statedesc.prop ? 'with property '+statedesc.prop : ''})`;
|
|
@@ -1253,7 +1258,7 @@ class StatesController extends EventEmitter {
|
|
|
1253
1258
|
let has_published = false;
|
|
1254
1259
|
if (devStates.states !== undefined) {
|
|
1255
1260
|
try {
|
|
1256
|
-
const states = devStates.states.filter(statedesc => payload.hasOwnProperty(statedesc.prop
|
|
1261
|
+
const states = devStates.states.filter(statedesc => payload.hasOwnProperty(statedesc.prop ? statedesc.prop: statedesc.id)
|
|
1257
1262
|
);
|
|
1258
1263
|
|
|
1259
1264
|
for (const stateInd in states) {
|
package/lib/zigbeecontroller.js
CHANGED
|
@@ -1465,6 +1465,17 @@ class ZigbeeController extends EventEmitter {
|
|
|
1465
1465
|
}
|
|
1466
1466
|
}
|
|
1467
1467
|
retry = 0;
|
|
1468
|
+
if (readKey.converter) {
|
|
1469
|
+
const tt = preparedOptions.transition || preparedOptions.transition_time;
|
|
1470
|
+
const did = deviceId;
|
|
1471
|
+
setTimeout(async () => {
|
|
1472
|
+
try {
|
|
1473
|
+
await readKey.converter.convertGet(target, readKey.key, {device:entity.device}) }
|
|
1474
|
+
catch (error) {
|
|
1475
|
+
this.warn(`error reading ${readKey.key} from ${deviceId} : ${error?.message}`);
|
|
1476
|
+
}
|
|
1477
|
+
}, tt ? tt * 1000 : 100);
|
|
1478
|
+
}
|
|
1468
1479
|
} catch (error) {
|
|
1469
1480
|
if (has_elevated_debug) {
|
|
1470
1481
|
const message = `caught error ${error?.message? error.message : 'no reason given'} when setting value for device ${deviceId}.`;
|
|
@@ -1483,10 +1494,6 @@ class ZigbeeController extends EventEmitter {
|
|
|
1483
1494
|
}
|
|
1484
1495
|
} while (retry > 0);
|
|
1485
1496
|
|
|
1486
|
-
if (readKey.converter) {
|
|
1487
|
-
const tt = preparedOptions.transition || preparedOptions.transition_time;
|
|
1488
|
-
setTimeout(async () => { await readKey.converter.convertGet(target, readKey.key, {device:entity.device})}, tt ? tt * 1000 : 100)
|
|
1489
|
-
}
|
|
1490
1497
|
|
|
1491
1498
|
});
|
|
1492
1499
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.zigbee",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.3",
|
|
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.9.3",
|
|
31
|
-
"zigbee-herdsman": "
|
|
32
|
-
"zigbee-herdsman-converters": "
|
|
31
|
+
"zigbee-herdsman": "8.0.2",
|
|
32
|
+
"zigbee-herdsman-converters": "25.104.0"
|
|
33
33
|
},
|
|
34
34
|
"description": "Zigbee devices",
|
|
35
35
|
"devDependencies": {
|