zigbee-herdsman-converters 25.1.0 → 25.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.
Files changed (200) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/converters/toZigbee.d.ts.map +1 -1
  3. package/dist/converters/toZigbee.js +131 -143
  4. package/dist/converters/toZigbee.js.map +1 -1
  5. package/dist/devices/amina.d.ts.map +1 -1
  6. package/dist/devices/amina.js +7 -37
  7. package/dist/devices/amina.js.map +1 -1
  8. package/dist/devices/aurora_lighting.d.ts.map +1 -1
  9. package/dist/devices/aurora_lighting.js +1 -0
  10. package/dist/devices/aurora_lighting.js.map +1 -1
  11. package/dist/devices/awox.d.ts.map +1 -1
  12. package/dist/devices/awox.js +8 -0
  13. package/dist/devices/awox.js.map +1 -1
  14. package/dist/devices/bacchus.d.ts.map +1 -1
  15. package/dist/devices/bacchus.js +6 -2
  16. package/dist/devices/bacchus.js.map +1 -1
  17. package/dist/devices/bosch.d.ts.map +1 -1
  18. package/dist/devices/bosch.js +38 -25
  19. package/dist/devices/bosch.js.map +1 -1
  20. package/dist/devices/centralite.js.map +1 -1
  21. package/dist/devices/ctm.js.map +1 -1
  22. package/dist/devices/custom_devices_diy.d.ts.map +1 -1
  23. package/dist/devices/custom_devices_diy.js +2 -3
  24. package/dist/devices/custom_devices_diy.js.map +1 -1
  25. package/dist/devices/danfoss.d.ts.map +1 -1
  26. package/dist/devices/danfoss.js +2 -9
  27. package/dist/devices/danfoss.js.map +1 -1
  28. package/dist/devices/dawon_dns.js.map +1 -1
  29. package/dist/devices/develco.d.ts.map +1 -1
  30. package/dist/devices/develco.js.map +1 -1
  31. package/dist/devices/diyruz.js.map +1 -1
  32. package/dist/devices/eglo.js +1 -1
  33. package/dist/devices/eglo.js.map +1 -1
  34. package/dist/devices/ewelink.d.ts.map +1 -1
  35. package/dist/devices/ewelink.js +1 -5
  36. package/dist/devices/ewelink.js.map +1 -1
  37. package/dist/devices/gmmts.d.ts.map +1 -1
  38. package/dist/devices/gmmts.js +15 -5
  39. package/dist/devices/gmmts.js.map +1 -1
  40. package/dist/devices/heiman.d.ts.map +1 -1
  41. package/dist/devices/heiman.js +5 -1
  42. package/dist/devices/heiman.js.map +1 -1
  43. package/dist/devices/imhotepcreation.js.map +1 -1
  44. package/dist/devices/immax.js.map +1 -1
  45. package/dist/devices/innr.d.ts.map +1 -1
  46. package/dist/devices/innr.js +8 -0
  47. package/dist/devices/innr.js.map +1 -1
  48. package/dist/devices/inovelli.d.ts.map +1 -1
  49. package/dist/devices/inovelli.js +20 -128
  50. package/dist/devices/inovelli.js.map +1 -1
  51. package/dist/devices/keen_home.js.map +1 -1
  52. package/dist/devices/kmpcil.js.map +1 -1
  53. package/dist/devices/legrand.d.ts.map +1 -1
  54. package/dist/devices/legrand.js +2 -0
  55. package/dist/devices/legrand.js.map +1 -1
  56. package/dist/devices/lincukoo.d.ts.map +1 -1
  57. package/dist/devices/lincukoo.js +77 -1
  58. package/dist/devices/lincukoo.js.map +1 -1
  59. package/dist/devices/livolo.d.ts.map +1 -1
  60. package/dist/devices/livolo.js.map +1 -1
  61. package/dist/devices/lixee.d.ts.map +1 -1
  62. package/dist/devices/lixee.js +9 -4
  63. package/dist/devices/lixee.js.map +1 -1
  64. package/dist/devices/lytko.d.ts.map +1 -1
  65. package/dist/devices/lytko.js +12 -10
  66. package/dist/devices/lytko.js.map +1 -1
  67. package/dist/devices/moes.js.map +1 -1
  68. package/dist/devices/niko.d.ts.map +1 -1
  69. package/dist/devices/niko.js +23 -7
  70. package/dist/devices/niko.js.map +1 -1
  71. package/dist/devices/nodon.js.map +1 -1
  72. package/dist/devices/orvibo.d.ts.map +1 -1
  73. package/dist/devices/orvibo.js +9 -3
  74. package/dist/devices/orvibo.js.map +1 -1
  75. package/dist/devices/orztech.js +1 -1
  76. package/dist/devices/orztech.js.map +1 -1
  77. package/dist/devices/owon.d.ts.map +1 -1
  78. package/dist/devices/owon.js +2 -3
  79. package/dist/devices/owon.js.map +1 -1
  80. package/dist/devices/perenio.d.ts.map +1 -1
  81. package/dist/devices/perenio.js +1 -1
  82. package/dist/devices/perenio.js.map +1 -1
  83. package/dist/devices/philips.d.ts.map +1 -1
  84. package/dist/devices/philips.js +7 -0
  85. package/dist/devices/philips.js.map +1 -1
  86. package/dist/devices/pushok.js.map +1 -1
  87. package/dist/devices/qa.js.map +1 -1
  88. package/dist/devices/robb.d.ts.map +1 -1
  89. package/dist/devices/robb.js +2 -1
  90. package/dist/devices/robb.js.map +1 -1
  91. package/dist/devices/salus_controls.d.ts.map +1 -1
  92. package/dist/devices/salus_controls.js.map +1 -1
  93. package/dist/devices/sber.d.ts.map +1 -1
  94. package/dist/devices/sber.js +12 -8
  95. package/dist/devices/sber.js.map +1 -1
  96. package/dist/devices/schneider_electric.d.ts.map +1 -1
  97. package/dist/devices/schneider_electric.js +7 -6
  98. package/dist/devices/schneider_electric.js.map +1 -1
  99. package/dist/devices/sengled.d.ts.map +1 -1
  100. package/dist/devices/sengled.js.map +1 -1
  101. package/dist/devices/shinasystem.js +4 -4
  102. package/dist/devices/shinasystem.js.map +1 -1
  103. package/dist/devices/siglis.js +10 -10
  104. package/dist/devices/siglis.js.map +1 -1
  105. package/dist/devices/simpla_home.d.ts +1 -1
  106. package/dist/devices/simpla_home.d.ts.map +1 -1
  107. package/dist/devices/simpla_home.js.map +1 -1
  108. package/dist/devices/sinope.js.map +1 -1
  109. package/dist/devices/slacky_diy.d.ts.map +1 -1
  110. package/dist/devices/slacky_diy.js +3 -1
  111. package/dist/devices/slacky_diy.js.map +1 -1
  112. package/dist/devices/smartthings.js.map +1 -1
  113. package/dist/devices/sonoff.d.ts +29 -0
  114. package/dist/devices/sonoff.d.ts.map +1 -1
  115. package/dist/devices/sonoff.js +51 -14
  116. package/dist/devices/sonoff.js.map +1 -1
  117. package/dist/devices/sunricher.d.ts +15 -0
  118. package/dist/devices/sunricher.d.ts.map +1 -1
  119. package/dist/devices/sunricher.js +3 -3
  120. package/dist/devices/sunricher.js.map +1 -1
  121. package/dist/devices/tubeszb.js.map +1 -1
  122. package/dist/devices/tuya.d.ts.map +1 -1
  123. package/dist/devices/tuya.js +10 -10
  124. package/dist/devices/tuya.js.map +1 -1
  125. package/dist/devices/ubisys.d.ts.map +1 -1
  126. package/dist/devices/ubisys.js +4 -7
  127. package/dist/devices/ubisys.js.map +1 -1
  128. package/dist/devices/wirenboard.d.ts.map +1 -1
  129. package/dist/devices/wirenboard.js +5 -3
  130. package/dist/devices/wirenboard.js.map +1 -1
  131. package/dist/devices/xyzroe.d.ts.map +1 -1
  132. package/dist/devices/xyzroe.js +2 -4
  133. package/dist/devices/xyzroe.js.map +1 -1
  134. package/dist/devices/yandex.d.ts.map +1 -1
  135. package/dist/devices/yandex.js +18 -6
  136. package/dist/devices/yandex.js.map +1 -1
  137. package/dist/devices/yokis.d.ts.map +1 -1
  138. package/dist/devices/yokis.js +4 -6
  139. package/dist/devices/yokis.js.map +1 -1
  140. package/dist/lib/develco.d.ts +24 -5
  141. package/dist/lib/develco.d.ts.map +1 -1
  142. package/dist/lib/develco.js +1 -1
  143. package/dist/lib/develco.js.map +1 -1
  144. package/dist/lib/ewelink.d.ts +4 -4
  145. package/dist/lib/ewelink.d.ts.map +1 -1
  146. package/dist/lib/ewelink.js.map +1 -1
  147. package/dist/lib/generateDefinition.js.map +1 -1
  148. package/dist/lib/ikea.d.ts +30 -1
  149. package/dist/lib/ikea.d.ts.map +1 -1
  150. package/dist/lib/ikea.js +6 -1
  151. package/dist/lib/ikea.js.map +1 -1
  152. package/dist/lib/legacy.d.ts +33 -1
  153. package/dist/lib/legacy.d.ts.map +1 -1
  154. package/dist/lib/legacy.js +21 -23
  155. package/dist/lib/legacy.js.map +1 -1
  156. package/dist/lib/legrand.d.ts.map +1 -1
  157. package/dist/lib/legrand.js +5 -6
  158. package/dist/lib/legrand.js.map +1 -1
  159. package/dist/lib/light.d.ts +2 -1
  160. package/dist/lib/light.d.ts.map +1 -1
  161. package/dist/lib/light.js.map +1 -1
  162. package/dist/lib/lumi.d.ts +33 -33
  163. package/dist/lib/lumi.d.ts.map +1 -1
  164. package/dist/lib/lumi.js +8 -9
  165. package/dist/lib/lumi.js.map +1 -1
  166. package/dist/lib/modernExtend.d.ts +41 -58
  167. package/dist/lib/modernExtend.d.ts.map +1 -1
  168. package/dist/lib/modernExtend.js +70 -15
  169. package/dist/lib/modernExtend.js.map +1 -1
  170. package/dist/lib/namron.d.ts +25 -25
  171. package/dist/lib/namron.d.ts.map +1 -1
  172. package/dist/lib/namron.js +5 -6
  173. package/dist/lib/namron.js.map +1 -1
  174. package/dist/lib/nodon.d.ts.map +1 -1
  175. package/dist/lib/nodon.js.map +1 -1
  176. package/dist/lib/philips.d.ts.map +1 -1
  177. package/dist/lib/philips.js +9 -10
  178. package/dist/lib/philips.js.map +1 -1
  179. package/dist/lib/reporting.d.ts +4 -7
  180. package/dist/lib/reporting.d.ts.map +1 -1
  181. package/dist/lib/reporting.js.map +1 -1
  182. package/dist/lib/sunricher.d.ts.map +1 -1
  183. package/dist/lib/sunricher.js +6 -4
  184. package/dist/lib/sunricher.js.map +1 -1
  185. package/dist/lib/tuya.d.ts +4 -4
  186. package/dist/lib/tuya.d.ts.map +1 -1
  187. package/dist/lib/tuya.js +32 -30
  188. package/dist/lib/tuya.js.map +1 -1
  189. package/dist/lib/types.d.ts +2 -1
  190. package/dist/lib/types.d.ts.map +1 -1
  191. package/dist/lib/ubisys.d.ts +88 -8
  192. package/dist/lib/ubisys.d.ts.map +1 -1
  193. package/dist/lib/ubisys.js +0 -3
  194. package/dist/lib/ubisys.js.map +1 -1
  195. package/dist/lib/utils.d.ts +10 -8
  196. package/dist/lib/utils.d.ts.map +1 -1
  197. package/dist/lib/utils.js +8 -5
  198. package/dist/lib/utils.js.map +1 -1
  199. package/dist/models-index.json +1 -1
  200. package/package.json +2 -2
