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/exposes.js CHANGED
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
4
- const statesDefs = require(__dirname + '/states.js').states;
5
- const rgb = require(__dirname + '/rgb.js');
6
- const utils = require(__dirname + '/utils.js');
7
- const colors = require(__dirname + '/colors.js');
4
+ const statesDefs = require('./states.js').states;
5
+ const rgb = require('./rgb.js');
6
+ const utils = require('./utils.js');
7
+ const colors = require('./colors.js');
8
8
  const ea = zigbeeHerdsmanConverters.exposes.access;
9
9
 
10
10
  function genState(expose, role, name, desc) {
@@ -32,7 +32,7 @@ function genState(expose, role, name, desc) {
32
32
  state.getter = payload => (payload[propName] === (expose.value_on || 'ON'));
33
33
  }
34
34
  else {
35
- state.getter = payload => ( undefined);
35
+ state.getter = payload => undefined;
36
36
  }
37
37
  if (writable) {
38
38
  state.setter = (value) => (value) ? (expose.value_on || 'ON') : ((expose.value_off != undefined) ? expose.value_off : 'OFF');
@@ -72,7 +72,7 @@ function genState(expose, role, name, desc) {
72
72
  write: writable,
73
73
  read: true,
74
74
  type: 'string',
75
- states: expose.values.map((item) => `${item}:${item}`).join(';'),
75
+ states: expose.values.map(item => `${item}:${item}`).join(';'),
76
76
  };
77
77
  if (expose.endpoint) {
78
78
  state.epname = expose.endpoint;
@@ -103,8 +103,6 @@ function genState(expose, role, name, desc) {
103
103
  return state;
104
104
  }
105
105
 
106
-
107
-
108
106
  function createFromExposes(model, def) {
109
107
  const states = [];
110
108
  // make the different (set and get) part of state is updatable if different exposes is used for get and set
@@ -121,22 +119,24 @@ function createFromExposes(model, def) {
121
119
  if (state === undefined) {
122
120
  return 0;
123
121
  }
124
- if (access === undefined) access = ea.ALL;
122
+ if (access === undefined) {
123
+ access = ea.ALL;
124
+ }
125
125
  state.readable = (access & ea.STATE) > 0;
126
126
  state.writable = (access & ea.SET) > 0;
127
- const stateExists = states.findIndex( (element, index, array) => (element.id === state.id ));
128
- if (stateExists < 0 ) {
127
+ const stateExists = states.findIndex( (element, index, array) => element.id === state.id);
128
+ if (stateExists < 0) {
129
129
  state.write = state.writable;
130
- if (! state.writable) {
131
- if ( state.hasOwnProperty('setter') ) {
130
+ if (!state.writable) {
131
+ if (state.hasOwnProperty('setter')) {
132
132
  delete state.setter;
133
133
  }
134
- if ( state.hasOwnProperty('setattr') ) {
134
+ if (state.hasOwnProperty('setattr')) {
135
135
  delete state.setattr;
136
136
  }
137
137
  }
138
- if (! state.readable) {
139
- if (state.hasOwnProperty('getter') ) {
138
+ if (!state.readable) {
139
+ if (state.hasOwnProperty('getter')) {
140
140
  //to awid some worning on unprocessed data
141
141
  state.getter = payload => ( undefined );
142
142
  }
@@ -144,7 +144,7 @@ function createFromExposes(model, def) {
144
144
  return states.push(state);
145
145
  }
146
146
  else {
147
- if ( (state.readable) && (! states[stateExists].readable ) ) {
147
+ if ((state.readable) && (!states[stateExists].readable)) {
148
148
  states[stateExists].read = state.read;
149
149
  // as state is readable, it can't be button or event
150
150
  if (states[stateExists].role === 'button') {
@@ -160,58 +160,58 @@ function createFromExposes(model, def) {
160
160
  // trying to remove the `prop` property, as main key for get and set,
161
161
  // as it can be different in new and old states, and leave only:
162
162
  // setattr for old and id for new
163
- if (( state.hasOwnProperty('prop') ) && (state.prop === state.id)) {
163
+ if ((state.hasOwnProperty('prop')) && (state.prop === state.id)) {
164
164
  if ( states[stateExists].hasOwnProperty('prop') ) {
165
165
  if (states[stateExists].prop !== states[stateExists].id) {
166
- if (! states[stateExists].hasOwnProperty('setattr')) {
166
+ if (!states[stateExists].hasOwnProperty('setattr')) {
167
167
  states[stateExists].setattr = states[stateExists].prop;
168
168
  }
169
169
  }
170
170
  delete states[stateExists].prop;
171
171
  }
172
- }
173
- else if ( state.hasOwnProperty('prop') ) {
172
+ } else if ( state.hasOwnProperty('prop') ) {
174
173
  states[stateExists].prop = state.prop;
175
174
  }
176
175
  states[stateExists].readable = true;
177
176
  }
178
- if ( (state.writable) && (! states[stateExists].writable ) ) {
177
+ if ((state.writable) && (!states[stateExists].writable)) {
179
178
  states[stateExists].write = state.writable;
180
179
  // use new state `setter`
181
- if ( state.hasOwnProperty('setter') ) {
180
+ if (state.hasOwnProperty('setter')) {
182
181
  states[stateExists].setter = state.setter;
183
182
  }
184
183
  // use new state `setterOpt`
185
- if ( state.hasOwnProperty('setterOpt') ) {
184
+ if (state.hasOwnProperty('setterOpt')) {
186
185
  states[stateExists].setterOpt = state.setterOpt;
187
186
  }
188
187
  // use new state `inOptions`
189
- if ( state.hasOwnProperty('inOptions') ) {
188
+ if (state.hasOwnProperty('inOptions')) {
190
189
  states[stateExists].inOptions = state.inOptions;
191
190
  }
192
191
  // as we have new state, responsible for set, we have to use new `isOption`
193
192
  // or remove it
194
- if (((! state.hasOwnProperty('isOption') ) || (state.isOptions === false))
193
+ if (((!state.hasOwnProperty('isOption')) || (state.isOptions === false))
195
194
  && (states[stateExists].hasOwnProperty('isOption'))) {
196
195
  delete states[stateExists].isOption;
197
- }
198
- else {
196
+ } else {
199
197
  states[stateExists].isOption = state.isOption;
200
198
  }
199
+
201
200
  // use new `setattr` or `prop` as `setattr`
202
- if ( state.hasOwnProperty('setattr') ) {
201
+ if (state.hasOwnProperty('setattr')) {
203
202
  states[stateExists].setattr = state.setattr;
204
- }
205
- else if ( state.hasOwnProperty('prop') ) {
203
+ } else if (state.hasOwnProperty('prop')) {
206
204
  states[stateExists].setattr = state.prop;
207
205
  }
206
+
208
207
  // remove `prop` equal to if, due to prop is uses as key in set and get
209
- if ( states[stateExists].prop === states[stateExists].id) {
208
+ if (states[stateExists].prop === states[stateExists].id) {
210
209
  delete states[stateExists].prop;
211
210
  }
212
- if ( state.hasOwnProperty('epname') ) {
211
+ if (state.hasOwnProperty('epname')) {
213
212
  states[stateExists].epname = state.epname;
214
213
  }
214
+
215
215
  states[stateExists].writable = true;
216
216
  }
217
217
  return states.length;
@@ -242,6 +242,7 @@ function createFromExposes(model, def) {
242
242
  }, prop.access);
243
243
  break;
244
244
  }
245
+
245
246
  case 'brightness': {
246
247
  const stateNameB = expose.endpoint ? `brightness_${expose.endpoint}` : 'brightness';
247
248
  pushToStates({
@@ -255,12 +256,8 @@ function createFromExposes(model, def) {
255
256
  min: 0, // ignore expose.value_min
256
257
  max: 100, // ignore expose.value_max
257
258
  inOptions: true,
258
- getter: payload => {
259
- return utils.bulbLevelToAdapterLevel(payload[stateNameB]);
260
- },
261
- setter: (value) => {
262
- return utils.adapterLevelToBulbLevel(value);
263
- },
259
+ getter: payload => utils.bulbLevelToAdapterLevel(payload[stateNameB]),
260
+ setter: value => utils.adapterLevelToBulbLevel(value),
264
261
  setterOpt: (value, options) => {
265
262
  const hasTransitionTime = options && options.hasOwnProperty('transition_time');
266
263
  const transitionTime = hasTransitionTime ? options.transition_time : 0;
@@ -268,7 +265,7 @@ function createFromExposes(model, def) {
268
265
  preparedOptions.brightness = utils.adapterLevelToBulbLevel(value);
269
266
  return preparedOptions;
270
267
  },
271
- readResponse: (resp) => {
268
+ readResponse: resp => {
272
269
  const respObj = resp[0];
273
270
  if (respObj.status === 0 && respObj.attrData != undefined) {
274
271
  return utils.bulbLevelToAdapterLevel(respObj.attrData);
@@ -282,30 +279,30 @@ function createFromExposes(model, def) {
282
279
  }
283
280
  case 'color_temp': {
284
281
  const stateNameT = expose.endpoint ? `colortemp_${expose.endpoint}` : 'colortemp';
285
- pushToStates({
286
- id: stateNameT,
287
- prop: expose.endpoint ? `color_temp_${expose.endpoint}` : 'color_temp',
288
- name: `Color temperature ${expose.endpoint ? expose.endpoint : ''}`.trim(),
289
- icon: undefined,
290
- role: 'level.color.temperature',
291
- write: true,
292
- read: true,
293
- type: 'number',
294
- // Ignore min and max value, so setting mireds and Kelvin with conversion to mireds works.
295
- // https://github.com/ioBroker/ioBroker.zigbee/pull/1433#issuecomment-1113837035
296
- min: undefined,
297
- max: undefined,
298
- setter: (value) => {
299
- return utils.toMired(value);
300
- },
301
- setterOpt: (value, options) => {
302
- const hasTransitionTime = options && options.hasOwnProperty('transition_time');
303
- const transitionTime = hasTransitionTime ? options.transition_time : 0;
304
- return {...options, transition: transitionTime};
282
+ pushToStates(
283
+ {
284
+ id: stateNameT,
285
+ prop: expose.endpoint ? `color_temp_${expose.endpoint}` : 'color_temp',
286
+ name: `Color temperature ${expose.endpoint ? expose.endpoint : ''}`.trim(),
287
+ icon: undefined,
288
+ role: 'level.color.temperature',
289
+ write: true,
290
+ read: true,
291
+ type: 'number',
292
+ // Ignore min and max value, so setting mireds and Kelvin with conversion to mireds works.
293
+ // https://github.com/ioBroker/ioBroker.zigbee/pull/1433#issuecomment-1113837035
294
+ min: undefined,
295
+ max: undefined,
296
+ setter: value => utils.toMired(value),
297
+ setterOpt: (value, options) => {
298
+ const hasTransitionTime = options && options.hasOwnProperty('transition_time');
299
+ const transitionTime = hasTransitionTime ? options.transition_time : 0;
300
+ return {...options, transition: transitionTime};
301
+ },
302
+ epname: expose.endpoint,
303
+ setattr: 'color_temp',
305
304
  },
306
- epname: expose.endpoint,
307
- setattr: 'color_temp',
308
- }, prop.access);
305
+ prop.access);
309
306
  pushToStates(statesDefs.colortemp_move, prop.access);
310
307
  break;
311
308
  }
@@ -320,7 +317,7 @@ function createFromExposes(model, def) {
320
317
  write: true,
321
318
  read: true,
322
319
  type: 'string',
323
- setter: (value) => {
320
+ setter: value => {
324
321
  // convert RGB to XY for set
325
322
  /*
326
323
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(value);
@@ -342,9 +339,8 @@ function createFromExposes(model, def) {
342
339
  xy = rgb.rgb_to_cie(rgbcolor.r, rgbcolor.g, rgbcolor.b);
343
340
  return {
344
341
  x: xy[0],
345
- y: xy[1]
342
+ y: xy[1],
346
343
  };
347
-
348
344
  },
349
345
  setterOpt: (value, options) => {
350
346
  const hasTransitionTime = options && options.hasOwnProperty('transition_time');
@@ -354,7 +350,7 @@ function createFromExposes(model, def) {
354
350
  getter: payload => {
355
351
  if (payload.color && payload.color.hasOwnProperty('x') && payload.color.hasOwnProperty('y')) {
356
352
  const colorval = rgb.cie_to_rgb(payload.color.x, payload.color.y);
357
- return '#' + utils.decimalToHex(colorval[0]) + utils.decimalToHex(colorval[1]) + utils.decimalToHex(colorval[2]);
353
+ return `#${utils.decimalToHex(colorval[0])}${utils.decimalToHex(colorval[1])}${utils.decimalToHex(colorval[2])}`;
358
354
  } else {
359
355
  return undefined;
360
356
  }
@@ -375,14 +371,13 @@ function createFromExposes(model, def) {
375
371
  write: true,
376
372
  read: true,
377
373
  type: 'string',
378
- setter: (value) => {
374
+ setter: value => {
379
375
  const _rgb = colors.ParseColor(value);
380
376
  const hsv = rgb.rgbToHSV(_rgb.r, _rgb.g, _rgb.b, true);
381
377
  return {
382
378
  hue: Math.min(Math.max(hsv.h,1),359),
383
379
  saturation: hsv.s,
384
380
  // brightness: Math.floor(hsv.v * 2.55),
385
-
386
381
  };
387
382
  },
388
383
  setterOpt: (value, options) => {
@@ -396,7 +391,7 @@ function createFromExposes(model, def) {
396
391
  pushToStates({
397
392
  id: expose.endpoint ? `hue_${expose.endpoint}` : 'hue',
398
393
  prop: expose.endpoint ? `color_${expose.endpoint}` : 'color',
399
- name: `Hue ${expose.endpoint ? expose.endpoint : ''}`.trim(),
394
+ name: `Hue ${expose.endpoint || ''}`.trim(),
400
395
  icon: undefined,
401
396
  role: 'level.color.hue',
402
397
  write: true,
@@ -423,11 +418,12 @@ function createFromExposes(model, def) {
423
418
  const hue_correction_table = [];
424
419
  options.hue_calibration.split(',').forEach(element => {
425
420
  const match = /([0-9]+):([0-9]+)/.exec(element);
426
- if (match && match.length ==3)
427
- hue_correction_table.push({ in: Number(match[1]), out: Number(match[2])});
421
+ if (match && match.length === 3)
422
+ hue_correction_table.push({in: Number(match[1]), out: Number(match[2])});
428
423
  });
429
- if (hue_correction_table.length > 0)
424
+ if (hue_correction_table.length > 0) {
430
425
  return {...options, transition: transitionTime, hue_correction: hue_correction_table};
426
+ }
431
427
  }
432
428
  return {...options, transition: transitionTime};
433
429
  },
@@ -445,12 +441,10 @@ function createFromExposes(model, def) {
445
441
  min: 0,
446
442
  max: 100,
447
443
  inOptions: true,
448
- setter: (value, options) => {
449
- return {
450
- hue: options.hue,
451
- saturation: value,
452
- };
453
- },
444
+ setter: (value, options) => ({
445
+ hue: options.hue,
446
+ saturation: value,
447
+ }),
454
448
  setterOpt: (value, options) => {
455
449
  const hasTransitionTime = options && options.hasOwnProperty('transition_time');
456
450
  const transitionTime = hasTransitionTime ? options.transition_time : 0;
@@ -463,11 +457,12 @@ function createFromExposes(model, def) {
463
457
  const hue_correction_table = [];
464
458
  options.hue_calibration.split(',').forEach(element => {
465
459
  const match = /([0-9]+):([0-9]+)/.exec(element);
466
- if (match && match.length ==3)
460
+ if (match && match.length === 3)
467
461
  hue_correction_table.push({ in: Number(match[1]), out: Number(match[2])});
468
462
  });
469
- if (hue_correction_table.length > 0)
463
+ if (hue_correction_table.length > 0) {
470
464
  return {...options, transition: transitionTime, hue_correction: hue_correction_table};
465
+ }
471
466
  }
472
467
  return {...options, transition: transitionTime};
473
468
  },
@@ -485,12 +480,10 @@ function createFromExposes(model, def) {
485
480
  read: false,
486
481
  type: 'string',
487
482
  inOptions: true,
488
- setter: (value, options) => {
489
- return {
490
- hue: options.hue,
491
- saturation: options.saturation,
492
- };
493
- },
483
+ setter: (value, options) => ({
484
+ hue: options.hue,
485
+ saturation: options.saturation,
486
+ }),
494
487
  setterOpt: (value, options) => {
495
488
  const hasTransitionTime = options && options.hasOwnProperty('transition_time');
496
489
  const transitionTime = hasTransitionTime ? options.transition_time : 0;
@@ -498,20 +491,20 @@ function createFromExposes(model, def) {
498
491
  if (hasHueCalibrationTable)
499
492
  try {
500
493
  return {...options, transition: transitionTime, hue_correction: JSON.parse(options.hue_calibration)};
501
- }
502
- catch {
494
+ } catch {
503
495
  const hue_correction_table = [];
504
496
  options.hue_calibration.split(',').forEach(element => {
505
497
  const match = /([0-9]+):([0-9]+)/.exec(element);
506
- if (match && match.length ==3)
498
+ if (match && match.length === 3) {
507
499
  hue_correction_table.push({ in: Number(match[1]), out: Number(match[2])});
500
+ }
508
501
  });
509
- if (hue_correction_table.length > 0)
502
+ if (hue_correction_table.length > 0) {
510
503
  return {...options, transition: transitionTime, hue_correction: hue_correction_table};
504
+ }
511
505
  }
512
506
  return {...options, transition: transitionTime};
513
507
  },
514
-
515
508
  }, prop.access);
516
509
  break;
517
510
  }
@@ -582,19 +575,20 @@ function createFromExposes(model, def) {
582
575
  break;
583
576
  }
584
577
  }
585
- if (state) pushToStates(state, expose.access);
578
+ if (state) {
579
+ pushToStates(state, expose.access);
580
+ }
586
581
  break;
587
582
 
588
583
  case 'enum':
589
584
  switch (expose.name) {
590
585
  case 'action': {
591
-
592
586
  // Ansatz:
593
587
 
594
- // Action aufspalten in 2 Blöcke:
595
- // Action (bekommt text ausser hold und release, auto reset nach 250 ms)
596
- // Hold: wird gesetzt bei hold, gelöscht bei passendem Release
597
-
588
+ // Action aufspalten in 2 Blöcke:
589
+ // Action (bekommt text ausser hold und release, auto reset nach 250 ms)
590
+ // Hold: wird gesetzt bei hold, gelöscht bei passendem Release
591
+
598
592
  if (!Array.isArray(expose.values)) break;
599
593
  const hasHold = expose.values.find((actionName) => actionName.includes('hold'));
600
594
  const hasRelease = expose.values.find((actionName) => actionName.includes('release'));
@@ -613,7 +607,7 @@ function createFromExposes(model, def) {
613
607
  write: false,
614
608
  read: true,
615
609
  type: 'boolean',
616
- getter: payload => (payload.action === actionName) ? true : (payload.action === releaseActionName) ? false : undefined,
610
+ getter: payload => payload.action === actionName ? true : (payload.action === releaseActionName ? false : undefined),
617
611
  };
618
612
  } else {
619
613
  state = {
@@ -625,7 +619,7 @@ function createFromExposes(model, def) {
625
619
  write: false,
626
620
  read: true,
627
621
  type: 'boolean',
628
- getter: payload => (payload.action === actionName) ? true : undefined,
622
+ getter: payload => payload.action === actionName ? true : undefined,
629
623
  isEvent: true,
630
624
  };
631
625
  }
@@ -676,7 +670,9 @@ function createFromExposes(model, def) {
676
670
  break;
677
671
  }
678
672
  }
679
- if (state) pushToStates(state, expose.access);
673
+ if (state) {
674
+ pushToStates(state, expose.access);
675
+ }
680
676
  break;
681
677
 
682
678
  case 'text':
@@ -739,7 +735,7 @@ function createFromExposes(model, def) {
739
735
  return result;
740
736
  };
741
737
  st.setattr = expose.property;
742
- };
738
+ }
743
739
  // if we have a composite expose, the payload will be an object {expose.property : {prop.property: value}}
744
740
  if (prop.access & ea.STATE) {
745
741
  st.getter = payload => {
@@ -750,11 +746,10 @@ function createFromExposes(model, def) {
750
746
  return undefined;
751
747
  }
752
748
  };
749
+ } else {
750
+ st.getter = payload => undefined;
753
751
  }
754
- else {
755
- st.getter = payload => { return undefined };
756
- }
757
- ;
752
+
758
753
  pushToStates(st, prop.access);
759
754
  }
760
755
  break;
@@ -764,8 +759,8 @@ function createFromExposes(model, def) {
764
759
  }
765
760
  const newDev = {
766
761
  models: [model],
767
- icon: icon,
768
- states: states,
762
+ icon,
763
+ states,
769
764
  exposed: true,
770
765
  };
771
766
  // make the function code printable in log
@@ -775,11 +770,11 @@ function createFromExposes(model, def) {
775
770
  }
776
771
 
777
772
  function applyExposes(mappedDevices, byModel, allExcludesObj) {
778
- // for exlude search
773
+ // for exclude search
779
774
  const allExcludesStr = JSON.stringify(allExcludesObj);
780
775
  // create or update device from exposes
781
776
  for (const deviceDef of zigbeeHerdsmanConverters.definitions) {
782
- const strippedModel = (deviceDef.model) ? deviceDef.model.replace(/\0.*$/g, '').trim() : '';
777
+ const strippedModel = (deviceDef.model) ? deviceDef.model.replace(/0.*$/g, '').trim() : '';
783
778
  // check if device is mapped
784
779
  const existsMap = byModel.get(strippedModel);
785
780
 
@@ -794,7 +789,7 @@ function applyExposes(mappedDevices, byModel, allExcludesObj) {
794
789
  existsMap.exposed = true;
795
790
  }
796
791
  } catch (e) {
797
- console.log(`Wrong expose devicedefinition ${deviceDef.vendor} ${deviceDef.model}` );
792
+ console.log(`Wrong expose devicedefinition ${deviceDef.vendor} ${deviceDef.model}`);
798
793
  }
799
794
  }
800
795
  }