iobroker.zigbee 1.8.18 → 1.8.20

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.
Files changed (60) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +421 -415
  3. package/admin/adapter-settings.js +244 -244
  4. package/admin/admin.js +2981 -2981
  5. package/admin/i18n/de/translations.json +108 -108
  6. package/admin/i18n/en/translations.json +108 -108
  7. package/admin/i18n/es/translations.json +102 -102
  8. package/admin/i18n/fr/translations.json +108 -108
  9. package/admin/i18n/it/translations.json +102 -102
  10. package/admin/i18n/nl/translations.json +108 -108
  11. package/admin/i18n/pl/translations.json +108 -108
  12. package/admin/i18n/pt/translations.json +102 -102
  13. package/admin/i18n/ru/translations.json +108 -108
  14. package/admin/i18n/uk/translations.json +108 -108
  15. package/admin/i18n/zh-cn/translations.json +102 -102
  16. package/admin/img/philips_hue_lom001.png +0 -0
  17. package/admin/index.html +159 -159
  18. package/admin/index_m.html +1356 -1356
  19. package/admin/moment.min.js +1 -1
  20. package/admin/shuffle.min.js +2 -2
  21. package/admin/tab_m.html +1009 -1009
  22. package/admin/vis-network.min.css +1 -1
  23. package/admin/vis-network.min.js +27 -27
  24. package/admin/words.js +110 -110
  25. package/docs/de/basedocu.md +19 -19
  26. package/docs/de/readme.md +126 -126
  27. package/docs/en/readme.md +128 -128
  28. package/docs/flashing_via_arduino_(en).md +110 -110
  29. package/docs/ru/readme.md +28 -28
  30. package/docs/tutorial/groups-1.png +0 -0
  31. package/docs/tutorial/groups-2.png +0 -0
  32. package/docs/tutorial/tab-dev-1.png +0 -0
  33. package/io-package.json +27 -9
  34. package/lib/backup.js +171 -171
  35. package/lib/binding.js +319 -319
  36. package/lib/colors.js +465 -465
  37. package/lib/commands.js +534 -534
  38. package/lib/developer.js +145 -145
  39. package/lib/devices.js +3135 -3135
  40. package/lib/exclude.js +162 -162
  41. package/lib/exposes.js +913 -913
  42. package/lib/groups.js +345 -345
  43. package/lib/json.js +59 -59
  44. package/lib/networkmap.js +55 -55
  45. package/lib/ota.js +198 -198
  46. package/lib/rgb.js +297 -297
  47. package/lib/seriallist.js +48 -48
  48. package/lib/states.js +6420 -6420
  49. package/lib/statescontroller.js +672 -672
  50. package/lib/tools.js +54 -54
  51. package/lib/utils.js +163 -163
  52. package/lib/zbBaseExtension.js +36 -36
  53. package/lib/zbDelayedAction.js +144 -144
  54. package/lib/zbDeviceAvailability.js +319 -319
  55. package/lib/zbDeviceConfigure.js +147 -147
  56. package/lib/zbDeviceEvent.js +48 -48
  57. package/lib/zigbeecontroller.js +989 -989
  58. package/main.js +65 -37
  59. package/package.json +6 -4
  60. package/support/docgen.js +93 -93
package/main.js CHANGED
@@ -13,6 +13,8 @@ try {
13
13
  }
14
14
  const originalLogMethod = debug.log;
15
15
 
16
+ const zigbeeHerdsmanConvertersUtils = require('zigbee-herdsman-converters/lib/utils');
17
+
16
18
  const safeJsonStringify = require('./lib/json');
17
19
  const fs = require('fs');
18
20
  const path = require('path');
@@ -271,30 +273,6 @@ class Zigbee extends utils.Adapter {
271
273
 
272
274
  }
273
275
  }
