iobroker.zigbee 1.8.0 → 1.8.3

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 (89) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc.json +37 -0
  3. package/.github/FUNDING.yml +3 -0
  4. package/.github/auto-merge.yml +17 -0
  5. package/.github/dependabot.yml +24 -0
  6. package/.github/stale.yml +13 -0
  7. package/.github/workflows/codeql.yml +41 -0
  8. package/.github/workflows/dependabot-automerge.yml +22 -0
  9. package/.github/workflows/test-and-release.yml +149 -0
  10. package/.releaseconfig.json +3 -0
  11. package/.travis/wiki.sh +28 -0
  12. package/.travis.yml +41 -0
  13. package/README.md +32 -9
  14. package/admin/admin.js +466 -482
  15. package/admin/i18n/de/translations.json +2 -2
  16. package/admin/index_m.html +1 -1
  17. package/admin/tab_m.html +3 -44
  18. package/admin/words.js +2 -2
  19. package/gulpfile.js +464 -0
  20. package/io-package.json +19 -26
  21. package/lib/backup.js +2 -2
  22. package/lib/binding.js +24 -23
  23. package/lib/colors.js +14 -16
  24. package/lib/commands.js +82 -89
  25. package/lib/developer.js +7 -6
  26. package/lib/devices.js +153 -144
  27. package/lib/exclude.js +36 -30
  28. package/lib/exposes.js +111 -106
  29. package/lib/groups.js +54 -53
  30. package/lib/json.js +4 -3
  31. package/lib/networkmap.js +2 -2
  32. package/lib/ota.js +15 -23
  33. package/lib/rgb.js +44 -47
  34. package/lib/seriallist.js +16 -21
  35. package/lib/states.js +496 -482
  36. package/lib/statescontroller.js +164 -170
  37. package/lib/utils.js +21 -22
  38. package/lib/zbBaseExtension.js +4 -4
  39. package/lib/zbDelayedAction.js +13 -5
  40. package/lib/zbDeviceAvailability.js +44 -47
  41. package/lib/zbDeviceConfigure.js +19 -7
  42. package/lib/zbDeviceEvent.js +4 -3
  43. package/lib/zigbeecontroller.js +96 -88
  44. package/main.js +133 -149
  45. package/package.json +15 -29
  46. package/test/integration.js +5 -0
  47. package/test/mocha.custom.opts +2 -0
  48. package/test/mocha.setup.js +14 -0
  49. package/test/package.js +5 -0
  50. package/test/unit.js +5 -0
  51. package/docs/de/img/CC2531.png +0 -0
  52. package/docs/de/img/CC2538_CC2592_PA.PNG +0 -0
  53. package/docs/de/img/CC2591.png +0 -0
  54. package/docs/de/img/boards.jpg +0 -0
  55. package/docs/de/img/cc26x2r.PNG +0 -0
  56. package/docs/de/img/results.jpg +0 -0
  57. package/docs/de/img/sku_429478_2.png +0 -0
  58. package/docs/de/img/sku_429601_2.png +0 -0
  59. package/docs/de/readme.md +0 -27
  60. package/docs/en/img/CC2531.png +0 -0
  61. package/docs/en/img/CC2591.png +0 -0
  62. package/docs/en/img/deconz.png +0 -0
  63. package/docs/en/img/sku_429478_2.png +0 -0
  64. package/docs/en/img/sku_429601_2.png +0 -0
  65. package/docs/en/readme.md +0 -30
  66. package/docs/flashing_via_arduino_(en).md +0 -110
  67. package/docs/ru/img/CC2531.png +0 -0
  68. package/docs/ru/img/CC2591.png +0 -0
  69. package/docs/ru/img/sku_429478_2.png +0 -0
  70. package/docs/ru/img/sku_429601_2.png +0 -0
  71. package/docs/ru/readme.md +0 -28
  72. package/docs/tutorial/CC2530_20190425.zip +0 -0
  73. package/docs/tutorial/CC2530_CC2591_20190515.zip +0 -0
  74. package/docs/tutorial/CC2530_CC2592_20190515.zip +0 -0
  75. package/docs/tutorial/CC2531_20190425.zip +0 -0
  76. package/docs/tutorial/adm5_1.PNG +0 -0
  77. package/docs/tutorial/adm5_2.PNG +0 -0
  78. package/docs/tutorial/cat.PNG +0 -0
  79. package/docs/tutorial/groups-1.png +0 -0
  80. package/docs/tutorial/groups-2.png +0 -0
  81. package/docs/tutorial/inst.PNG +0 -0
  82. package/docs/tutorial/reflash-finish.PNG +0 -0
  83. package/docs/tutorial/reflash-step0.png +0 -0
  84. package/docs/tutorial/reflash-step1.PNG +0 -0
  85. package/docs/tutorial/reflash-step2.PNG +0 -0
  86. package/docs/tutorial/settings.png +0 -0
  87. package/docs/tutorial/tab-dev-1.png +0 -0
  88. package/docs/tutorial/zigbee.png +0 -0
  89. package/docs/tutorial/zigbee15.png +0 -0
