iobroker.zigbee2mqtt 3.0.13 → 3.0.14

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
@@ -22,6 +22,9 @@ This adapter allows to control the data points of the devices of a Zigbee2MQTT i
22
22
  [Adapter Documentation](https://github.com/arteck/ioBroker.zigbee2mqtt/blob/main/docs/wiki.md)
23
23
 
24
24
  ## Changelog
25
+ ### 3.0.14 (2026-01-27)
26
+ * (arteck) back to sharp 0.33.5
27
+
25
28
  ### 3.0.13 (2026-01-25)
26
29
  * (arteck) add action dp
27
30
 
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "zigbee2mqtt",
4
- "version": "3.0.13",
4
+ "version": "3.0.14",
5
5
  "news": {
6
+ "3.0.14": {
7
+ "en": "back to sharp 0.33.5",
8
+ "de": "zurück zu sharp 0,33,5",
9
+ "ru": "вернуться к sharp 0.33.5",
10
+ "pt": "voltar ao valor nítido 0,33,5",
11
+ "nl": "terug naar sharp 0,335",
12
+ "fr": "retour à la version 0.33.5",
13
+ "it": "torna a 0,33,5 tagliente",
14
+ "es": "de nuevo al 0,33,5",
15
+ "pl": "powrót do sharp 0,33,5",
16
+ "uk": "назад до sharp 0.33.5",
17
+ "zh-cn": "回到清晰的 0.33.5"
18
+ },
6
19
  "3.0.13": {
7
20
  "en": "add action dp",
8
21
  "de": "aktion dp hinzufügen",
@@ -235,7 +235,6 @@ class DeviceController {
235
235
  type: 'boolean',
236
236
  setter: (value) => (value ? scene.id : undefined),
237
237
  };
238
-
239
238
  newDevice.states.push(sceneSate);
240
239
  }
241
240
 
@@ -299,12 +298,15 @@ class DeviceController {
299
298
  if (device.ieee_address.includes('group_')) {
300
299
  deviceObj.native.groupDevice = true;
301
300
  deviceObj.common.statusStates.onlineId = `${this.adapter.name}.${this.adapter.instance}.${device.ieee_address}.available`;
302
- } else if (device.disabled || device.disabled == true) { // // Disabled Device
301
+ }
302
+ // Disabled Device
303
+ else if (device.disabled || device.disabled == true) {
303
304
  // Placeholder for possible later logic
304
- } else { // Only the onlineId is set if the device is not disabled
305
- deviceObj.common.statusStates.onlineId = `${this.adapter.name}.${this.adapter.instance}.${device.ieee_address}.available`;
306
305
  }
307
-
306
+ // Only the onlineId is set if the device is not disabled
307
+ else {
308
+ deviceObj.common.statusStates.onlineId = `${this.adapter.name}.${this.adapter.instance}.${device.ieee_address}.available`;
309
+ }
308
310
  await this.adapter.extendObjectAsync(device.ieee_address, deviceObj);
309
311
  this.createCache[device.ieee_address] = { name: deviceName, description: description };
310
312
  }
package/lib/exposes.js CHANGED
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  'use strict';
4
2
 
5
3
  const statesDefs = require('./states').states;
@@ -757,18 +755,13 @@ access = z2mAccess.ALL;
757
755
  }
758
756
  }
759
757
  if (state) {
760
- pushToStates(state, expose.access);
761
- }
758
+ pushToStates(state, expose.access);
759
+ }
762
760
  break;
763
761
 
