iobroker.zigbee 3.1.4 → 3.1.6

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/lib/commands.js CHANGED
@@ -176,6 +176,9 @@ class Commands {
176
176
  case 'downloadIcons':
177
177
  this.triggerIconDownload(obj);
178
178
  break;
179
+ case 'aliveCheck':
180
+ this.adapter.sendTo(obj.from, obj.command, {msg:'success'}, obj.callback);
181
+ break;
179
182
  default:
180
183
  this.debug(`Commands: Command ${obj.command} is unknown`);
181
184
  //this.adapter.sendTo(obj.from, obj.command, obj.message, obj.callback);
@@ -336,10 +339,6 @@ class Commands {
336
339
  }
337
340
  }
338
341
 
339
-
340
- async handleDeviceforInfo(device, states) {
341
- }
342
-
343
342
  async handleGroupforInfo(group, groups) {
344
343
  group.icon = 'img/group.png';
345
344
  group.vendor = 'ioBroker';
@@ -355,7 +354,13 @@ class Commands {
355
354
  if (member && typeof member.ieee === 'string') {
356
355
  const memberId = member.ieee.substr(2);
357
356
  const device = await this.adapter.getObjectAsync(`${this.adapter.namespace}.${member.ieee.substr(2)}`);
358
- if (groups.hasOwnProperty(memberId)) { if (!groups[memberId].includes(groupID)) groups[memberId].push(groupID)} else groups[memberId] = [groupID]
357
+ const item = groups[memberId] || { groups:[], gep: { }};
358
+ const gep = item.gep[member.epid] || [];
359
+
360
+ if (!item.groups.includes(groupID)) item.groups.push(groupID);
361
+ if (!gep.includes(`${groupID}`)) gep.push(`${groupID}`);
362
+ item.gep[member.epid] = gep;
363
+ groups[memberId] = item;
359
364
  if (device) {
360
365
  member.device = device.common.name;
361
366
  } else {
@@ -370,7 +375,7 @@ class Commands {
370
375
  }
371
376
  }
372
377
 
373
- async fillInfo(device, device_stateDefs, all_states) {
378
+ async fillInfo(device, device_stateDefs, all_states, models) {
374
379
  device.statesDef = (device_stateDefs || []).filter(stateDef => {
375
380
  const sid = stateDef._id.replace(this.adapter.namespace + '.', '');
376
381
  const names = sid.split('.');
@@ -394,7 +399,23 @@ class Commands {
394
399
  });
395
400
 
396
401
  const id = getZbId(device._id);
397
- device.info = this.buildDeviceInfo(await this.zbController.resolveEntity(id));
402
+ const entity = await this.zbController.resolveEntity(id)
403
+
404
+ device.info = this.buildDeviceInfo(entity);
405
+
406
+ const UID = models.UIDbyModel[device.info?.mapped?.model || 'unknown'] || `m_${Object.keys(models.UIDbyModel).length}`;
407
+ if (models.byUID.hasOwnProperty(UID)) {
408
+ models.byUID[UID].devices.push(device);
409
+ }
410
+ else {
411
+ models.byUID[UID] = {
412
+ model:device.info.mapped,
413
+ availableOptions : [...device.info?.mapped?.options || [], ...['use_legacy_model']],
414
+ setOptions: this.adapter.stController.localConfig.getByModel(device.info?.mapped?.model || 'unknown') || [],
415
+ devices: [device],
416
+ }
417
+ models.UIDbyModel[device.info?.mapped?.model || 'unknown'] = UID;
418
+ }
398
419
  // check configuration
399
420
  try {
400
421
  if (device.info) {
@@ -403,13 +424,11 @@ class Commands {
403
424
  [device.info.device, device.info.mapped],
404
425
  );
405
426
  if (result.length > 0) device.isConfigured = !result[0];
406
- }
427
+ device.paired = true;
428
+ } else device.paired = false;
407
429
  } catch (error) {
408
430
  this.warn('error calling shouldConfigure: ' + error && error.message ? error.message : 'no error message');
409
431
  }
410
- device.paired = !!device.info;
411
-
412
-
413
432
  }
414
433
 
415
434
  buildDeviceInfo(device) {
@@ -418,11 +437,11 @@ class Commands {
418
437
  rv.device = {
419
438
  modelZigbee:device.device.modelID,
420
439
  type:device.device.type,
421
- ieee:device.device.ieeeAddr,
422
- nwk:device.device.networkAddress,
440
+ ieee:device.device.ieeeAddr || device.device.groupID,
441
+ nwk:device.device.networkAddress || 0,
423
442
  manuf_id:device.device.maufacturerID,
424
443
  manuf_name:device.device.manufacturerName,
425
- manufacturer:device.mapped.vendor,
444
+ manufacturer:device.mapped?.vendor,
426
445
  power:device.device.powerSource,
427
446
  app_version:device.device.applicationVersion,
428
447
  hard_version:device.device.hardwareVersion,
@@ -442,25 +461,40 @@ class Commands {
442
461
  output_clusters:ep.outputClusters,
443
462
  })
444
463
  }
445
- rv.mapped = {
446
- model:device.mapped.model,
447
- description:device.mapped.description,
448
- //fingerprint:JSON.stringify(device.mapped.fingerprint),
449
- vendor:device.mapped.vendor,
450
- hasOnEvent:device.mapped.onEvent != undefined,
451
- hasConfigure:device.mapped.configure != undefined,
452
- options:[],
453
- }
454
- if (device.mapped.options && typeof (device.mapped.options == 'object')) {
455
- const optionDesc = [];
456
- for (const option of device.mapped.options) {
457
- if (option.name)
458
- rv.mapped.options.push(option.name);
464
+ if (device.mapped) {
465
+ rv.mapped = {
466
+ model:device.mapped.model,
467
+ description:device.mapped.description,
468
+ //fingerprint:JSON.stringify(device.mapped.fingerprint),
469
+ vendor:device.mapped.vendor,
470
+ hasOnEvent:device.mapped.onEvent != undefined,
471
+ hasConfigure:device.mapped.configure != undefined,
472
+ options:[],
473
+ }
474
+ if (device.mapped.options && typeof (device.mapped.options == 'object')) {
475
+ for (const option of device.mapped.options) {
476
+ if (option.name) {
477
+ rv.mapped.options.push(option.name);
478
+ }
479
+ }
480
+ }
481
+ }
482
+ else {
483
+ rv.mapped = {
484
+ model:device.name,
485
+ description:device.name,
486
+ vendor:'not set',
487
+ hasOnEvent: false,
488
+ hasConfigure: false,
489
+ options:[],
459
490
  }
460
491
  }
461
492
  }
462
493
  catch (error) {
463
- this.warn(`Error ${error && error.message + ' ' ? error.message : ''}building device info for ${JSON.stringify(device)}`);
494
+ if (device && device.name === 'Coordinator') return rv;
495
+ const dev = device ? device.device || {} : {}
496
+ const msg = device ? `device ${device.name} (${dev.ieeeAddr}, NWK ${dev.networkAddres}, ID: ${dev.ID})` : 'undefined device';
497
+ this.warn(`Error ${error && error.message ? error.message + ' ' : ''}building device info for ${msg}`);
464
498
  }
465
499
  return rv;
466
500
  }
@@ -472,19 +506,23 @@ class Commands {
472
506
  }
473
507
  const exists = devices.find((dev) => (dev._id && device.device.ieeeAddr === getZbId(dev._id)));
474
508
  if (!exists) {
475
- devices.push({
476
- _id: device.device.ieeeAddr,
477
- icon: 'img/unknown.png',
509
+ const coordinatorData = {
510
+ _id : `${this.adapter.namespace}.${device.device.ieeeAddr.substring(2)}`,
478
511
  paired: true,
479
512
  info: this.buildDeviceInfo(device),
480
- common: {
481
- name: undefined,
482
- type: undefined,
483
- },
484
- native: {}
485
- });
513
+ native: { id: device.device.ieeeAddr.substring(2) },
514
+ mapped : { model:'Coordinator' },
515
+ statesDev: [],
516
+ }
517
+ if (device.device.name === 'Coordinator') {
518
+ coordinatorData.icon = 'zigbee.png';
519
+ coordinatorData.common = { name: undefined, type: undefined };
520
+ } else {
521
+ coordinatorData.common = { name: 'Coordinator', type: 'Coordinator' };
522
+ coordinatorData.icon= 'img/unknown.png';
523
+ }
524
+ devices.push(coordinatorData);
486
525
  }
487
-
488
526
  }
489
527
 
490
528
  async getDevices(from, command, id, callback) {
@@ -493,13 +531,14 @@ class Commands {
493
531
  this.adapter.sendTo(from, command, {error: 'No active connection to Zigbee Hardware!'}, callback);
494
532
  return;
495
533
  }
496
- const rooms = await this.adapter.getEnumsAsync('enum.rooms') || {};
534
+ const roomsEnum = await this.adapter.getEnumsAsync('enum.rooms') || {};
497
535
  const deviceObjects = (id ? [await this.adapter.getObjectAsync(id)] : await this.adapter.getDevicesAsync());
498
536
  const all_states = id ? await this.adapter.getStatesAsync(id + '.*') : await this.adapter.getStatesAsync('*');
499
537
  const all_stateDefs = id ? await this.adapter.getStatesOfAsync(id) : await this.adapter.getStatesOfAsync();
500
538
  const illegalDevices = [];
501
539
  const groups = {};
502
540
  const PromiseChain = [];
541
+ const models = { byUID : {}, UIDbyModel: {} };
503
542
  for (const devInfo of deviceObjects) {
504
543
  if (devInfo._id.indexOf('group') > -1) {
505
544
  PromiseChain.push(this.handleGroupforInfo(devInfo, groups));
@@ -515,25 +554,26 @@ class Commands {
515
554
  devInfo.link_quality_lc = lq_state ? lq_state.lc : undefined;
516
555
  const battery_state = all_states[`${devInfo._id}.battery`];
517
556
  devInfo.battery = battery_state ? battery_state.val : undefined;
518
- devInfo.rooms = [];
519
- for (const room in rooms) {
520
- if (!rooms.hasOwnProperty(room) ||
521
- !rooms[room] ||
522
- !rooms[room].common ||
523
- !rooms[room].common.members
524
- ) {
525
- continue;
526
- }
527
- if (rooms[room].common.members.includes(devInfo._id)) {
528
- devInfo.rooms.push(rooms[room].common.name);
529
- }
530
- }
531
557
 
532
558
  }
533
- PromiseChain.push(this.fillInfo(devInfo, all_stateDefs.filter(item => item._id.startsWith(devInfo._id)),all_states));
559
+ devInfo.rooms = [];
560
+ const rooms = roomsEnum['enum.rooms'] || {};
561
+ for (const room of Object.keys(rooms)) {
562
+ if (!rooms.hasOwnProperty(room) ||
563
+ !rooms[room] ||
564
+ !rooms[room].common ||
565
+ !rooms[room].common.members
566
+ ) {
567
+ continue;
568
+ }
569
+ if (rooms[room].common.members.includes(devInfo._id)) {
570
+ devInfo.rooms.push(rooms[room].common.name);
571
+ }
572
+ }
573
+ PromiseChain.push(this.fillInfo(devInfo, all_stateDefs.filter(item => item._id.startsWith(devInfo._id)),all_states, models));
534
574
  }
535
575
  if (!id) {
536
- for (const client of this.zbController.getClientIterator(false)) {
576
+ for (const client of this.zbController.getClientIterator(true)) {
537
577
  PromiseChain.push(this.appendDevicesWithoutObjects(deviceObjects,client))
538
578
  }
539
579
  }
@@ -543,14 +583,20 @@ class Commands {
543
583
  for (const groupmember in groups) {
544
584
  const device = deviceObjects.find(dev => (groupmember === dev.native.id));
545
585
  if (device) {
546
- device.groups = groups[groupmember];
586
+ device.groups = groups[groupmember].groups;
587
+ device.groups_by_ep = groups[groupmember].gep;
547
588
  }
548
589
  }
549
590
 
550
591
 
551
592
  this.debug(`getDevices contains ${deviceObjects.length} Devices`);
552
593
  const rv = { devices:deviceObjects, inLog:this.adapter.deviceDebug.logStatus, }
553
- if (!id) rv.byId = this.adapter.deviceDebug.collectDebugData();
594
+ if (!id) {
595
+ rv.deviceDebugData = this.adapter.deviceDebug.collectDebugData();
596
+ rv.localOverrides = this.adapter.stController.localConfig.localData;
597
+ rv.models = models.byUID;
598
+ }
599
+
554
600
  if (this.stController) {
555
601
  rv.clean = this.stController.CleanupRequired();
556
602
  rv.errors = this.stController.getStashedErrors();
@@ -777,7 +823,6 @@ class Commands {
777
823
  this.debug(`updateLocalConfigItems : ${JSON.stringify(msg)}`);
778
824
  const target = msg.target.replace(`${this.adapter.namespace}.`, '');
779
825
  const entity = await this.zbController.resolveEntity(target);
780
- //this.warn('entity for ' + target + ' is '+ JSON.stringify(entity))
781
826
  if (entity && !entity.mapped) {
782
827
  this.warn('unable to set local Override for device whithout mapped model');
783
828
  return;
@@ -811,13 +856,18 @@ class Commands {
811
856
  await this.stController.localConfig.updateLocalOverride(target, (entity ? entity.mapped.model : 'group'), prop, msg.data[prop], msg.global);
812
857
  }
813
858
  }
814
- if (entity) {
815
- this.debug('updateLocalConfigItems with Entity');
816
- this.stController.updateDev(target, entity.mapped.model, entity.mapped.model, () => {this.adapter.sendTo(from, command, {}, callback)});
859
+ try {
860
+ if (entity) {
861
+ this.debug('updateLocalConfigItems with Entity');
862
+ this.stController.updateDev(target, entity.mapped.model, entity.mapped.model, () => {this.adapter.sendTo(from, command, {}, callback)});
863
+ }
864
+ else {
865
+ this.debug('updateLocalConfigItems without Entity');
866
+ this.stController.updateDev(target, undefined, 'group',() => {this.adapter.sendTo(from, command, {}, callback)});
867
+ }
817
868
  }
818
- else {
819
- this.debug('updateLocalConfigItems without Entity');
820
- this.stController.updateDev(target, undefined, 'group',() => {this.adapter.sendTo(from, command, {}, callback)});
869
+ catch (error) {
870
+ this.adapter.sendTo(from, command, {err: error.message}, callback);
821
871
  }
822
872
  }
823
873
  }
@@ -841,6 +891,9 @@ class Commands {
841
891
  //const targetModel = msg.model ? msg.model : '';
842
892
  }
843
893
  else {
894
+ if (msg.getAllData) {
895
+ this.adapter.sendTo(from, command, this.stController.localConfig.localData, callback);
896
+ }
844
897
  rv.error = `missing data in message ${JSON.stringify(msg)}`;
845
898
  }
846
899
  }
package/lib/developer.js CHANGED
File without changes
package/lib/exposes.js CHANGED
@@ -801,7 +801,7 @@ function createFromExposes(model, def, device, log) {
801
801
 
802
802
  case 'climate':
803
803
  for (const prop of expose.features) {
804
- switch (prop.name) {
804
+ /* switch (prop.name) {
805
805
  case 'away_mode':
806
806
  pushToStates(statesDefs.climate_away_mode, prop.access);
807
807
  break;
@@ -814,7 +814,8 @@ function createFromExposes(model, def, device, log) {
814
814
  default:
815
815
  pushToStates(genState(prop), prop.access);
816
816
  break;
817
- }
817
+ }*/
818
+ pushToStates(genState(prop), prop.access);
818
819
  }
819
820
  break;
820
821
 
@@ -329,6 +329,14 @@ class localConfig extends EventEmitter {
329
329
  return rv;
330
330
  }
331
331
 
332
+ getByModel(id) {
333
+ return this.localData.by_model[id] || {};
334
+ }
335
+
336
+ getByDevice(id) {
337
+ return this.localData.by_id[id] || {};
338
+ }
339
+
332
340
  }
333
341
 
334
342
  module.exports = localConfig;
package/lib/ota.js CHANGED
File without changes
@@ -458,7 +458,7 @@ class StatesController extends EventEmitter {
458
458
  if (stateDesc.id === 'send_payload') {
459
459
  try {
460
460
  const json_value = JSON.parse(value);
461
- const payload = {device: deviceId.replace('0x', ''), payload: json_value, model:model, stateModel:stateModel};
461
+ const payload = {device: deviceId.replace('0x', ''), payload: json_value, model:model, stateModel:stateModel, acknowledge:true};
462
462
  if (has_elevated_debug) this.emit('device_debug', { ID:debugID, data: { flag: '04' ,payload:value ,states:[{id:stateDesc.id, value:json_value, payload:'none'}], IO:false }});
463
463
 
464
464
  this.emit('send_payload', payload, debugID, has_elevated_debug);
File without changes
@@ -67,7 +67,6 @@ class DeviceEvent extends BaseExtension {
67
67
 
68
68
 
69
69
  if (mappedDevice && mappedDevice.onEvent && eventData.data) {
70
- this.warn(`calling onEvent for ${eventData.type} on ${device.ieeeAddr}`);
71
70
  try {
72
71
  mappedDevice.onEvent(eventData);
73
72
  }
@@ -618,6 +618,7 @@ class ZigbeeController extends EventEmitter {
618
618
  device: coordinator,
619
619
  endpoint: coordinator.getEndpoint(1),
620
620
  name: 'Coordinator',
621
+ mapped: { model: 'Coordinator'},
621
622
  options:{}
622
623
  };
623
624
  }
@@ -657,6 +658,7 @@ class ZigbeeController extends EventEmitter {
657
658
  return {
658
659
  type: 'device',
659
660
  device: device,
661
+ mapped: { model: 'Coordinator'},
660
662
  endpoint: device.getEndpoint(1),
661
663
  name: 'Coordinator',
662
664
  };
@@ -676,7 +678,7 @@ class ZigbeeController extends EventEmitter {
676
678
  endpoint = device.endpoints[0];
677
679
  }
678
680
  }
679
- const options = this.adapter.stController.localConfig.getOptions(device.ieeeAddr, mapped.model);
681
+ const options = mapped ? this.adapter.stController.localConfig.getOptions(device.ieeeAddr, mapped.model) : {};
680
682
  return {
681
683
  type: 'device',
682
684
  device,
@@ -731,13 +733,14 @@ class ZigbeeController extends EventEmitter {
731
733
  }
732
734
 
733
735
  try {
734
- if (this.HerdsmanStarted) {
736
+ if (this.herdsmanStarted) {
735
737
  await this.permitJoin(0);
736
738
  await this.herdsman.stop();
737
- this.HerdsmanStarted = false;
739
+ this.herdsmanStarted = false;
738
740
  this.info('zigbecontroller stopped successfully');
741
+ return;
739
742
  }
740
- this.info('zigbecontroller stopped successfully - ZH was not running');
743
+ else this.info('zigbecontroller stopped successfully - ZH was not running');
741
744
  } catch (error) {
742
745
  this.sendError(error);
743
746
  if (this.herdsmanStarted) {
@@ -759,6 +762,7 @@ class ZigbeeController extends EventEmitter {
759
762
 
760
763
  // Permit join
761
764
  async permitJoin(permitTime, devid) {
765
+ if (!this.herdsmanStarted) return false;
762
766
  try {
763
767
  this._permitJoinTime = permitTime;
764
768
  await this.herdsman.permitJoin(permitTime);
@@ -876,10 +880,11 @@ class ZigbeeController extends EventEmitter {
876
880
  async handleDeviceAnnounce(message) {
877
881
  if (this.debugActive) this.debug('handleDeviceAnnounce', message);
878
882
  const entity = await this.resolveEntity(message.device || message.ieeeAddr);
879
- const friendlyName = entity.name;
880
-
883
+ const friendlyName = entity ? entity.name : message.ieeeAddr ? message.ieeeAddr : message.device && message.device.ieeeAddr ? message.device.ieeeAddr : 'without data';
881
884
 
882
885
  this.emit('pairing', `Device '${friendlyName}' announced itself`);
886
+ if (!entity) return;
887
+
883
888
  if (this.adapter.stController.checkDebugDevice(friendlyName)) {
884
889
  this.emit('device_debug', {ID: Date.now(), data: {flag:'da', states:[{id: '--', value:'--', payload:message}] , IO:true} ,message:`Device '${friendlyName}' announced itself`});
885
890
  }
@@ -1386,7 +1391,7 @@ class ZigbeeController extends EventEmitter {
1386
1391
  // device: name of the device. For a device zigbee.0.0011223344556677 this would be 0011223344556677
1387
1392
  // payload: The data to send to the device as JSON object (key/Value pairs)
1388
1393
  // endpoint: optional: the endpoint to send the data to, if supported.
1389
- //
1394
+ // acknowledge: optional: if to update the devices 'send_payload' DP (if present) after successful publish
1390
1395
  async publishPayload(payload, debugID, has_elevated_debug) {
1391
1396
  let payloadObj = {};
1392
1397
  if (typeof payload === 'string') {
@@ -1450,6 +1455,9 @@ class ZigbeeController extends EventEmitter {
1450
1455
  }
1451
1456
  try {
1452
1457
  await this.publishFromState(`0x${payload.device}`, payload.model, payload.stateModel, stateList, payload.options, debugID, has_elevated_debug);
1458
+ if (payload.acknowledge) {
1459
+ this.emit('acknowledge_state', payload.device, payload.model, { id:'send_payload' }, undefined);
1460
+ }
1453
1461
  return {success: true};
1454
1462
  } catch (error) {
1455
1463
  this.log.error(`Error ${error.code} on send command to ${payload.device}.` + ` Error: ${error.stack} ` + `Send command to ${payload.device} failed with ` + error);
package/main.js CHANGED
@@ -274,7 +274,6 @@ class Zigbee extends utils.Adapter {
274
274
 
275
275
  SandboxRequire(sandbox, items) {
276
276
  if (!items) return true;
277
- //let converterLoaded = true;
278
277
  for (const item of items) {
279
278
  const modulePath = item[2].replace(/['"]/gm, '');
280
279
 
@@ -350,9 +349,6 @@ class Zigbee extends utils.Adapter {
350
349
  converterLoaded = false;
351
350
  this.log.error(`converter does not export any converter array, please add 'module.exports' statement to ${mN}`);
352
351
  }
353
-
354
- //fs.writeFileSync(mN+'.tmp', modifiedCode)
355
-
356
352
  if (converterLoaded) {
357
353
  try {
358
354
  this.log.warn('Trying to run sandbox for ' + mN);
@@ -422,7 +418,6 @@ class Zigbee extends utils.Adapter {
422
418
  }
423
419
  else try {
424
420
  await this.zbController.stopHerdsman();
425
- //this.logToPairing('herdsman stopped !');
426
421
  this.sendTo(from, command, { status:true }, callback);
427
422
  } catch (error) {
428
423
  this.sendTo(from, command, { status:true, error }, callback);
@@ -458,12 +453,6 @@ class Zigbee extends utils.Adapter {
458
453
  this.setState('info.connection', false, true);
459
454
  this.logToPairing(`Failed to start Zigbee: ${error && error.message ? error.message : 'no message given'}`)
460
455
  this.log.error(`Failed to start Zigbee: ${error && error.message ? error.message : 'no message given'}`);
461
- /* if (error.stack) {
462
- this.log.error(error.stack);
463
- } else {
464
- this.log.error(error);
465
- }
466
- */
467
456
  this.sendError(error, `Failed to start Zigbee`);
468
457
  if (noReconnect) return false;
469
458
 
@@ -668,12 +657,18 @@ class Zigbee extends utils.Adapter {
668
657
  }
669
658
 
670
659
  acknowledgeState(deviceId, model, stateDesc, value) {
671
- if (model === 'group') {
672
- const stateId = `${this.namespace}.group_${deviceId}.${stateDesc.id}`;
673
- this.setState(stateId, value, true);
674
- } else {
675
- const stateId = `${this.namespace}.${deviceId.replace('0x', '')}.${stateDesc.id}`;
676
- this.setState(stateId, value, true);
660
+ const stateId = (model === 'group' ?
661
+ `${this.namespace}.group_${deviceId}.${stateDesc.id}` :
662
+ `${this.namespace}.${deviceId.replace('0x', '')}.${stateDesc.id}`);
663
+ if (value === undefined) try {
664
+ this.getState(stateId, (err, state) => { if (!err && state.hasOwnProperty('val')) this.setState(stateId, state.val, true)});
665
+ }
666
+ catch (error) {
667
+ this.log.warn(`Error acknowledging ${stateId} without value: ${error && error.message ? error.message : 'no reason given'}`);
668
+ }
669
+ else try { this.setState(stateId, value, true); }
670
+ catch (error) {
671
+ this.log.warn(`Error acknowledging ${stateId} with value ${JSON.stringify(value)}: ${error && error.message ? error.message : 'no reason given'}`);
677
672
  }
678
673
  }
679
674
 
@@ -754,10 +749,8 @@ class Zigbee extends utils.Adapter {
754
749
  this.log.info('cleaning everything up');
755
750
  await this.callPluginMethod('stop');
756
751
  if (this.stController) chain.push(this.stController.stop());
757
- if (this.zbController) {
758
- chain.push(this.zbController.stop());
759
- }
760
- Promise.all(chain);
752
+ if (this.zbController) chain.push(this.zbController.stop());
753
+ await Promise.all(chain);
761
754
  this.log.info('cleanup successful');
762
755
  callback();
763
756
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zigbee",
3
- "version": "3.1.4",
3
+ "version": "3.1.6",
4
4
  "author": {
5
5
  "name": "Kirov Ilya",
6
6
  "email": "kirovilya@gmail.com"
@@ -29,7 +29,7 @@
29
29
  "uri-js": "^4.4.1",
30
30
  "typescript": "^5.9.2",
31
31
  "zigbee-herdsman": "^6.0.0",
32
- "zigbee-herdsman-converters": "25.31.0"
32
+ "zigbee-herdsman-converters": "^25.37.0"
33
33
  },
34
34
  "description": "Zigbee devices",
35
35
  "devDependencies": {
@@ -37,10 +37,10 @@
37
37
  "@alcalzone/release-script-plugin-iobroker": "^3.7.2",
38
38
  "@alcalzone/release-script-plugin-license": "^3.7.0",
39
39
  "@alcalzone/release-script-plugin-manual-review": "^3.7.0",
40
- "@iobroker/testing": "^5.1.0",
40
+ "@iobroker/testing": "^5.1.1",
41
41
  "chai": "^5.2.1",
42
42
  "chai-as-promised": "^7.1.1",
43
- "eslint": "^9.30.0",
43
+ "eslint": "^9.36.0",
44
44
  "eslint-config-prettier": "^9.1.0",
45
45
  "eslint-plugin-prettier": "^5.5.4",
46
46
  "mixin-deep": "^2.0.1",