iobroker.zigbee 2.0.0 → 2.0.2

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.
package/lib/exposes.js CHANGED
@@ -1,11 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
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
- const ea = require('zigbee-herdsman-converters/lib/exposes.js').access;
4
+ const statesDefs = require('./states').states;
5
+ const rgb = require('./rgb');
6
+ const utils = require('./utils');
7
+ const colors = require('./colors');
8
+ const ea = require('zigbee-herdsman-converters/lib/exposes').access;
9
+
10
+
11
+ const __logger = undefined;
9
12
 
10
13
  function genState(expose, role, name, desc) {
11
14
  let state;
@@ -16,6 +19,7 @@ function genState(expose, role, name, desc) {
16
19
  const stateId = stname.replace(/\*/g, '');
17
20
  const stateName = (desc || expose.description || expose.name);
18
21
  const propName = expose.property;
22
+ // 'switch' | 'lock' | 'binary' | 'list' | 'numeric' | 'enum' | 'text' | 'composite' | 'light' | 'cover' | 'fan' | 'climate';
19
23
  switch (expose.type) {
20
24
  case 'binary':
21
25
  state = {
@@ -133,7 +137,7 @@ function genState(expose, role, name, desc) {
133
137
  return state;
134
138
  }
135
139
 
136
- function createFromExposes(model, def) {
140
+ function createFromExposes(model, def, device, log) {
137
141
  const states = [];
138
142
  // make the different (set and get) part of state is updatable if different exposes is used for get and set
139
143
  // as example:
@@ -252,15 +256,12 @@ function createFromExposes(model, def) {
252
256
  if (typeof def.exposes == 'object') {
253
257
  for (const expose of def.exposes) {
254
258
  genStateFromExpose(expose);
255
-
256
-
257
259
  }
258
260
  }
259
261
 
260
262
  // maybee here check manufacturerName for tuya devices
261
263
  if (typeof def.exposes == 'function') {
262
- const expFunction = def.exposes(def, {}); // maybee here check manufacturerName for tuya devices
263
-
264
+ const expFunction = def.exposes(device, {}); // maybee here check manufacturerName for tuya devices
264
265
  for (const expose of expFunction) {
265
266
  genStateFromExpose(expose);
266
267
  }
@@ -275,12 +276,24 @@ function createFromExposes(model, def) {
275
276
 
276
277
  return newDev;
277
278
 
278
-
279
+ function hasMultipleProperties(obj, prop, len) {
280
+ const l = (len ? len: Object.keys.length(obj));
281
+ if (l != prop.length) return false;
282
+ for (const key of prop) {
283
+ if (!obj.hasOwnProperty(key)) return false;
284
+ }
285
+ return true;
286
+ };
279
287
 
280
288
  function genStateFromExpose(expose) {
281
289
  let state;
282
290
  switch (expose.type) {
283
- case 'light':
291
+ case 'light': {
292
+ let hasColorXY = false;
293
+ let hasColorHS = false;
294
+ let colorXYprop = undefined;
295
+ let colorHSprop = undefined;
296
+
284
297
  for (const prop of expose.features) {
285
298
  switch (prop.name) {
286
299
  case 'state': {
@@ -364,237 +377,14 @@ function createFromExposes(model, def) {
364
377
  pushToStates(statesDefs.colortemp_move, prop.access);
365
378
  break;
366
379
  }
367
- case 'color_xy': {
368
- const stateNameC = expose.endpoint ? `color_${expose.endpoint}` : 'color';
369
- pushToStates({
370
- id: stateNameC,
371
- prop: expose.endpoint ? `color_${expose.endpoint}` : 'color',
372
- name: `Color ${expose.endpoint ? expose.endpoint : ''}`.trim(),
373
- icon: undefined,
374
- role: 'level.color.rgb',
375
- write: true,
376
- read: true,
377
- type: 'string',
378
- setter: value => {
379
- // convert RGB to XY for set
380
- /*
381
- const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(value);
382
- let xy = [0, 0];
383
- if (result) {
384
- const r = parseInt(result[1], 16),
385
- g = parseInt(result[2], 16),
386
- b = parseInt(result[3], 16);
387
- xy = rgb.rgb_to_cie(r, g, b);
388
- }
389
- return {
390
- x: xy[0],
391
- y: xy[1]
392
- };
393
- */
394
- let xy = [0, 0];
395
- const rgbcolor = colors.ParseColor(value);
396
-
397
- xy = rgb.rgb_to_cie(rgbcolor.r, rgbcolor.g, rgbcolor.b);
398
- return {
399
- x: xy[0],
400
- y: xy[1],
401
- };
402
- },
403
- setterOpt: (value, options) => {
404
- const hasTransitionTime = options && options.hasOwnProperty('transition_time');
405
- const transitionTime = hasTransitionTime ? options.transition_time : 0;
406
- return {...options, transition: transitionTime};
407
- },
408
- getter: payload => {
409
- if (payload.color && payload.color.hasOwnProperty('x') && payload.color.hasOwnProperty('y')) {
410
- const colorval = rgb.cie_to_rgb(payload.color.x, payload.color.y);
411
- return `#${utils.decimalToHex(colorval[0])}${utils.decimalToHex(colorval[1])}${utils.decimalToHex(colorval[2])}`;
412
- } else {
413
- return undefined;
414
- }
415
- },
416
- epname: expose.endpoint,
417
- setattr: 'color',
418
- }, prop.access);
419
- break;
420
- }
380
+ case 'color_xy':
381
+ colorXYprop = prop;
382
+ hasColorXY = true; break;
421
383
  case 'color_hs': {
422
- const stateNameH = expose.endpoint ? `color_${expose.endpoint}` : 'color';
423
- pushToStates({
424
- id: stateNameH,
425
- prop: expose.endpoint ? `color_${expose.endpoint}` : 'color',
426
- name: `Color ${expose.endpoint ? expose.endpoint : ''}`.trim(),
427
- icon: undefined,
428
- role: 'level.color.rgb',
429
- write: true,
430
- read: true,
431
- type: 'string',
432
- setter: value => {
433
- const _rgb = colors.ParseColor(value);
434
- const hsv = rgb.rgbToHSV(_rgb.r, _rgb.g, _rgb.b, true);
435
- return {
436
- hue: Math.min(Math.max(hsv.h, 1), 359),
437
- saturation: hsv.s,
438
- // brightness: Math.floor(hsv.v * 2.55),
439
- };
440
- },
441
- setterOpt: (value, options) => {
442
- const hasTransitionTime = options && options.hasOwnProperty('transition_time');
443
- const transitionTime = hasTransitionTime ? options.transition_time : 0;
444
- return {...options, transition: transitionTime};
445
- },
446
- epname: expose.endpoint,
447
- setattr: 'color',
448
- }, prop.access);
449
- pushToStates({
450
- id: expose.endpoint ? `hue_${expose.endpoint}` : 'hue',
451
- prop: expose.endpoint ? `color_${expose.endpoint}` : 'color',
452
- name: `Hue ${expose.endpoint || ''}`.trim(),
453
- icon: undefined,
454
- role: 'level.color.hue',
455
- write: true,
456
- read: false,
457
- type: 'number',
458
- min: 0,
459
- max: 360,
460
- inOptions: true,
461
- setter: (value, options) => {
462
- return {
463
- hue: value,
464
- saturation: options.saturation,
465
- };
466
- },
467
- setterOpt: (value, options) => {
468
- const hasTransitionTime = options && options.hasOwnProperty('transition_time');
469
- const transitionTime = hasTransitionTime ? options.transition_time : 0;
470
- const hasHueCalibrationTable = options && options.hasOwnProperty('hue_calibration');
471
- if (hasHueCalibrationTable)
472
- try {
473
- return {
474
- ...options,
475
- transition: transitionTime,
476
- hue_correction: JSON.parse(options.hue_calibration)
477
- };
478
- } catch {
479
- const hue_correction_table = [];
480
- options.hue_calibration.split(',').forEach(element => {
481
- const match = /([0-9]+):([0-9]+)/.exec(element);
482
- if (match && match.length === 3)
483
- hue_correction_table.push({
484
- in: Number(match[1]),
485
- out: Number(match[2])
486
- });
487
- });
488
- if (hue_correction_table.length > 0) {
489
- return {
490
- ...options,
491
- transition: transitionTime,
492
- hue_correction: hue_correction_table
493
- };
494
- }
495
- }
496
- return {...options, transition: transitionTime};
497
- },
498
-
499
- }, prop.access);
500
- pushToStates({
501
- id: expose.endpoint ? `saturation_${expose.endpoint}` : 'saturation',
502
- prop: expose.endpoint ? `color_${expose.endpoint}` : 'color',
503
- name: `Saturation ${expose.endpoint ? expose.endpoint : ''}`.trim(),
504
- icon: undefined,
505
- role: 'level.color.saturation',
506
- write: true,
507
- read: false,
508
- type: 'number',
509
- min: 0,
510
- max: 100,
511
- inOptions: true,
512
- setter: (value, options) => ({
513
- hue: options.hue,
514
- saturation: value,
515
- }),
516
- setterOpt: (value, options) => {
517
- const hasTransitionTime = options && options.hasOwnProperty('transition_time');
518
- const transitionTime = hasTransitionTime ? options.transition_time : 0;
519
- const hasHueCalibrationTable = options && options.hasOwnProperty('hue_calibration');
520
- if (hasHueCalibrationTable)
521
- try {
522
- return {
523
- ...options,
524
- transition: transitionTime,
525
- hue_correction: JSON.parse(options.hue_calibration)
526
- };
527
- } catch {
528
- const hue_correction_table = [];
529
- options.hue_calibration.split(',').forEach(element => {
530
- const match = /([0-9]+):([0-9]+)/.exec(element);
531
- if (match && match.length === 3)
532
- hue_correction_table.push({
533
- in: Number(match[1]),
534
- out: Number(match[2])
535
- });
536
- });
537
- if (hue_correction_table.length > 0) {
538
- return {
539
- ...options,
540
- transition: transitionTime,
541
- hue_correction: hue_correction_table
542
- };
543
- }
544
- }
545
- return {...options, transition: transitionTime};
546
- },
547
-
548
- }, prop.access);
384
+ colorHSprop = prop;
385
+ hasColorHS = true;
549
386
  pushToStates(statesDefs.hue_move, prop.access);
550
387
  pushToStates(statesDefs.saturation_move, prop.access);
551
- pushToStates({
552
- id: 'hue_calibration',
553
- prop: 'color',
554
- name: 'Hue color calibration table',
555
- icon: undefined,
556
- role: 'table',
557
- write: true,
558
- read: false,
559
- type: 'string',
560
- inOptions: true,
561
- setter: (value, options) => ({
562
- hue: options.hue,
563
- saturation: options.saturation,
564
- }),
565
- setterOpt: (value, options) => {
566
- const hasTransitionTime = options && options.hasOwnProperty('transition_time');
567
- const transitionTime = hasTransitionTime ? options.transition_time : 0;
568
- const hasHueCalibrationTable = options && options.hasOwnProperty('hue_calibration');
569
- if (hasHueCalibrationTable)
570
- try {
571
- return {
572
- ...options,
573
- transition: transitionTime,
574
- hue_correction: JSON.parse(options.hue_calibration)
575
- };
576
- } catch {
577
- const hue_correction_table = [];
578
- options.hue_calibration.split(',').forEach(element => {
579
- const match = /([0-9]+):([0-9]+)/.exec(element);
580
- if (match && match.length === 3) {
581
- hue_correction_table.push({
582
- in: Number(match[1]),
583
- out: Number(match[2])
584
- });
585
- }
586
- });
587
- if (hue_correction_table.length > 0) {
588
- return {
589
- ...options,
590
- transition: transitionTime,
591
- hue_correction: hue_correction_table
592
- };
593
- }
594
- }
595
- return {...options, transition: transitionTime};
596
- },
597
- }, prop.access);
598
388
  break;
599
389
  }
600
390
  default:
@@ -602,9 +392,181 @@ function createFromExposes(model, def) {
602
392
  break;
603
393
  }
604
394
  }
395
+ if (hasColorXY || hasColorHS) {
396
+ const nameWithEp = expose.endpoint ? `color_${expose.endpoint}` : 'color';
397
+ pushToStates({
398
+ id: nameWithEp,
399
+ name: `Color ${expose.endpoint ? expose.endpoint : ''}`.trim(),
400
+ icon: undefined,
401
+ role: 'level.color.rgb',
402
+ write: true,
403
+ read: true,
404
+ type: 'string',
405
+ setter: value => {
406
+ try {
407
+ // JSON
408
+ const colorJSON = JSON.parse(value.replaceAll("'",'"'));
409
+ const numProp = Object.keys(colorJSON).length;
410
+ if (hasMultipleProperties(colorJSON, ['hsb'], numProp)) return colorJSON;
411
+ if (hasMultipleProperties(colorJSON, ['hsl'], numProp)) return colorJSON;
412
+ if (hasMultipleProperties(colorJSON, ['hsv'], numProp)) return colorJSON;
413
+ if (hasMultipleProperties(colorJSON, ['h','s','b'], numProp)) return colorJSON;
414
+ if (hasMultipleProperties(colorJSON, ['h','s','v'], numProp)) return colorJSON;
415
+ if (hasMultipleProperties(colorJSON, ['h','s','l'], numProp)) return colorJSON;
416
+ if (hasMultipleProperties(colorJSON, ['hue', 'saturation'], numProp)) return colorJSON;
417
+ if (hasMultipleProperties(colorJSON, ['hex'], numProp)) return colorJSON;
418
+ if (hasMultipleProperties(colorJSON, ['rgb'], numProp)) return colorJSON;
419
+ if (hasMultipleProperties(colorJSON, ['x', 'y'], numProp)) return colorJSON;
420
+ if (hasMultipleProperties(colorJSON, ['r', 'g', 'b'], numProp)) return colorJSON;
421
+ //return { json:colorJSON, numProp:numProp, value:value };
422
+ }
423
+ catch (error) {
424
+ //return { error: error.message };
425
+ };
426
+ // hex or named color
427
+ const rgbcolor = colors.ParseColor(value);
428
+ return rgbcolor;
429
+ },
430
+ setterOpt: (value, options) => {
431
+ const hasTransitionTime = options && options.hasOwnProperty('transition_time');
432
+ const transitionTime = hasTransitionTime ? options.transition_time : 0;
433
+ return {...options, transition: transitionTime};
434
+ },
435
+ getter: payload => {
436
+ if (typeof payload.color == 'object') {
437
+ const colorJSON = payload.color;
438
+ const color = JSON.stringify(colorJSON)
439
+ const numProp = Object.keys(colorJSON);
440
+ if (hasMultipleProperties(colorJSON, ['hsb'], numProp)) return color;
441
+ if (hasMultipleProperties(colorJSON, ['hsl'], numProp)) return color;
442
+ if (hasMultipleProperties(colorJSON, ['hsv'], numProp)) return color;
443
+ if (hasMultipleProperties(colorJSON, ['h','s','b'], numProp)) return color;
444
+ if (hasMultipleProperties(colorJSON, ['h','s','v'], numProp)) return color;
445
+ if (hasMultipleProperties(colorJSON, ['h','s','l'], numProp)) return color;
446
+ if (hasMultipleProperties(colorJSON, ['hue', 'saturation'], numProp)) return color;
447
+ if (hasMultipleProperties(colorJSON, ['hex'], numProp)) return color;
448
+ if (hasMultipleProperties(colorJSON, ['rgb'], numProp)) return color;
449
+ if (hasMultipleProperties(colorJSON, ['x', 'y'], numProp)) return color;
450
+ if (hasMultipleProperties(colorJSON, ['r', 'g', 'b'], numProp)) return color;
451
+ }
452
+ return undefined;
453
+ },
454
+ epname: expose.endpoint,
455
+ setattr: 'color',
456
+ }, (colorHSprop ? colorHSprop.access : colorXYprop.access));
457
+ if (hasColorXY) {
458
+ let channelWithEp = expose.endpoint ? `color_xy_${expose.endpoint}` : 'color_xy';
459
+ pushToStates({
460
+ id: `${channelWithEp}.x`,
461
+ name: `X`,
462
+ icon: undefined,
463
+ role: 'level.color',
464
+ write: true,
465
+ read: true,
466
+ type: 'number',
467
+ min: 0,
468
+ max: 1,
469
+ compositeKey: channelWithEp,
470
+ compositeTimeout: 500,
471
+ compositeState: 'color'
472
+ }, colorXYprop.access);
473
+ pushToStates({
474
+ id: `${channelWithEp}.y`,
475
+ name: `Y`,
476
+ icon: undefined,
477
+ role: 'level.color',
478
+ write: true,
479
+ read: true,
480
+ type: 'number',
481
+ min: 0,
482
+ max: 1,
483
+ compositeKey: channelWithEp,
484
+ compositeTimeout: 500,
485
+ compositeState: 'color'
486
+ }, colorXYprop.access);
487
+ channelWithEp = expose.endpoint ? `color_rgb_${expose.endpoint}` : 'color_rgb';
488
+ pushToStates({
489
+ id: `${channelWithEp}.r`,
490
+ name: `Red`,
491
+ icon: undefined,
492
+ role: 'level.color.red',
493
+ write: true,
494
+ read: true,
495
+ type: 'number',
496
+ min: 0,
497
+ max: 255,
498
+ compositeKey: channelWithEp,
499
+ compositeTimeout: 500,
500
+ compositeState: 'color',
501
+ composites: [`${channelWithEp}.r`,`${channelWithEp}.g`]
502
+ }, colorXYprop.access);
503
+ pushToStates({
504
+ id: `${channelWithEp}.g`,
505
+ name: `Green`,
506
+ icon: undefined,
507
+ role: 'level.color.green',
508
+ write: true,
509
+ read: true,
510
+ type: 'number',
511
+ min: 0,
512
+ max: 255,
513
+ compositeKey: channelWithEp,
514
+ compositeTimeout: 500,
515
+ compositeState: 'color',
516
+ composites: [`${channelWithEp}.x`,`${channelWithEp}.y`]
517
+ });
518
+ pushToStates({
519
+ id: `${channelWithEp}.b`,
520
+ name: `Blue`,
521
+ icon: undefined,
522
+ role: 'level.color.blue',
523
+ write: true,
524
+ read: true,
525
+ type: 'number',
526
+ min: 0,
527
+ max: 255,
528
+ compositeKey: channelWithEp,
529
+ compositeTimeout: 500,
530
+ compositeState: 'color'
531
+ }, colorXYprop.access);
532
+ }
533
+ if (hasColorHS) {
534
+ const channelWithEp = expose.endpoint ? `color_hs_${expose.endpoint}` : 'color_hs';
535
+ pushToStates({
536
+ id: `${channelWithEp}.hue`,
537
+ name: `Hue`,
538
+ icon: undefined,
539
+ role: 'level.color.hue',
540
+ write: true,
541
+ read: true,
542
+ type: 'number',
543
+ min: 0,
544
+ max: 360,
545
+ compositeKey: channelWithEp,
546
+ compositeTimeout: 500,
547
+ compositeState: 'color'
548
+ }, colorHSprop.access);
549
+ pushToStates({
550
+ id: `${channelWithEp}.saturation`,
551
+ name: `Saturation`,
552
+ icon: undefined,
553
+ role: 'level.color',
554
+ write: true,
555
+ read: true,
556
+ type: 'number',
557
+ min: 0,
558
+ max: 100,
559
+ compositeKey: channelWithEp,
560
+ compositeTimeout: 500,
561
+ compositeState: 'color'
562
+ }, colorHSprop.access);
563
+
564
+ }
565
+ }
566
+
605
567
  pushToStates(statesDefs.transition_time, ea.STATE_SET);
606
568
  break;
607
-
569
+ }
608
570
  case 'switch':
609
571
  for (const prop of expose.features) {
610
572
  switch (prop.name) {
@@ -671,25 +633,33 @@ function createFromExposes(model, def) {
671
633
 
672
634
  case 'enum':
673
635
  switch (expose.name) {
636
+
674
637
  case 'action': {
675
638
  // Ansatz:
676
-
677
- // Action aufspalten in 2 Blöcke:
678
- // Action (bekommt text ausser hold und release, auto reset nach 250 ms)
679
- // Hold: wird gesetzt bei hold, gelöscht bei passendem Release
639
+ //generate an 'action' state\
640
+ state = genState(expose);
641
+ state.isEvent = true;
642
+ pushToStates(state, expose.access);
680
643
 
681
644
  if (!Array.isArray(expose.values)) break;
682
- const hasHold = expose.values.find((actionName) => actionName.includes('hold'));
683
- const hasRelease = expose.values.find((actionName) => actionName.includes('release'));
684
- const hasPress = expose.values.find((actionName) => actionName.includes('press'));
685
- const hasPressRelease = expose.values.find((actionName) => actionName.includes('press_release'));
645
+ // identify hold/release pairs
646
+ // if pairs of (prefix)press(postfix) and (prefix)release(postfix) or
647
+ // (prefix)hold(postfix) and (prefix)release(postfix)
648
+ // exist, the release action will not get its own state. Instead, the
649
+ // respective press or hold state will not be an event and be cleared at release time
650
+ //
651
+ const phr = {};
652
+ const phc = expose.values.filter((actionName) => actionName.match(/hold|press/gm));
653
+ for (const actionName of phc) {
654
+ const releasestr = actionName.replace(/hold|press/gm, 'release');
655
+ const release = expose.values.find((actionName) => actionName == releasestr);
656
+ phr[actionName]=release;
657
+ if (release) phr[release]= 'IGNORE';
658
+ }
686
659
  for (const actionName of expose.values) {
687
- // is release state ? - skip
688
- if (hasHold && hasRelease && actionName.includes('release')) continue;
689
- // is hold state ?
690
- if (hasHold && hasRelease && actionName.includes('hold')) {
691
- const releaseActionName = actionName.replace('hold', 'release');
692
- const releaseActionName2 = actionName.concat('_release');
660
+ const release = phr[actionName];
661
+ if (release === 'IGNORE') continue // a release message for which a press or hold exists.
662
+ if (release) { // a press or hold state with a matching release state
693
663
  state = {
694
664
  id: actionName.replace(/\*/g, ''),
695
665
  prop: 'action',
@@ -699,25 +669,10 @@ function createFromExposes(model, def) {
699
669
  write: false,
700
670
  read: true,
701
671
  type: 'boolean',
702
- getter: payload => payload.action === actionName ? true : (payload.action === releaseActionName || payload.action === releaseActionName2 ? false : undefined),
703
- };
704
- } else if (hasPress && hasPressRelease && actionName.includes('press')) {
705
- let getterKey = actionName.concat('_release');
706
- if (expose.values.indexOf(getterKey) < 0) getterKey = actionName;
707
- state = {
708
- id: actionName.replace(/\*/g, ''),
709
- prop: 'action',
710
- name: actionName,
711
- icon: undefined,
712
- role: 'button',
713
- write: false,
714
- read: true,
715
- type: 'boolean',
716
- getter: payload => payload.action === getterKey ? true : undefined,
717
- isEvent: true,
672
+ getter: payload => payload.action === actionName ? true : (payload.action === release ? false : undefined),
718
673
  };
719
674
  } else {
720
- state = {
675
+ state = {
721
676
  id: actionName.replace(/\*/g, ''),
722
677
  prop: 'action',
723
678
  name: actionName,
@@ -911,16 +866,15 @@ function createFromExposes(model, def) {
911
866
  }
912
867
 
913
868
  }
914
- function applyExposes(mappedDevices, byModel, allExcludesObj) {
915
- // for exclude search
916
- const allExcludesStr = JSON.stringify(allExcludesObj);
917
- // create or update device from exposes
869
+
870
+ function applyExposes(mappedDevices, byModel) {
871
+ // create or device from exposes
918
872
  for (const deviceDef of zigbeeHerdsmanConverters.definitions) {
919
- applyDeviceDef(mappedDevices, byModel, allExcludesStr, deviceDef);
873
+ applyDeviceDef(mappedDevices, byModel, deviceDef);
920
874
 
921
875
  if (deviceDef.hasOwnProperty('whiteLabel')) {
922
876
  for (const deviceWhiteLabel of deviceDef.whiteLabel) {
923
- applyDeviceDef(mappedDevices, byModel, allExcludesStr, {
877
+ applyDeviceDef(mappedDevices, byModel, {
924
878
  ...deviceDef,
925
879
  model: deviceWhiteLabel.model,
926
880
  vendor: deviceWhiteLabel.vendor,
@@ -931,26 +885,29 @@ function applyExposes(mappedDevices, byModel, allExcludesObj) {
931
885
  }
932
886
  }
933
887
 
934
- function applyDeviceDef(mappedDevices, byModel, allExcludesStr, deviceDef) {
888
+ async function applyExposeForDevice(mappedDevices, byModel, device) {
889
+ const deviceDef = await zigbeeHerdsmanConverters.findByDevice(device);
890
+ if (!deviceDef) return false;
891
+ applyDeviceDef(mappedDevices, byModel, deviceDef, device);
892
+ return true;
893
+ }
894
+
895
+ function applyDeviceDef(mappedDevices, byModel, deviceDef, device) {
935
896
  const stripModel = utils.getModelRegEx(deviceDef.model);
936
897
  const existsMap = byModel.get(stripModel);
937
-
938
- if ((deviceDef.hasOwnProperty('exposes') && (!existsMap || !existsMap.hasOwnProperty('states'))) || allExcludesStr.indexOf(stripModel) > 0) {
898
+ if (deviceDef.hasOwnProperty('exposes') && (!existsMap || !existsMap.hasOwnProperty('states'))) {
939
899
  try {
940
- const newDevice = createFromExposes(stripModel, deviceDef);
941
- if (!existsMap) {
942
- mappedDevices.push(newDevice);
943
- byModel.set(stripModel, newDevice);
944
- } else {
945
- existsMap.states = newDevice.states;
946
- existsMap.exposed = true;
947
- }
900
+ const newDevice = createFromExposes(stripModel, deviceDef, device);
901
+ mappedDevices.push(newDevice);
902
+ byModel.set(stripModel, newDevice);
903
+
948
904
  } catch (e) {
949
- console.log(`Wrong expose device definition ${deviceDef.vendor} ${stripModel}`);
905
+ //this.debug('empty catch in exposes');
950
906
  }
951
907
  }
952
908
  }
953
909
 
954
910
  module.exports = {
955
911
  applyExposes: applyExposes,
912
+ applyExposeForDevice: applyExposeForDevice,
956
913
  };