@@ -75,7 +75,10 @@ exports.on_off = {
75
75
  if (typeof offWaitTime !== "number") {
76
76
  throw Error("The off_wait_time value must be a number!");
77
77
  }
78
- const payload = { ctrlbits: 0, ontime: Math.round(onTime * 10), offwaittime: Math.round(offWaitTime * 10) };
78
+ const payload = meta.converterOptions
79
+ ? // TODO: better typing? currently used in a single place??
80
+ meta.converterOptions
81
+ : { ctrlbits: 0, ontime: Math.round(onTime * 10), offwaittime: Math.round(offWaitTime * 10) };
79
82
  await entity.command("genOnOff", "onWithTimedOff", payload, utils.getOptions(meta.mapped, entity));
80
83
  }
81
84
  else {
@@ -95,11 +98,9 @@ exports.light_color = {
95
98
  key: ["color"],
96
99
  options: [exposes.options.color_sync(), exposes.options.transition()],
97
100
  convertSet: async (entity, key, value, meta) => {
98
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
99
- let command;
100
101
  const newColor = libColor.Color.fromConverterArg(value);
101
102
  const newState = {};
102
- const zclData = { transtime: utils.getTransition(entity, key, meta).time };
103
+ const transtime = utils.getTransition(entity, key, meta).time;
103
104
  const supportsHueAndSaturation = utils.getMetaValue(entity, meta.mapped, "supportsHueAndSaturation", "allEqual", true);
104
105
  const supportsEnhancedHue = utils.getMetaValue(entity, meta.mapped, "supportsEnhancedHue", "allEqual", true);
105
106
  if (newColor.isHSV() && !supportsHueAndSaturation) {
@@ -119,57 +120,48 @@ exports.light_color = {
119
120
  }
120
121
  newState.color_mode = constants.colorModeLookup[1];
121
122
  newState.color = xy.toObject();
122
- zclData.colorx = utils.mapNumberRange(xy.x, 0, 1, 0, 65535);
123
- zclData.colory = utils.mapNumberRange(xy.y, 0, 1, 0, 65535);
124
- command = "moveToColor";
123
+ const colorx = utils.mapNumberRange(xy.x, 0, 1, 0, 65535);
124
+ const colory = utils.mapNumberRange(xy.y, 0, 1, 0, 65535);
125
+ await entity.command("lightingColorCtrl", "moveToColor", { transtime, colorx, colory }, utils.getOptions(meta.mapped, entity));
125
126
  }
126
127
  else if (newColor.isHSV()) {
127
128
  const hsv = newColor.hsv;
128
129
  const hsvCorrected = hsv.colorCorrected(meta);
129
130
  newState.color_mode = constants.colorModeLookup[0];
130
131
  newState.color = hsv.toObject(false);
131
- if (hsv.hue !== null) {
132
- if (supportsEnhancedHue) {
133
- zclData.enhancehue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 65535);
134
- }
135
- else {
136
- zclData.hue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 254);
137
- }
138
- // @ts-expect-error ignore
139
- zclData.direction = value.direction || 0;
140
- }
141
- if (hsv.saturation != null) {
142
- zclData.saturation = utils.mapNumberRange(hsvCorrected.saturation, 0, 100, 0, 254);
143
- }
144
- if (hsv.value !== null) {
145
- // fallthrough to genLevelCtrl
146
- // @ts-expect-error ignore
147
- value.brightness = utils.mapNumberRange(hsvCorrected.value, 0, 100, 0, 254);
132
+ if (hsv.value !== null && utils.isObject(value)) {
133
+ await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: utils.mapNumberRange(hsvCorrected.value, 0, 100, 0, 254), transtime }, utils.getOptions(meta.mapped, entity));
148
134
  }
149
135
  if (hsv.hue !== null && hsv.saturation !== null) {
136
+ const saturation = utils.mapNumberRange(hsvCorrected.saturation, 0, 100, 0, 254);
150
137
  if (supportsEnhancedHue) {
151
- command = "enhancedMoveToHueAndSaturation";
138
+ const enhancehue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 65535);
139
+ await entity.command("lightingColorCtrl", "enhancedMoveToHueAndSaturation", { transtime, enhancehue, saturation }, utils.getOptions(meta.mapped, entity));
152
140
  }
153
141
  else {
154
- command = "moveToHueAndSaturation";
142
+ const hue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 254);
143
+ await entity.command("lightingColorCtrl", "moveToHueAndSaturation", { transtime, hue, saturation }, utils.getOptions(meta.mapped, entity));
155
144
  }
