iobroker.zigbee 1.8.1 → 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 +31 -8
  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 +18 -25
  21. package/lib/backup.js +2 -2
  22. package/lib/binding.js +37 -32
  23. package/lib/colors.js +158 -163
  24. package/lib/commands.js +90 -99
  25. package/lib/developer.js +12 -9
  26. package/lib/devices.js +179 -169
  27. package/lib/exclude.js +36 -30
  28. package/lib/exposes.js +139 -163
  29. package/lib/groups.js +83 -81
  30. package/lib/json.js +6 -5
  31. package/lib/networkmap.js +3 -2
  32. package/lib/ota.js +18 -34
  33. package/lib/rgb.js +72 -114
  34. package/lib/seriallist.js +20 -25
  35. package/lib/states.js +526 -511
  36. package/lib/statescontroller.js +183 -206
  37. package/lib/utils.js +23 -24
  38. package/lib/zbBaseExtension.js +4 -4
  39. package/lib/zbDelayedAction.js +13 -5
  40. package/lib/zbDeviceAvailability.js +65 -69
  41. package/lib/zbDeviceConfigure.js +21 -9
  42. package/lib/zbDeviceEvent.js +4 -3
  43. package/lib/zigbeecontroller.js +103 -109
  44. package/main.js +147 -163
  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 \((.+?)\)/);
