iobroker.zigbee 1.8.3 → 1.8.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.
Files changed (87) hide show
  1. package/README.md +3 -0
  2. package/admin/admin.js +512 -493
  3. package/admin/index_m.html +1171 -1001
  4. package/admin/tab_m.html +44 -3
  5. package/docs/de/img/CC2531.png +0 -0
  6. package/docs/de/img/CC2538_CC2592_PA.PNG +0 -0
  7. package/docs/de/img/CC2591.png +0 -0
  8. package/docs/de/img/boards.jpg +0 -0
  9. package/docs/de/img/cc26x2r.PNG +0 -0
  10. package/docs/de/img/results.jpg +0 -0
  11. package/docs/de/img/sku_429478_2.png +0 -0
  12. package/docs/de/img/sku_429601_2.png +0 -0
  13. package/docs/de/readme.md +27 -0
  14. package/docs/en/img/CC2531.png +0 -0
  15. package/docs/en/img/CC2591.png +0 -0
  16. package/docs/en/img/deconz.png +0 -0
  17. package/docs/en/img/sku_429478_2.png +0 -0
  18. package/docs/en/img/sku_429601_2.png +0 -0
  19. package/docs/en/readme.md +30 -0
  20. package/docs/flashing_via_arduino_(en).md +110 -0
  21. package/docs/ru/img/CC2531.png +0 -0
  22. package/docs/ru/img/CC2591.png +0 -0
  23. package/docs/ru/img/sku_429478_2.png +0 -0
  24. package/docs/ru/img/sku_429601_2.png +0 -0
  25. package/docs/ru/readme.md +28 -0
  26. package/docs/tutorial/CC2530_20190425.zip +0 -0
  27. package/docs/tutorial/CC2530_CC2591_20190515.zip +0 -0
  28. package/docs/tutorial/CC2530_CC2592_20190515.zip +0 -0
  29. package/docs/tutorial/CC2531_20190425.zip +0 -0
  30. package/docs/tutorial/adm5_1.PNG +0 -0
  31. package/docs/tutorial/adm5_2.PNG +0 -0
  32. package/docs/tutorial/cat.PNG +0 -0
  33. package/docs/tutorial/groups-1.png +0 -0
  34. package/docs/tutorial/groups-2.png +0 -0
  35. package/docs/tutorial/inst.PNG +0 -0
  36. package/docs/tutorial/reflash-finish.PNG +0 -0
  37. package/docs/tutorial/reflash-step0.png +0 -0
  38. package/docs/tutorial/reflash-step1.PNG +0 -0
  39. package/docs/tutorial/reflash-step2.PNG +0 -0
  40. package/docs/tutorial/settings.png +0 -0
  41. package/docs/tutorial/tab-dev-1.png +0 -0
  42. package/docs/tutorial/zigbee.png +0 -0
  43. package/docs/tutorial/zigbee15.png +0 -0
  44. package/io-package.json +17 -25
  45. package/lib/backup.js +2 -2
  46. package/lib/binding.js +32 -37
  47. package/lib/colors.js +163 -158
  48. package/lib/commands.js +100 -91
  49. package/lib/developer.js +9 -12
  50. package/lib/devices.js +168 -178
  51. package/lib/exclude.js +30 -36
  52. package/lib/exposes.js +163 -139
  53. package/lib/groups.js +81 -83
  54. package/lib/json.js +5 -6
  55. package/lib/networkmap.js +2 -3
  56. package/lib/ota.js +34 -18
  57. package/lib/rgb.js +114 -72
  58. package/lib/seriallist.js +25 -20
  59. package/lib/states.js +511 -526
  60. package/lib/statescontroller.js +206 -183
  61. package/lib/utils.js +24 -23
  62. package/lib/zbBaseExtension.js +4 -4
  63. package/lib/zbDelayedAction.js +5 -13
  64. package/lib/zbDeviceAvailability.js +69 -65
  65. package/lib/zbDeviceConfigure.js +9 -21
  66. package/lib/zbDeviceEvent.js +3 -4
  67. package/lib/zigbeecontroller.js +133 -128
  68. package/main.js +169 -154
  69. package/package.json +27 -13
  70. package/.eslintignore +0 -2
  71. package/.eslintrc.json +0 -37
  72. package/.github/FUNDING.yml +0 -3
  73. package/.github/auto-merge.yml +0 -17
  74. package/.github/dependabot.yml +0 -24
  75. package/.github/stale.yml +0 -13
  76. package/.github/workflows/codeql.yml +0 -41
  77. package/.github/workflows/dependabot-automerge.yml +0 -22
  78. package/.github/workflows/test-and-release.yml +0 -149
  79. package/.releaseconfig.json +0 -3
  80. package/.travis/wiki.sh +0 -28
  81. package/.travis.yml +0 -41
  82. package/gulpfile.js +0 -464
  83. package/test/integration.js +0 -5
  84. package/test/mocha.custom.opts +0 -2
  85. package/test/mocha.setup.js +0 -14
  86. package/test/package.js +0 -5
  87. package/test/unit.js +0 -5