764
- case 'enum': {
762
+ case 'enum':
765
763
  switch (expose.name) {
766
764
  case 'action': {
767
- //generate an 'action' state\
768
- state = genState(expose);
769
- state.isEvent = true;
770
- pushToStates(state, expose.access);
771
-
772
765
  if (!Array.isArray(expose.values)) {
773
766
  break;
774
767
  }
@@ -806,8 +799,8 @@ access = z2mAccess.ALL;
806
799
  // is release -> hold state? - skip
807
800
  if (
808
801
  config.simpleHoldReleaseState == true &&
809
- actionName.endsWith('release') &&
810
- expose.values.find((x) => x == actionName.replace('release', 'hold'))
802
+ actionName.endsWith('release') &&
803
+ expose.values.find((x) => x == actionName.replace('release', 'hold'))
811
804
  ) {
812
805
  continue;
813
806
  }
@@ -815,8 +808,8 @@ access = z2mAccess.ALL;
815
808
  // is stop - move state? - skip
816
809
  if (
817
810
  config.simpleMoveStopState == true &&
818
- actionName.endsWith('stop') &&
819
- expose.values.find((x) => x.includes(actionName.replace('stop', 'move')))
811
+ actionName.endsWith('stop') &&
812
+ expose.values.find((x) => x.includes(actionName.replace('stop', 'move')))
820
813
  ) {
821
814
  continue;
822
815
  }
@@ -824,16 +817,17 @@ access = z2mAccess.ALL;
824
817
  // is release -> press state? - skip
825
818
  if (
826
819
  config.simplePressReleaseState == true &&
827
- actionName.endsWith('release') &&
828
- expose.values.find((x) => x == actionName.replace('release', 'press'))
820
+ actionName.endsWith('release') &&
821
+ expose.values.find((x) => x == actionName.replace('release', 'press'))
829
822
  ) {
830
823
  continue;
831
824
  }
832
825
 
833
826
  // is hold -> release state ?
834
- if (config.simpleHoldReleaseState == true &&
835
- actionName.endsWith('hold') &&
836
- expose.values.find((x) => x == actionName.replace('hold', 'release'))
827
+ if (
828
+ config.simpleHoldReleaseState == true &&
829
+ actionName.endsWith('hold') &&
830
+ expose.values.find((x) => x == actionName.replace('hold', 'release'))
837
831
  ) {
838
832
  pushToStates(
839
833
  {
@@ -861,10 +855,12 @@ access = z2mAccess.ALL;
861
855
  },
862
856
  expose.access
863
857
  );
864
- } else if ( // is move -> stop state ?
858
+ }
859
+ // is move -> stop state ?
860
+ else if (
865
861
  config.simpleMoveStopState == true &&
866
- actionName.includes('move') &&
867
- expose.values.find((x) => x == `${actionName.split('_')[0]}_stop`)
862
+ actionName.includes('move') &&
863
+ expose.values.find((x) => x == `${actionName.split('_')[0]}_stop`)
868
864
  ) {
869
865
  pushToStates(
870
866
  {
@@ -889,10 +885,12 @@ access = z2mAccess.ALL;
889
885
  },
890
886
  expose.access
891
887
  );
892
- } else if ( // is press -> release state ?
888
+ }
889
+ // is press -> release state ?
890
+ else if (
893
891
  config.simplePressReleaseState == true &&
894
- actionName.endsWith('press') &&
895
- expose.values.find((x) => x == actionName.replace('press', 'release'))
892
+ actionName.endsWith('press') &&
893
+ expose.values.find((x) => x == actionName.replace('press', 'release'))
896
894
  ) {
897
895
  pushToStates(
898
896
  {
@@ -971,8 +969,8 @@ access = z2mAccess.ALL;
971
969
 
972
970
  if (
973
971
  payload.action_color &&
974
- payload.action_color.hasOwnProperty('x') &&
975
- payload.action_color.hasOwnProperty('y')
972
+ payload.action_color.hasOwnProperty('x') &&
973
+ payload.action_color.hasOwnProperty('y')
976
974
  ) {
977
975
  const colorval = rgb.cie_to_rgb(
978
976
  payload.action_color.x,
@@ -980,9 +978,9 @@ access = z2mAccess.ALL;
980
978
  );
981
979
  return (
982
980
  `#${
983
- utils.decimalToHex(colorval[0])
984
- }${utils.decimalToHex(colorval[1])
985
- }${utils.decimalToHex(colorval[2])}`
981
+ utils.decimalToHex(colorval[0])
982
+ }${utils.decimalToHex(colorval[1])
983
+ }${utils.decimalToHex(colorval[2])}`
986
984
  );
987
985
  }
988
986
  return undefined;
@@ -1077,7 +1075,34 @@ access = z2mAccess.ALL;
1077
1075
  },
1078
1076
  expose.access
1079
1077
  );
1080
- } else {
1078
+ }
1079
+ // else if (actionName == 'hue_move') {
1080
+ // pushToStates({
1081
+ // id: 'hue_move',
1082
+ // name: 'Hue move rate',
1083
+ // icon: undefined,
1084
+ // role: 'level.color.hue',
1085
+ // write: false,
1086
+ // read: true,
1087
+ // type: 'number',
1088
+ // min: 0,
1089
+ // max: 360,
1090
+ // def: 0,
1091
+ // isEvent: true,
1092
+ // getter: (payload) => {
1093
+ // if (payload.action != 'hue_move') {
1094
+ // return undefined;
1095
+ // }
1096
+
1097
+ // if (payload.action_level) {
1098
+ // return payload.action_level;
1099
+ // } else {
1100
+ // return undefined;
1101
+ // }
1102
+ // }
1103
+ // }, expose.access);
1104
+ // }
1105
+ else {
1081
1106
  pushToStates(
1082
1107
  {
1083
1108
  id: actionName.replace(/\*/g, ''),
@@ -1099,7 +1124,7 @@ access = z2mAccess.ALL;
1099
1124
  // Can the device simulated_brightness?
1100
1125
  if (
1101
1126
  definition.options &&
1102
- definition.options.find((x) => x.property == 'simulated_brightness')
1127
+ definition.options.find((x) => x.property == 'simulated_brightness')
1103
1128
  ) {
1104
1129
  pushToStates(statesDefs.simulated_brightness, z2mAccess.STATE);
1105
1130
  }
@@ -1114,7 +1139,7 @@ access = z2mAccess.ALL;
1114
1139
  pushToStates(state, expose.access);
1115
1140
  }
1116
1141
  break;
1117
- }
1142
+
1118
1143
  case 'binary':
1119
1144
  if (expose.endpoint) {
1120
1145
  state = genState(expose);
@@ -24,8 +24,7 @@ class MqttServerController {
24
24
  const db = new NedbPersistence({
25
25
  path: `${core.getAbsoluteInstanceDataDir(this.adapter)}/mqttData`,
26
26
  prefix: '',
27
- });
28
-
27
+ });
29
28
  const aedes = Aedes({ persistence: db });
30
29
  mqttServer = net.createServer(aedes.handle);
31
30
  mqttServer.listen(this.adapter.config.mqttServerPort, this.adapter.config.mqttServerIPBind, () => {
@@ -43,7 +42,6 @@ class MqttServerController {
43
42
  */
44
43
  async createDummyMQTTServer() {
45
44
  try {
46
-
47
45
  const aedes = Aedes();
48
46
  mqttServer = net.createServer(aedes.handle);
49
47
  mqttServer.listen(this.adapter.config.mqttServerPort, this.adapter.config.mqttServerIPBind, () => {
package/lib/rgb.js CHANGED
@@ -58,17 +58,12 @@ function cie_to_rgb(x, y, brightness) {
58
58
 
59
59
  const z = 1.0 - x - y;
60
60
  const Y = (brightness / 254).toFixed(2);
61
-
62
61
  const X = (Y / y) * x;
63
-
64
62
  const Z = (Y / y) * z;
65
63
 
66
64
  //Convert to RGB using Wide RGB D65 conversion
67
-
68
65
  let red = X * 1.656492 - Y * 0.354851 - Z * 0.255038;
69
-
70
66
  let green = -X * 0.707196 + Y * 1.655397 + Z * 0.036152;
71
-
72
67
  let blue = X * 0.051713 - Y * 0.121364 + Z * 1.01153;
73
68
 
74
69
  //If red, green or blue is larger than 1.0 set it back to the maximum of 1.0
@@ -134,15 +129,11 @@ function rgb_to_cie(red, green, blue) {
134
129
  let x = (X / (X + Y + Z)).toFixed(4);
135
130
  let y = (Y / (X + Y + Z)).toFixed(4);
136
131
 
137
-
138
132
  if (isNaN(x)) {
139
-
140
133
  x = 0;
141
134
  }
142
135
 
143
-
144
136
  if (isNaN(y)) {
145
-
146
137
  y = 0;
147
138
  }
148
139
 
@@ -234,20 +225,20 @@ function rgbToHSV(r, g, b, numeric) {
234
225
  break;
235
226
  }
236
227
  if (numeric) {
237
- return {
238
-
228
+ return {
229
+
239
230
  h: Math.round(h * 360),
240
231
  s: Math.round(s * 100),
241
232
  v: Math.round(v * 100),
242
233
  };
243
- }
244
- return {
245
-
234
+ }
235
+ return {
236
+
246
237
  h: (h * 360).toFixed(3),
247
238
  s: (s * 100).toFixed(3),
248
239
  v: (v * 100).toFixed(3),
249
- };
250
- }
240
+ };
241
+ }
251
242
 
252
243
  /**
253
244
  *
@@ -123,15 +123,19 @@ class StatesController {
123
123
  // Is an action
124
124
  if (state.prop && state.prop == 'action') {
125
125
  actionStates.push(state);
126
- } else if (
127
- // Is not an action
126
+ }
127
+ // Is not an action
128
128
  // check if its a motion sensor (occupancy state) and if configuration is set to update state every time
129
129
  // if yes, use setStateSafelyAsync instead of setStateChangedSafelyAsync
130
- this.adapter.config.allwaysUpdateOccupancyState === true && state.id === 'occupancy' && value === true
130
+ else if (
131
+ this.adapter.config.allwaysUpdateOccupancyState === true &&
132
+ state.id === 'occupancy' &&
133
+ value === true
131
134
  ) {
132
135
  await this.setStateSafelyAsync(stateName, value);
133
- } else {
134
- // end section for motion sensor update
136
+ }
137
+ // end section for motion sensor update
138
+ else {
135
139
  if (state.getter) {
136
140
  await this.setStateChangedSafelyAsync(stateName, state.getter(messageObj.payload));
137
141
  } else {
@@ -150,20 +154,19 @@ class StatesController {
150
154
 
151
155
  try {
152
156
  if (state.isEvent && state.isEvent == true) {
153
- const gettr = state.getter(messageObj.payload);
154
157
  if (state.type == 'boolean') {
155
- await this.setStateWithTimeoutAsync(stateName, gettr, 450);
158
+ await this.setStateWithTimeoutAsync(stateName, state.getter(messageObj.payload), 450);
156
159
  } else {
157
- await this.setStateSafelyAsync(stateName, gettr);
160
+ await this.setStateSafelyAsync(stateName, state.getter(messageObj.payload));
158
161
  }
159
- // publish the action into action dp
160
- if (state.prop && state.prop == 'action') {
161
- await this.setStateSafelyAsync(`${device.ieee_address}.action`, messageObj.payload.action);
162
- }
163
-
164
162
  } else {
165
163
  await this.setStateChangedSafelyAsync(stateName, state.getter(messageObj.payload));
166
164
  }
165
+
166
+ // publish the action into action dp
167
+ if (state.prop && state.prop == 'action') {
168
+ await this.setStateSafelyAsync(`${device.ieee_address}.action`, messageObj.payload.action);
169
+ }
167
170
  } catch (err) {
168
171
  incStatsQueue[incStatsQueue.length] = messageObj;
169
172
  this.adapter.log.debug(`Can not set ${stateName}, queue state in incStatsQueue!`);
@@ -212,7 +215,6 @@ class StatesController {
212
215
  }
213
216
  timeOutCache[stateName] = setTimeout(() => {
214
217
  this.adapter.setStateAsync(stateName, !value, true);
215
-
216
218
  }, timeout);
217
219
  }
218
220
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.zigbee2mqtt",
3
- "version": "3.0.13",
3
+ "version": "3.0.14",
4
4
  "description": "Zigbee2MQTT adapter for ioBroker",
5
5
  "author": {
6
6
  "name": "Dennis Rathjen and Arthur Rupp",
@@ -31,7 +31,7 @@
31
31
  "mqtt": "^5.14.1",
32
32
  "net": "^1.0.2",
33
33
  "node-schedule": "^2.1.1",
34
- "sharp": "^0.34.5",
34
+ "sharp": "^0.33.5",
35
35
  "ws": "^8.18.3"
36
36
  },
37
37
  "devDependencies": {