141
- this.log.error(`${message} no error code (${(em ? em[1] : 'undefined')})`);
138
+ if (error.code === undefined)
139
+ {
140
+ let em = error.stack.match(/failed \((.+?)\) at/);
141
+ if (!em) em = error.stack.match(/failed \((.+?)\)/);
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,11 +164,10 @@ 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
 
175
- debugLog(data, ...args) {
170
+ debugLog (data, ...args) {
176
171
  const message = (args) ? util.format(data, ...args) : data;
177
172
  this.log.debug(message.slice(message.indexOf('zigbee-herdsman')));
178
173
  }
@@ -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'];
@@ -250,23 +244,24 @@ class Zigbee extends utils.Adapter {
250
244
  try {
251
245
  const DebugIdentify = require('./debugidentify');
252
246
  debugversion = DebugIdentify.ReportIdentifier();
253
- } catch {
247
+ }
248
+ catch {
254
249
  debugversion = ' npm ...';
255
250
  }
256
251
 
257
252
  // installed version
258
253
  let gitVers = '';
259
254
  try {
260
- this.log.info(`Starting Zigbee ${debugversion}`);
255
+ this.log.info('Starting Zigbee ' + debugversion);
261
256
 
262
- await this.getForeignObject(`system.adapter.${this.namespace}`, (err, obj) => {
257
+ await this.getForeignObject('system.adapter.' + this.namespace, (err, obj) => {
263
258
  if (!err && obj && obj.common.installedFrom && obj.common.installedFrom.includes('://')) {
264
259
  const instFrom = obj.common.installedFrom;
265
- gitVers = gitVers + instFrom.replace('tarball', 'commit');
260
+ gitVers = gitVers + instFrom.replace('tarball','commit');
266
261
  } else {
267
262
  gitVers = obj.common.installedFrom;
268
263
  }
269
- this.log.info(`Installed Version: ${gitVers}`);
264
+ this.log.info('Installed Version: ' + gitVers );
270
265
  });
271
266
 
272
267
  await this.zbController.start();
@@ -279,7 +274,6 @@ class Zigbee extends utils.Adapter {
279
274
  this.log.error(error);
280
275
  }
281
276
  this.sendError(error, `Failed to start Zigbee`);
282
-
283
277
  if (this.reconnectCounter > 0) {
284
278
  this.tryToReconnect();
285
279
  }
@@ -296,11 +290,11 @@ class Zigbee extends utils.Adapter {
296
290
  }
297
291
 
298
292
  tryToReconnect() {
299
- this.reconnectTimer = setTimeout(() => {
300
- if (this.config.port.includes('tcp://')) {
301
- // Controller connect though Wi-Fi.
302
- // Unlikely USB dongle, connection broken may only cause user unplugged the dongle,
303
- // Wi-Fi connected gateway is possible that device connection is broken caused by
293
+ 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
304
298
  // AP issue or Zigbee gateway power is turned off unexpectedly.
305
299
  // So try to reconnect gateway every 10 seconds all the time.
306
300
  this.log.info(`Try to reconnect.`);
@@ -309,7 +303,7 @@ class Zigbee extends utils.Adapter {
309
303
  this.reconnectCounter -= 1;
310
304
  }
311
305
  this.doConnect();
312
- }, 10 * 1000); // every 10 seconds
306
+ }, 10*1000); // every 10 seconds
313
307
  }
314
308
 
315
309
  async onZigbeeAdapterReady() {
@@ -318,13 +312,13 @@ class Zigbee extends utils.Adapter {
318
312
  // https://github.com/ioBroker/ioBroker.zigbee/issues/668
319
313
  const extPanIdFix = this.config.extPanIdFix ? this.config.extPanIdFix : false;
320
314
  if (!extPanIdFix) {
321
- const configExtPanId = this.config.extPanID ? '0x' + this.config.extPanID.toLowerCase() : '0xdddddddddddddddd';
315
+ const configExtPanId = this.config.extPanID ? '0x'+this.config.extPanID.toLowerCase() : '0xdddddddddddddddd';
322
316
  let networkExtPanId = (await this.zbController.herdsman.getNetworkParameters()).extendedPanID;
323
317
  let needChange = false;
324
318
  this.log.debug(`Config value ${configExtPanId} : Network value ${networkExtPanId}`);
325
319
  const adapterType = this.config.adapterType || 'zstack';
326
320
  if (adapterType === 'zstack') {
327
- if (configExtPanId !== networkExtPanId) {
321
+ if (configExtPanId != networkExtPanId) {
328
322
  try {
329
323
  // try to read from nvram
330
324
  const result = await this.zbController.herdsman.adapter.znp.request(
@@ -340,9 +334,9 @@ class Zigbee extends utils.Adapter {
340
334
  2, // ZnpCommandStatus.INVALID_PARAM
341
335
  ]
342
336
  );
343
- const nwExtPanId = '0x' + result.payload.value.reverse().toString('hex');
337
+ const nwExtPanId = '0x'+result.payload.value.reverse().toString('hex');
344
338
  this.log.debug(`Config value ${configExtPanId} : nw value ${nwExtPanId}`);
345
- if (configExtPanId !== nwExtPanId) {
339
+ if (configExtPanId != nwExtPanId) {
346
340
  networkExtPanId = nwExtPanId;
347
341
  needChange = true;
348
342
  }
@@ -372,36 +366,37 @@ class Zigbee extends utils.Adapter {
372
366
  for (const device of devicesFromDB) {
373
367
  const entity = await this.zbController.resolveEntity(device);
374
368
  if (entity) {
375
- const model = entity.mapped ? entity.mapped.model : entity.device.modelID;
376
- this.stController.updateDev(device.ieeeAddr.substr(2), model, model, () =>
377
- 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
+ });
378
373
  }
379
374
  }
380
375
  await this.callPluginMethod('start', [this.zbController, this.stController]);
381
376
  }
382
377
 
383
378
  async checkIfModelUpdate(entity) {
384
- const model = entity.mapped ? entity.mapped.model : entity.device.modelID,
379
+ const model = (entity.mapped) ? entity.mapped.model : entity.device.modelID,
385
380
  device = entity.device,
386
381
  devId = device.ieeeAddr.substr(2);
387
-
388
382
  return new Promise((resolve) => {
389
383
  this.getObject(devId, (err, obj) => {
390
- if (obj && obj.common.type !== model) {
384
+ if (obj && obj.common.type != model) {
391
385
  // let's change model
392
386
  this.getStatesOf(devId, (err, states) => {
393
387
  if (!err && states) {
394
388
  const chain = [];
395
- states.forEach((state) =>
396
- chain.push(this.deleteStateAsync(devId, null, state._id)));
397
-
398
- Promise.all(chain)
399
- .then(() =>
400
- this.stController.deleteDeviceStates(devId, () =>
401
- this.stController.updateDev(devId, model, model, async () => {
402
- await this.stController.syncDevStates(device, model);
403
- resolve();
404
- })));
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
+ });
405
400
  } else {
406
401
  resolve();
407
402
  }
@@ -413,16 +408,17 @@ class Zigbee extends utils.Adapter {
413
408
  });
414
409
  }
415
410
 
416
- async onZigbeeEvent(type, entity, message) {
417
- this.log.debug(`Type ${type} device ${safeJsonStringify(entity)} incoming event: ${safeJsonStringify(message)}`);
418
- const device = entity.device;
419
- const mappedModel = entity.mapped;
420
- const model = (entity.mapped) ? entity.mapped.model : entity.device.modelID;
421
- const cluster = message.cluster;
422
- const devId = device.ieeeAddr.substr(2);
423
- const meta = {device};
424
411
 
425
- // this assigment give possibility to use iobroker logger in code of the converters, via meta.logger
412
+
413
+ async onZigbeeEvent(type, entity, message){
414
+ 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
426
422
  meta.logger = this.log;
427
423
 
428
424
  await this.checkIfModelUpdate(entity);
@@ -443,14 +439,12 @@ class Zigbee extends utils.Adapter {
443
439
  }
444
440
  let converters = mappedModel.fromZigbee.filter(c => c && c.cluster === cluster && (
445
441
  (c.type instanceof Array) ? c.type.includes(type) : c.type === type));
446
-
447
442
  if (!converters.length && type === 'readResponse') {
448
443
  converters = mappedModel.fromZigbee.filter(c => c.cluster === cluster && (
449
444
  (c.type instanceof Array) ? c.type.includes('attributeReport') : c.type === 'attributeReport'));
450
445
  }
451
-
452
446
  if (!converters.length) {
453
- if (type !== 'readResponse') {
447
+ if (type != 'readResponse') {
454
448
  this.log.debug(
455
449
  `No converter available for '${mappedModel.model}' with cluster '${cluster}' and type '${type}'`
456
450
  );
@@ -482,10 +476,10 @@ class Zigbee extends utils.Adapter {
482
476
 
483
477
  acknowledgeState(deviceId, model, stateDesc, value) {
484
478
  if (model === 'group') {
485
- const stateId = `${this.namespace}.group_${deviceId}.${stateDesc.id}`;
479
+ const stateId = this.namespace + '.group_' + deviceId + '.' + stateDesc.id;
486
480
  this.setState(stateId, value, true);
487
481
  } else {
488
- const stateId = `${this.namespace}.${deviceId.replace('0x', '')}.${stateDesc.id}`;
482
+ const stateId = this.namespace + '.' + deviceId.replace('0x', '') + '.' + stateDesc.id;
489
483
  this.setState(stateId, value, true);
490
484
  }
491
485
  }
@@ -496,9 +490,9 @@ class Zigbee extends utils.Adapter {
496
490
  });
497
491
  }
498
492
 
499
- async publishFromState(deviceId, model, stateModel, stateList, options) {
493
+ async publishFromState(deviceId, model, stateModel, stateList, options){
500
494
  let isGroup = false;
501
- if (model === 'group') {
495
+ if (model == 'group') {
502
496
  isGroup = true;
503
497
  deviceId = parseInt(deviceId);
504
498
  }
@@ -509,17 +503,17 @@ class Zigbee extends utils.Adapter {
509
503
  this.log.debug(`No mapped model for ${model}`);
510
504
  return;
511
505
  }
512
- this.log.debug(`Mapped Model: ${JSON.stringify(mappedModel)}`);
506
+ this.log.debug('Mapped Model: ' + JSON.stringify(mappedModel));
513
507
 
514
- stateList.forEach(async changedState => {
508
+ stateList.forEach(async(changedState) => {
515
509
  const stateDesc = changedState.stateDesc;
516
510
  const value = changedState.value;
517
511
 
518
- if (stateDesc.id === 'send_payload') {
512
+ if (stateDesc.id == 'send_payload') {
519
513
  try {
520
514
  const json_value = JSON.parse(value);
521
- const payload = {device: deviceId.replace('0x', ''), payload: json_value};
522
- const result = await this.sendPayload(payload);
515
+ const payload = { device:deviceId.replace('0x', ''), payload:json_value };
516
+ const result = await(this.SendPayload(payload));
523
517
  if (result.hasOwnProperty('success') && result.success) {
524
518
  this.acknowledgeState(deviceId, model, stateDesc, value);
525
519
  }
@@ -538,7 +532,7 @@ class Zigbee extends utils.Adapter {
538
532
  // if this is the device query state => trigger the device query
539
533
 
540
534
  // on activation of the 'device_query' state trigger hardware query where possible
541
- if (stateDesc.id === 'device_query') {
535
+ if (stateDesc.id == 'device_query') {
542
536
  if (this.query_device_block.indexOf(deviceId) > -1) {
543
537
  this.log.warn(`Device query for '${entity.device.ieeeAddr}' blocked`);
544
538
  return;
@@ -560,18 +554,16 @@ class Zigbee extends utils.Adapter {
560
554
  }
561
555
  this.log.debug(`Device query for '${entity.device.ieeeAddr}' done`);
562
556
  const idToRemove = deviceId;
563
- setTimeout(() => {
557
+ setTimeout(()=>{
564
558
  const idx = this.query_device_block.indexOf(idToRemove);
565
- if (idx > -1) {
566
- this.query_device_block.splice(idx);
567
- }
559
+ if (idx > -1) this.query_device_block.splice(idx);
568
560
  }, 10000);
569
561
  }
570
562
  return;
571
563
  }
572
564
  return;
573
565
  }
574
- 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)));
575
567
  if (!converter) {
576
568
  this.log.error(`No converter available for '${model}' with key '${stateDesc.id}' `);
577
569
  this.sendError(`No converter available for '${model}' with key '${stateDesc.id}' `);
@@ -582,7 +574,7 @@ class Zigbee extends utils.Adapter {
582
574
  const preparedOptions = (stateDesc.setterOpt) ? stateDesc.setterOpt(value, options) : {};
583
575
  let syncStateList = [];
584
576
  if (stateModel && stateModel.syncStates) {
585
- stateModel.syncStates.forEach(syncFunct => {
577
+ stateModel.syncStates.forEach((syncFunct) => {
586
578
  const res = syncFunct(stateDesc, value, options);
587
579
  if (res) {
588
580
  syncStateList = syncStateList.concat(res);
@@ -601,14 +593,12 @@ class Zigbee extends utils.Adapter {
601
593
  target = await this.zbController.resolveEntity(deviceId, epName);
602
594
  target = target.endpoint;
603
595
  }
604
-
605
596
  this.log.debug(`target: ${safeJsonStringify(target)}`);
606
-
607
597
  const meta = {
608
598
  endpoint_name: epName,
609
599
  options: preparedOptions,
610
600
  device: entity.device,
611
- mapped: model === 'group' ? [] : mappedModel,
601
+ mapped: (model == 'group') ? [] : mappedModel,
612
602
  message: {[key]: preparedValue},
613
603
  logger: this.log,
614
604
  state: {},
@@ -620,24 +610,23 @@ class Zigbee extends utils.Adapter {
620
610
  const result = await converter.convertSet(target, key, preparedValue, meta);
621
611
  this.log.debug(`convert result ${safeJsonStringify(result)}`);
622
612
  if (result !== undefined) {
623
- if (stateModel && !isGroup) {
613
+ if (stateModel && !isGroup)
624
614
  this.acknowledgeState(deviceId, model, stateDesc, value);
625
- }
626
615
  // process sync state list
627
616
  this.processSyncStatesList(deviceId, model, syncStateList);
628
-
629
617
  if (isGroup) {
630
618
  await this.callPluginMethod('queryGroupMemberState', [deviceId, stateDesc]);
631
619
  this.acknowledgeState(deviceId, model, stateDesc, value);
632
620
  }
633
621
  }
634
- } catch (error) {
635
- this.filterError(`Error ${error.code} on send command to ${deviceId}.` +
636
- ` Error: ${error.stack}`, `Send command to ${deviceId} failed with`, error);
622
+ } catch(error) {
623
+ this.filterError(`Error ${error.code} on send command to ${deviceId}.`+
624
+ ` Error: ${error.stack}`, `Send command to ${deviceId} failed with`, error);
637
625
  }
638
626
  });
639
627
  }
640
-
628
+ //
629
+ //
641
630
  // This function is introduced to explicitly allow user level scripts to send Commands
642
631
  // directly to the zigbee device. It utilizes the zigbee-herdsman-converters to generate
643
632
  // the exact zigbee message to be sent and can be used to set device options which are
@@ -650,79 +639,74 @@ class Zigbee extends utils.Adapter {
650
639
  // payload: The data to send to the device as JSON object (key/Value pairs)
651
640
  // endpoint: optional: the endpoint to send the data to, if supported.
652
641
  //
653
- async sendPayload(payload) {
642
+ async SendPayload(payload) {
654
643
  this.log.debug(`publishToDevice called with ${safeJsonStringify(payload)}`);
655
- let payloadObj = {};
644
+ let payload_obj = {};
656
645
  if (typeof payload === 'string') {
657
646
  try {
658
- payloadObj = JSON.parse(payload);
647
+ payload_obj = JSON.parse();
659
648
  } catch (e) {
660
649
  this.log.error(`Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`);
661
650
  this.sendError(e, `Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`);
662
- return {
663
- success: false,
664
- error: `Unable to parse ${safeJsonStringify(payload)}: ${safeJsonStringify(e)}`
665
- };
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) {
716
- this.filterError(`Error ${error.code} on send command to ${payload.device}.` +
717
- ` Error: ${error.stack}`, `Send command to ${payload.device} failed with`, error);
718
- return {success: false, error};
719
696
  }
720
- } catch (e) {
721
- return {success: false, error: e};
697
+ catch (error)
698
+ {
699
+ this.filterError(`Error ${error.code} on send command to ${payload.device}.`+
700
+ ` Error: ${error.stack}`, `Send command to ${payload.device} failed with`, error);
701
+ return {success:false, error: error};
702
+ }
703
+ }
704
+ catch (e) {
705
+ return {success:false, error: e};
722
706
  }
723
- }
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
  */
@@ -857,7 +841,7 @@ class Zigbee extends utils.Adapter {
857
841
  }
858
842
  if (data === 0) {
859
843
  // set pairing mode off
860
- this.setState('info.pairingMode', false, true);
844
+ this.setState('info.pairingMode', false,true);
861
845
  _pairingMode = false;
862
846
  }
863
847
  if (data) {
@@ -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);