@@ -41,7 +41,7 @@ class ZigbeeController extends EventEmitter {
41
41
  super();
42
42
  this.adapter = adapter;
43
43
  this._permitJoinTime = 0;
44
- this.herdsman_started = false;
44
+ this.herdsmanStarted = false;
45
45
  this.extensions = [
46
46
  new DeviceAvailabilityExt(this, {}),
47
47
  new DeviceConfigureExt(this, {}),
@@ -85,7 +85,12 @@ class ZigbeeController extends EventEmitter {
85
85
 
86
86
  this.debug(`Using zigbee-herdsman with settings: ${JSON.stringify(herdsmanSettings)}`);
87
87
  this.herdsman = new ZigbeeHerdsman.Controller(herdsmanSettings, this.adapter.log);
88
- this.callExtensionMethod('setOptions', [{ disableActivePing: options.disablePing, disableForcedPing: false, pingTimeout:300, pingCount:3 }] );
88
+ this.callExtensionMethod('setOptions', [{
89
+ disableActivePing: options.disablePing,
90
+ disableForcedPing: false,
91
+ pingTimeout: 300,
92
+ pingCount: 3
93
+ }]);
89
94
  }
90
95
 
91
96
  // Start controller
@@ -93,8 +98,8 @@ class ZigbeeController extends EventEmitter {
93
98
  try {
94
99
  //this.debug(`Using zigbee-herdsman with settings2: ${JSON.stringify(this)}`);
95
100
  this.debug(`Starting zigbee-herdsman...`);
96
- await this.herdsman.start();
97
101
 
102
+ // install event handlers before start
98
103
  this.herdsman.on('adapterDisconnected', this.handleDisconnected.bind(this));
99
104
  this.herdsman.on('deviceAnnounce', this.handleDeviceAnnounce.bind(this));
100
105
  this.herdsman.on('deviceInterview', this.handleDeviceInterview.bind(this));
@@ -102,29 +107,30 @@ class ZigbeeController extends EventEmitter {
102
107
  this.herdsman.on('deviceLeave', this.handleDeviceLeave.bind(this));
103
108
  this.herdsman.on('message', this.handleMessage.bind(this));
104
109
 
110
+ await this.herdsman.start();
111
+
105
112
  this.debug('zigbee-herdsman started');
106
- this.herdsman_started = true;
113
+ this.herdsmanStarted = true;
107
114
  this.info(`Coordinator firmware version: ${JSON.stringify(await this.herdsman.getCoordinatorVersion())}`);
108
115
 
109
116
  // debug info from herdsman getNetworkParameters
110
117
  const debNetworkParam = JSON.parse(JSON.stringify(await this.herdsman.getNetworkParameters()));
111
- const extendedPanIDDebug = (typeof debNetworkParam.extendedPanID == 'string') ? debNetworkParam.extendedPanID.replace('0x','') : debNetworkParam.extendedPanID;
118
+ const extendedPanIDDebug = typeof debNetworkParam.extendedPanID === 'string' ? debNetworkParam.extendedPanID.replace('0x', '') : debNetworkParam.extendedPanID;
112
119
 
113
120
  let extPanIDDebug = '';
114
121
  for (let i = extendedPanIDDebug.length - 1; i >= 0; i--) {
115
- extPanIDDebug += extendedPanIDDebug[i-1];
122
+ extPanIDDebug += extendedPanIDDebug[i - 1];
116
123
  extPanIDDebug += extendedPanIDDebug[i];
117
124
  i--;
118
125
  }
119
126
 
120
127
  this.debug(`Zigbee network parameters: panID=${debNetworkParam.panID} channel=${debNetworkParam.channel} extendedPanID=${extPanIDDebug}`);
121
-
122
128
  } catch (e) {
123
129
  this.sendError(e);
124
- this.error('Starting zigbee-herdsman problem : ' + JSON.stringify(e.message));
130
+ this.error(`Starting zigbee-herdsman problem : ${JSON.stringify(e.message)}`);
125
131
  throw 'Error herdsman start';
126
132
  }
127
- // Check if we have to turn off the led
133
+ // Check if we have to turn off the LED
128
134
  try {
129
135
  if (this.disableLed) {
130
136
  this.info('Disable LED');
@@ -141,7 +147,7 @@ class ZigbeeController extends EventEmitter {
141
147
  let powerText = 'normal';
142
148
 
143
149
  if (this.transmitPower != '0') {
144
- switch(this.transmitPower) {
150
+ switch (this.transmitPower) {
145
151
  case '-22':
146
152
  powerText = 'low';
147
153
  break;
@@ -157,7 +163,7 @@ class ZigbeeController extends EventEmitter {
157
163
  }
158
164
 
159
165
 
160
- this.info(' --> transmitPower : ' + powerText);
166
+ this.info(` --> transmitPower : ${powerText}`);
161
167
  try {
162
168
  await this.herdsman.setTransmitPower(this.transmitPower);
163
169
  } catch (e) {
@@ -165,7 +171,6 @@ class ZigbeeController extends EventEmitter {
165
171
  this.info('Unable to set transmit power, unsupported function.');
166
172
  }
167
173
 
168
-
169
174
  // Call extensions
170
175
  this.callExtensionMethod('onZigbeeStarted', []);
171
176
 
@@ -176,20 +181,21 @@ class ZigbeeController extends EventEmitter {
176
181
  } else {
177
182
  this.info(`Currently no devices.`);
178
183
  }
184
+
179
185
  for (const device of devices) {
180
186
  const entity = await this.resolveEntity(device);
181
- this.adapter.getObject(device.ieeeAddr.substr(2),(err, obj) => {
182
- if (obj && obj.common && obj.common.deactivated)
183
- {
187
+ this.adapter.getObject(device.ieeeAddr.substr(2), (err, obj) => {
188
+ if (obj && obj.common && obj.common.deactivated) {
184
189
  this.callExtensionMethod('deregisterDevicePing', [device, entity]);
185
- }
186
- else {
190
+ } else {
187
191
  this.callExtensionMethod('registerDevicePing', [device, entity]);
188
192
  }
189
193
  });
190
194
  // ensure that objects for all found clients are present
191
195
 
192
- if (entity.mapped) this.emit('new', entity);
196
+ if (entity.mapped) {
197
+ this.emit('new', entity);
198
+ }
193
199
  this.info(
194
200
  (entity.device.ieeeAddr) +
195
201
  ` (addr ${entity.device.networkAddress}): ` +
@@ -252,7 +258,7 @@ class ZigbeeController extends EventEmitter {
252
258
  if (all) {
253
259
  return devices;
254
260
  } else {
255
- return devices.filter((device) => device.type !== 'Coordinator');
261
+ return devices.filter(device => device.type !== 'Coordinator');
256
262
  }
257
263
  } else {
258
264
  return [];
@@ -261,8 +267,11 @@ class ZigbeeController extends EventEmitter {
261
267
 
262
268
  async getGroups() {
263
269
  try {
264
- const rv = await this.herdsman.getGroups();
265
- return rv;
270
+ if (this.herdsman) {
271
+ return await this.herdsman.getGroups();
272
+ } else {
273
+ return null;
274
+ }
266
275
  } catch (error) {
267
276
  this.sendError(error);
268
277
  this.error(JSON.stringify(error));
@@ -271,12 +280,12 @@ class ZigbeeController extends EventEmitter {
271
280
  }
272
281
 
273
282
  async removeGroupById(id) {
274
- const group = await this.getGroupByID(id);
283
+ const group = await this.getGroupByID(id);
275
284
  try {
276
- if (group) group.removeFromDatabase();
285
+ group && group.removeFromDatabase();
277
286
  } catch (error) {
278
287
  this.sendError(error);
279
- this.error('error in removeGroupById: ' + error);
288
+ this.error(`error in removeGroupById: ${error}`);
280
289
  }
281
290
  }
282
291
 
@@ -290,18 +299,16 @@ class ZigbeeController extends EventEmitter {
290
299
  }
291
300
 
292
301
  async verifyGroupExists(id) {
293
- const nid = (typeof(id) === 'number' ? id:parseInt(id));
302
+ const nid = typeof id === 'number' ? id : parseInt(id);
294
303
  let group = await this.herdsman.getGroupByID(nid);
295
304
  if (!group) {
296
305
  group = await this.herdsman.createGroup(nid);
297
306
  group.toZigbee = groupConverters;
298
307
  group.model = 'group';
299
- this.debug('verifyGroupExists: created group ' + nid);
300
- }
301
- else {
302
- this.debug('verifyGroupExists: group ' + nid + ' exists');
308
+ this.debug(`verifyGroupExists: created group ${nid}`);
309
+ } else {
310
+ this.debug(`verifyGroupExists: group ${nid} exists`);
303
311
  }
304
-
305
312
  }
306
313
 
307
314
  async getGroupMembersFromController(id) {
@@ -309,22 +316,30 @@ class ZigbeeController extends EventEmitter {
309
316
  try {
310
317
  const group = await this.getGroupByID(id);
311
318
  if (group) {
312
- const groupmembers = group.members;
313
- for (const member of groupmembers) {
314
- const epid = (member.ID ? member.ID:-1);
319
+ const groupMembers = group.members;
320
+ for (const member of groupMembers) {
321
+ const epid = member.ID ? member.ID : -1;
315
322
  const nwk = member.deviceNetworkAddress;
316
323
  const device = this.getDeviceByNetworkAddress(nwk);
317
- if (device && device.ieeeAddr) members.push( { ieee:device.ieeeAddr, model:device.modelID, epid:epid, ep:member } );
324
+ if (device && device.ieeeAddr) {
325
+ members.push({
326
+ ieee: device.ieeeAddr,
327
+ model: device.modelID,
328
+ epid,
329
+ ep: member
330
+ });
331
+ }
318
332
  }
319
- }
320
- else {
333
+ } else {
321
334
  return undefined;
322
335
  }
323
-
324
336
  } catch (error) {
325
337
  this.sendError(error);
326
- if (error) this.error('getGroupMembersFromController: error is ' + JSON.stringify(error) + ' ' + JSON.stringify(new Error().stack));
327
- else this.error('unidentifed error in getGroupMembersFromController');
338
+ if (error) {
339
+ this.error(`getGroupMembersFromController: error is ${JSON.stringify(error)} ${JSON.stringify(new Error().stack)}`);
340
+ } else {
341
+ this.error('unidentified error in getGroupMembersFromController');
342
+ }
328
343
  }
329
344
  return members;
330
345
  }
@@ -342,7 +357,7 @@ class ZigbeeController extends EventEmitter {
342
357
  }
343
358
 
344
359
  async resolveEntity(key, ep) {
345
- //assert(typeof key === 'string' || key.constructor.name === 'Device', `Wrong type '${typeof key}'`);
360
+ // assert(typeof key === 'string' || key.constructor.name === 'Device', `Wrong type '${typeof key}'`);
346
361
 
347
362
  if (typeof key === 'string') {
348
363
  if (key === 'coordinator') {
@@ -379,8 +394,6 @@ class ZigbeeController extends EventEmitter {
379
394
  endpoints: device.endpoints,
380
395
  name: key,
381
396
  };
382
- } else {
383
- return;
384
397
  }
385
398
  }
386
399
  } else if (typeof key === 'number') {
@@ -404,7 +417,7 @@ class ZigbeeController extends EventEmitter {
404
417
  }
405
418
  }
406
419
 
407
- async incMsgHandler(message){
420
+ async incMsgHandler(message) {
408
421
  this.debug('incoming msg', message);
409
422
  const device = await this.herdsman.getDeviceByIeeeAddr(message.srcaddr);
410
423
  if (!device) {
@@ -431,21 +444,21 @@ class ZigbeeController extends EventEmitter {
431
444
  await this.herdsman.stop();
432
445
  } catch (error) {
433
446
  this.sendError(error);
434
- if (this.herdsman_started)
447
+ if (this.herdsmanStarted) {
435
448
  this.error(`Failed to stop zigbee (${error.stack})`);
436
- else {
449
+ } else {
437
450
  this.warn(`Failed to stop zigbee during startup`);
438
451
  }
439
452
  }
440
453
  }
441
454
 
442
455
  async handleDisconnected() {
443
- this.herdsman_started = false;
456
+ this.herdsmanStarted = false;
444
457
  this.emit('disconnect');
445
458
  }
446
459
 
447
460
  connected() {
448
- return this.herdsman_started;
461
+ return this.herdsmanStarted;
449
462
  }
450
463
 
451
464
  // Permit join
@@ -462,8 +475,8 @@ class ZigbeeController extends EventEmitter {
462
475
  } else {
463
476
  this.info('Zigbee: disabling joining new devices.');
464
477
  }
465
- try
466
- {
478
+
479
+ try {
467
480
  if (permitTime && !this.herdsman.getPermitJoin()) {
468
481
  clearInterval(this._permitJoinInterval);
469
482
  this._permitJoinTime = permitTime;
@@ -509,6 +522,7 @@ class ZigbeeController extends EventEmitter {
509
522
  this.debug(`Force remove`);
510
523
  }
511
524
  }
525
+
512
526
  try {
513
527
  await device.removeFromDatabase();
514
528
  } catch (error) {
@@ -518,7 +532,7 @@ class ZigbeeController extends EventEmitter {
518
532
  this.debug(`Failed to remove from DB ${error.stack}`);
519
533
  }
520
534
  this.debug('Remove successful.');
521
- if (callback) callback();
535
+ callback && callback();
522
536
  this.callExtensionMethod(
523
537
  'onDeviceRemove',
524
538
  [device],
@@ -527,7 +541,7 @@ class ZigbeeController extends EventEmitter {
527
541
  } catch (error) {
528
542
  this.sendError(error);
529
543
  this.error(`Failed to remove ${error.stack}`);
530
- if (callback) callback(`Failed to remove ${error.stack}`);
544
+ callback && callback(`Failed to remove ${error.stack}`);
531
545
  }
532
546
  }
533
547
 
@@ -536,7 +550,7 @@ class ZigbeeController extends EventEmitter {
536
550
  try {
537
551
  this.debug('handleDeviceLeave', message);
538
552
  const entity = await this.resolveEntity(message.device || message.ieeeAddr);
539
- const friendlyName = (entity) ? entity.name : message.ieeeAddr;
553
+ const friendlyName = entity ? entity.name : message.ieeeAddr;
540
554
  this.debug(`Device '${friendlyName}' left the network`);
541
555
  this.emit('leave', message.ieeeAddr);
542
556
  // Call extensions
@@ -560,15 +574,17 @@ class ZigbeeController extends EventEmitter {
560
574
  if (entity && entity.mapped) {
561
575
  this.callExtensionMethod(
562
576
  'onZigbeeEvent',
563
- [ {'device': message.device, 'type': 'deviceAnnounce'}, (entity ? entity.mapped : null)]);
577
+ [{'device': message.device, 'type': 'deviceAnnounce'}, entity ? entity.mapped : null]);
564
578
  }
565
579
  } catch (error) {
566
580
  this.sendError(error);
567
581
  this.error(`Failed to handleDeviceLeave ${error.stack}`);
568
582
  }
569
-
583
+
570
584
  this.emit('pairing', `Device '${friendlyName}' announced itself`);
571
- if (!this.herdsman.getPermitJoin()) this.callExtensionMethod('registerDevicePing', [message.device, entity]);
585
+ if (!this.herdsman.getPermitJoin()) {
586
+ this.callExtensionMethod('registerDevicePing', [message.device, entity]);
587
+ }
572
588
  // if has modelID so can create device
573
589
  if (entity.device && entity.device._modelID) {
574
590
  entity.device.modelID = entity.device._modelID;
@@ -576,7 +592,6 @@ class ZigbeeController extends EventEmitter {
576
592
  }
577
593
  }
578
594
 
579
-
580
595
  async handleDeviceJoined(message) {
581
596
  this.debug('handleDeviceJoined', message);
582
597
  //const entity = await this.resolveEntity(message.device || message.ieeeAddr);
@@ -593,7 +608,7 @@ class ZigbeeController extends EventEmitter {
593
608
  const entity = await this.resolveEntity(message.device || message.ieeeAddr);
594
609
  const friendlyName = entity.name;
595
610
  if (message.status === 'successful') {
596
- this.info(`Successfully interviewed '${friendlyName}', device has succesfully been paired`);
611
+ this.info(`Successfully interviewed '${friendlyName}', device has successfully been paired`);
597
612
 
598
613
  if (entity.mapped) {
599
614
  const {vendor, description, model} = entity.mapped;
@@ -620,7 +635,7 @@ class ZigbeeController extends EventEmitter {
620
635
  this.emit('new', entity);
621
636
  }
622
637
  } else if (message.status === 'failed') {
623
- this.error(`Failed to interview '${friendlyName}', device has not succesfully been paired. ${message.error}`);
638
+ this.error(`Failed to interview '${friendlyName}', device has not successfully been paired. ${message.error}`);
624
639
  this.emit('pairing', 'Interview failed', friendlyName);
625
640
  } else {
626
641
  if (message.status === 'started') {
@@ -650,12 +665,11 @@ class ZigbeeController extends EventEmitter {
650
665
 
651
666
  async getMap(callback) {
652
667
  try {
653
-
654
668
  const devices = this.herdsman.getDevices(true);
655
669
  const lqis = [];
656
670
  const routing = [];
657
671
 
658
- for (const device of devices.filter((d) => d.type != 'EndDevice')) {
672
+ for (const device of devices.filter((d) => d.type !== 'EndDevice')) {
659
673
  const resolved = await this.resolveEntity(device);
660
674
  let result;
661
675
 
@@ -663,8 +677,7 @@ class ZigbeeController extends EventEmitter {
663
677
  result = await device.lqi();
664
678
  } catch (error) {
665
679
  this.sendError(error);
666
- if (error)
667
- this.debug(`Failed to execute LQI for '${resolved.name}'. ${safeJsonStringify(error.stack)}`);
680
+ error && this.debug(`Failed to execute LQI for '${resolved.name}'. ${safeJsonStringify(error.stack)}`);
668
681
 
669
682
  lqis.push({
670
683
  parent: 'undefined',
@@ -679,7 +692,7 @@ class ZigbeeController extends EventEmitter {
679
692
 
680
693
  if (result !== undefined) {
681
694
  for (const dev of result.neighbors) {
682
- if (dev.ieeeAddr !== '0xffffffffffffffff' && dev !== undefined) {
695
+ if (dev !== undefined && dev.ieeeAddr !== '0xffffffffffffffff') {
683
696
  lqis.push({
684
697
  parent: resolved.device.ieeeAddr,
685
698
  networkAddress: dev.networkAddress,
@@ -687,7 +700,7 @@ class ZigbeeController extends EventEmitter {
687
700
  lqi: dev.linkquality,
688
701
  relationship: dev.relationship,
689
702
  depth: dev.depth,
690
- status: (dev.linkquality > 0) ? 'online' : 'offline',
703
+ status: dev.linkquality > 0 ? 'online' : 'offline',
691
704
  });
692
705
  }
693
706
  }
@@ -718,11 +731,10 @@ class ZigbeeController extends EventEmitter {
718
731
  }
719
732
  }
720
733
  this.debug(`Routing table succeeded for '${resolved.name}'`);
721
-
722
734
  }
723
735
  this.debug(`Get map succeeded ${safeJsonStringify(lqis)}`);
724
736
 
725
- if (callback) callback({lqis: lqis, routing: routing});
737
+ callback && callback({lqis, routing});
726
738
  } catch (error) {
727
739
  this.sendError(error);
728
740
  this.debug(`Failed to get map: ${safeJsonStringify(error.stack)}`);
@@ -755,7 +767,7 @@ class ZigbeeController extends EventEmitter {
755
767
  if (type === 'foundation') {
756
768
  cfg.disableDefaultResponse = true;
757
769
  if (cmd === 'read' && !Array.isArray(zclData)) {
758
- // needs to be iterateable (string[] | number [])
770
+ // needs to be iterable (string[] | number [])
759
771
  zclData[Symbol.iterator] = function* () {
760
772
  let k;
761
773
  for (k in this) {
@@ -769,17 +781,15 @@ class ZigbeeController extends EventEmitter {
769
781
  } else {
770
782
  result = await endpoint[cmd](cid, zclData, cfg);
771
783
  }
772
- if (callback) callback(undefined, result);
773
- }
774
- else if(type === 'functionalResp'){
775
- cfg.disableDefaultResponse = false;
776
- const result = await endpoint.commandResponse(cid, cmd, zclData, cfg, zclSeqNum);
777
- if (callback) callback(undefined, result);
778
- }
779
- else {
784
+ callback && callback(undefined, result);
785
+ } else if (type === 'functionalResp') {
786
+ cfg.disableDefaultResponse = false;
787
+ const result = await endpoint.commandResponse(cid, cmd, zclData, cfg, zclSeqNum);
788
+ callback && callback(undefined, result);
789
+ } else {
780
790
  cfg.disableDefaultResponse = false;
781
791
  const result = await endpoint.command(cid, cmd, zclData, cfg);
782
- if (callback) callback(undefined, result);
792
+ callback && callback(undefined, result);
783
793
  }
784
794
  }
785
795
 
@@ -790,66 +800,60 @@ class ZigbeeController extends EventEmitter {
790
800
  this.debug(`addDevFromGroup - entity: ${safeJsonStringify(entity)}`);
791
801
  this.debug(`addDevFromGroup - group: ${safeJsonStringify(group)}`);
792
802
  if (epid != undefined) {
793
- for (const ep of entity.endpoints) {
794
- if (ep.ID == epid && (ep.inputClusters.includes(4) || ep.outputClusters.includes(4)))
795
- {
796
- this.debug(`adding endpoint ${ep.ID} (${epid}) to group ${groupId}`)
797
- await(ep.addToGroup(group.mapped));
803
+ for (const ep of entity.endpoints) {
804
+ if (ep.ID === epid && (ep.inputClusters.includes(4) || ep.outputClusters.includes(4))) {
805
+ this.debug(`adding endpoint ${ep.ID} (${epid}) to group ${groupId}`);
806
+ await (ep.addToGroup(group.mapped));
807
+ }
798
808
  }
799
- }
800
-
801
- }
802
- else
803
- {
804
- if (entity.endpoint.inputClusters.includes(4))
805
- {
806
- this.debug(`adding endpoint ${entity.endpoint.ID} to group`)
809
+ } else {
810
+ if (entity.endpoint.inputClusters.includes(4)) {
811
+ this.debug(`adding endpoint ${entity.endpoint.ID} to group`);
807
812
  await entity.endpoint.addToGroup(group.mapped);
808
- }
809
- else {
813
+ } else {
810
814
  let added = false;
811
- for (const ep of entity.endpoints)
812
- {
813
- if (ep.inputClusters.includes(4))
814
- {
815
- this.debug(`adding endpoint ${ep.ID} to group`)
815
+ for (const ep of entity.endpoints) {
816
+ if (ep.inputClusters.includes(4)) {
817
+ this.debug(`adding endpoint ${ep.ID} to group`);
816
818
  await ep.addToGroup(group.mapped);
817
819
  added = true;
818
820
  break;
819
821
  }
820
822
  }
821
- if (!added) throw ('cluster genGroups not supported');
823
+ if (!added) {
824
+ throw ('cluster genGroups not supported');
825
+ }
822
826
  }
823
827
  }
824
828
  } catch (error) {
825
829
  this.sendError(error);
826
830
  this.error(`Exception when trying to Add ${devId} to group ${groupId}`, error);
827
- return { error:`Failed to add ${devId} to group ${groupId}: ${JSON.stringify(error)}` };
831
+ return {error: `Failed to add ${devId} to group ${groupId}: ${JSON.stringify(error)}`};
828
832
  }
829
833
  return {};
830
834
  }
831
835
 
832
836
  async removeDevFromGroup(devId, groupId, epid) {
833
- try {
834
- const entity = await this.resolveEntity(devId);
835
- const group = await this.resolveEntity(groupId);
836
- this.debug(`removeDevFromGroup - entity: ${safeJsonStringify(entity)}`);
837
- this.debug(`removeDevFromGroup - group: ${safeJsonStringify(group)}`);
838
- if (epid != undefined) {
839
- for (const ep of entity.endpoints) {
840
- if (ep.ID == epid && (ep.inputClusters.includes(4) || ep.outputClusters.includes(4)))
841
- {
842
- this.debug(`removing endpoint ${ep.ID} (${epid}) group ${groupId}`)
843
- await(ep.removeFromGroup(group.mapped))
844
- }
845
- }
846
- } else await entity.endpoint.removeFromGroup(group.mapped);
847
- } catch (error) {
848
- this.sendError(error);
849
- this.error(`Exception when trying remove ${devId} (ep ${epid?epid:entity.endpoint.ID}) from group ${devId}`, error);
850
- return { error: `Failed to remove dev ${devId} (ep ${epid?epid:entity.endpoint.ID}) from group ${devId}`};
851
- }
852
- return {};
837
+ let entity;
838
+ try {
839
+ entity = await this.resolveEntity(devId);
840
+ const group = await this.resolveEntity(groupId);
841
+ this.debug(`removeDevFromGroup - entity: ${safeJsonStringify(entity)}`);
842
+ this.debug(`removeDevFromGroup - group: ${safeJsonStringify(group)}`);
843
+ if (epid != undefined) {
844
+ for (const ep of entity.endpoints) {
845
+ if (ep.ID === epid && (ep.inputClusters.includes(4) || ep.outputClusters.includes(4))) {
846
+ this.debug(`removing endpoint ${ep.ID} (${epid}) group ${groupId}`);
847
+ await ep.removeFromGroup(group.mapped);
848
+ }
849
+ }
850
+ } else await entity.endpoint.removeFromGroup(group.mapped);
851
+ } catch (error) {
852
+ this.sendError(error);
853
+ this.error(`Exception when trying remove ${devId} (ep ${epid ? epid : (entity ? entity.endpoint.ID : '')}) from group ${devId}`, error);
854
+ return {error: `Failed to remove dev ${devId} (ep ${epid ? epid : (entity ? entity.endpoint.ID : '')}) from group ${devId}`};
855
+ }
856
+ return {};
853
857
  }
854
858
 
855
859
  async removeDevFromAllGroups(devId) {
@@ -857,14 +861,15 @@ class ZigbeeController extends EventEmitter {
857
861
  const entity = await this.resolveEntity(devId);
858
862
  this.debug(`entity: ${safeJsonStringify(entity)}`);
859
863
  for (const ep of entity.endpoints) {
860
- if (ep.inputClusters.includes(4) || ep.outputClusters.includes(4))
861
- await ep.removefromAllGroups();
864
+ if (ep.inputClusters.includes(4) || ep.outputClusters.includes(4)) {
865
+ await ep.removefromAllGroups();
866
+ }
862
867
  }
863
- //await entity.endpoint.removeFromAllGroups();
868
+ // await entity.endpoint.removeFromAllGroups();
864
869
  } catch (error) {
865
870
  this.sendError(error);
866
871
  this.error(`Exception when trying remove ${devId} from all groups`, error);
867
- return { error: `Failed to remove dev ${devId} from all groups: ${error}`};
872
+ return {error: `Failed to remove dev ${devId} from all groups: ${error}`};
868
873
  }
869
874
  return {};
870
875
  }
@@ -874,7 +879,7 @@ class ZigbeeController extends EventEmitter {
874
879
  target = !target ? this.getCoordinator() : target;
875
880
 
876
881
  this.debug(`Binding ${log}`);
877
- ep.bind(cluster, target, (error) => {
882
+ ep.bind(cluster, target, error => {
878
883
  if (error) {
879
884
  this.sendError(error);
880
885
  this.error(`Failed to bind ${log} - (${error})`);
@@ -905,11 +910,11 @@ class ZigbeeController extends EventEmitter {
905
910
  reset(mode, callback) {
906
911
  try {
907
912
  this.herdsman.reset(mode);
908
- if (callback) callback();
913
+ callback && callback();
909
914
  } catch (error) {
910
915
  this.sendError(error);
911
916
  this.error(`Failed to reset ${error.stack}`);
912
- if (callback) callback(error);
917
+ callback && callback(error);
913
918
  }
914
919
  }
915
920
 
@@ -933,12 +938,12 @@ class ZigbeeController extends EventEmitter {
933
938
  nwkmanageraddr: 0x0000
934
939
  };
935
940
  const energyScan = this.herdsman.adapter.znp.waitFor(
936
- 2, //unpi_1.Constants.Type.AREQ,
937
- 5, //Subsystem.ZDO,
941
+ 2, // unpi_1.Constants.Type.AREQ,
942
+ 5, // Subsystem.ZDO,
938
943
  'mgmtNwkUpdateNotify'
939
944
  );
940
945
  await this.herdsman.adapter.znp.request(
941
- 0x5, //Subsystem.ZDO
946
+ 0x5, // Subsystem.ZDO
942
947
  'mgmtNwkUpdateReq',
943
948
  payload,
944
949
  energyScan.ID