iobroker.zigbee2mqtt 2.2.1 → 2.3.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.
package/README.md CHANGED
@@ -30,6 +30,11 @@ This adapter allows to control the data points of the devices of a Zigbee2MQTT i
30
30
  Placeholder for the next version (at the beginning of the line):
31
31
  ### **WORK IN PROGRESS**
32
32
  -->
33
+ ### 2.3.0 (2022-10-30)
34
+
35
+ - (o0shojo0o) added support for the `toggle` of states that support this.
36
+ - (o0shojo0o) added correct handling of `color_move` and `color_temperature_move`
37
+
33
38
  ### 2.2.1 (2022-10-25)
34
39
 
35
40
  - (o0shojo0o) fix state roles and access
@@ -40,7 +45,7 @@ This adapter allows to control the data points of the devices of a Zigbee2MQTT i
40
45
 
41
46
  - (o0shojo0o) added support for [Lidl HG06467 effects](https://www.zigbee2mqtt.io/devices/HG06467.html#trigger-effects)
42
47
  - (o0shojo0o) added support for hs color
43
- - (o0shojo0o) simulated_brightness data point is added only for supported devices
48
+ - (o0shojo0o) `simulated_brightness` data point is added only for supported devices
44
49
 
45
50
  ### 2.1.1 (2022-10-16)
46
51
 
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "zigbee2mqtt",
4
- "version": "2.2.1",
4
+ "version": "2.3.0",
5
5
  "news": {
6
+ "2.3.0": {
7
+ "en": "added support for the `toggle` of states that support this.\nadded correct handling of `color_move` and `color_temperature_move`",
8
+ "de": "zusätzliche unterstützung für den kippen von staaten, die dies unterstützen.\nkorrekte handhabung von color_move und color_temperature_move",
9
+ "ru": "добавлена поддержка в отношении государств, которые поддерживают это.\nдобавлена правильная обработка color_move и color_temperature_move",
10
+ "pt": "acrescentou apoio para o conjunto de estados que apoiam isso.\nadicionado manuseio correto de color_move e color_temperature_move",
11
+ "nl": "steun toegevoegd voor de toggle van staten die dit ondersteunen.\nvoegde de juiste kleding en kleurtemperatuur toe",
12
+ "fr": "a ajouté un soutien pour la lutte des etats qui appuient cela.\nla manipulation correcte de color_move et color_temperature_move",
13
+ "it": "ha aggiunto il sostegno per la lotta di stati che sostengono questo.\naggiunto corretto trattamento di colore_move e colore_temperature_move",
14
+ "es": "agregó apoyo para la lucha de estados que apoyan esto.\nañadido correcto manejo de color_move y color_temperature_move",
15
+ "pl": "dodał wsparcie dla porozumień stanów, które to wspierają.\ndodano poprawne zachowanie koloru i kolor_temperature_move",
16
+ "uk": "додана підтримка для тягових станів, які підтримують це.\nдодано правильну обробку кольором_move та color_ infrastructure_move",
17
+ "zh-cn": "此外,还支持支持这一国家。.\n· 删除白色、流血和色色色色色彩。"
18
+ },
6
19
  "2.2.1": {
7
20
  "en": "fix state roles and access\nfix state handling\nfix createZ2MMessage",
8
21
  "de": "zustandsrollen und zugriff beheben\nmanuelle zustandsbearbeitung\nfix erstellenZ2MMessage",
@@ -79,18 +92,6 @@
79
92
  "es": "*! ¡CAMBIANDO\n\nopciones adicionales para MQTT-Server externo\nconexión a zigbe2mqtt completamente rediseñado y cambiado a MQTT\nmuchos bugfixes\nautomáticamente poner las acciones del botón de nuevo a falso\nsoporte añadido para función Zigbee2MQTT simulado_brightness\ncontrol de configuración añadido\nproducción de registro agregada sobre detalles de coordinadores",
80
93
  "pl": "! BREAKING CHANGE! (ANG.)\n\nobsługa MQTT-Server\nzigbe2mqtt całkowicie przerobił i zmienił MQTT\nwiele błędów\nautomatycznie ustawione akcje przycisku\ndodano obsługę Zigbee2MQTT\nsprawdzać\ndokładna produkcja logów na temat szczegółów koordynacji",
81
94
  "zh-cn": "页:1 BREAKREANGE*\n\n外贸总协定\n与zigbe2mqt完全重新工作,并改装到外贸总协定\n批发\n自动建立但顿行动回到虚假的行动\n对Zigbee2MQTT特征的增援\n增幅检查\n协调员的产出"
82
- },
83
- "0.2.0": {
84
- "en": "group states corrected\nadded option 'Use Kelvin instead of mired for the color temps'\nremove available logic, now will use the information from z2m\nrename noLogDevices to logfilter\nlots of bugfixes\nadded noLogDevices functionality\nadded debugmessage for specific device functionality\nadded some states are default false\nadded support for scenes defined on a device\nfix available state role\nfix subscribeWritableStates",
85
- "de": "gruppenzustände korrigiert\nzusatzoption 'Use Kelvin anstelle von mired für die Farbe Tempos '\ndie verfügbare logik entfernen, jetzt die informationen von z2m verwenden\numbenennen noLogDevices zum Logfilter\nviele bugfixes\nnoLogDevices Funktionalität hinzugefügt\ndebugmessage für spezifische gerätefunktionalität\neinige zustände standardmäßig falsch hinzugefügt\nunterstützung für szenen, die auf einem gerät definiert sind\nfix verfügbare zustandsrolle\nabonnierenWritableState",
86
- "ru": "исправлены состояния группы\nдобавлена опция 'Используйте Kelvin вместо mired для цветовых темп « »\nудалить доступную логику, теперь будет использовать информацию из z2m\nпереименовать noLogDevices для logfilter\nмного багфиксов\nдобавлена функция noLogDevices\nдобавлено debugmessage для конкретной функциональности устройства\nдобавлены некоторые государства по умолчанию false\nдобавлена поддержка сцен, определенных на устройстве\nисправить доступную государственную роль\nисправить подпискуWritableStates",
87
- "pt": "estados do grupo corrigidos\nopção adicionada 'Use Kelvin em vez de mired para os temps de cor '\nremover a lógica disponível, agora usará as informações do z2m\nrenomear noLogDevices para logfilter\nlotes de correções de bugs\nadicionado noLogDevices funcionalidade\nadicionado debugmessage para funcionalidade específica do dispositivo\nadicionado alguns estados são padrão falso\nsuporte adicionado para cenas definidas em um dispositivo\ncorrigir a função estadual disponível\ncorrigir assinantesEstados disponíveis",
88
- "nl": "de groep zegt:\nvoegde optie 'Use Kelvin' in plaats van de kleuren tempen '\nverwijder de logica, nu zal de informatie van z2m gebruiken\nnoLog Devices\nveel insectenfixen\nnoLog Devices functionaliteit\nvoegde debugmesage toe voor specifieke apparaat functionaliteit\nsommige staten zijn vals\nsteun voor scènes gedefinieerd op een apparaat\nbeschikbare staatsrol\nvertaling:",
89
- "fr": "états de groupe corrigés\noption ajoutée 'Utiliser Kelvin au lieu de mired pour le temps de couleur '\nsupprimer la logique disponible, maintenant utilisera les informations de z2m\nrenommer noLogDevices to logfilter\nbeaucoup de bugfixes\najout de fonctionnalité noLogDevices\najout debugmessage pour la fonctionnalité de périphérique spécifique\ncertains états ajoutés sont par défaut faux\nsupport ajouté pour les scènes définies sur un appareil\nle rôle de l ' état\nfixer souscrire",
90
- "it": "gruppo stati corretti\nopzione aggiunta 'Usa Kelvin invece di mired per le tentazioni di colore '\nrimuovere la logica disponibile, ora userà le informazioni da z2m\nrinominare noLogDevices per logfilter\nmolti bugfix\naggiunto noLogDevices funzionalità\ndebugmessage aggiunto per funzionalità specifiche del dispositivo\naggiunto alcuni stati sono falsi di default\nsupporto aggiunto per scene definite su un dispositivo\ncorrezione del ruolo di stato disponibile\nfissare abbonamentiWritableStates",
91
- "es": "estados del grupo corregidos\nopción agregada 'Use Kelvin en lugar de mired para el color temps '\neliminar la lógica disponible, ahora utilizará la información de z2m\nnoLogDevices to logfilter\nmuchos bugfixes\nnoLogDevices funcionalidad\ndebugmesage añadido para la funcionalidad específica del dispositivo\nañadido algunos estados son falsos\nsoporte añadido para escenas definidas en un dispositivo\nfijar la función estatal disponible\nfijar suscriptosEstados disponibles",
92
- "pl": "państwa grupowe poprawiły\ndodał opcję 'Use Kelvin' zamiast śmiać kolorowe tempo. '\nzdejmowanie dostępnej logiki wykorzystuje obecnie informacje z 2 m\nnazwa NoLogDevices (ang.)\nwiele błędów\ndodano obsługę NoLogDevices\ndodanie debugmessage dla konkretnej funkcjonalności\ndodanie niektórych stanów jest fałszywe\ndodano wsparcie dla scen zdefiniowanych na urządzenie\nfunkcja stanowa\nrecovery",
93
- "zh-cn": "更正\n加上“Use Kelvin”的备选办法,而不是对色彩的诱惑。 评 注\n删除现有逻辑,现在将使用兹2m的信息。\n目 录\n批发\n增加无车辆功能\n增加特定装置功能的碎片\n另有一些国家的违约情况\n对一个装置所界定的场地的更多支持\nf 现有国家作用\nfix 有线性的国家"
94
95
  }
95
96
  },
96
97
  "titleLang": {
@@ -6,11 +6,12 @@ const rgb = require('./rgb.js');
6
6
  //const createCache = {};
7
7
 
8
8
  class DeviceController {
9
- constructor(adapter, deviceCache, groupCache, config, createCache) {
9
+ constructor(adapter, deviceCache, groupCache, config, logCustomizations, createCache) {
10
10
  this.adapter = adapter;
11
11
  this.groupCache = groupCache;
12
12
  this.deviceCache = deviceCache;
13
13
  this.config = config;
14
+ this.logCustomizations = logCustomizations;
14
15
  this.createCache = createCache;
15
16
  }
16
17
 
@@ -25,6 +26,9 @@ class DeviceController {
25
26
  scenes = scenes.concat(expose.endpoints[key].scenes);
26
27
  }
27
28
  }
29
+ if (this.logCustomizations.debugDevices.includes(expose.ieee_address)) {
30
+ this.adapter.log.warn(`--->>> fromZ2M -> ${expose.ieee_address} exposes: ${JSON.stringify(expose)}`);
31
+ }
28
32
  // if the device is already present in the cache, remove it
29
33
  this.removeDeviceByIeee(this.deviceCache, expose.ieee_address);
30
34
  defineDeviceFromExposes(this.deviceCache, expose.friendly_name, expose.ieee_address, expose.definition, expose.power_source, scenes, this.config);
package/lib/exposes.js CHANGED
@@ -149,15 +149,6 @@ function genState(expose, role, name, desc) {
149
149
 
150
150
  function createFromExposes(deviceID, ieee_address, definitions, power_source, scenes, config) {
151
151
  const states = [];
152
- // make the different (set and get) part of state is updatable if different exposes is used for get and set
153
- // as example:
154
- // ...
155
- // exposes.binary('some_option', ea.STATE, true, false).withDescription('Some Option'),
156
- // exposes.composite('options', 'options')
157
- // .withDescription('Some composite Options')
158
- // .withFeature(exposes.binary('some_option', ea.SET, true, false).withDescription('Some Option'))
159
- //in this case one state - `some_option` has two different exposes for set an get, we have to combine it ...
160
-
161
152
  function pushToStates(state, access) {
162
153
  if (state === undefined) {
163
154
  return 0;
@@ -292,6 +283,21 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
292
283
  epname: expose.endpoint,
293
284
  setattr: 'state',
294
285
  }, prop.access);
286
+ // features contains TOGGLE?
287
+ if (prop.value_toggle) {
288
+ pushToStates({
289
+ id: `${prop.property}_toggle`,
290
+ prop: `${prop.property}_toggle`,
291
+ name: `Toggle state of the ${prop.property}`,
292
+ icon: undefined,
293
+ role: 'button',
294
+ write: true,
295
+ read: true,
296
+ type: 'boolean',
297
+ setattr: prop.property,
298
+ setter: (value) => (value) ? prop.value_toggle : undefined
299
+ });
300
+ }
295
301
  break;
296
302
  }
297
303
  case 'brightness': {
@@ -580,6 +586,21 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
580
586
  switch (prop.name) {
581
587
  case 'state':
582
588
  pushToStates(genState(prop, 'switch'), prop.access);
589
+ // features contains TOGGLE?
590
+ if (prop.value_toggle) {
591
+ pushToStates({
592
+ id: `${prop.property}_toggle`,
593
+ prop: `${prop.property}_toggle`,
594
+ name: `Toggle state of the ${prop.property}`,
595
+ icon: undefined,
596
+ role: 'button',
597
+ write: true,
598
+ read: true,
599
+ type: 'boolean',
600
+ setattr: prop.property,
601
+ setter: (value) => (value) ? prop.value_toggle : undefined
602
+ });
603
+ }
583
604
  break;
584
605
  default:
585
606
  pushToStates(genState(prop), prop.access);
@@ -659,21 +680,22 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
659
680
  switch (expose.name) {
660
681
  case 'action': {
661
682
 
662
- // Ansatz:
663
-
664
- // Action aufspalten in 2 Blöcke:
665
- // Action (bekommt text ausser hold und release, auto reset nach 250 ms)
666
- // Hold: wird gesetzt bei hold, gelöscht bei passendem Release
683
+ if (!Array.isArray(expose.values)) {
684
+ break;
685
+ }
667
686
 
668
- if (!Array.isArray(expose.values)) break;
669
687
  const hasHold = expose.values.find((actionName) => actionName.includes('hold'));
670
688
  const hasRelease = expose.values.find((actionName) => actionName.includes('release'));
689
+
671
690
  for (const actionName of expose.values) {
672
691
  // is release state ? - skip
673
- if (hasHold && hasRelease && actionName.includes('release')) continue;
692
+ if (hasHold && hasRelease && actionName.includes('release')) {
693
+ continue;
694
+ }
695
+
674
696
  // is hold state ?
675
697
  if (hasHold && hasRelease && actionName.includes('hold')) {
676
- state = {
698
+ pushToStates({
677
699
  id: actionName.replace(/\*/g, ''),
678
700
  prop: 'action',
679
701
  name: actionName,
@@ -695,9 +717,67 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
695
717
  }
696
718
  return undefined;
697
719
  },
698
- };
699
- } else {
700
- state = {
720
+ }, expose.access);
721
+ }
722
+ else if (actionName.includes('color_temperature_move')) {
723
+ pushToStates({
724
+ id: 'color_temperature_move',
725
+ prop: 'action',
726
+ name: 'Color temperature move value',
727
+ icon: undefined,
728
+ role: 'level.color.temperature',
729
+ write: false,
730
+ read: true,
731
+ type: 'number',
732
+ def: config.useKelvin == true ? utils.miredKelvinConversion(150) : 500,
733
+ min: config.useKelvin == true ? utils.miredKelvinConversion(500) : 150,
734
+ max: config.useKelvin == true ? utils.miredKelvinConversion(150) : 500,
735
+ unit: config.useKelvin == true ? 'K' : 'mired',
736
+ getter: (payload) => {
737
+ if (payload.action != 'color_temperature_move') {
738
+ return undefined;
739
+ }
740
+
741
+ if (payload.action_color_temperature) {
742
+ if (config.useKelvin == true) {
743
+ return utils.miredKelvinConversion(payload.action_color_temperature);
744
+ }
745
+ else {
746
+ return payload.action_color_temperature;
747
+ }
748
+ }
749
+ },
750
+ }, expose.access);
751
+
752
+ }
753
+ else if (actionName.includes('color_move')) {
754
+ pushToStates({
755
+ id: 'color_move',
756
+ prop: 'action',
757
+ name: 'Color move value',
758
+ icon: undefined,
759
+ role: 'level.color.rgb',
760
+ write: false,
761
+ read: true,
762
+ type: 'string',
763
+ def: '#ffffff',
764
+ getter: (payload) => {
765
+ if (payload.action != 'color_move') {
766
+ return undefined;
767
+ }
768
+
769
+ if (payload.action_color && payload.action_color.hasOwnProperty('x') && payload.action_color.hasOwnProperty('y')) {
770
+ const colorval = rgb.cie_to_rgb(payload.action_color.x, payload.action_color.y);
771
+ return '#' + utils.decimalToHex(colorval[0]) + utils.decimalToHex(colorval[1]) + utils.decimalToHex(colorval[2]);
772
+ }
773
+ else {
774
+ return undefined;
775
+ }
776
+ }
777
+ }, expose.access);
778
+ }
779
+ else {
780
+ pushToStates({
701
781
  id: actionName.replace(/\*/g, ''),
702
782
  prop: 'action',
703
783
  name: actionName,
@@ -709,27 +789,12 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
709
789
  def: false,
710
790
  isEvent: true,
711
791
  getter: payload => (payload.action === actionName) ? true : undefined,
712
- };
792
+ }, expose.access);
713
793
  }
714
- pushToStates(state, expose.access);
715
794
  }
716
795
  // Can the device simulated_brightness?
717
796
  if (definitions.options && definitions.options.find(x => x.property == 'simulated_brightness')) {
718
- pushToStates({
719
- id: 'simulated_brightness',
720
- prop: 'brightness',
721
- name: 'Simulated brightness',
722
- icon: undefined,
723
- role: 'level.dimmer',
724
- write: true,
725
- read: true,
726
- type: 'number',
727
- unit: '%',
728
- def: 0,
729
- getter: payload => {
730
- return utils.bulbLevelToAdapterLevel(payload.brightness);
731
- },
732
- }, expose.access);
797
+ pushToStates(statesDefs.simulated_brightness, z2mAccess.STATE);
733
798
  }
734
799
  state = null;
735
800
  break;
@@ -791,6 +856,21 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
791
856
  switch (prop.name) {
792
857
  case 'state':
793
858
  pushToStates(genState(prop, 'switch'), prop.access);
859
+ // features contains TOGGLE?
860
+ if (prop.value_toggle) {
861
+ pushToStates({
862
+ id: `${prop.property}_toggle`,
863
+ prop: `${prop.property}_toggle`,
864
+ name: `Toggle state of the ${prop.property}`,
865
+ icon: undefined,
866
+ role: 'button',
867
+ write: true,
868
+ read: true,
869
+ type: 'boolean',
870
+ setattr: prop.property,
871
+ setter: (value) => (value) ? prop.value_toggle : undefined
872
+ });
873
+ }
794
874
  break;
795
875
  default:
796
876
  pushToStates(genState(prop), prop.access);
@@ -881,16 +961,9 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
881
961
  // Add default states
882
962
  pushToStates(statesDefs.available, z2mAccess.STATE);
883
963
 
884
- const newDevice = {
885
- id: deviceID,
886
- ieee_address: ieee_address,
887
- power_source: power_source,
888
- states: states,
889
- };
890
-
891
964
  // Create buttons for scenes
892
965
  for (const scene of scenes) {
893
- const sceneSate = {
966
+ pushToStates({
894
967
  id: `scene_${scene.id}`,
895
968
  prop: `scene_recall`,
896
969
  name: scene.name,
@@ -900,11 +973,16 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
900
973
  read: true,
901
974
  type: 'boolean',
902
975
  setter: (value) => (value) ? scene.id : undefined
903
- };
904
- // @ts-ignore
905
- newDevice.states.push(sceneSate);
976
+ });
906
977
  }
907
978
 
979
+ const newDevice = {
980
+ id: deviceID,
981
+ ieee_address: ieee_address,
982
+ power_source: power_source,
983
+ states: states,
984
+ };
985
+
908
986
  return newDevice;
909
987
  }
910
988
 
package/lib/states.js CHANGED
@@ -56,8 +56,8 @@ const unitLookup = {
56
56
  'frequency': 'Hz',
57
57
  'power_factor': 'pf',
58
58
  'illuminance_lux': 'lx',
59
-
60
59
  };
60
+
61
61
  const timers = {};
62
62
 
63
63
  const states = {
@@ -72,7 +72,7 @@ const states = {
72
72
  type: 'number',
73
73
  min: 0,
74
74
  max: 255,
75
- def: 10,
75
+ def: 0,
76
76
  },
77
77
 
78
78
  available: {
@@ -86,6 +86,108 @@ const states = {
86
86
  type: 'boolean',
87
87
  def: false,
88
88
  },
89
+
90
+ color_read: {
91
+ id: 'color',
92
+ prop: 'action',
93
+ name: 'Color',
94
+ icon: undefined,
95
+ role: 'level.color.rgb',
96
+ write: false,
97
+ read: true,
98
+ type: 'string',
99
+ def: '#ffffff',
100
+ getter: (payload) => {
101
+ if (payload.action != 'color_wheel') {
102
+ return undefined;
103
+ }
104
+
105
+ if (payload.color && payload.color.hasOwnProperty('x') && payload.color.hasOwnProperty('y')) {
106
+ const colorval = rgb.cie_to_rgb(payload.color.x, payload.color.y);
107
+ return '#' + utils.decimalToHex(colorval[0]) + utils.decimalToHex(colorval[1]) + utils.decimalToHex(colorval[2]);
108
+ }
109
+ else {
110
+ return undefined;
111
+ }
112
+ },
113
+ },
114
+
115
+ simulated_brightness: {
116
+ id: 'simulated_brightness',
117
+ prop: 'brightness',
118
+ name: 'Simulated brightness',
119
+ icon: undefined,
120
+ role: 'level.dimmer',
121
+ write: true,
122
+ read: true,
123
+ type: 'number',
124
+ unit: '%',
125
+ def: 0,
126
+ getter: payload => {
127
+ return utils.bulbLevelToAdapterLevel(payload.brightness);
128
+ },
129
+ },
130
+
131
+ state: {
132
+ id: 'state',
133
+ name: 'Switch state',
134
+ icon: undefined,
135
+ role: 'switch',
136
+ write: true,
137
+ read: true,
138
+ type: 'boolean',
139
+ getter: payload => (payload.state === 'ON'),
140
+ setter: (value) => (value) ? 'ON' : 'OFF',
141
+ },
142
+
143
+ brightness: {
144
+ id: 'brightness',
145
+ name: 'Brightness',
146
+ icon: undefined,
147
+ role: 'level.dimmer',
148
+ write: true,
149
+ read: true,
150
+ type: 'number',
151
+ unit: '%',
152
+ min: 0,
153
+ max: 100,
154
+ getter: payload => {
155
+ return utils.bulbLevelToAdapterLevel(payload.brightness);
156
+ },
157
+ setter: (value) => {
158
+ return utils.adapterLevelToBulbLevel(value);
159
+ }
160
+ },
161
+
162
+ brightness_move: {
163
+ id: 'brightness_move',
164
+ prop: 'brightness_move',
165
+ name: 'Dimming',
166
+ icon: undefined,
167
+ role: 'state',
168
+ write: true,
169
+ read: false,
170
+ type: 'number',
171
+ min: -50,
172
+ max: 50,
173
+ def: 0
174
+ },
175
+
176
+ colortemp_move: {
177
+ id: 'colortemp_move',
178
+ prop: 'color_temp_move',
179
+ name: 'Colortemp change',
180
+ icon: undefined,
181
+ role: 'state',
182
+ write: true,
183
+ read: false,
184
+ type: 'number',
185
+ min: -50,
186
+ max: 50,
187
+ def: 0
188
+ },
189
+
190
+ //#################################################################
89
191
  device_query: { // button to trigger device read
90
192
  id: 'device_query',
91
193
  prop: 'device_query',
@@ -462,22 +564,7 @@ const states = {
462
564
  isEvent: true,
463
565
  getter: payload => (payload.click === 'both_double') ? true : undefined,
464
566
  },
465
- state: {
466
- id: 'state',
467
- name: 'Switch state',
468
- icon: undefined,
469
- role: 'switch',
470
- write: true,
471
- read: true,
472
- type: 'boolean',
473
- getter: payload => (payload.state === 'ON'),
474
- setter: (value) => (value) ? 'ON' : 'OFF',
475
- setterOpt: (value, options) => {
476
- const stateValue = (value ? 'ON' : 'OFF');
477
- return { ...options, state: stateValue };
478
- },
479
- inOptions: true,
480
- },
567
+
481
568
  stateEp: {
482
569
  id: 'state',
483
570
  name: 'Switch state',
@@ -1182,37 +1269,7 @@ const states = {
1182
1269
  return utils.bulbLevelToAdapterLevel(payload.brightness);
1183
1270
  },
1184
1271
  },
1185
- brightness: {
1186
- id: 'brightness',
1187
- name: 'Brightness',
1188
- icon: undefined,
1189
- role: 'level.dimmer',
1190
- write: true,
1191
- read: true,
1192
- type: 'number',
1193
- unit: '%',
1194
- min: 0,
1195
- max: 100,
1196
- getter: payload => {
1197
- return utils.bulbLevelToAdapterLevel(payload.brightness);
1198
- },
1199
- setter: (value, options) => {
1200
- return utils.adapterLevelToBulbLevel(value);
1201
- },
1202
- setterOpt: (value, options) => {
1203
- const hasTransitionTime = options && options.hasOwnProperty('transition_time');
1204
- const transitionTime = hasTransitionTime ? options.transition_time : 0;
1205
- const preparedOptions = { ...options, transition: transitionTime };
1206
- preparedOptions.brightness = utils.adapterLevelToBulbLevel(value);
1207
- return preparedOptions;
1208
- },
1209
- readResponse: (resp) => {
1210
- const respObj = resp[0];
1211
- if (respObj.status === 0 && respObj.attrData != undefined) {
1212
- return utils.bulbLevelToAdapterLevel(respObj.attrData);
1213
- }
1214
- },
1215
- },
1272
+
1216
1273
  colortemp: {
1217
1274
  id: 'colortemp',
1218
1275
  prop: 'color_temp',
@@ -5293,32 +5350,6 @@ const states = {
5293
5350
  min: -50,
5294
5351
  max: 50
5295
5352
  },
5296
- brightness_move: {
5297
- id: 'brightness_move',
5298
- prop: 'brightness_move',
5299
- name: 'Dimming',
5300
- icon: undefined,
5301
- role: 'state',
5302
- write: true,
5303
- read: false,
5304
- type: 'number',
5305
- min: -50,
5306
- max: 50,
5307
- def: 0
5308
- },
5309
- colortemp_move: {
5310
- id: 'colortemp_move',
5311
- prop: 'color_temp_move',
5312
- name: 'Colortemp change',
5313
- icon: undefined,
5314
- role: 'state',
5315
- write: true,
5316
- read: false,
5317
- type: 'number',
5318
- min: -50,
5319
- max: 50,
5320
- def: 0
5321
- },
5322
5353
  hue_move: {
5323
5354
  id: 'hue_move',
5324
5355
  prop: 'hue_move',
@@ -36,6 +36,11 @@ class Z2mController {
36
36
  stateID = deviceState.prop;
37
37
  }
38
38
 
39
+ if (deviceState.setattr) {
40
+ stateID = deviceState.setattr;
41
+ }
42
+
43
+
39
44
  const controlObj = {
40
45
  payload: {
41
46
  [stateID]: stateVal
package/main.js CHANGED
@@ -46,7 +46,7 @@ class Zigbee2mqtt extends core.Adapter {
46
46
 
47
47
  async onReady() {
48
48
  statesController = new StatesController(this, deviceCache, groupCache, logCustomizations, createCache);
49
- deviceController = new DeviceController(this, deviceCache, groupCache, this.config, createCache);
49
+ deviceController = new DeviceController(this, deviceCache, groupCache, this.config, logCustomizations, createCache);
50
50
  z2mController = new Z2mController(this, deviceCache, groupCache, logCustomizations);
51
51
 
52
52
  // Initialize your adapter here
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zigbee2mqtt",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "Zigbee2MQTT adapter for ioBroker",
5
5
  "author": {
6
6
  "name": "Dennis Rathjen",
@@ -24,19 +24,19 @@
24
24
  "aedes-persistence-nedb": "^2.0.3",
25
25
  "mqtt": "^4.3.7",
26
26
  "net": "^1.0.2",
27
- "ws": "^8.9.0"
27
+ "ws": "^8.10.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@alcalzone/release-script-plugin-iobroker": "^3.5.9",
31
31
  "@alcalzone/release-script-plugin-license": "^3.5.9",
32
32
  "@alcalzone/release-script": "^3.5.9",
33
- "@iobroker/adapter-dev": "^1.1.0",
33
+ "@iobroker/adapter-dev": "^1.2.0",
34
34
  "@iobroker/testing": "^4.1.0",
35
35
  "@tsconfig/node14": "^1.0.3",
36
36
  "@types/chai": "^4.3.3",
37
37
  "@types/chai-as-promised": "^7.1.5",
38
38
  "@types/mocha": "^10.0.0",
39
- "@types/node": "^18.11.3",
39
+ "@types/node": "^18.11.7",
40
40
  "@types/proxyquire": "^1.3.28",
41
41
  "@types/sinon": "^10.0.13",
42
42
  "@types/sinon-chai": "^3.2.8",