156
145
  }
157
146
  else if (hsv.hue !== null) {
147
+ const direction = value.direction || 0;
158
148
  if (supportsEnhancedHue) {
159
- command = "enhancedMoveToHue";
149
+ const enhancehue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 65535);
150
+ await entity.command("lightingColorCtrl", "enhancedMoveToHue", { transtime, enhancehue, direction }, utils.getOptions(meta.mapped, entity));
160
151
  }
161
152
  else {
162
- command = "moveToHue";
153
+ const hue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 254);
154
+ await entity.command("lightingColorCtrl", "moveToHue", { transtime, hue, direction }, utils.getOptions(meta.mapped, entity));
163
155
  }
164
156
  }
165
157
  else if (hsv.saturation !== null) {
166
- command = "moveToSaturation";
158
+ const saturation = utils.mapNumberRange(hsvCorrected.saturation, 0, 100, 0, 254);
159
+ await entity.command("lightingColorCtrl", "moveToSaturation", { transtime, saturation }, utils.getOptions(meta.mapped, entity));
167
160
  }
168
161
  }
169
- if (utils.isObject(value) && value.brightness != null) {
170
- await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: Number(value.brightness), transtime: utils.getTransition(entity, key, meta).time }, utils.getOptions(meta.mapped, entity));
162
+ else {
163
+ throw new Error("Invalid color");
171
164
  }
