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/main.js CHANGED
@@ -40,21 +40,20 @@ const createByteArray = function (hexString) {
40
40
  return bytes;
41
41
  };
42
42
 
43
- const E_INFO=1;
44
- const E_DEBUG=2;
45
- const E_WARN=3;
46
- const E_ERROR=4;
43
+ const E_INFO = 1;
44
+ const E_DEBUG = 2;
45
+ const E_WARN = 3;
46
+ const E_ERROR = 4;
47
47
 
48
48
  let _pairingMode = false;
49
49
 
50
50
  const errorCodes = {
51
- 9999: { severity:E_INFO, message:'No response'},
52
- 233: { severity:E_DEBUG, message:'MAC NO ACK'},
53
- 205: { severity:E_WARN, message:'No network route'},
54
- 134: { severity:E_WARN, message:'Unnsupported Attribute'},
51
+ 9999: {severity: E_INFO, message: 'No response'},
52
+ 233: {severity: E_DEBUG, message: 'MAC NO ACK'},
53
+ 205: {severity: E_WARN, message: 'No network route'},
54
+ 134: {severity: E_WARN, message: 'Unsupported Attribute'},
55
55
  };
56
56
 
57
-
58
57
  class Zigbee extends utils.Adapter {
59
58
  /**
60
59
  * @param {Partial<ioBroker.AdapterOptions>} [options={}]
@@ -93,14 +92,15 @@ class Zigbee extends utils.Adapter {
93
92
  case 'SendToDevice': {
94
93
  let rv = {
95
94
  success: false,
96
- loc:-1,
95
+ loc: -1,
97
96
  };
97
+
98
98
  try {
99
- rv = await this.SendPayload(obj.message);
100
- }
101
- catch (e) {
99
+ rv = await this.sendPayload(obj.message);
100
+ } catch (e) {
102
101
  rv.error = e;
103
102
  }
103
+
104
104
  this.sendTo(obj.from, obj.command, rv, obj.callback);
105
105
  break;
106
106
  }
@@ -115,15 +115,15 @@ class Zigbee extends utils.Adapter {
115
115
  const Sentry = sentryInstance.getSentryObject();
116
116
  if (Sentry) {
117
117
  if (message) {
118
- Sentry.configureScope(scope => {
118
+ Sentry.configureScope(scope =>
119
119
  scope.addBreadcrumb({
120
- type: "error", // predefined types
121
- category: "error message",
120
+ type: 'error', // predefined types
121
+ category: 'error message',
122
122
  level: Sentry.Severity.Error,
123
- message: message
124
- });
125
- });
123
+ message
124
+ }));
126
125
  }
126
+
127
127
  if (typeof error == 'string') {
128
128
  Sentry.captureException(new Error(error));
129
129
  } else {
@@ -135,27 +135,31 @@ class Zigbee extends utils.Adapter {
135
135
  }
136
136
 
137
137
  filterError(errormessage, message, error) {
138
- if (error.code === undefined)
139
- {
140
- let em = error.stack.match(/failed \((.+?)\) at/);
141
- if (!em) em = error.stack.match(/failed \((.+?)\)/);
138
+ if (error.code === undefined) {
139
+ let em = error.stack.match(/failed \((.+?)\) at/);
140
+ em = em || error.stack.match(/failed \((.+?)\)/);
142
141
  this.log.error(`${message} no error code (${(em ? em[1]:'undefined')})`);
143
142
  this.sendError(error, `${message} no error code`);
144
143
  this.log.debug(`Stack trace for ${em}: ${error.stack}`);
145
144
  return;
146
145
  }
146
+
147
147
  const ecode = errorCodes[error.code];
148
148
  if (ecode === undefined) {
149
149
  this.log.error(errormessage);
150
150
  this.sendError(error, errormessage);
151
151
  return;
152
152
  }
153
+
153
154
  switch (ecode.severity) {
154
- case E_INFO: this.log.info(`${message}: Code ${error.code} (${ecode.message})`);
155
+ case E_INFO:
156
+ this.log.info(`${message}: Code ${error.code} (${ecode.message})`);
155
157
  break;
156
- case E_DEBUG: this.log.debug(`${message}: Code ${error.code} (${ecode.message})`);
158
+ case E_DEBUG:
159
+ this.log.debug(`${message}: Code ${error.code} (${ecode.message})`);
157
160
  break;
158
- case E_WARN: this.log.warn(`${message}: Code ${error.code} (${ecode.message})`);
161
+ case E_WARN:
162
+ this.log.warn(`${message}: Code ${error.code} (${ecode.message})`);
159
163
  break;
160
164
  case E_ERROR:
161
165
  this.log.error(`${message}: Code ${error.code} (${ecode.message})`);
@@ -164,6 +168,7 @@ class Zigbee extends utils.Adapter {
164
168
  default:
165
169
  this.log.error(`${message}: Code ${error.code} (malformed error)`);
166
170
  this.sendError(error, `${message}: Code ${error.code} (malformed error)`);
171
+ break;
167
172
  }
168
173
  }
169
174
 
@@ -181,9 +186,8 @@ class Zigbee extends utils.Adapter {
181
186
  // external converters
182
187
  this.applyExternalConverters();
183
188
  // get exclude list from object
184
- this.getState('exclude.all', (err, state) => {
185
- this.stController.getExcludeExposes(state);
186
- });
189
+ this.getState('exclude.all', (err, state) =>
190
+ this.stController.getExcludeExposes(state));
187
191
 
188
192
  this.subscribeStates('*');
189
193
  // set connection false before connect to zigbee
@@ -212,7 +216,9 @@ class Zigbee extends utils.Adapter {
212
216
  }
213
217
  const extfiles = this.config.external.split(';');
214
218
  for (const moduleName of extfiles) {
215
- if (!moduleName) continue;
219
+ if (!moduleName) {
220
+ continue;
221
+ }
216
222
  this.log.info(`Apply converter from module: ${moduleName}`);
217
223
  const sandbox = {
218
224
  require,
@@ -231,7 +237,7 @@ class Zigbee extends utils.Adapter {
231
237
  }
232
238
  }
233
239
 
234
- applyExternalConverters(){
240
+ applyExternalConverters() {
235
241
  for (const definition of this.getExternalDefinition()) {
236
242
  const toAdd = {...definition};
237
243
  delete toAdd['homeassistant'];
@@ -252,16 +258,16 @@ class Zigbee extends utils.Adapter {
252
258
  // installed version
253
259
  let gitVers = '';
254
260
  try {
255
- this.log.info('Starting Zigbee ' + debugversion);
261
+ this.log.info(`Starting Zigbee ${debugversion}`);
256
262
 
257
- await this.getForeignObject('system.adapter.' + this.namespace, (err, obj) => {
263
+ await this.getForeignObject(`system.adapter.${this.namespace}`, (err, obj) => {
258
264
  if (!err && obj && obj.common.installedFrom && obj.common.installedFrom.includes('://')) {
259
265
  const instFrom = obj.common.installedFrom;
260
- gitVers = gitVers + instFrom.replace('tarball','commit');
266
+ gitVers = gitVers + instFrom.replace('tarball', 'commit');
261
267
  } else {
262
268
  gitVers = obj.common.installedFrom;
263
269
  }
264
- this.log.info('Installed Version: ' + gitVers );
270
+ this.log.info(`Installed Version: ${gitVers}`);
265
271
  });
266
272
 
267
273
  await this.zbController.start();
@@ -274,6 +280,7 @@ class Zigbee extends utils.Adapter {
274
280
  this.log.error(error);
275
281
  }
276
282
  this.sendError(error, `Failed to start Zigbee`);
283
+
277
284
  if (this.reconnectCounter > 0) {
278
285
  this.tryToReconnect();
279
286
  }
@@ -291,10 +298,10 @@ class Zigbee extends utils.Adapter {
291
298
 
292
299
  tryToReconnect() {
293
300
  this.reconnectTimer = setTimeout(()=>{
294
- if (this.config.port.indexOf('tcp://') !== -1) {
295
- // Controller connect though WiFi.
296
- // Unlikely USB dongle, connection broken may only caused user unpluged the dongle,
297
- // WiFi connected gateway is possible that device connection is broken caused by
301
+ if (this.config.port.includes('tcp://')) {
302
+ // Controller connect though Wi-Fi.
303
+ // Unlikely USB dongle, connection broken may only cause user unplugged the dongle,
304
+ // Wi-Fi connected gateway is possible that device connection is broken caused by
298
305
  // AP issue or Zigbee gateway power is turned off unexpectedly.
299
306
  // So try to reconnect gateway every 10 seconds all the time.
300
307
  this.log.info(`Try to reconnect.`);
@@ -303,7 +310,7 @@ class Zigbee extends utils.Adapter {
303
310
  this.reconnectCounter -= 1;
304
311
  }
305
312
  this.doConnect();
306
- }, 10*1000); // every 10 seconds
313
+ }, 10 * 1000); // every 10 seconds
307
314
  }
308
315
 
309
316
  async onZigbeeAdapterReady() {
@@ -312,13 +319,13 @@ class Zigbee extends utils.Adapter {
312
319
  // https://github.com/ioBroker/ioBroker.zigbee/issues/668
313
320
  const extPanIdFix = this.config.extPanIdFix ? this.config.extPanIdFix : false;
314
321
  if (!extPanIdFix) {
315
- const configExtPanId = this.config.extPanID ? '0x'+this.config.extPanID.toLowerCase() : '0xdddddddddddddddd';
322
+ const configExtPanId = this.config.extPanID ? '0x' + this.config.extPanID.toLowerCase() : '0xdddddddddddddddd';
316
323
  let networkExtPanId = (await this.zbController.herdsman.getNetworkParameters()).extendedPanID;
317
324
  let needChange = false;
318
325
  this.log.debug(`Config value ${configExtPanId} : Network value ${networkExtPanId}`);
319
326
  const adapterType = this.config.adapterType || 'zstack';
320
327
  if (adapterType === 'zstack') {
321
- if (configExtPanId != networkExtPanId) {
328
+ if (configExtPanId !== networkExtPanId) {
322
329
  try {
323
330
  // try to read from nvram
324
331
  const result = await this.zbController.herdsman.adapter.znp.request(
@@ -334,9 +341,9 @@ class Zigbee extends utils.Adapter {
334
341
  2, // ZnpCommandStatus.INVALID_PARAM
335
342
  ]
336
343
  );
337
- const nwExtPanId = '0x'+result.payload.value.reverse().toString('hex');
344
+ const nwExtPanId = '0x' + result.payload.value.reverse().toString('hex');
338
345
  this.log.debug(`Config value ${configExtPanId} : nw value ${nwExtPanId}`);
339
- if (configExtPanId != nwExtPanId) {
346
+ if (configExtPanId !== nwExtPanId) {
340
347
  networkExtPanId = nwExtPanId;
341
348
  needChange = true;
342
349
  }
@@ -366,37 +373,36 @@ class Zigbee extends utils.Adapter {
366
373
  for (const device of devicesFromDB) {
367
374
  const entity = await this.zbController.resolveEntity(device);
368
375
  if (entity) {
369
- const model = (entity.mapped) ? entity.mapped.model : entity.device.modelID;
370
- this.stController.updateDev(device.ieeeAddr.substr(2), model, model, () => {
371
- this.stController.syncDevStates(device, model);
372
- });
376
+ const model = entity.mapped ? entity.mapped.model : entity.device.modelID;
377
+ this.stController.updateDev(device.ieeeAddr.substr(2), model, model, () =>
378
+ this.stController.syncDevStates(device, model));
373
379
  }
374
380
  }
375
381
  await this.callPluginMethod('start', [this.zbController, this.stController]);
376
382
  }
377
383
 
378
384
  async checkIfModelUpdate(entity) {
379
- const model = (entity.mapped) ? entity.mapped.model : entity.device.modelID,
385
+ const model = entity.mapped ? entity.mapped.model : entity.device.modelID,
380
386
  device = entity.device,
381
387
  devId = device.ieeeAddr.substr(2);
388
+
382
389
  return new Promise((resolve) => {
383
390
  this.getObject(devId, (err, obj) => {
384
- if (obj && obj.common.type != model) {
391
+ if (obj && obj.common.type !== model) {
385
392
  // let's change model
386
393
  this.getStatesOf(devId, (err, states) => {
387
394
  if (!err && states) {
388
395
  const chain = [];
389
- states.forEach((state) => {
390
- chain.push(this.deleteStateAsync(devId, null, state._id));
391
- });
392
- Promise.all(chain).then(()=>{
393
- this.stController.deleteDeviceStates(devId, () => {
394
- this.stController.updateDev(devId, model, model, async () => {
395
- await this.stController.syncDevStates(device, model);
396
- resolve();
397
- });
398
- });
399
- });
396
+ states.forEach((state) =>
397
+ chain.push(this.deleteStateAsync(devId, null, state._id)));
398
+
399
+ Promise.all(chain)
400
+ .then(() =>
401
+ this.stController.deleteDeviceStates(devId, () =>
402
+ this.stController.updateDev(devId, model, model, async () => {
403
+ await this.stController.syncDevStates(device, model);
404
+ resolve();
405
+ })));
400
406
  } else {
401
407
  resolve();
402
408
  }
@@ -412,13 +418,14 @@ class Zigbee extends utils.Adapter {
412
418
 
413
419
  async onZigbeeEvent(type, entity, message){
414
420
  this.log.debug(`Type ${type} device ${safeJsonStringify(entity)} incoming event: ${safeJsonStringify(message)}`);
415
- const device = entity.device,
416
- mappedModel = entity.mapped,
417
- model = (entity.mapped) ? entity.mapped.model : entity.device.modelID,
418
- cluster = message.cluster,
419
- devId = device.ieeeAddr.substr(2),
420
- meta = {device: device};
421
- //this assigment give possibility to use iobroker logger in code of the converters, via meta.logger
421
+ const device = entity.device;
422
+ const mappedModel = entity.mapped;
423
+ const model = (entity.mapped) ? entity.mapped.model : entity.device.modelID;
424
+ const cluster = message.cluster;
425
+ const devId = device.ieeeAddr.substr(2);
426
+ const meta = {device};
427
+
428
+ // this assigment give possibility to use iobroker logger in code of the converters, via meta.logger
422
429
  meta.logger = this.log;
423
430
 
424
431
  await this.checkIfModelUpdate(entity);
@@ -439,12 +446,14 @@ class Zigbee extends utils.Adapter {
439
446
  }
440
447
  let converters = mappedModel.fromZigbee.filter(c => c && c.cluster === cluster && (
441
448
  (c.type instanceof Array) ? c.type.includes(type) : c.type === type));
449
+
442
450
  if (!converters.length && type === 'readResponse') {
443
451
  converters = mappedModel.fromZigbee.filter(c => c.cluster === cluster && (
444
452
  (c.type instanceof Array) ? c.type.includes('attributeReport') : c.type === 'attributeReport'));
445
453
  }
454
+
446
455
  if (!converters.length) {
447
- if (type != 'readResponse') {
456
+ if (type !== 'readResponse') {
448
457
  this.log.debug(
449
458
  `No converter available for '${mappedModel.model}' with cluster '${cluster}' and type '${type}'`
450
459
  );
@@ -476,10 +485,10 @@ class Zigbee extends utils.Adapter {
476
485
 
477
486
  acknowledgeState(deviceId, model, stateDesc, value) {
478
487
  if (model === 'group') {
479
- const stateId = this.namespace + '.group_' + deviceId + '.' + stateDesc.id;
488
+ const stateId = `${this.namespace}.group_${deviceId}.${stateDesc.id}`;
480
489
  this.setState(stateId, value, true);
481
490
  } else {
482
- const stateId = this.namespace + '.' + deviceId.replace('0x', '') + '.' + stateDesc.id;
491
+ const stateId = `${this.namespace}.${deviceId.replace('0x', '')}.${stateDesc.id}`;
483
492
  this.setState(stateId, value, true);
484
493
  }
485
494
  }
@@ -492,7 +501,7 @@ class Zigbee extends utils.Adapter {
492
501
 
493
502
  async publishFromState(deviceId, model, stateModel, stateList, options){
494
503
  let isGroup = false;
495
- if (model == 'group') {
504
+ if (model === 'group') {
496
505
  isGroup = true;
497
506
  deviceId = parseInt(deviceId);
498
507
  }
@@ -503,17 +512,17 @@ class Zigbee extends utils.Adapter {
503
512
  this.log.debug(`No mapped model for ${model}`);
504
513
  return;
505
514
  }
506
- this.log.debug('Mapped Model: ' + JSON.stringify(mappedModel));
515
+ this.log.debug(`Mapped Model: ${JSON.stringify(mappedModel)}`);
507
516
 
508
- stateList.forEach(async(changedState) => {
517
+ stateList.forEach(async changedState => {
509
518
  const stateDesc = changedState.stateDesc;
510
519
  const value = changedState.value;
511
520
 
512
- if (stateDesc.id == 'send_payload') {
521
+ if (stateDesc.id === 'send_payload') {
513
522
  try {
514
523
  const json_value = JSON.parse(value);
515
- const payload = { device:deviceId.replace('0x', ''), payload:json_value };
516
- const result = await(this.SendPayload(payload));
524
+ const payload = {device: deviceId.replace('0x', ''), payload: json_value};
525
+ const result = await(this.sendPayload(payload));
517
526
  if (result.hasOwnProperty('success') && result.success) {
518
527
  this.acknowledgeState(deviceId, model, stateDesc, value);
519
528
  }
@@ -532,7 +541,7 @@ class Zigbee extends utils.Adapter {
532
541
  // if this is the device query state => trigger the device query
533
542
 
534
543
  // on activation of the 'device_query' state trigger hardware query where possible
535
- if (stateDesc.id == 'device_query') {
544
+ if (stateDesc.id === 'device_query') {
536
545
  if (this.query_device_block.indexOf(deviceId) > -1) {
537
546
  this.log.warn(`Device query for '${entity.device.ieeeAddr}' blocked`);
538
547
  return;
@@ -554,16 +563,18 @@ class Zigbee extends utils.Adapter {
554
563
  }
555
564
  this.log.debug(`Device query for '${entity.device.ieeeAddr}' done`);
556
565
  const idToRemove = deviceId;
557
- setTimeout(()=>{
566
+ setTimeout(() => {
558
567
  const idx = this.query_device_block.indexOf(idToRemove);
559
- if (idx > -1) this.query_device_block.splice(idx);
568
+ if (idx > -1) {
569
+ this.query_device_block.splice(idx);
570
+ }
560
571
  }, 10000);
561
572
  }
562
573
  return;
563
574
  }
564
575
  return;
565
576
  }
566
- const converter = mappedModel.toZigbee.find((c) => c && (c.key.includes(stateDesc.prop) || c.key.includes(stateDesc.setattr) || c.key.includes(stateDesc.id)));
577
+ const converter = mappedModel.toZigbee.find(c => c && (c.key.includes(stateDesc.prop) || c.key.includes(stateDesc.setattr) || c.key.includes(stateDesc.id)));
567
578
  if (!converter) {
568
579
  this.log.error(`No converter available for '${model}' with key '${stateDesc.id}' `);
569
580
  this.sendError(`No converter available for '${model}' with key '${stateDesc.id}' `);
@@ -574,7 +585,7 @@ class Zigbee extends utils.Adapter {
574
585
  const preparedOptions = (stateDesc.setterOpt) ? stateDesc.setterOpt(value, options) : {};
575
586
  let syncStateList = [];
576
587
  if (stateModel && stateModel.syncStates) {
577
- stateModel.syncStates.forEach((syncFunct) => {
588
+ stateModel.syncStates.forEach(syncFunct => {
578
589
  const res = syncFunct(stateDesc, value, options);
579
590
  if (res) {
580
591
  syncStateList = syncStateList.concat(res);
@@ -593,12 +604,14 @@ class Zigbee extends utils.Adapter {
593
604
  target = await this.zbController.resolveEntity(deviceId, epName);
594
605
  target = target.endpoint;
595
606
  }
607
+
596
608
  this.log.debug(`target: ${safeJsonStringify(target)}`);
609
+
597
610
  const meta = {
598
611
  endpoint_name: epName,
599
612
  options: preparedOptions,
600
613
  device: entity.device,
601
- mapped: (model == 'group') ? [] : mappedModel,
614
+ mapped: model === 'group' ? [] : mappedModel,
602
615
  message: {[key]: preparedValue},
603
616
  logger: this.log,
604
617
  state: {},
@@ -610,23 +623,24 @@ class Zigbee extends utils.Adapter {
610
623
  const result = await converter.convertSet(target, key, preparedValue, meta);
611
624
  this.log.debug(`convert result ${safeJsonStringify(result)}`);
612
625
  if (result !== undefined) {
613
- if (stateModel && !isGroup)
626
+ if (stateModel && !isGroup) {
614
627
  this.acknowledgeState(deviceId, model, stateDesc, value);
628
+ }
615
629
  // process sync state list
616
630
  this.processSyncStatesList(deviceId, model, syncStateList);
631
+
617
632
  if (isGroup) {
618
633
  await this.callPluginMethod('queryGroupMemberState', [deviceId, stateDesc]);
619
634
  this.acknowledgeState(deviceId, model, stateDesc, value);
620
635
  }
621
636
  }
622
- } catch(error) {
637
+ } catch (error) {
623
638
  this.filterError(`Error ${error.code} on send command to ${deviceId}.`+
624
639
  ` Error: ${error.stack}`, `Send command to ${deviceId} failed with`, error);
625
640
  }
626
641
  });
627
642
  }
628
- //
629
- //
643
+
630
644
  // This function is introduced to explicitly allow user level scripts to send Commands
631
645
  // directly to the zigbee device. It utilizes the zigbee-herdsman-converters to generate
632
646
  // the exact zigbee message to be sent and can be used to set device options which are
@@ -639,74 +653,76 @@ class Zigbee extends utils.Adapter {
639
653
  // payload: The data to send to the device as JSON object (key/Value pairs)
640
654
  // endpoint: optional: the endpoint to send the data to, if supported.
641
655
  //
642
- async SendPayload(payload) {
656
+ async sendPayload(payload) {
643
657
  this.log.debug(`publishToDevice called with ${safeJsonStringify(payload)}`);
644
- let payload_obj = {};
658
+ let payloadObj = {};
645
659
  if (typeof payload === 'string') {
646
660
  try {
647
- payload_obj = JSON.parse();
661
+ payloadObj = JSON.parse(payload);
648
662
  } catch (e) {
649
663
  this.log.error(`Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`);
650
664
  this.sendError(e, `Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`);
651
- return {success:false, error: `Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`};
665
+ return {success: false, error: `Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`};
652
666
  }
653
667
  } else if (typeof payload === 'object') {
654
- payload_obj = payload;
668
+ payloadObj = payload;
655
669
  }
656
- if (payload_obj.hasOwnProperty('device') && payload_obj.hasOwnProperty('payload'))
657
- {
670
+
671
+ if (payloadObj.hasOwnProperty('device') && payloadObj.hasOwnProperty('payload')) {
658
672
  try {
659
- const isDevice = payload.device.indexOf('group_') == -1;
673
+ const isDevice = !payload.device.includes('group_');
660
674
  const stateList = [];
661
- const devID = (isDevice ? `0x${payload.device}`:parseInt(payload.device.replace('group_', '')));
675
+ const devID = isDevice ? `0x${payload.device}`:parseInt(payload.device.replace('group_', ''));
662
676
 
663
677
  const entity = await this.zbController.resolveEntity(devID);
664
678
  if (!entity) {
665
- this.log.error(`Device ${safeJsonStringify(payload_obj.device)} not found`);
666
- this.sendError(`Device ${safeJsonStringify(payload_obj.device)} not found`);
667
- return {success: false, error: `Device ${safeJsonStringify(payload_obj.device)} not found`};
679
+ this.log.error(`Device ${safeJsonStringify(payloadObj.device)} not found`);
680
+ this.sendError(`Device ${safeJsonStringify(payloadObj.device)} not found`);
681
+ return {success: false, error: `Device ${safeJsonStringify(payloadObj.device)} not found`};
668
682
  }
669
683
  const mappedModel = entity.mapped;
670
684
  if (!mappedModel) {
671
- this.log.error(`No Model for Device ${safeJsonStringify(payload_obj.device)}`);
672
- this.sendError(`No Model for Device ${safeJsonStringify(payload_obj.device)}`);
673
- return {success: false, error: `No Model for Device ${safeJsonStringify(payload_obj.device)}`};
685
+ this.log.error(`No Model for Device ${safeJsonStringify(payloadObj.device)}`);
686
+ this.sendError(`No Model for Device ${safeJsonStringify(payloadObj.device)}`);
687
+ return {success: false, error: `No Model for Device ${safeJsonStringify(payloadObj.device)}`};
674
688
  }
675
- if (typeof payload_obj.payload !== 'object') {
676
- this.log.error(`Illegal payload type for ${safeJsonStringify(payload_obj.device)}`);
677
- this.sendError(`Illegal payload type for ${safeJsonStringify(payload_obj.device)}`);
678
- return {success: false, error: `Illegal payload type for ${safeJsonStringify(payload_obj.device)}`};
689
+ if (typeof payloadObj.payload !== 'object') {
690
+ this.log.error(`Illegal payload type for ${safeJsonStringify(payloadObj.device)}`);
691
+ this.sendError(`Illegal payload type for ${safeJsonStringify(payloadObj.device)}`);
692
+ return {success: false, error: `Illegal payload type for ${safeJsonStringify(payloadObj.device)}`};
679
693
  }
680
- for (const key in payload_obj.payload) {
681
- if (payload_obj.payload[key] != undefined) {
682
- const datatype = typeof payload_obj.payload[key];
683
- stateList.push({stateDesc: {
684
- id:key,
685
- prop:key,
686
- role:'state',
687
- type:datatype,
688
- epname:payload_obj.endpoint,
689
- }, value: payload_obj.payload[key], index:0, timeout:0});
694
+ for (const key in payloadObj.payload) {
695
+ if (payloadObj.payload[key] != undefined) {
696
+ const datatype = typeof payloadObj.payload[key];
697
+ stateList.push({
698
+ stateDesc: {
699
+ id: key,
700
+ prop: key,
701
+ role: 'state',
702
+ type: datatype,
703
+ epname: payloadObj.endpoint,
704
+ },
705
+ value: payloadObj.payload[key],
706
+ index: 0,
707
+ timeout: 0,
708
+ });
690
709
  }
691
710
  }
692
711
  try {
693
- this.log.debug(`Calling publish to state for ${safeJsonStringify(payload_obj.device)} with ${safeJsonStringify(stateList)}`);
712
+ this.log.debug(`Calling publish to state for ${safeJsonStringify(payloadObj.device)} with ${safeJsonStringify(stateList)}`);
694
713
  await this.publishFromState(`0x${payload.device}`, '', undefined, stateList, payload.options);
695
714
  return {success: true};
696
- }
697
- catch (error)
698
- {
715
+ } catch (error) {
699
716
  this.filterError(`Error ${error.code} on send command to ${payload.device}.`+
700
717
  ` Error: ${error.stack}`, `Send command to ${payload.device} failed with`, error);
701
- return {success:false, error: error};
718
+ return {success: false, error};
702
719
  }
720
+ } catch (e) {
721
+ return {success: false, error: e};
703
722
  }
704
- catch (e) {
705
- return {success:false, error: e};
706
- }
707
-
708
723
  }
709
- return {success:false, error: 'missing parameter device or payload in message ' + JSON.stringify(payload)};
724
+
725
+ return {success: false, error: `missing parameter device or payload in message ${JSON.stringify(payload)}`};
710
726
  }
711
727
 
712
728
 
@@ -732,7 +748,7 @@ class Zigbee extends utils.Adapter {
732
748
  this.log.debug(`Leave device event: ${ieeeAddr}`);
733
749
  if (ieeeAddr) {
734
750
  const devId = ieeeAddr.substr(2);
735
- this.log.debug('Delete device ' + devId + ' from iobroker.');
751
+ this.log.debug(`Delete device ${devId} from iobroker.`);
736
752
  this.stController.deleteDeviceStates(devId);
737
753
  }
738
754
  }
@@ -756,7 +772,7 @@ class Zigbee extends utils.Adapter {
756
772
  }
757
773
  }
758
774
  }
759
-
775
+
760
776
  /**
761
777
  * @param {() => void} callback
762
778
  */
@@ -856,7 +872,7 @@ class Zigbee extends utils.Adapter {
856
872
  }
857
873
 
858
874
  expandFileName(fn) {
859
- return path.join(utils.getAbsoluteInstanceDataDir(this), fn);
875
+ return path.join(utils.getAbsoluteInstanceDataDir(this), fn);
860
876
  }
861
877
 
862
878
  onLog(level, msg, data) {
@@ -867,8 +883,8 @@ class Zigbee extends utils.Adapter {
867
883
  logger = this.log.error;
868
884
  if (data)
869
885
  data = data.toString();
870
- this.logToPairing('Error: ' + msg + '. ' + data, true);
871
- this.sendError('Error: ' + msg + '. ' + data);
886
+ this.logToPairing(`Error: ${msg}. ${data}`, true);
887
+ this.sendError(`Error: ${msg}. ${data}`);
872
888
  break;
873
889
  case 'debug':
874
890
  logger = this.log.debug;
@@ -882,9 +898,9 @@ class Zigbee extends utils.Adapter {
882
898
  }
883
899
  if (data) {
884
900
  if (typeof data === 'string') {
885
- logger(msg + '. ' + data);
901
+ logger(`${msg}. ${data}`);
886
902
  } else {
887
- logger(msg + '. ' + safeJsonStringify(data));
903
+ logger(`${msg}. ${safeJsonStringify(data)}`);
888
904
  }
889
905
  } else {
890
906
  logger(msg);