iobroker.zigbee 1.7.5 → 1.8.0

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 (50) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +22 -29
  3. package/admin/admin.js +494 -469
  4. package/admin/i18n/de/translations.json +108 -0
  5. package/admin/i18n/en/translations.json +108 -0
  6. package/admin/i18n/es/translations.json +102 -0
  7. package/admin/i18n/fr/translations.json +108 -0
  8. package/admin/i18n/it/translations.json +102 -0
  9. package/admin/i18n/nl/translations.json +108 -0
  10. package/admin/i18n/pl/translations.json +108 -0
  11. package/admin/i18n/pt/translations.json +102 -0
  12. package/admin/i18n/ru/translations.json +108 -0
  13. package/admin/i18n/uk/translations.json +108 -0
  14. package/admin/i18n/zh-cn/translations.json +102 -0
  15. package/admin/index_m.html +1 -1
  16. package/admin/tab_m.html +44 -3
  17. package/admin/words.js +107 -108
  18. package/io-package.json +326 -357
  19. package/lib/backup.js +2 -2
  20. package/lib/binding.js +23 -24
  21. package/lib/colors.js +16 -14
  22. package/lib/commands.js +89 -82
  23. package/lib/developer.js +6 -7
  24. package/lib/devices.js +145 -154
  25. package/lib/exclude.js +30 -36
  26. package/lib/exposes.js +106 -111
  27. package/lib/groups.js +53 -54
  28. package/lib/json.js +3 -4
  29. package/lib/networkmap.js +2 -2
  30. package/lib/ota.js +23 -15
  31. package/lib/rgb.js +47 -44
  32. package/lib/seriallist.js +21 -10
  33. package/lib/states.js +488 -498
  34. package/lib/statescontroller.js +170 -164
  35. package/lib/utils.js +22 -21
  36. package/lib/zbBaseExtension.js +4 -4
  37. package/lib/zbDelayedAction.js +5 -13
  38. package/lib/zbDeviceAvailability.js +47 -44
  39. package/lib/zbDeviceConfigure.js +18 -23
  40. package/lib/zbDeviceEvent.js +3 -4
  41. package/lib/zigbeecontroller.js +97 -100
  42. package/main.js +149 -133
  43. package/package.json +33 -19
  44. package/.eslintignore +0 -2
  45. package/.eslintrc.json +0 -37
  46. package/.github/FUNDING.yml +0 -3
  47. package/.github/stale.yml +0 -13
  48. package/.github/workflows/test-and-release.yml +0 -151
  49. package/.travis/wiki.sh +0 -28
  50. package/admin/adapter-settings.js +0 -244