172
- await entity.command("lightingColorCtrl", command, zclData, utils.getOptions(meta.mapped, entity));
173
165
  return { state: libColor.syncColorState(newState, meta.state, entity, meta.options) };
174
166
  },
175
167
  convertGet: async (entity, key, meta) => {
@@ -511,7 +503,7 @@ exports.cover_via_brightness = {
511
503
  : meta.options.invert_cover;
512
504
  utils.assertNumber(value);
513
505
  const position = invert ? 100 - value : value;
514
- await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: utils.mapNumberRange(Number(position), 0, 100, 0, 255).toString(), transtime: 0 }, utils.getOptions(meta.mapped, entity));
506
+ await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: utils.mapNumberRange(Number(position), 0, 100, 0, 255), transtime: 0 }, utils.getOptions(meta.mapped, entity));
515
507
  return { state: { position: value } };
516
508
  },
517
509
  convertGet: async (entity, key, meta) => {
@@ -598,11 +590,15 @@ exports.squawk = {
598
590
  exports.cover_state = {
599
591
  key: ["state"],
600
592
  convertSet: async (entity, key, value, meta) => {
601
- const lookup = { open: "upOpen", close: "downClose", stop: "stop", on: "upOpen", off: "downClose" };
593
+ const lookup = {
594
+ open: "upOpen",
595
+ close: "downClose",
596
+ stop: "stop",
597
+ on: "upOpen",
598
+ off: "downClose",
599
+ };
602
600
  utils.assertString(value, key);
603
- // biome-ignore lint/style/noParameterAssign: ignored using `--suppress`
604
- value = value.toLowerCase();
605
- await entity.command("closuresWindowCovering", utils.getFromLookup(value, lookup), {}, utils.getOptions(meta.mapped, entity));
601
+ await entity.command("closuresWindowCovering", utils.getFromLookup(value.toLowerCase(), lookup), {}, utils.getOptions(meta.mapped, entity));
606
602
  },
607
603
  };
608
604
  exports.cover_position_tilt = {
@@ -785,7 +781,14 @@ exports.level_config = {
785
781
  }
786
782
  },
787
783
  convertGet: async (entity, key, meta) => {
788
- for (const attribute of ["onOffTransitionTime", "onTransitionTime", "offTransitionTime", "startUpCurrentLevel", "onLevel", "options"]) {
784
+ for (const attribute of [
785
+ "onOffTransitionTime",
786
+ "onTransitionTime",
787
+ "offTransitionTime",
788
+ "startUpCurrentLevel",
789
+ "onLevel",
790
+ "options",
791
+ ]) {
789
792
  try {
790
793
  await entity.read("genLevelCtrl", [attribute]);
791
794
  }
@@ -821,24 +824,23 @@ exports.ballast_config = {
821
824
  convertGet: async (entity, key, meta) => {
822
825
  let result = {};
823
826
  for (const attrName of [
824
- "ballast_status",
825
- "min_level",
826
- "max_level",
827
- "power_on_level",
828
- "power_on_fade_time",
829
- "intrinsic_ballast_factor",
830
- "ballast_factor_adjustment",
831
- "lamp_quantity",
832
- "lamp_type",
833
- "lamp_manufacturer",
834
- "lamp_rated_hours",
835
- "lamp_burn_hours",
836
- "lamp_alarm_mode",
837
- "lamp_burn_hours_trip_point",
827
+ "ballastStatus",
828
+ "minLevel",
829
+ "maxLevel",
830
+ "powerOnLevel",
831
+ "powerOnFadeTime",
832
+ "intrinsicBallastFactor",
833
+ "ballastFactorAdjustment",
834
+ "lampQuantity",
835
+ "lampType",
836
+ "lampManufacturer",
837
+ "lampRatedHours",
838
+ "lampBurnHours",
839
+ "lampAlarmMode",
840
+ "lampBurnHoursTripPoint",
838
841
  ]) {
839
842
  try {
840
- // @ts-expect-error ignore
841
- result = { ...result, ...(await entity.read("lightingBallastCfg", [utils.toCamelCase(attrName)])) };
843
+ result = { ...result, ...(await entity.read("lightingBallastCfg", [attrName])) };
842
844
  }
843
845
  catch {
844
846
  // continue regardless of error
@@ -930,7 +932,8 @@ exports.light_colortemp_move = {
930
932
  key: ["colortemp_move", "color_temp_move"],
931
933
  convertSet: async (entity, key, value, meta) => {
932
934
  // Initialize payload with default constraints
933
- const payload = { minimum: 0, maximum: 600 };
935
+ let minimum = 0;
936
+ let maximum = 600;
934
937
  let rate;
935
938
  let movemode;
936
939
  // Handle different input formats
@@ -953,8 +956,8 @@ exports.light_colortemp_move = {
953
956
  throw new Error(`${key}: invalid string value "${value}". Expected "stop", "release", "0", "up", "1", or "down"`);
954
957
  }
955
958
  // Use legacy constraints for string-based commands
956
- payload.minimum = 153;
957
- payload.maximum = 370;
959
+ minimum = 153;
960
+ maximum = 370;
958
961
  }
959
962
  else if (utils.isNumber(value)) {
960
963
  // Simple number input
@@ -992,26 +995,23 @@ exports.light_colortemp_move = {
992
995
  if (value.minimum != null) {
993
996
  const minValue = Number(value.minimum);
994
997
  utils.assertNumber(minValue, `${key}.minimum`);
995
- payload.minimum = minValue;
998
+ minimum = minValue;
996
999
  }
997
1000
  if (value.maximum != null) {
998
1001
  const maxValue = Number(value.maximum);
999
1002
  utils.assertNumber(maxValue, `${key}.maximum`);
1000
- payload.maximum = maxValue;
1003
+ maximum = maxValue;
1001
1004
  }
1002
1005
  // Validate constraints
1003
- if (payload.minimum >= payload.maximum) {
1004
- throw new Error(`${key}: minimum (${payload.minimum}) must be less than maximum (${payload.maximum})`);
1006
+ if (minimum >= maximum) {
1007
+ throw new Error(`${key}: minimum (${minimum}) must be less than maximum (${maximum})`);
1005
1008
  }
1006
1009
  }
1007
1010
  else {
1008
1011
  throw new Error(`${key}: invalid value type. Expected number, string, or object with rate property`);
1009
1012
  }
1010
- // Set final payload values
1011
- payload.rate = rate;
1012
- payload.movemode = movemode;
1013
1013
  // Send command
1014
- await entity.command("lightingColorCtrl", "moveColorTemp", payload, utils.getOptions(meta.mapped, entity));
1014
+ await entity.command("lightingColorCtrl", "moveColorTemp", { minimum, maximum, rate, movemode }, utils.getOptions(meta.mapped, entity));
1015
1015
  // Read current color temperature if stopping
1016
1016
  if (movemode === 0) {
1017
1017
  const entityToRead = utils.getEntityOrFirstGroupMember(entity);
@@ -1076,17 +1076,18 @@ exports.light_hue_saturation_move = {
1076
1076
  value = value === "stop" ? value : Number(value);
1077
1077
  const command = key === "hue_move" ? "moveHue" : "moveSaturation";
1078
1078
  const attribute = key === "hue_move" ? "currentHue" : "currentSaturation";
1079
- const payload = {};
1079
+ let rate = 0;
1080
+ let movemode = 0;
1080
1081
  if (value === "stop" || value === 0) {
1081
- payload.rate = 1;
1082
- payload.movemode = 0;
1082
+ rate = 1;
1083
+ movemode = 0;
1083
1084
  }
1084
1085
  else {
1085
1086
  utils.assertNumber(value, key);
1086
- payload.rate = Math.abs(value);
1087
- payload.movemode = value > 0 ? 1 : 3;
1087
+ rate = Math.abs(value);
1088
+ movemode = value > 0 ? 1 : 3;
1088
1089
  }
1089
- await entity.command("lightingColorCtrl", command, payload, utils.getOptions(meta.mapped, entity));
1090
+ await entity.command("lightingColorCtrl", command, { rate, movemode }, utils.getOptions(meta.mapped, entity));
1090
1091
  // We cannot determine the hue/saturation from the current state so we read it, because
1091
1092
  // - Color mode could have been switched (x/y or colortemp)
1092
1093
  if (value === "stop" || value === 0) {
@@ -1172,7 +1173,6 @@ exports.light_onoff_brightness = {
1172
1173
  try {
1173
1174
  const attributeRead = await entity.read("genLevelCtrl", ["onLevel"]);
1174
1175
  if (attributeRead !== undefined) {
1175
- // @ts-expect-error ignore
1176
1176
  onLevel = attributeRead.onLevel;
1177
1177
  }
1178
1178
  }
@@ -1252,7 +1252,7 @@ exports.light_colortemp_startup = {
1252
1252
  // biome-ignore lint/style/noParameterAssign: ignored using `--suppress`
1253
1253
  value = light.clampColorTemp(value, colorTempMin, colorTempMax);
1254
1254
  }
1255
- await entity.write("lightingColorCtrl", { startUpColorTemperature: value }, utils.getOptions(meta.mapped, entity));
1255
+ await entity.write("lightingColorCtrl", { startUpColorTemperature: value /* type failure? */ }, utils.getOptions(meta.mapped, entity));
1256
1256
  return { state: { color_temp_startup: value } };
1257
1257
  },
1258
1258
  convertGet: async (entity, key, meta) => {
@@ -1366,29 +1366,28 @@ exports.thermostat_weekly_schedule = {
1366
1366
  ]}}
1367
1367
  */
1368
1368
  utils.assertObject(value, key);
1369
- const payload = {
1370
- dayofweek: value.dayofweek,
1371
- transitions: value.transitions,
1372
- };
1373
- if (Array.isArray(payload.transitions)) {
1369
+ let daysofweek = value.dayofweek;
1370
+ const transitions = value.transitions;
1371
+ let numoftrans = 0;
1372
+ const modes = [];
1373
+ if (Array.isArray(transitions)) {
1374
1374
  // calculate numoftrans
1375
1375
  if (typeof value.numoftrans !== "undefined") {
1376
1376
  logger_1.logger.warning(`weekly_schedule: ignoring provided numoftrans value (${JSON.stringify(value.numoftrans)}), this is now calculated automatically`, NS);
1377
1377
  }
1378
- payload.numoftrans = payload.transitions.length;
1378
+ numoftrans = transitions.length;
1379
1379
  // mode is calculated below
1380
1380
  if (typeof value.mode !== "undefined") {
1381
1381
  logger_1.logger.warning(`weekly_schedule: ignoring provided mode value (${JSON.stringify(value.mode)}), this is now calculated automatically`, NS);
1382
1382
  }
1383
- payload.mode = [];
1384
1383
  // transform transition payload values if needed
1385
- for (const elem of payload.transitions) {
1386
- // update payload.mode if needed
1387
- if (elem.heatSetpoint != null && !payload.mode.includes("heat")) {
1388
- payload.mode.push("heat");
1384
+ for (const elem of transitions) {
1385
+ // update mode if needed
1386
+ if (elem.heatSetpoint != null && !modes.includes("heat")) {
1387
+ modes.push("heat");
1389
1388
  }
1390
- if (elem.coolSetpoint != null && !payload.mode.includes("cool")) {
1391
- payload.mode.push("cool");
1389
+ if (elem.coolSetpoint != null && !modes.includes("cool")) {
1390
+ modes.push("cool");
1392
1391
  }
1393
1392
  // transform setpoint values if numeric
1394
1393
  if (typeof elem.heatSetpoint === "number") {
@@ -1429,18 +1428,17 @@ exports.thermostat_weekly_schedule = {
1429
1428
  }
1430
1429
  // map array of desired modes to bitmask
1431
1430
  let mode = 0;
1432
- for (let m of payload.mode) {
1431
+ for (const m of modes) {
1433
1432
  // lookup mode bit
1434
- m = utils.getKey(constants.thermostatScheduleMode, m.toLowerCase(), m, Number);
1435
- mode |= 1 << m;
1433
+ mode |= 1 << utils.getKey(constants.thermostatScheduleMode, m, 0, Number);
1436
1434
  }
1437
- payload.mode = mode;
1438
1435
  // map array of days to desired dayofweek bitmask
1439
- if (typeof payload.dayofweek === "string")
1440
- payload.dayofweek = [payload.dayofweek];
1441
- if (Array.isArray(payload.dayofweek)) {
1442
- let dayofweek = 0;
1443
- for (let d of payload.dayofweek) {
1436
+ if (typeof daysofweek === "string") {
1437
+ daysofweek = [daysofweek];
1438
+ }
1439
+ let dayofweek = 0;
1440
+ if (Array.isArray(daysofweek)) {
1441
+ for (let d of daysofweek) {
1444
1442
  if (typeof d === "object") {
1445
1443
  if (d.day == null) {
1446
1444
  throw new Error(`weekly_schedule: expected dayofweek to be string or {"day": "str"}, but got '${JSON.stringify(d)}'!`);
@@ -1451,9 +1449,8 @@ exports.thermostat_weekly_schedule = {
1451
1449
  d = utils.getKey(constants.thermostatDayOfWeek, d.toLowerCase(), d, Number);
1452
1450
  dayofweek |= 1 << d;
1453
1451
  }
1454
- payload.dayofweek = dayofweek;
1455
1452
  }
1456
- await entity.command("hvacThermostat", "setWeeklySchedule", payload, utils.getOptions(meta.mapped, entity));
1453
+ await entity.command("hvacThermostat", "setWeeklySchedule", { dayofweek, numoftrans, transitions, mode }, utils.getOptions(meta.mapped, entity));
1457
1454
  },
1458
1455
  convertGet: async (entity, key, meta) => {
1459
1456
  const payload = {
@@ -1549,8 +1546,7 @@ exports.thermostat_keypad_lockout = {
1549
1546
  exports.thermostat_temperature_setpoint_hold = {
1550
1547
  key: ["temperature_setpoint_hold"],
1551
1548
  convertSet: async (entity, key, value, meta) => {
1552
- const tempSetpointHold = value;
1553
- await entity.write("hvacThermostat", { tempSetpointHold });
1549
+ await entity.write("hvacThermostat", { tempSetpointHold: value });
1554
1550
  },
1555
1551
  convertGet: async (entity, key, meta) => {
1556
1552
  await entity.read("hvacThermostat", ["tempSetpointHold"]);
@@ -1559,8 +1555,7 @@ exports.thermostat_temperature_setpoint_hold = {
1559
1555
  exports.thermostat_temperature_setpoint_hold_duration = {
1560
1556
  key: ["temperature_setpoint_hold_duration"],
1561
1557
  convertSet: async (entity, key, value, meta) => {
1562
- const tempSetpointHoldDuration = value;
1563
- await entity.write("hvacThermostat", { tempSetpointHoldDuration });
1558
+ await entity.write("hvacThermostat", { tempSetpointHoldDuration: value });
1564
1559
  },
1565
1560
  convertGet: async (entity, key, meta) => {
1566
1561
  await entity.read("hvacThermostat", ["tempSetpointHoldDuration"]);
@@ -1582,7 +1577,7 @@ exports.fan_speed = {
1582
1577
  key: ["speed"],
1583
1578
  convertSet: async (entity, key, value, meta) => {
1584
1579
  utils.assertNumber(value);
1585
- await entity.command("genLevelCtrl", "moveToLevel", { level: value.toString(), transtime: 0 }, utils.getOptions(meta.mapped, entity));
1580
+ await entity.command("genLevelCtrl", "moveToLevel", { level: value, transtime: 0 }, utils.getOptions(meta.mapped, entity));
1586
1581
  return { state: { speed: value } };
1587
1582
  },
1588
1583
  convertGet: async (entity, key, meta) => {
@@ -1978,7 +1973,7 @@ exports.humidity = {
1978
1973
  exports.elko_power_status = {
1979
1974
  key: ["system_mode"],
1980
1975
  convertSet: async (entity, key, value, meta) => {
1981
- await entity.write("hvacThermostat", { elkoPowerStatus: value === "heat" });
1976
+ await entity.write("hvacThermostat", { elkoPowerStatus: value === "heat" ? 1 : 0 });
1982
1977
  return { state: { system_mode: value } };
1983
1978
  },
1984
1979
  convertGet: async (entity, key, meta) => {
@@ -2181,7 +2176,9 @@ exports.livolo_cover_state = {
2181
2176
  default:
2182
2177
  throw new Error(`Value '${value}' is not a valid cover position (must be one of 'OPEN' or 'CLOSE')`);
2183
2178
  }
2184
- await entity.writeStructured("genPowerCfg", [payload], options);
2179
+ await entity.writeStructured("genPowerCfg",
2180
+ // @ts-expect-error workaround write custom payload
2181
+ [payload], options);
2185
2182
  return {
2186
2183
  state: {
2187
2184
  moving: true,
@@ -2242,14 +2239,18 @@ exports.livolo_cover_options = {
2242
2239
  (must be one of 'FORWARD' or 'REVERSE')`);
2243
2240
  }
2244
2241
  const payload = { 4865: { value: [direction, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] } };
2245
- await entity.write("genPowerCfg", payload, options);
2242
+ await entity.write("genPowerCfg",
2243
+ // @ts-expect-error workaround write custom payload
2244
+ payload, options);
2246
2245
  }
2247
2246
  if (value.motor_speed != null) {
2248
2247
  if (value.motor_speed < 20 || value.motor_speed > 40) {
2249
2248
  throw new Error("livolo_cover_options: Motor speed is out of range (20-40)");
2250
2249
  }
2251
2250
  const payload = { 4609: { value: [value.motor_speed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] } };
2252
- await entity.write("genPowerCfg", payload, options);
2251
+ await entity.write("genPowerCfg",
2252
+ // @ts-expect-error workaround write custom payload
2253
+ payload, options);
2253
2254
  }
2254
2255
  },
2255
2256
  };
@@ -2546,8 +2547,7 @@ exports.danfoss_adaptation_settings = {
2546
2547
  exports.danfoss_adaptation_control = {
2547
2548
  key: ["adaptation_run_control"],
2548
2549
  convertSet: async (entity, key, value, meta) => {
2549
- const payload = { danfossAdaptionRunControl: utils.getKey(constants.danfossAdaptionRunControl, value, value, Number) };
2550
- await entity.write("hvacThermostat", payload, manufacturerOptions.danfoss);
2550
+ await entity.write("hvacThermostat", { danfossAdaptionRunControl: utils.getKey(constants.danfossAdaptionRunControl, value, value, Number) }, manufacturerOptions.danfoss);
2551
2551
  return { state: { adaptation_run_control: value } };
2552
2552
  },
2553
2553
  convertGet: async (entity, key, meta) => {
@@ -2557,8 +2557,7 @@ exports.danfoss_adaptation_control = {
2557
2557
  exports.danfoss_regulation_setpoint_offset = {
2558
2558
  key: ["regulation_setpoint_offset"],
2559
2559
  convertSet: async (entity, key, value, meta) => {
2560
- const payload = { danfossRegulationSetpointOffset: value };
2561
- await entity.write("hvacThermostat", payload, manufacturerOptions.danfoss);
2560
+ await entity.write("hvacThermostat", { danfossRegulationSetpointOffset: value }, manufacturerOptions.danfoss);
2562
2561
  return { state: { regulation_setpoint_offset: value } };
2563
2562
  },
2564
2563
  convertGet: async (entity, key, meta) => {
@@ -2634,7 +2633,7 @@ exports.danfoss_system_status_code = {
2634
2633
  exports.danfoss_heat_supply_request = {
2635
2634
  key: ["heat_supply_request"],
2636
2635
  convertGet: async (entity, key, meta) => {
2637
- await entity.read("haDiagnostic", ["danfossHeatsupplyRequest"], manufacturerOptions.danfoss);
2636
+ await entity.read("haDiagnostic", ["danfossHeatSupplyRequest"], manufacturerOptions.danfoss);
2638
2637
  },
2639
2638
  };
2640
2639
  exports.danfoss_system_status_water = {
@@ -2980,15 +2979,13 @@ exports.tuya_led_controller = {
2980
2979
  return { state: { state: value.toUpperCase() } };
2981
2980
  }
2982
2981
  if (key === "color") {
2983
- const hue = {};
2984
- const saturation = {};
2985
2982
  utils.assertObject(value);
2986
- hue.hue = utils.mapNumberRange(value.h, 0, 360, 0, 254);
2987
- saturation.saturation = utils.mapNumberRange(value.s, 0, 100, 0, 254);
2988
- hue.transtime = saturation.transtime = 0;
2989
- hue.direction = 0;
2990
- await entity.command("lightingColorCtrl", "moveToHue", hue, utils.getOptions(meta.mapped, entity));
2991
- await entity.command("lightingColorCtrl", "moveToSaturation", saturation, utils.getOptions(meta.mapped, entity));
2983
+ const hue = utils.mapNumberRange(value.h, 0, 360, 0, 254);
2984
+ const saturation = utils.mapNumberRange(value.s, 0, 100, 0, 254);
2985
+ const transtime = 0;
2986
+ const direction = 0;
2987
+ await entity.command("lightingColorCtrl", "moveToHue", { hue, transtime, direction }, utils.getOptions(meta.mapped, entity));
2988
+ await entity.command("lightingColorCtrl", "moveToSaturation", { saturation, transtime }, utils.getOptions(meta.mapped, entity));
2992
2989
  }
2993
2990
  },
2994
2991
  convertGet: async (entity, key, meta) => {
@@ -3559,16 +3556,16 @@ exports.diyruz_zintercom_config = {
3559
3556
  },
3560
3557
  convertGet: async (entity, key, meta) => {
3561
3558
  const payloads = {
3562
- mode: ["closuresDoorLock", 0x0051],
3563
- sound: ["closuresDoorLock", 0x0052],
3564
- time_ring: ["closuresDoorLock", 0x0053],
3565
- time_talk: ["closuresDoorLock", 0x0054],
3566
- time_open: ["closuresDoorLock", 0x0055],
3567
- time_bell: ["closuresDoorLock", 0x0057],
3568
- time_report: ["closuresDoorLock", 0x0056],
3559
+ mode: 0x0051,
3560
+ sound: 0x0052,
3561
+ time_ring: 0x0053,
3562
+ time_talk: 0x0054,
3563
+ time_open: 0x0055,
3564
+ time_bell: 0x0057,
3565
+ time_report: 0x0056,
3569
3566
  };
3570
3567
  const v = utils.getFromLookup(key, payloads);
3571
- await entity.read(v[0], [v[1]]);
3568
+ await entity.read("closuresDoorLock", [v]);
3572
3569
  },
3573
3570
  };
3574
3571
  exports.power_source = {
@@ -3662,13 +3659,11 @@ exports.scene_store = {
3662
3659
  utils.saveSceneState(member, sceneid, groupid, meta.membersState[member.getDevice().ieeeAddr], scenename);
3663
3660
  }
3664
3661
  }
3665
- // @ts-expect-error ignore
3666
3662
  }
3667
3663
  else if (response.status === 0) {
3668
3664
  utils.saveSceneState(entity, sceneid, groupid, meta.state, scenename);
3669
3665
  }
3670
3666
  else {
3671
- // @ts-expect-error ignore
3672
3667
  throw new Error(`Scene add not successful ('${zigbee_herdsman_1.Zcl.Status[response.status]}')`);
3673
3668
  }
3674
3669
  logger_1.logger.info("Successfully stored scene", NS);
@@ -3890,13 +3885,11 @@ exports.scene_remove = {
3890
3885
  utils.deleteSceneState(member, sceneid, groupid);
3891
3886
  }
3892
3887
  }
3893
- // @ts-expect-error ignore
3894
3888
  }
3895
3889
  else if (response.status === 0) {
3896
3890
  utils.deleteSceneState(entity, sceneid, groupid);
3897
3891
  }
3898
3892
  else {
3899
- // @ts-expect-error ignore
3900
3893
  throw new Error(`Scene remove not successful ('${zigbee_herdsman_1.Zcl.Status[response.status]}')`);
3901
3894
  }
3902
3895
  logger_1.logger.info("Successfully removed scene", NS);
@@ -4107,7 +4100,7 @@ exports.viessmann_window_open_force = {
4107
4100
  key: ["window_open_force"],
4108
4101
  convertSet: async (entity, key, value, meta) => {
4109
4102
  if (typeof value === "boolean") {
4110
- await entity.write("hvacThermostat", { viessmannWindowOpenForce: value }, manufacturerOptions.viessmann);
4103
+ await entity.write("hvacThermostat", { viessmannWindowOpenForce: value ? 1 : 0 }, manufacturerOptions.viessmann);
4111
4104
  return { state: { window_open_force: value } };
4112
4105
  }
4113
4106
  logger_1.logger.error("window_open_force must be a boolean!", NS);
@@ -4126,11 +4119,9 @@ exports.dawondns_only_off = {
4126
4119
  key: ["state"],
4127
4120
  convertSet: async (entity, key, value, meta) => {
4128
4121
  utils.assertString(value, key);
4129
- // biome-ignore lint/style/noParameterAssign: ignored using `--suppress`
4130
- value = value.toLowerCase();
4131
- utils.assertString(value, key);
4132
- utils.validateValue(value, ["off"]);
4133
- await entity.command("genOnOff", value, {}, utils.getOptions(meta.mapped, entity));
4122
+ const lowerValue = value.toLowerCase();
4123
+ utils.validateValue(lowerValue, ["off"]);
4124
+ await entity.command("genOnOff", lowerValue, {}, utils.getOptions(meta.mapped, entity));
4134
4125
  },
4135
4126
  convertGet: async (entity, key, meta) => {
4136
4127
  await entity.read("genOnOff", ["onOff"]);
@@ -4218,8 +4209,7 @@ exports.schneider_dimmer_mode = {
4218
4209
  exports.wiser_dimmer_mode = {
4219
4210
  key: ["dimmer_mode"],
4220
4211
  convertSet: async (entity, key, value, meta) => {
4221
- const controlMode = utils.getKey(constants.wiserDimmerControlMode, value, value, Number);
4222
- await entity.write("lightingBallastCfg", { wiserControlMode: controlMode }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC });
4212
+ await entity.write("lightingBallastCfg", { wiserControlMode: utils.getKey(constants.wiserDimmerControlMode, value, value, Number) }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC });
4223
4213
  return { state: { dimmer_mode: value } };
4224
4214
  },
4225
4215
  convertGet: async (entity, key, meta) => {
@@ -4364,17 +4354,15 @@ exports.wiser_sed_thermostat_local_temperature_calibration = {
4364
4354
  exports.wiser_sed_thermostat_keypad_lockout = {
4365
4355
  key: ["keypad_lockout"],
4366
4356
  convertSet: async (entity, key, value, meta) => {
4367
- const keypadLockout = utils.getKey(constants.keypadLockoutMode, value, value, Number);
4368
- await entity.write("hvacUserInterfaceCfg", { keypadLockout }, { srcEndpoint: 11, disableDefaultResponse: true });
4357
+ await entity.write("hvacUserInterfaceCfg", { keypadLockout: utils.getKey(constants.keypadLockoutMode, value, value, Number) }, { srcEndpoint: 11, disableDefaultResponse: true });
4369
4358
  return { state: { keypad_lockout: value } };
4370
4359
  },
4371
4360
  };
4372
4361
  exports.sihas_set_people = {
4373
4362
  key: ["people"],
4374
4363
  convertSet: async (entity, key, value, meta) => {
4375
- const payload = { presentValue: value };
4376
4364
  const endpoint = meta.device.endpoints.find((e) => e.supportsInputCluster("genAnalogInput"));
4377
- await endpoint.write("genAnalogInput", payload);
4365
+ await endpoint.write("genAnalogInput", { presentValue: value });
4378
4366
  },
4379
4367
  convertGet: async (entity, key, meta) => {
4380
4368
  const endpoint = meta.device.endpoints.find((e) => e.supportsInputCluster("genAnalogInput"));