274
-
275
- /* if (this.config.external === undefined) {
276
- return;
277
- }
278
- const extfiles = this.config.external.split(';');
279
- for (const moduleName of extfiles) {
280
- if (!moduleName) continue;
281
- this.log.info(`Apply converter from module: ${moduleName}`);
282
- const sandbox = {
283
- require,
284
- module: {},
285
- };
286
- const converterCode = fs.readFileSync(moduleName, {encoding: 'utf8'});
287
- vm.runInNewContext(converterCode, sandbox);
288
- const converter = sandbox.module.exports;
289
- if (Array.isArray(converter)) {
290
- for (const item of converter) {
291
- yield item;
292
- }
293
- } else {
294
- yield converter;
295
- }
296
- }
297
- */
298
276
  }
299
277
 
300
278
  applyExternalConverters() {
@@ -483,6 +461,7 @@ class Zigbee extends utils.Adapter {
483
461
 
484
462
  async onZigbeeEvent(type, entity, message) {
485
463
  this.log.debug(`Type ${type} device ${safeJsonStringify(entity)} incoming event: ${safeJsonStringify(message)}`);
464
+
486
465
  const device = entity.device;
487
466
  const mappedModel = entity.mapped;
488
467
  const model = entity.mapped ? entity.mapped.model : entity.device.modelID;
@@ -493,25 +472,65 @@ class Zigbee extends utils.Adapter {
493
472
  // this assigment give possibility to use iobroker logger in code of the converters, via meta.logger
494
473
  meta.logger = this.log;
495
474
 
496
- await this.checkIfModelUpdate(entity);
497
- // always publish link_quality
498
- if (message.linkquality) {
475
+ await this.checkIfModelUpdate(entity);
476
+
477
+ let voltage = 0;
478
+ let battKey = false;
479
+
480
+ if (mappedModel.meta != undefined && mappedModel.meta.battery != undefined) {
481
+ const isVoltage = entity.mapped.meta.battery.hasOwnProperty('voltageToPercentage');
482
+
483
+ if (isVoltage) {
484
+ const keys = Object.keys(message.data);
485
+
486
+ for (const key of keys) {
487
+ const value = message.data[key];
488
+
489
+ this.log.debug(`--> BatteryValue ${safeJsonStringify(value)} from battery search`);
490
+
491
+ if (value != undefined && value[1] != undefined) {
492
+ if (key == 65282 && value[1][1] != undefined) {
493
+ voltage = value[1][1].elmVal;
494
+ battKey = true;
495
+ break;
496
+ }
497
+ if (key == 65281) {
498
+ voltage = value[1];
499
+ battKey = true;
500
+ break;
501
+ }
502
+ }
503
+ }
504
+ }
505
+ }
506
+
507
+ // always publish link_quality and battery
508
+ if (message.linkquality) { // send battery with
499
509
  this.publishToState(devId, model, {linkquality: message.linkquality});
510
+ if (battKey) {
511
+ this.publishToState(devId, model, {voltage: voltage});
512
+ const battProz = zigbeeHerdsmanConvertersUtils.batteryVoltageToPercentage(voltage,entity.mapped.meta.battery.voltageToPercentage);
513
+ this.publishToState(devId, model, {battery: battProz});
514
+ }
500
515
  }
516
+
501
517
  // publish raw event to "from_zigbee"
502
518
  // some cleanup
503
519
  const msgForState = Object.assign({}, message);
504
520
  delete msgForState['device'];
505
521
  delete msgForState['endpoint'];
522
+
506
523
  msgForState['endpoint_id'] = message.endpoint.ID;
507
524
  this.publishToState(devId, model, {msg_from_zigbee: safeJsonStringify(msgForState)});
508
525
 
509
526
  if (!entity.mapped) {
510
527
  return;
511
528
  }
529
+
512
530
  let converters = mappedModel.fromZigbee.filter(c => c && c.cluster === cluster && (
513
531
  (c.type instanceof Array) ? c.type.includes(type) : c.type === type));
514
532
 
533
+
515
534
  if (!converters.length && type === 'readResponse') {
516
535
  converters = mappedModel.fromZigbee.filter(c => c.cluster === cluster && (
517
536
  (c.type instanceof Array) ? c.type.includes('attributeReport') : c.type === 'attributeReport'));
@@ -519,24 +538,33 @@ class Zigbee extends utils.Adapter {
519
538
 
520
539
  if (!converters.length) {
521
540
  if (type !== 'readResponse') {
522
- this.log.debug(`No converter available for '${mappedModel.model}' '${devId}' with cluster '${cluster}' and type '${type}'`
523
- );
541
+ this.log.debug(`No converter available for '${mappedModel.model}' '${devId}' with cluster '${cluster}' and type '${type}'`);
524
542
  }
525
543
  return;
526
544
  }
527
545
 
528
- const publish = (payload) => {
529
- this.log.debug(`Publish '${safeJsonStringify(payload)}' devId '${devId}'`);
530
- if (payload) {
531
- this.publishToState(devId, model, payload);
546
+ let payload = {};
547
+
548
+ const publish = (_payload) => {
549
+ if (_payload) {
550
+ this.publishToState(devId, model, _payload);
532
551
  }
533
552
  };
534
553
 
535
- for (const converter of converters) {
536
- let payload = await converter.convert(mappedModel, message, publish, mappedModel.options, meta);
537
- if (payload) {
538
- publish(payload);
554
+ try {
555
+ for (const converter of converters) {
556
+ this.stController.collectOptions(devId, model, (options) => {
557
+ payload = converter.convert(mappedModel, message, publish, options, meta);
558
+
559
+ if (payload) {
560
+ if (Object.keys(payload).length) {
561
+ publish(payload);
562
+ }
563
+ }
564
+ });
539
565
  }
566
+ } catch (err) {
567
+ this.log.error(`convert problem with '${model}' '${devId}' `);
540
568
  }
541
569
  }
542
570
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zigbee",
3
- "version": "1.8.18",
3
+ "version": "1.8.20",
4
4
  "author": {
5
5
  "name": "Kirov Ilya",
6
6
  "email": "kirovilya@gmail.com"
@@ -25,13 +25,14 @@
25
25
  "tar": "^6.1.15",
26
26
  "typescript": "^5.1.6",
27
27
  "zigbee-herdsman": "0.17.2",
28
- "zigbee-herdsman-converters": "15.41.0"
28
+ "zigbee-herdsman-converters": "15.49.0"
29
29
  },
30
30
  "description": "Zigbee devices",
31
31
  "devDependencies": {
32
- "@alcalzone/release-script": "^3.5.9",
33
- "@alcalzone/release-script-plugin-iobroker": "^3.5.9",
32
+ "@alcalzone/release-script": "^3.6.0",
33
+ "@alcalzone/release-script-plugin-iobroker": "^3.6.0",
34
34
  "@alcalzone/release-script-plugin-license": "^3.5.9",
35
+ "@alcalzone/release-script-plugin-manual-review": "^3.5.9",
35
36
  "@iobroker/testing": "^4.1.0",
36
37
  "axios": "^1.3.4",
37
38
  "chai": "^4.3.7",
@@ -83,6 +84,7 @@
83
84
  "test:integration": "mocha test/integration --exit",
84
85
  "watch:parcel": "parcel admin/src/index.tsx -d admin/build --hmr-port 1235",
85
86
  "test:js": "mocha --opts test/mocha.custom.opts",
87
+ "lint": "eslint .",
86
88
  "release": "release-script",
87
89
  "release-patch": "release-script patch --yes --no-update-lockfile",
88
90
  "release-minor": "release-script minor --yes --no-update-lockfile",
package/support/docgen.js CHANGED
@@ -1,93 +1,93 @@
1
- /**
2
- * This script generates the supported devices page.
3
- *
4
- */
5
-
6
- let devices = [...require('zigbee-herdsman-converters').devices];
7
-
8
- for (const device of devices) {
9
- if (device.whiteLabel) {
10
- for (const whiteLabel of device.whiteLabel) {
11
- const whiteLabelDevice = {
12
- ...device,
13
- model: whiteLabel.model,
14
- vendor: whiteLabel.vendor,
15
- description: whiteLabel.description,
16
- whiteLabelOf: device,
17
- };
18
-
19
- delete whiteLabelDevice.whiteLabel;
20
-
21
- devices.push(whiteLabelDevice);
22
- }
23
- }
24
- }
25
-
26
- devices = new Map(devices.map((d) => [d.model, d]));
27
-
28
- const Devices = require('../lib/devices');
29
- let iobDevices = Devices.devices;
30
- Devices.fillStatesWithExposes('');
31
-
32
- const iobCount = iobDevices.filter((d) => (!d.exposed)).length;
33
- iobDevices = new Map(iobDevices.map((d) => d.models.map((m) => [m, d])).flat());
34
-
35
- const fs = require('fs');
36
- const outputdir = process.argv[2];
37
-
38
- if (!outputdir) {
39
- console.error('Please specify an output directory');
40
- }
41
-
42
- const file = 'Supported-devices.md';
43
- let text = `*NOTE: Automatically generated by 'npm run docgen'* \n\n` +
44
- `Currently **${iobDevices.size}**(${iobCount} described in adapter) devices are supported.\n\n` +
45
- `(⭐EXP) - means that the device is presented automatically, based on the 'exposes' from the zigbee-herdsman-converters.\n\n`;
46
-
47
- const logDevices = (devmodels) => {
48
- let result = '';
49
-
50
- devmodels.forEach((devmodel) => {
51
- const iobDevice = iobDevices.get(devmodel);
52
- const device = devices.get(devmodel);
53
- const pathImg = (iobDevice.icon.startsWith('http')) ? devmodel : iobDevice.icon.replace(new RegExp('img/', 'g'), '').replace(new RegExp('.png', 'g'), '');
54
- const icon = (iobDevice.icon.startsWith('http')) ? iobDevice.icon : `https://github.com/ioBroker/ioBroker.zigbee/raw/master/admin/${iobDevice.icon}`;
55
- let brand;
56
- const models = [];
57
- let zmodels;
58
- if (device.zigbeeModel) {
59
- zmodels = device.zigbeeModel;
60
- } else {
61
- zmodels = [devmodel];
62
- }
63
- zmodels.forEach((modelId) => {
64
- const re = /[^\x20-\x7E]+/g;
65
- const model = modelId.replace(re, ' ');
66
- const desc = `${device.description} (${device.supports})`;
67
- const name = `**${device.model}${(iobDevice.exposed) ? ' (⭐EXP)': ''}**<br>`;
68
- if (brand == undefined) {
69
- brand= {
70
- name: name,
71
- desc: desc,
72
- pathImg: pathImg,
73
- };
74
- }
75
- models.push(model);
76
- });
77
- const modelsStr = models.join(', ');
78
- result += `| ${brand.name} (${modelsStr}) | ${brand.desc} | ![${brand.pathImg}](${icon}) |\n`;
79
- });
80
-
81
- return result;
82
- };
83
-
84
- const vendors = Array.from(new Set([...iobDevices.keys()].map((m) => (devices.get(m)) ? devices.get(m).vendor : null)));
85
- vendors.sort();
86
- text += '| Model | Description | Picture |\n';
87
- text += '| ------------- | ------------- | -------------------------- |\n';
88
- vendors.forEach((vendor) => {
89
- text += `| | **${vendor}** | |\n`;
90
- text += logDevices([...iobDevices.keys()].map((m) => devices.get(m)).filter((d) => d && d.vendor === vendor).map((d) => d.model));
91
- });
92
-
93
- fs.writeFileSync(outputdir + '/' + file, text);
1
+ /**
2
+ * This script generates the supported devices page.
3
+ *
4
+ */
5
+
6
+ let devices = [...require('zigbee-herdsman-converters').devices];
7
+
8
+ for (const device of devices) {
9
+ if (device.whiteLabel) {
10
+ for (const whiteLabel of device.whiteLabel) {
11
+ const whiteLabelDevice = {
12
+ ...device,
13
+ model: whiteLabel.model,
14
+ vendor: whiteLabel.vendor,
15
+ description: whiteLabel.description,
16
+ whiteLabelOf: device,
17
+ };
18
+
19
+ delete whiteLabelDevice.whiteLabel;
20
+
21
+ devices.push(whiteLabelDevice);
22
+ }
23
+ }
24
+ }
25
+
26
+ devices = new Map(devices.map((d) => [d.model, d]));
27
+
28
+ const Devices = require('../lib/devices');
29
+ let iobDevices = Devices.devices;
30
+ Devices.fillStatesWithExposes('');
31
+
32
+ const iobCount = iobDevices.filter((d) => (!d.exposed)).length;
33
+ iobDevices = new Map(iobDevices.map((d) => d.models.map((m) => [m, d])).flat());
34
+
35
+ const fs = require('fs');
36
+ const outputdir = process.argv[2];
37
+
38
+ if (!outputdir) {
39
+ console.error('Please specify an output directory');
40
+ }
41
+
42
+ const file = 'Supported-devices.md';
43
+ let text = `*NOTE: Automatically generated by 'npm run docgen'* \n\n` +
44
+ `Currently **${iobDevices.size}**(${iobCount} described in adapter) devices are supported.\n\n` +
45
+ `(⭐EXP) - means that the device is presented automatically, based on the 'exposes' from the zigbee-herdsman-converters.\n\n`;
46
+
47
+ const logDevices = (devmodels) => {
48
+ let result = '';
49
+
50
+ devmodels.forEach((devmodel) => {
51
+ const iobDevice = iobDevices.get(devmodel);
52
+ const device = devices.get(devmodel);
53
+ const pathImg = (iobDevice.icon.startsWith('http')) ? devmodel : iobDevice.icon.replace(new RegExp('img/', 'g'), '').replace(new RegExp('.png', 'g'), '');
54
+ const icon = (iobDevice.icon.startsWith('http')) ? iobDevice.icon : `https://github.com/ioBroker/ioBroker.zigbee/raw/master/admin/${iobDevice.icon}`;
55
+ let brand;
56
+ const models = [];
57
+ let zmodels;
58
+ if (device.zigbeeModel) {
59
+ zmodels = device.zigbeeModel;
60
+ } else {
61
+ zmodels = [devmodel];
62
+ }
63
+ zmodels.forEach((modelId) => {
64
+ const re = /[^\x20-\x7E]+/g;
65
+ const model = modelId.replace(re, ' ');
66
+ const desc = `${device.description} (${device.supports})`;
67
+ const name = `**${device.model}${(iobDevice.exposed) ? ' (⭐EXP)': ''}**<br>`;
68
+ if (brand == undefined) {
69
+ brand= {
70
+ name: name,
71
+ desc: desc,
72
+ pathImg: pathImg,
73
+ };
74
+ }
75
+ models.push(model);
76
+ });
77
+ const modelsStr = models.join(', ');
78
+ result += `| ${brand.name} (${modelsStr}) | ${brand.desc} | ![${brand.pathImg}](${icon}) |\n`;
79
+ });
80
+
81
+ return result;
82
+ };
83
+
84
+ const vendors = Array.from(new Set([...iobDevices.keys()].map((m) => (devices.get(m)) ? devices.get(m).vendor : null)));
85
+ vendors.sort();
86
+ text += '| Model | Description | Picture |\n';
87
+ text += '| ------------- | ------------- | -------------------------- |\n';
88
+ vendors.forEach((vendor) => {
89
+ text += `| | **${vendor}** | |\n`;
90
+ text += logDevices([...iobDevices.keys()].map((m) => devices.get(m)).filter((d) => d && d.vendor === vendor).map((d) => d.model));
91
+ });
92
+
93
+ fs.writeFileSync(outputdir + '/' + file, text);