iobroker.zigbee 3.3.1-alpha.0 → 3.3.2

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.
@@ -1230,6 +1230,20 @@ class ZigbeeController extends EventEmitter {
1230
1230
  */
1231
1231
  }
1232
1232
 
1233
+
1234
+ async getConverterValue(converter, target, key, preparedValue, preparedObject, meta) {
1235
+ if (preparedObject) {
1236
+ // try {
1237
+ return { result:await converter.convertSet(target, key, preparedObject, meta), fromObject:true };
1238
+ // }
1239
+ // catch (error)
1240
+ // {
1241
+ // return { result:await converter.convertSet(target, key, preparedValue, meta), fromObject:false };
1242
+ // }
1243
+ }
1244
+ else return { result:await converter.convertSet(target, key, preparedValue, meta), fromObject:false };
1245
+ }
1246
+
1233
1247
  // publish via converter
1234
1248
  //
1235
1249
  async publishFromState(deviceId, model, stateModel, stateList, options, debugID, has_elevated_debug) {
@@ -1284,6 +1298,12 @@ class ZigbeeController extends EventEmitter {
1284
1298
 
1285
1299
  return;
1286
1300
  }
1301
+ // force read for brightness
1302
+ const skey = stateDesc.setattr || stateDesc.prop || stateDesc.id;
1303
+ const readKey = { key: undefined, converter: undefined };
1304
+ if (skey === 'brightness') readKey.key = 'state';
1305
+ if (skey === 'state') readKey.key = 'brightness';
1306
+
1287
1307
  for (const c of mappedModel.toZigbee) {
1288
1308
 
1289
1309
  if (!c.hasOwnProperty('convertSet')) continue;
@@ -1292,6 +1312,8 @@ class ZigbeeController extends EventEmitter {
1292
1312
  {
1293
1313
  if (converter === undefined)
1294
1314
  {
1315
+ if (readKey.key && readKey.converter === undefined && c.hasOwnProperty('convertGet'))
1316
+ readKey.converter = c;
1295
1317
  converter = c;
1296
1318
  if (has_elevated_debug) {
1297
1319
  const message = `Setting converter to keyless converter for ${deviceId} of type ${model}`;
@@ -1326,8 +1348,14 @@ class ZigbeeController extends EventEmitter {
1326
1348
  converter = c;
1327
1349
  msg_counter++;
1328
1350
  }
1351
+ if (readKey.key && c.key.includes(readKey.key) && c.hasOwnProperty('convertGet'))
1352
+ readKey.converter = c;
1329
1353
  }
1330
1354
  if (converter === undefined) {
1355
+ if (stateDesc.isInternalState) {
1356
+ this.emit('acknowledge_state', deviceId, undefined, stateDesc , undefined );
1357
+ return;
1358
+ }
1331
1359
  const message = `No converter available for '${model}' with key '${stateDesc.id}' `;
1332
1360
  if (has_elevated_debug) {
1333
1361
  this.emit('device_debug', { ID:debugID, data: { error: 'NOCONV',states:[{id:stateDesc.id, value:value, payload:'no converter'}] , IO:false }, message:message});
@@ -1353,7 +1381,7 @@ class ZigbeeController extends EventEmitter {
1353
1381
 
1354
1382
  const epName = stateDesc.epname !== undefined ? stateDesc.epname : (stateDesc.prop || stateDesc.id);
1355
1383
  const key = stateDesc.setattr || stateDesc.prop || stateDesc.id;
1356
- const message = `convert ${key} with value ${safeJsonStringify(preparedValue)} and options ${safeJsonStringify(preparedOptions)} for device ${deviceId} with Endpoint ${epName}`;
1384
+ const message = `convert ${key} with value ${safeJsonStringify(preparedValue)} and options ${safeJsonStringify(preparedOptions)} for device ${deviceId} ${stateDesc.epname ? `with Endpoint ${epName}` : 'without Endpoint'}`;
1357
1385
  if (has_elevated_debug) {
1358
1386
  this.emit('device_debug', { ID:debugID, data: { flag: '04', payload: {key:key, ep: stateDesc.epname, value:preparedValue, options:preparedOptions}, IO:false }, message:message});
1359
1387
  }
@@ -1371,7 +1399,7 @@ class ZigbeeController extends EventEmitter {
1371
1399
  if (this.debugActive) this.debug(`target: ${safeJsonStringify(target)}`);
1372
1400
 
1373
1401
  const meta = {
1374
- endpoint_name: epName,
1402
+ endpoint_name: stateDesc.epname,
1375
1403
  options: preparedOptions,
1376
1404
  device: entity.device,
1377
1405
  mapped: model === 'group' ? [] : mappedModel,
@@ -1398,10 +1426,22 @@ class ZigbeeController extends EventEmitter {
1398
1426
  }
1399
1427
  }
1400
1428
  let retry = 2;
1429
+ /*
1430
+ let preparedObject = null;
1431
+ try {
1432
+ preparedObject = JSON.parse(preparedValue);
1433
+ }
1434
+ catch (error)
1435
+ { }
1436
+ */
1437
+
1401
1438
  do
1402
1439
  {
1403
1440
  try {
1404
1441
  const result = await converter.convertSet(target, key, preparedValue, meta);
1442
+ const fromObject = false;
1443
+ const preparedObject = null;
1444
+ //const { result, fromObject } = await this.getConverterValue(converter, target, key, preparedValue, preparedObject, meta);
1405
1445
  const message = `convert result ${safeJsonStringify(result)} for device ${deviceId}`;
1406
1446
  if (isGroup)
1407
1447
  this.emit('published', deviceId, model, stateModel, stateList, options, debugID, has_elevated_debug );
@@ -1411,7 +1451,7 @@ class ZigbeeController extends EventEmitter {
1411
1451
  else
1412
1452
  if (this.debugActive) this.debug(message);
1413
1453
  if (result !== undefined) {
1414
- if (stateModel && !isGroup && !stateDesc.noack) {
1454
+ if (!stateDesc.noack) {
1415
1455
  this.emit('acknowledge_state', deviceId, model, stateDesc, value );
1416
1456
  }
1417
1457
  // process sync state list
@@ -1419,7 +1459,8 @@ class ZigbeeController extends EventEmitter {
1419
1459
  }
1420
1460
  else {
1421
1461
  if (has_elevated_debug) {
1422
- const message = `Convert does not return a result result for ${key} with ${safeJsonStringify(preparedValue)} on device ${deviceId}.`;
1462
+ const stringvalue = fromObject ? safeJsonStringify(preparedObject) : typeof preparedValue == 'object' ? safeJsonStringify(preparedValue) : preparedValue;
1463
+ const message = `Convert does not return a result result for ${key} with ${stringvalue} on device ${deviceId}.`;
1423
1464
  this.emit('device_debug', { ID:debugID, data: { flag: '06' , IO:false }, message:message});
1424
1465
  }
1425
1466
  }
@@ -1440,7 +1481,13 @@ class ZigbeeController extends EventEmitter {
1440
1481
  ` Error: ${error.message}`, `Send command to ${deviceId} failed with`, error);
1441
1482
  }
1442
1483
  }
1443
- } while (retry > 0)
1484
+ } while (retry > 0);
1485
+
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
+
1444
1491
  });
1445
1492
  } catch (err) {
1446
1493
  const message = `No entity for ${deviceId} : ${err && err.message ? err.message : 'no error message'}`;
@@ -1574,14 +1621,16 @@ class ZigbeeController extends EventEmitter {
1574
1621
  for (const converter of mappedModel.toZigbee) {
1575
1622
  if (converter.hasOwnProperty('convertGet')) {
1576
1623
  cCount++;
1577
- const sources = [];
1578
- if (converter.endpoints && epmap) {
1579
- for (const epname of converter.endpoints) {
1624
+ const sources = new Set();
1625
+ if (!converter.endpoints) sources.add(entity.device.endpoints[0]);
1626
+ const epCandidates = converter.endpoints ? converter.endpoints : epmap ? Object.keys(epmap) : undefined;
1627
+ if (epCandidates) {
1628
+ for (const epname of epCandidates) {
1580
1629
  const source = entity.device.endpoints.find((id) => id.ID == epmap[epname]);
1581
- if (source) sources.push(source);
1630
+ if (source) sources.add(source);
1582
1631
  }
1583
1632
  }
1584
- if (sources.length == 0) sources.push(entity.device.endpoints[0]);
1633
+ if (sources.size == 0) sources.add(entity.device.endpoints[0]);
1585
1634
  for (const source of sources) {
1586
1635
  for (const k of converter.key)
1587
1636
  try {
package/main.js CHANGED
@@ -130,15 +130,13 @@ class Zigbee extends utils.Adapter {
130
130
  const Sentry = sentryInstance.getSentryObject();
131
131
  if (Sentry) {
132
132
  if (message) {
133
- Sentry.configureScope(scope =>
134
- scope.addBreadcrumb({
135
- type: 'error', // predefined types
136
- category: 'error message',
137
- level: 'error',
138
- message
139
- }));
133
+ Sentry && Sentry.withScope(scope => scope.addBreadcrumb({
134
+ type: 'error', // predefined types
135
+ category: 'error message',
136
+ level: 'error',
137
+ message
138
+ }));
140
139
  }
141
-
142
140
  if (typeof error == 'string') {
143
141
  Sentry.captureException(new Error(error));
144
142
  } else {
@@ -641,13 +639,13 @@ class Zigbee extends utils.Adapter {
641
639
  await this.callPluginMethod('start', [this.zbController, this.stController]);
642
640
  }
643
641
 
644
- async syncAllDeviceStates(resetRoles) {
642
+ async syncAllDeviceStates(rebuildStates) {
645
643
  this.stController.CleanupRequired(false);
646
- if (resetRoles) this.stController.clearModelDefinitions();
644
+ if (rebuildStates) this.stController.clearModelDefinitions();
647
645
  const devicesFromObjects = (await this.getDevicesAsync()).filter(item => item.native.id.length ==16).map((item) => `0x${item.native.id}`);
648
646
  const devicesFromDB = this.zbController.getClientIterator(false);
649
647
  for (const device of devicesFromDB) {
650
- if (resetRoles) {
648
+ if (rebuildStates) {
651
649
  const hM = await zigbeeHerdsmanConverters.findByDevice(device);
652
650
  await this.stController.AddModelFromHerdsman(device, hM ? hM.model : device.modelID);
653
651
  }
@@ -660,7 +658,7 @@ class Zigbee extends utils.Adapter {
660
658
  if (entity) {
661
659
  const model = entity.mapped ? entity.mapped.model : entity.device.modelID;
662
660
  this.stController.updateDev(zbIdorIeeetoAdId(this, device.ieeeAddr, false), model, model, () =>
663
- this.stController.syncDevStates(device, model, resetRoles));
661
+ this.stController.syncDevStates(device, model));
664
662
  }
665
663
  else (this.log.debug('resolveEntity returned no entity'));
666
664
  }
@@ -705,15 +703,12 @@ class Zigbee extends utils.Adapter {
705
703
  await this.stController.AddModelFromHerdsman(entity.device, model)
706
704
  if (device) {
707
705
  this.getObject(zbIdorIeeetoAdId(this, device.ieeeAddr, false), (err, obj) => {
708
- if (!obj) {
709
- const model = (entity.mapped) ? entity.mapped.model : entity.device.modelID;
710
- if (this.debugActive) this.log.debug(`new device ${device.ieeeAddr} ${device.networkAddress} ${model} `);
706
+ const model = (entity.mapped) ? entity.mapped.model : entity.device.modelID;
707
+ if (this.debugActive) this.log.debug(`new device ${device.ieeeAddr} ${device.networkAddress} ${model} `);
711
708
 
712
- this.logToPairing(`New device joined '${device.ieeeAddr}' model ${model}`, true);
713
- this.stController.updateDev(zbIdorIeeetoAdId(this, device.ieeeAddr, false), model, model, () =>
714
- this.stController.syncDevStates(device, model, false));
715
- }
716
- else if (this.debugActive) this.log.debug(`Device ${safeJsonStringify(entity)} rejoined, no new device`);
709
+ if (!obj) this.logToPairing(`New device joined '${device.ieeeAddr}' model ${model}`, true);
710
+ this.stController.updateDev(zbIdorIeeetoAdId(this, device.ieeeAddr, false), model, model, () =>
711
+ this.stController.syncDevStates(device, model));
717
712
  });
718
713
  }
719
714
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zigbee",
3
- "version": "3.3.1-alpha.0",
3
+ "version": "3.3.2",
4
4
  "author": {
5
5
  "name": "Kirov Ilya",
6
6
  "email": "kirovilya@gmail.com"
@@ -23,13 +23,13 @@
23
23
  "dependencies": {
24
24
  "@iobroker/adapter-core": "^3.3.2",
25
25
  "@iobroker/dm-utils": "^1.0.13",
26
- "humanize-duration": "^3.33.1",
26
+ "humanize-duration": "^3.33.2",
27
27
  "tar": "^7.5.2",
28
28
  "ajv": "^8.17.1",
29
29
  "uri-js": "^4.4.1",
30
30
  "typescript": "^5.9.3",
31
- "zigbee-herdsman": "^7.0.0",
32
- "zigbee-herdsman-converters": "25.84.0"
31
+ "zigbee-herdsman": "^8.0.1",
32
+ "zigbee-herdsman-converters": "^25.99.0"
33
33
  },
34
34
  "description": "Zigbee devices",
35
35
  "devDependencies": {
@@ -38,7 +38,7 @@
38
38
  "@alcalzone/release-script-plugin-license": "^4.0.0",
39
39
  "@alcalzone/release-script-plugin-manual-review": "^4.0.0",
40
40
  "@iobroker/testing": "^5.2.2",
41
- "eslint": "^9.39.1",
41
+ "eslint": "^9.39.2",
42
42
  "eslint-config-prettier": "^9.1.0",
43
43
  "eslint-plugin-prettier": "^5.5.4",
44
44
  "mixin-deep": "^2.0.1",