package/lib/utils.js CHANGED
@@ -24,7 +24,7 @@ function bulbLevelToAdapterLevel(bulbLevel) {
24
24
  // - Bulb level range [2...254] is linearly mapped to adapter level range [1...100].
25
25
  if (bulbLevel >= 2) {
26
26
  // Perform linear mapping of range [2...254] to [1...100]
27
- return (Math.round((bulbLevel - 2) * 99 / 252) + 1);
27
+ return Math.round((bulbLevel - 2) * 99 / 252) + 1;
28
28
  } else {
29
29
  // The bulb is considered off. Even a bulb level of "1" is considered as off.
30
30
  return 0;
@@ -42,7 +42,7 @@ function adapterLevelToBulbLevel(adapterLevel) {
42
42
  // Please read the comments there regarding the rules applied here for mapping the values.
43
43
  if (adapterLevel) {
44
44
  // Perform linear mapping of range [1...100] to [2...254]
45
- return (Math.round((adapterLevel - 1) * 252 / 99) + 2);
45
+ return Math.round((adapterLevel - 1) * 252 / 99) + 2;
46
46
  } else {
47
47
  // Switch the bulb off. Some bulbs need "0" (IKEA), others "1" (HUE), and according to the
48
48
  // ZigBee docs "1" is the "minimum possible level"... we choose "0" here which seems to work.
@@ -53,7 +53,7 @@ function adapterLevelToBulbLevel(adapterLevel) {
53
53
  function bytesArrayToWordArray(ba) {
54
54
  const wa = [];
55
55
  for (let i = 0; i < ba.length; i++) {
56
- wa[(i / 2) | 0] |= ba[i] << (8*(i % 2));
56
+ wa[(i / 2) | 0] |= ba[i] << (8 * (i % 2));
57
57
  }
58
58
  return wa;
59
59
  }
@@ -91,24 +91,25 @@ function decimalToHex(decimal, padding) {
91
91
 
92
92
  function getZbId(adapterDevId) {
93
93
  const idx = adapterDevId.indexOf('group');
94
- if (idx > 0) return adapterDevId.substr(idx+6);
95
- return '0x' + adapterDevId.split('.')[2];
94
+ if (idx > 0) {
95
+ return adapterDevId.substr(idx+6);
96
+ }
97
+ return `0x${adapterDevId.split('.')[2]}`;
96
98
  }
97
99
 
98
100
  function getAdId(adapter, id) {
99
- return adapter.namespace + '.' + id.split('.')[2]; // iobroker device id
101
+ return `${adapter.namespace}.${id.split('.')[2]}`; // iobroker device id
100
102
  }
101
103
 
102
104
  function flatten(arr) {
103
- return arr.reduce((flat, toFlatten) => {
104
- return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
105
- }, []);
105
+ return arr.reduce((flat, toFlatten) =>
106
+ flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten), []);
106
107
  }
107
108
 
108
109
  const forceEndDevice = flatten(
109
110
  ['QBKG03LM', 'QBKG04LM', 'ZNMS13LM', 'ZNMS12LM']
110
- .map((model) => zigbeeHerdsmanConverters.devices.find((d) => d.model === model))
111
- .map((mappedModel) => mappedModel.zigbeeModel));
111
+ .map(model => zigbeeHerdsmanConverters.devices.find((d) => d.model === model))
112
+ .map(mappedModel => mappedModel.zigbeeModel));
112
113
 
113
114
  // Xiaomi uses 4151 and 4447 (lumi.plug) as manufacturer ID.
114
115
  const xiaomiManufacturerID = [4151, 4447];
@@ -117,7 +118,7 @@ const ikeaTradfriManufacturerID = [4476];
117
118
  function sanitizeImageParameter(parameter) {
118
119
  const replaceByDash = [/\?/g, /&/g, /[^a-z\d\-_./:]/gi, /[/]/gi];
119
120
  let sanitized = parameter;
120
- replaceByDash.forEach((r) => sanitized = sanitized.replace(r, '-'));
121
+ replaceByDash.forEach(r => sanitized = sanitized.replace(r, '-'));
121
122
  return sanitized;
122
123
  }
123
124
 
@@ -132,7 +133,7 @@ function getDeviceIcon(definition) {
132
133
  return icon;
133
134
  }
134
135
 
135
- exports.secondsToMilliseconds = (seconds) => seconds * 1000;
136
+ exports.secondsToMilliseconds = seconds => seconds * 1000;
136
137
  exports.bulbLevelToAdapterLevel = bulbLevelToAdapterLevel;
137
138
  exports.adapterLevelToBulbLevel = adapterLevelToBulbLevel;
138
139
  exports.bytesArrayToWordArray = bytesArrayToWordArray;
@@ -141,11 +142,11 @@ exports.miredKelvinConversion = miredKelvinConversion;
141
142
  exports.decimalToHex = decimalToHex;
142
143
  exports.getZbId = getZbId;
143
144
  exports.getAdId = getAdId;
144
- exports.isRouter = (device) => device.type === 'Router' && !forceEndDevice.includes(device.modelID);
145
- exports.isBatteryPowered = (device) => device.powerSource && device.powerSource === 'Battery';
146
- exports.isXiaomiDevice = (device) => {
147
- return device.modelID !== 'lumi.router' && xiaomiManufacturerID.includes(device.manufacturerID) &&
148
- (!device.manufacturerName || !device.manufacturerName.startsWith('Trust'));
149
- };
150
- exports.isIkeaTradfriDevice = (device) => ikeaTradfriManufacturerID.includes(device.manufacturerID);
151
- exports.getDeviceIcon = getDeviceIcon;
145
+ exports.isRouter = device => device.type === 'Router' && !forceEndDevice.includes(device.modelID);
146
+ exports.isBatteryPowered = device => device.powerSource && device.powerSource === 'Battery';
147
+ exports.isXiaomiDevice = device =>
148
+ device.modelID !== 'lumi.router' &&
149
+ xiaomiManufacturerID.includes(device.manufacturerID) &&
150
+ (!device.manufacturerName || !device.manufacturerName.startsWith('Trust'));
151
+ exports.isIkeaTradfriDevice = device => ikeaTradfriManufacturerID.includes(device.manufacturerID);
152
+ exports.getDeviceIcon = getDeviceIcon;
@@ -14,18 +14,18 @@ class BaseExtension {
14
14
  }
15
15
 
16
16
  error(message, data) {
17
- this.zigbee.error(this.name + ':' + message, data);
17
+ this.zigbee.error(`${this.name}:${message}`, data);
18
18
  }
19
19
 
20
20
  warn(message, data) {
21
- this.zigbee.warn(this.name + ':' + message, data);
21
+ this.zigbee.warn(`${this.name}:${message}`, data);
22
22
  }
23
23
 
24
24
  debug(message, data) {
25
25
  if (this.elevate_debug)
26
- this.zigbee.warn('DE ' + this.name + ':' + message, data);
26
+ this.zigbee.warn(`DE ${this.name}:${message}`, data);
27
27
  else
28
- this.zigbee.debug(this.name + ':' + message, data);
28
+ this.zigbee.debug(`${this.name}:${message}`, data);
29
29
  }
30
30
 
31
31
  sendError(error, message) {
@@ -8,12 +8,11 @@ class DelayedAction extends BaseExtension {
8
8
 
9
9
  this.actions = {};
10
10
  this.zigbee.delayAction = this.delayAction.bind(this);
11
- this.name = "DelayedAction";
11
+ this.name = 'DelayedAction';
12
12
  }
13
13
 
14
14
  setOptions(options) {
15
- if (typeof(options) != 'object') return false;
16
- return true;
15
+ return typeof options === 'object';
17
16
  }
18
17
 
19
18
 
@@ -30,11 +29,7 @@ class DelayedAction extends BaseExtension {
30
29
  // return false;
31
30
  // }
32
31
 
33
- if (device.interviewing === true) {
34
- return false;
35
- }
36
-
37
- return true;
32
+ return device.interviewing !== true;
38
33
  }
39
34
 
40
35
  async onZigbeeStarted() {
@@ -97,10 +92,7 @@ class DelayedAction extends BaseExtension {
97
92
  }
98
93
  const foundDev = await this.zigbee.getDevice(device.ieeeAddr);
99
94
  if (!foundDev) {
100
- this.debug(
101
- `No found device ${device.ieeeAddr} ${device.modelID}, ` +
102
- `for doAction`
103
- );
95
+ this.debug(`No found device ${device.ieeeAddr} ${device.modelID}, for doAction`);
104
96
  delete this.actions[device.ieeeAddr];
105
97
  return;
106
98
  }
@@ -120,7 +112,7 @@ class DelayedAction extends BaseExtension {
120
112
  try {
121
113
  // do action
122
114
  await actionDef.action(device);
123
- this.info(`Do action succesfully ${device.ieeeAddr} ${device.modelID}`);
115
+ this.info(`Do action successfully ${device.ieeeAddr} ${device.modelID}`);
124
116
  toDelete.push(actionDef);
125
117
  } catch (error) {
126
118
  this.sendError(error);
@@ -44,65 +44,77 @@ class DeviceAvailability extends BaseExtension {
44
44
  // force publish availability for new devices
45
45
  this.zigbee.on('new', (entity) => {
46
46
  // wait for 1s for creating device states
47
- setTimeout(() => {
48
- this.publishAvailability(entity.device, true, true);
49
- }, 1000);
47
+ setTimeout(() =>
48
+ this.publishAvailability(entity.device, true, true), 1000);
50
49
  });
51
50
  this.startDevicePingQueue = []; // simple fifo array for starting device pings
52
51
  this.startDevicePingTimeout = null; // handle for the timeout which empties the queue
53
52
  this.startDevicePingDelay = 200; // 200 ms delay between starting the ping timeout
54
- this.name = "DeviceAvailability";
53
+ this.name = 'DeviceAvailability';
55
54
  this.elevate_debug = false;
56
55
  }
57
56
 
58
57
  setOptions(options) {
59
- if (typeof(options) != 'object') return false;
60
- if (options.disableActivePing) this.active_ping = false;
61
- if (options.disableForcedPing) this.forced_ping = false;
62
- if (typeof(options.pingTimeout)=='number') this.availability_timeout = Math.min(60,options.pingTimeout);
63
- if (typeof(options.pingCount)=='number') this.max_ping = Math.min(2, options.pingCount);
58
+ if (typeof options !== 'object') {
59
+ return false;
60
+ }
61
+ if (options.disableActivePing) {
62
+ this.active_ping = false;
63
+ }
64
+ if (options.disableForcedPing) {
65
+ this.forced_ping = false;
66
+ }
67
+ if (typeof options.pingTimeout === 'number') {
68
+ this.availability_timeout = Math.min(60,options.pingTimeout);
69
+ }
70
+ if (typeof options.pingCount === 'number') {
71
+ this.max_ping = Math.min(2, options.pingCount);
72
+ }
64
73
  return true;
65
74
  }
66
75
 
67
76
  isPingable(device) {
68
77
  if (this.active_ping)
69
78
  {
70
- if (this.forced_ping && forcedPingable.find((d) => d && d.hasOwnProperty('zigbeeModel') && d.zigbeeModel.includes(device.modelID))) {
79
+ if (this.forced_ping && forcedPingable.find(d => d && d.hasOwnProperty('zigbeeModel') && d.zigbeeModel.includes(device.modelID))) {
71
80
  return true;
72
81
  }
73
82
 
74
- const result = utils.isRouter(device) && !utils.isBatteryPowered(device);
75
- return result;
83
+ return utils.isRouter(device) && !utils.isBatteryPowered(device);
76
84
  }
77
85
  return false;
78
86
  }
79
87
 
80
88
  async getAllPingableDevices() {
81
89
  const clients = await this.zigbee.getClients();
82
- return clients.filter((d) => this.isPingable(d));
90
+ return clients.filter(d => this.isPingable(d));
83
91
  }
84
92
 
85
93
  async registerDevicePing(device, entity) {
86
- this.debug('register device Ping for ' + JSON.stringify(device.ieeeAddr));
94
+ this.debug(`register device Ping for ${JSON.stringify(device.ieeeAddr)}`);
87
95
  this.forcedNonPingable[device.ieeeAddr] = false;
88
96
  // this.warn(`Called registerDevicePing for '${device}' of '${entity}'`);
89
- if (!this.isPingable(device)) return;
97
+ if (!this.isPingable(device)) {
98
+ return;
99
+ }
90
100
  // ensure we do not already have this device in the queue
101
+ // TODO: Following does not work, may be `if (this.startDevicePingQueue.find(item => item && item.device === device)) { return; }`
91
102
  this.startDevicePingQueue.forEach(item => {
92
- if (item && item.device == device)
103
+ if (item && item.device == device) {
93
104
  return;
105
+ }
94
106
  });
95
107
  this.number_of_registered_devices++;
96
108
  this.availability_timeout = Math.max(Math.min(this.number_of_registered_devices * AverageTimeBetweenPings,MaxAvailabilityTimeout ),MinAvailabilityTimeout);
97
- this.startDevicePingQueue.push({device:device, entity:entity});
98
- if (this.startDevicePingTimeout == null)
99
- this.startDevicePingTimeout = setTimeout(async() => {
100
- await this.startDevicePing();
101
- }, this.startDevicePingDelay);
109
+ this.startDevicePingQueue.push({device, entity});
110
+ if (this.startDevicePingTimeout == null) {
111
+ this.startDevicePingTimeout = setTimeout(async() =>
112
+ await this.startDevicePing(), this.startDevicePingDelay);
113
+ }
102
114
  }
103
115
 
104
116
  async deregisterDevicePing(device) {
105
- this.info('deregister device Ping for deactivated device ' + JSON.stringify(device.ieeeAddr));
117
+ this.info(`deregister device Ping for deactivated device ${JSON.stringify(device.ieeeAddr)}`);
106
118
  this.forcedNonPingable[device.ieeeAddr] = true;
107
119
  if (this.timers[device.ieeeAddr]) {
108
120
  clearTimeout(this.timers[device.ieeeAddr]);
@@ -114,9 +126,8 @@ class DeviceAvailability extends BaseExtension {
114
126
  this.startDevicePingTimeout = null;
115
127
  const item = this.startDevicePingQueue.shift();
116
128
  if (this.startDevicePingQueue.length >0) {
117
- this.startDevicePingTimeout = setTimeout(async() => {
118
- await this.startDevicePing();
119
- }, this.startDevicePingDelay);
129
+ this.startDevicePingTimeout = setTimeout(async() =>
130
+ await this.startDevicePing(), this.startDevicePingDelay);
120
131
  }
121
132
  if (item && item.hasOwnProperty('device')) {
122
133
  this.handleIntervalPingable(item.device, item.entity);
@@ -131,15 +142,13 @@ class DeviceAvailability extends BaseExtension {
131
142
  const clients = await this.zigbee.getClients();
132
143
  // this.warn('onZigbeeStarted called');
133
144
  for (const device of clients) {
134
-
135
145
  if (this.isPingable(device)) {
136
146
  // this.setTimerPingable(device);
137
147
  } else {
138
148
  // this.warn(`Setting '${device.ieeeAddr}' as available - battery driven`);
139
149
  this.publishAvailability(device, true);
140
- this.timers[device.ieeeAddr] = setInterval(() => {
141
- this.handleIntervalNotPingable(device);
142
- },utils.secondsToMilliseconds(this.availability_timeout));
150
+ this.timers[device.ieeeAddr] = setInterval(() =>
151
+ this.handleIntervalNotPingable(device), utils.secondsToMilliseconds(this.availability_timeout));
143
152
  }
144
153
  }
145
154
  }
@@ -154,8 +163,8 @@ class DeviceAvailability extends BaseExtension {
154
163
  if (this.isPingable(device)) {
155
164
  let pingCount = this.ping_counters[device.ieeeAddr];
156
165
  if (pingCount === undefined) {
157
- this.ping_counters[device.ieeeAddr] = { failed: 0, reported: 0};
158
- pingCount = { failed: 0, reported: 0};
166
+ this.ping_counters[device.ieeeAddr] = {failed: 0, reported: 0};
167
+ pingCount = {failed: 0, reported: 0};
159
168
  }
160
169
 
161
170
  // first see if we can "ping" the device by reading a Status
@@ -185,26 +194,22 @@ class DeviceAvailability extends BaseExtension {
185
194
  this.ping_counters[device.ieeeAddr].failed = 0;
186
195
  } catch (error) {
187
196
  this.publishAvailability(device, false);
188
- if (pingCount.failed++ <= this.max_ping)
189
- {
197
+ if (pingCount.failed++ <= this.max_ping) {
190
198
  if (pingCount.failed < 2 && pingCount.reported < this.max_ping) {
191
199
  this.warn(`Failed to ping ${ieeeAddr} ${device.modelID}`);
192
200
  pingCount.reported++;
193
- }
194
- else {
201
+ } else {
195
202
  this.debug(`Failed to ping ${ieeeAddr} ${device.modelID} on ${pingCount} consecutive attempts`);
196
203
  }
197
204
  this.setTimerPingable(device, pingCount.failed);
198
205
  this.ping_counters[device.ieeeAddr]= pingCount;
199
- }
200
- else {
206
+ } else {
201
207
  this.warn(`Stopping to ping ${ieeeAddr} ${device.modelID} after ${pingCount.failed} ping attempts`);
202
208
  }
203
209
  }
204
210
  }
205
211
  }
206
212
 
207
-
208
213
  async handleIntervalNotPingable(device) {
209
214
  const entity = await this.zigbee.resolveEntity(device.ieeeAddr);
210
215
  if (!entity || !device.lastSeen) {
@@ -224,9 +229,8 @@ class DeviceAvailability extends BaseExtension {
224
229
  if (this.timers[device.ieeeAddr]) {
225
230
  clearTimeout(this.timers[device.ieeeAddr]);
226
231
  }
227
- this.timers[device.ieeeAddr] = setTimeout(async() => {
228
- await this.handleIntervalPingable(device);
229
- }, utils.secondsToMilliseconds(this.availability_timeout * factor));
232
+ this.timers[device.ieeeAddr] = setTimeout(async() =>
233
+ await this.handleIntervalPingable(device), utils.secondsToMilliseconds(this.availability_timeout * factor));
230
234
  }
231
235
 
232
236
  async stop() {
@@ -234,7 +238,7 @@ class DeviceAvailability extends BaseExtension {
234
238
  clearTimeout(timer);
235
239
  }
236
240
  const clients = await this.zigbee.getClients();
237
- clients.forEach((device) => this.publishAvailability(device, false));
241
+ clients.forEach(device => this.publishAvailability(device, false));
238
242
  }
239
243
 
240
244
  async onReconnect(device) {
@@ -290,8 +294,7 @@ class DeviceAvailability extends BaseExtension {
290
294
  const pc = this.ping_counters[device.ieeeAddr];
291
295
  if (pc == undefined) {
292
296
  this.ping_counters[device.ieeeAddr] = { failed:0, reported:0 };
293
- }
294
- else {
297
+ } else {
295
298
  this.ping_counters[device.ieeeAddr].failed++;
296
299
  }
297
300
 
@@ -10,20 +10,17 @@ const forcedConfigureOnEachStart = [
10
10
  zigbeeHerdsmanConverters.devices.find((d) => d.model === 'ZK03840')
11
11
  ];
12
12
 
13
-
14
-
15
13
  class DeviceConfigure extends BaseExtension {
16
14
  constructor(zigbee, options) {
17
15
  super(zigbee, options);
18
16
 
19
17
  this.configuring = new Set();
20
18
  this.attempts = {};
21
- this.name = "DeviceConfigure";
19
+ this.name = 'DeviceConfigure';
22
20
  }
23
21
 
24
22
  setOptions(options) {
25
- if (typeof(options) != 'object') return false;
26
- return true;
23
+ return typeof options === 'object';
27
24
  }
28
25
 
29
26
  shouldConfigure(device, mappedDevice) {
@@ -37,11 +34,8 @@ class DeviceConfigure extends BaseExtension {
37
34
  zigbeeHerdsmanConverters.getConfigureKey(mappedDevice)) {
38
35
  return false;
39
36
  }
40
- if (device.interviewing === true) {
41
- return false;
42
- }
43
37
 
44
- return true;
38
+ return device.interviewing !== true;
45
39
  }
46
40
 
47
41
  async onZigbeeStarted() {
@@ -53,7 +47,7 @@ class DeviceConfigure extends BaseExtension {
53
47
 
54
48
  if (forcedConfigureOnEachStart.find((d) => d && d.hasOwnProperty('zigbeeModel') && d.zigbeeModel.includes(device.modelID))) {
55
49
  this.debug(`DeviceConfigure ${device.ieeeAddr} ${device.modelID} forced by adapter config`);
56
- device.meta.configured = -1; // Force a reconfigure for this device
50
+ device.meta.configured = -1; // Force a reconfiguration for this device
57
51
  }
58
52
  if (this.shouldConfigure(device, mappedDevice)) {
59
53
  this.debug(`DeviceConfigure ${device.ieeeAddr} ${device.modelID} needed`);
@@ -64,9 +58,7 @@ class DeviceConfigure extends BaseExtension {
64
58
  }
65
59
  } catch (error) {
66
60
  this.sendError(error);
67
- this.error(
68
- `Failed to DeviceConfigure.onZigbeeStarted (${error.stack})`,
69
- );
61
+ this.error(`Failed to DeviceConfigure.onZigbeeStarted (${error.stack})`);
70
62
  }
71
63
  }
72
64
 
@@ -78,9 +70,7 @@ class DeviceConfigure extends BaseExtension {
78
70
  }
79
71
  } catch (error) {
80
72
  this.sendError(error);
81
- this.error(
82
- `Failed to DeviceConfigure.onZigbeeEvent (${error.stack})`,
83
- );
73
+ this.error(`Failed to DeviceConfigure.onZigbeeEvent (${error.stack})`);
84
74
  }
85
75
  }
86
76
 
@@ -95,9 +85,7 @@ class DeviceConfigure extends BaseExtension {
95
85
  }
96
86
  } catch (error) {
97
87
  this.sendError(error);
98
- this.error(
99
- `Failed to DeviceConfigure.onDeviceRemove (${error.stack})`,
100
- );
88
+ this.error(`Failed to DeviceConfigure.onDeviceRemove (${error.stack})`);
101
89
  }
102
90
  }
103
91
 
@@ -142,10 +130,17 @@ class DeviceConfigure extends BaseExtension {
142
130
  async doConfigure(device, mappedDevice) {
143
131
  this.info(`Configuring ${device.ieeeAddr} ${device.modelID}`);
144
132
  const coordinatorEndpoint = await this.zigbee.getDevicesByType('Coordinator')[0].endpoints[0];
145
- await mappedDevice.configure(device, coordinatorEndpoint);
146
- device.meta.configured = zigbeeHerdsmanConverters.getConfigureKey(mappedDevice);
147
- device.save();
148
- this.info(`DeviceConfigure successful ${device.ieeeAddr} ${device.modelID}`);
133
+ try {
134
+ await mappedDevice.configure(device, coordinatorEndpoint);
135
+ device.meta.configured = zigbeeHerdsmanConverters.getConfigureKey(mappedDevice);
136
+ device.save();
137
+ this.info(`DeviceConfigure successful ${device.ieeeAddr} ${device.modelID}`);
138
+ } catch (error) {
139
+ this.sendError(error);
140
+ this.error(
141
+ `Failed to DeviceConfigure.configure ${device.ieeeAddr} ${device.modelID} (${error.stack})`,
142
+ );
143
+ }
149
144
  }
150
145
  }
151
146
 
@@ -6,10 +6,9 @@ const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
6
6
  class DeviceEvent extends BaseExtension {
7
7
  constructor(zigbee, options) {
8
8
  super(zigbee, options);
9
- this.name = "DeviceEvent";
9
+ this.name = 'DeviceEvent';
10
10
  }
11
11
 
12
-
13
12
  async onZigbeeStarted() {
14
13
  for (const device of await this.zigbee.getClients()) {
15
14
  this.callOnEvent(device, 'start', {});
@@ -17,8 +16,8 @@ class DeviceEvent extends BaseExtension {
17
16
  }
18
17
 
19
18
  setOptions(options) {
20
- if (typeof(options) != 'object') return false;
21
- return true;
19
+ return typeof options === 'object';
20
+
22
21
  }
23
22
 
24
23
  onZigbeeEvent(data, mappedDevice) {