package/main.js CHANGED
@@ -40,20 +40,21 @@ 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: 'Unsupported 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:'Unnsupported Attribute'},
55
55
  };
56
56
 
57
+
57
58
  class Zigbee extends utils.Adapter {
58
59
  /**
59
60
  * @param {Partial<ioBroker.AdapterOptions>} [options={}]
@@ -92,15 +93,14 @@ class Zigbee extends utils.Adapter {
92
93
  case 'SendToDevice': {
93
94
  let rv = {
94
95
  success: false,
95
- loc: -1,
96
+ loc:-1,
96
97
  };
97
-
98
98
  try {
99
- rv = await this.sendPayload(obj.message);
100
- } catch (e) {
99
+ rv = await this.SendPayload(obj.message);
100
+ }
101
+ catch (e) {
101
102
  rv.error = e;
102
103
  }
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
124
- }));
123
+ message: message
124
+ });
125
+ });
125
126
  }
126
-
127
127
  if (typeof error == 'string') {
128
128
  Sentry.captureException(new Error(error));
129
129
  } else {
@@ -135,31 +135,27 @@ class Zigbee extends utils.Adapter {
135
135
  }
136
136
 
137
137
  filterError(errormessage, message, error) {
138
- if (error.code === undefined) {
139
- let em = error.stack.match(/failed \((.+?)\) at/);
140
- em = em || error.stack.match(/failed \((.+?)\)/);
138
+ if (error.code === undefined)
139
+ {
140
+ let em = error.stack.match(/failed \((.+?)\) at/);
141
+ if (!em) em = error.stack.match(/failed \((.+?)\)/);
141
142
  this.log.error(`${message} no error code (${(em ? em[1]:'undefined')})`);
142
143
  this.sendError(error, `${message} no error code`);
143
144
  this.log.debug(`Stack trace for ${em}: ${error.stack}`);
144
145
  return;
145
146
  }
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
-
154
153
  switch (ecode.severity) {
155
- case E_INFO:
156
- this.log.info(`${message}: Code ${error.code} (${ecode.message})`);
154
+ case E_INFO: this.log.info(`${message}: Code ${error.code} (${ecode.message})`);
157
155
  break;
158
- case E_DEBUG:
159
- this.log.debug(`${message}: Code ${error.code} (${ecode.message})`);
156
+ case E_DEBUG: this.log.debug(`${message}: Code ${error.code} (${ecode.message})`);
160
157
  break;
161
- case E_WARN:
162
- this.log.warn(`${message}: Code ${error.code} (${ecode.message})`);
158
+ case E_WARN: this.log.warn(`${message}: Code ${error.code} (${ecode.message})`);
163
159
  break;
164
160
  case E_ERROR:
165
161
  this.log.error(`${message}: Code ${error.code} (${ecode.message})`);
@@ -168,7 +164,6 @@ class Zigbee extends utils.Adapter {
168
164
  default:
169
165
  this.log.error(`${message}: Code ${error.code} (malformed error)`);
170
166
  this.sendError(error, `${message}: Code ${error.code} (malformed error)`);
171
- break;
172
167
  }
173
168
  }
174
169
 
@@ -186,8 +181,9 @@ class Zigbee extends utils.Adapter {
186
181
  // external converters
187
182
  this.applyExternalConverters();
188
183
  // get exclude list from object
189
- this.getState('exclude.all', (err, state) =>
190
- this.stController.getExcludeExposes(state));
184
+ this.getState('exclude.all', (err, state) => {
185
+ this.stController.getExcludeExposes(state);
186
+ });
191
187
 
192
188
  this.subscribeStates('*');
193
189
  // set connection false before connect to zigbee
@@ -216,9 +212,7 @@ class Zigbee extends utils.Adapter {
216
212
  }
217
213
  const extfiles = this.config.external.split(';');
218
214
  for (const moduleName of extfiles) {
219
- if (!moduleName) {
220
- continue;
221
- }
215
+ if (!moduleName) continue;
222
216
  this.log.info(`Apply converter from module: ${moduleName}`);
223
217
  const sandbox = {
224
218
  require,
@@ -237,7 +231,7 @@ class Zigbee extends utils.Adapter {
237
231
  }
238
232
  }
239
233
 
240
- applyExternalConverters() {
234
+ applyExternalConverters(){
241
235
  for (const definition of this.getExternalDefinition()) {
242
236
  const toAdd = {...definition};
243
237
  delete toAdd['homeassistant'];
@@ -258,16 +252,16 @@ class Zigbee extends utils.Adapter {
258
252
  // installed version
259
253
  let gitVers = '';
260
254
  try {
261
- this.log.info(`Starting Zigbee ${debugversion}`);
255
+ this.log.info('Starting Zigbee ' + debugversion);
262
256
 
263
- await this.getForeignObject(`system.adapter.${this.namespace}`, (err, obj) => {
257
+ await this.getForeignObject('system.adapter.' + this.namespace, (err, obj) => {
264
258
  if (!err && obj && obj.common.installedFrom && obj.common.installedFrom.includes('://')) {
265
259
  const instFrom = obj.common.installedFrom;
266
- gitVers = gitVers + instFrom.replace('tarball', 'commit');
260
+ gitVers = gitVers + instFrom.replace('tarball','commit');
267
261
  } else {
268
262
  gitVers = obj.common.installedFrom;
269
263
  }
270
- this.log.info(`Installed Version: ${gitVers}`);
264
+ this.log.info('Installed Version: ' + gitVers );
271
265
  });
272
266
 
273
267
  await this.zbController.start();
@@ -280,7 +274,6 @@ class Zigbee extends utils.Adapter {
280
274
  this.log.error(error);
281
275
  }
282
276
  this.sendError(error, `Failed to start Zigbee`);
283
-
284
277
  if (this.reconnectCounter > 0) {
285
278
  this.tryToReconnect();
286
279
  }
@@ -298,10 +291,10 @@ class Zigbee extends utils.Adapter {
298
291
 
299
292
  tryToReconnect() {
300
293
  this.reconnectTimer = setTimeout(()=>{
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
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
305
298
  // AP issue or Zigbee gateway power is turned off unexpectedly.
306
299
  // So try to reconnect gateway every 10 seconds all the time.
307
300
  this.log.info(`Try to reconnect.`);
@@ -310,7 +303,7 @@ class Zigbee extends utils.Adapter {
310
303
  this.reconnectCounter -= 1;
311
304
  }
312
305
  this.doConnect();
313
- }, 10 * 1000); // every 10 seconds
306
+ }, 10*1000); // every 10 seconds
314
307
  }
315
308
 
316
309
  async onZigbeeAdapterReady() {
@@ -319,13 +312,13 @@ class Zigbee extends utils.Adapter {
319
312
  // https://github.com/ioBroker/ioBroker.zigbee/issues/668
320
313
  const extPanIdFix = this.config.extPanIdFix ? this.config.extPanIdFix : false;
321
314
  if (!extPanIdFix) {
322
- const configExtPanId = this.config.extPanID ? '0x' + this.config.extPanID.toLowerCase() : '0xdddddddddddddddd';
315
+ const configExtPanId = this.config.extPanID ? '0x'+this.config.extPanID.toLowerCase() : '0xdddddddddddddddd';
323
316
  let networkExtPanId = (await this.zbController.herdsman.getNetworkParameters()).extendedPanID;
324
317
  let needChange = false;
325
318
  this.log.debug(`Config value ${configExtPanId} : Network value ${networkExtPanId}`);
326
319
  const adapterType = this.config.adapterType || 'zstack';
327
320
  if (adapterType === 'zstack') {
328
- if (configExtPanId !== networkExtPanId) {
321
+ if (configExtPanId != networkExtPanId) {
329
322
  try {
330
323
  // try to read from nvram
331
324
  const result = await this.zbController.herdsman.adapter.znp.request(
@@ -341,9 +334,9 @@ class Zigbee extends utils.Adapter {
341
334
  2, // ZnpCommandStatus.INVALID_PARAM
342
335
  ]
343
336
  );
344
- const nwExtPanId = '0x' + result.payload.value.reverse().toString('hex');
337
+ const nwExtPanId = '0x'+result.payload.value.reverse().toString('hex');
345
338
  this.log.debug(`Config value ${configExtPanId} : nw value ${nwExtPanId}`);
346
- if (configExtPanId !== nwExtPanId) {
339
+ if (configExtPanId != nwExtPanId) {
347
340
  networkExtPanId = nwExtPanId;
348
341
  needChange = true;
349
342
  }
@@ -373,36 +366,37 @@ class Zigbee extends utils.Adapter {
373
366
  for (const device of devicesFromDB) {
374
367
  const entity = await this.zbController.resolveEntity(device);
375
368
  if (entity) {
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));
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
+ });
379
373
  }
380
374
  }
381
375
  await this.callPluginMethod('start', [this.zbController, this.stController]);
382
376
  }
383
377
 
384
378
  async checkIfModelUpdate(entity) {
385
- const model = entity.mapped ? entity.mapped.model : entity.device.modelID,
379
+ const model = (entity.mapped) ? entity.mapped.model : entity.device.modelID,
386
380
  device = entity.device,
387
381
  devId = device.ieeeAddr.substr(2);
388
-
389
382
  return new Promise((resolve) => {
390
383
  this.getObject(devId, (err, obj) => {
391
- if (obj && obj.common.type !== model) {
384
+ if (obj && obj.common.type != model) {
392
385
  // let's change model
393
386
  this.getStatesOf(devId, (err, states) => {
394
387
  if (!err && states) {
395
388
  const chain = [];
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
- })));
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
+ });
406
400
  } else {
407
401
  resolve();
408
402
  }
@@ -418,14 +412,13 @@ class Zigbee extends utils.Adapter {
418
412
 
419
413
  async onZigbeeEvent(type, entity, message){
420
414
  this.log.debug(`Type ${type} device ${safeJsonStringify(entity)} incoming event: ${safeJsonStringify(message)}`);
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
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
429
422
  meta.logger = this.log;
430
423
 
431
424
  await this.checkIfModelUpdate(entity);
@@ -446,14 +439,12 @@ class Zigbee extends utils.Adapter {
446
439
  }
447
440
  let converters = mappedModel.fromZigbee.filter(c => c && c.cluster === cluster && (
448
441
  (c.type instanceof Array) ? c.type.includes(type) : c.type === type));
449
-
450
442
  if (!converters.length && type === 'readResponse') {
451
443
  converters = mappedModel.fromZigbee.filter(c => c.cluster === cluster && (
452
444
  (c.type instanceof Array) ? c.type.includes('attributeReport') : c.type === 'attributeReport'));
453
445
  }
454
-
455
446
  if (!converters.length) {
456
- if (type !== 'readResponse') {
447
+ if (type != 'readResponse') {
457
448
  this.log.debug(
458
449
  `No converter available for '${mappedModel.model}' with cluster '${cluster}' and type '${type}'`
459
450
  );
@@ -485,10 +476,10 @@ class Zigbee extends utils.Adapter {
485
476
 
486
477
  acknowledgeState(deviceId, model, stateDesc, value) {
487
478
  if (model === 'group') {
488
- const stateId = `${this.namespace}.group_${deviceId}.${stateDesc.id}`;
479
+ const stateId = this.namespace + '.group_' + deviceId + '.' + stateDesc.id;
489
480
  this.setState(stateId, value, true);
490
481
  } else {
491
- const stateId = `${this.namespace}.${deviceId.replace('0x', '')}.${stateDesc.id}`;
482
+ const stateId = this.namespace + '.' + deviceId.replace('0x', '') + '.' + stateDesc.id;
492
483
  this.setState(stateId, value, true);
493
484
  }
494
485
  }
@@ -501,7 +492,7 @@ class Zigbee extends utils.Adapter {
501
492
 
502
493
  async publishFromState(deviceId, model, stateModel, stateList, options){
503
494
  let isGroup = false;
504
- if (model === 'group') {
495
+ if (model == 'group') {
505
496
  isGroup = true;
506
497
  deviceId = parseInt(deviceId);
507
498
  }
@@ -512,17 +503,17 @@ class Zigbee extends utils.Adapter {
512
503
  this.log.debug(`No mapped model for ${model}`);
513
504
  return;
514
505
  }
515
- this.log.debug(`Mapped Model: ${JSON.stringify(mappedModel)}`);
506
+ this.log.debug('Mapped Model: ' + JSON.stringify(mappedModel));
516
507
 
517
- stateList.forEach(async changedState => {
508
+ stateList.forEach(async(changedState) => {
518
509
  const stateDesc = changedState.stateDesc;
519
510
  const value = changedState.value;
520
511
 
521
- if (stateDesc.id === 'send_payload') {
512
+ if (stateDesc.id == 'send_payload') {
522
513
  try {
523
514
  const json_value = JSON.parse(value);
524
- const payload = {device: deviceId.replace('0x', ''), payload: json_value};
525
- const result = await(this.sendPayload(payload));
515
+ const payload = { device:deviceId.replace('0x', ''), payload:json_value };
516
+ const result = await(this.SendPayload(payload));
526
517
  if (result.hasOwnProperty('success') && result.success) {
527
518
  this.acknowledgeState(deviceId, model, stateDesc, value);
528
519
  }
@@ -541,7 +532,7 @@ class Zigbee extends utils.Adapter {
541
532
  // if this is the device query state => trigger the device query
542
533
 
543
534
  // on activation of the 'device_query' state trigger hardware query where possible
544
- if (stateDesc.id === 'device_query') {
535
+ if (stateDesc.id == 'device_query') {
545
536
  if (this.query_device_block.indexOf(deviceId) > -1) {
546
537
  this.log.warn(`Device query for '${entity.device.ieeeAddr}' blocked`);
547
538
  return;
@@ -563,18 +554,16 @@ class Zigbee extends utils.Adapter {
563
554
  }
564
555
  this.log.debug(`Device query for '${entity.device.ieeeAddr}' done`);
565
556
  const idToRemove = deviceId;
566
- setTimeout(() => {
557
+ setTimeout(()=>{
567
558
  const idx = this.query_device_block.indexOf(idToRemove);
568
- if (idx > -1) {
569
- this.query_device_block.splice(idx);
570
- }
559
+ if (idx > -1) this.query_device_block.splice(idx);
571
560
  }, 10000);
572
561
  }
573
562
  return;
574
563
  }
575
564
  return;
576
565
  }
577
- const converter = mappedModel.toZigbee.find(c => c && (c.key.includes(stateDesc.prop) || c.key.includes(stateDesc.setattr) || c.key.includes(stateDesc.id)));
566
+ const converter = mappedModel.toZigbee.find((c) => c && (c.key.includes(stateDesc.prop) || c.key.includes(stateDesc.setattr) || c.key.includes(stateDesc.id)));
578
567
  if (!converter) {
579
568
  this.log.error(`No converter available for '${model}' with key '${stateDesc.id}' `);
580
569
  this.sendError(`No converter available for '${model}' with key '${stateDesc.id}' `);
@@ -585,7 +574,7 @@ class Zigbee extends utils.Adapter {
585
574
  const preparedOptions = (stateDesc.setterOpt) ? stateDesc.setterOpt(value, options) : {};
586
575
  let syncStateList = [];
587
576
  if (stateModel && stateModel.syncStates) {
588
- stateModel.syncStates.forEach(syncFunct => {
577
+ stateModel.syncStates.forEach((syncFunct) => {
589
578
  const res = syncFunct(stateDesc, value, options);
590
579
  if (res) {
591
580
  syncStateList = syncStateList.concat(res);
@@ -604,14 +593,12 @@ class Zigbee extends utils.Adapter {
604
593
  target = await this.zbController.resolveEntity(deviceId, epName);
605
594
  target = target.endpoint;
606
595
  }
607
-
608
596
  this.log.debug(`target: ${safeJsonStringify(target)}`);
609
-
610
597
  const meta = {
611
598
  endpoint_name: epName,
612
599
  options: preparedOptions,
613
600
  device: entity.device,
614
- mapped: model === 'group' ? [] : mappedModel,
601
+ mapped: (model == 'group') ? [] : mappedModel,
615
602
  message: {[key]: preparedValue},
616
603
  logger: this.log,
617
604
  state: {},
@@ -623,24 +610,23 @@ class Zigbee extends utils.Adapter {
623
610
  const result = await converter.convertSet(target, key, preparedValue, meta);
624
611
  this.log.debug(`convert result ${safeJsonStringify(result)}`);
625
612
  if (result !== undefined) {
626
- if (stateModel && !isGroup) {
613
+ if (stateModel && !isGroup)
627
614
  this.acknowledgeState(deviceId, model, stateDesc, value);
628
- }
629
615
  // process sync state list
630
616
  this.processSyncStatesList(deviceId, model, syncStateList);
631
-
632
617
  if (isGroup) {
633
618
  await this.callPluginMethod('queryGroupMemberState', [deviceId, stateDesc]);
634
619
  this.acknowledgeState(deviceId, model, stateDesc, value);
635
620
  }
636
621
  }
637
- } catch (error) {
622
+ } catch(error) {
638
623
  this.filterError(`Error ${error.code} on send command to ${deviceId}.`+
639
624
  ` Error: ${error.stack}`, `Send command to ${deviceId} failed with`, error);
640
625
  }
641
626
  });
642
627
  }
643
-
628
+ //
629
+ //
644
630
  // This function is introduced to explicitly allow user level scripts to send Commands
645
631
  // directly to the zigbee device. It utilizes the zigbee-herdsman-converters to generate
646
632
  // the exact zigbee message to be sent and can be used to set device options which are
@@ -653,76 +639,74 @@ class Zigbee extends utils.Adapter {
653
639
  // payload: The data to send to the device as JSON object (key/Value pairs)
654
640
  // endpoint: optional: the endpoint to send the data to, if supported.
655
641
  //
656
- async sendPayload(payload) {
642
+ async SendPayload(payload) {
657
643
  this.log.debug(`publishToDevice called with ${safeJsonStringify(payload)}`);
658
- let payloadObj = {};
644
+ let payload_obj = {};
659
645
  if (typeof payload === 'string') {
660
646
  try {
661
- payloadObj = JSON.parse(payload);
647
+ payload_obj = JSON.parse();
662
648
  } catch (e) {
663
649
  this.log.error(`Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`);
664
650
  this.sendError(e, `Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`);
665
- return {success: false, error: `Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`};
651
+ return {success:false, error: `Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`};
666
652
  }
667
653
  } else if (typeof payload === 'object') {
668
- payloadObj = payload;
654
+ payload_obj = payload;
669
655
  }
670
-
671
- if (payloadObj.hasOwnProperty('device') && payloadObj.hasOwnProperty('payload')) {
656
+ if (payload_obj.hasOwnProperty('device') && payload_obj.hasOwnProperty('payload'))
657
+ {
672
658
  try {
673
- const isDevice = !payload.device.includes('group_');
659
+ const isDevice = payload.device.indexOf('group_') == -1;
674
660
  const stateList = [];
675
- const devID = isDevice ? `0x${payload.device}`:parseInt(payload.device.replace('group_', ''));
661
+ const devID = (isDevice ? `0x${payload.device}`:parseInt(payload.device.replace('group_', '')));
676
662
 
677
663
  const entity = await this.zbController.resolveEntity(devID);
678
664
  if (!entity) {
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`};
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`};
682
668
  }
683
669
  const mappedModel = entity.mapped;
684
670
  if (!mappedModel) {
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)}`};
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)}`};
688
674
  }
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)}`};
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)}`};
693
679
  }
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
- });
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});
709
690
  }
710
691
  }
711
692
  try {
712
- this.log.debug(`Calling publish to state for ${safeJsonStringify(payloadObj.device)} with ${safeJsonStringify(stateList)}`);
693
+ this.log.debug(`Calling publish to state for ${safeJsonStringify(payload_obj.device)} with ${safeJsonStringify(stateList)}`);
713
694
  await this.publishFromState(`0x${payload.device}`, '', undefined, stateList, payload.options);
714
695
  return {success: true};
715
- } catch (error) {
696
+ }
697
+ catch (error)
698
+ {
716
699
  this.filterError(`Error ${error.code} on send command to ${payload.device}.`+
717
700
  ` Error: ${error.stack}`, `Send command to ${payload.device} failed with`, error);
718
- return {success: false, error};
701
+ return {success:false, error: error};
719
702
  }
720
- } catch (e) {
721
- return {success: false, error: e};
722
703
  }
723
- }
704
+ catch (e) {
705
+ return {success:false, error: e};
706
+ }
724
707
 
725
- return {success: false, error: `missing parameter device or payload in message ${JSON.stringify(payload)}`};
708
+ }
709
+ return {success:false, error: 'missing parameter device or payload in message ' + JSON.stringify(payload)};
726
710
  }
727
711
 
728
712
 
@@ -748,7 +732,7 @@ class Zigbee extends utils.Adapter {
748
732
  this.log.debug(`Leave device event: ${ieeeAddr}`);
749
733
  if (ieeeAddr) {
750
734
  const devId = ieeeAddr.substr(2);
751
- this.log.debug(`Delete device ${devId} from iobroker.`);
735
+ this.log.debug('Delete device ' + devId + ' from iobroker.');
752
736
  this.stController.deleteDeviceStates(devId);
753
737
  }
754
738
  }
@@ -772,7 +756,7 @@ class Zigbee extends utils.Adapter {
772
756
  }
773
757
  }
774
758
  }
775
-
759
+
776
760
  /**
777
761
  * @param {() => void} callback
778
762
  */
@@ -872,7 +856,7 @@ class Zigbee extends utils.Adapter {
872
856
  }
873
857
 
874
858
  expandFileName(fn) {
875
- return path.join(utils.getAbsoluteInstanceDataDir(this), fn);
859
+ return path.join(utils.getAbsoluteInstanceDataDir(this), fn);
876
860
  }
877
861
 
878
862
  onLog(level, msg, data) {
@@ -883,8 +867,8 @@ class Zigbee extends utils.Adapter {
883
867
  logger = this.log.error;
884
868
  if (data)
885
869
  data = data.toString();
886
- this.logToPairing(`Error: ${msg}. ${data}`, true);
887
- this.sendError(`Error: ${msg}. ${data}`);
870
+ this.logToPairing('Error: ' + msg + '. ' + data, true);
871
+ this.sendError('Error: ' + msg + '. ' + data);
888
872
  break;
889
873
  case 'debug':
890
874
  logger = this.log.debug;
@@ -898,9 +882,9 @@ class Zigbee extends utils.Adapter {
898
882
  }
899
883
  if (data) {
900
884
  if (typeof data === 'string') {
901
- logger(`${msg}. ${data}`);
885
+ logger(msg + '. ' + data);
902
886
  } else {
903
- logger(`${msg}. ${safeJsonStringify(data)}`);
887
+ logger(msg + '. ' + safeJsonStringify(data));
904
888
  }
905
889
  } else {
906
890
  logger(msg);