node-switchbot 3.6.0-beta.0 → 3.6.0-beta.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.
Files changed (329) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/device.d.ts +158 -53
  3. package/dist/device.d.ts.map +1 -1
  4. package/dist/device.js +319 -100
  5. package/dist/device.js.map +1 -1
  6. package/dist/device.test.d.ts +2 -0
  7. package/dist/device.test.d.ts.map +1 -0
  8. package/dist/device.test.js +152 -0
  9. package/dist/device.test.js.map +1 -0
  10. package/dist/index.d.ts +4 -7
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +6 -7
  13. package/dist/index.js.map +1 -1
  14. package/dist/parameter-checker.d.ts +1 -0
  15. package/dist/parameter-checker.d.ts.map +1 -1
  16. package/dist/parameter-checker.js +19 -11
  17. package/dist/parameter-checker.js.map +1 -1
  18. package/dist/parameter-checker.test.d.ts +2 -0
  19. package/dist/parameter-checker.test.d.ts.map +1 -0
  20. package/dist/parameter-checker.test.js +56 -0
  21. package/dist/parameter-checker.test.js.map +1 -0
  22. package/dist/settings.d.ts.map +1 -1
  23. package/dist/settings.js +21 -16
  24. package/dist/settings.js.map +1 -1
  25. package/dist/settings.test.js +13 -1
  26. package/dist/settings.test.js.map +1 -1
  27. package/dist/switchbot-ble.d.ts +7 -4
  28. package/dist/switchbot-ble.d.ts.map +1 -1
  29. package/dist/switchbot-ble.js +77 -37
  30. package/dist/switchbot-ble.js.map +1 -1
  31. package/dist/switchbot-ble.test.d.ts +2 -0
  32. package/dist/switchbot-ble.test.d.ts.map +1 -0
  33. package/dist/switchbot-ble.test.js +32 -0
  34. package/dist/switchbot-ble.test.js.map +1 -0
  35. package/dist/switchbot-openapi.d.ts +4 -7
  36. package/dist/switchbot-openapi.d.ts.map +1 -1
  37. package/dist/switchbot-openapi.js +19 -10
  38. package/dist/switchbot-openapi.js.map +1 -1
  39. package/dist/switchbot-openapi.test.d.ts +2 -0
  40. package/dist/switchbot-openapi.test.d.ts.map +1 -0
  41. package/dist/switchbot-openapi.test.js +36 -0
  42. package/dist/switchbot-openapi.test.js.map +1 -0
  43. package/dist/types/ble-guards.d.ts +12 -0
  44. package/dist/types/ble-guards.d.ts.map +1 -0
  45. package/dist/types/ble-guards.js +10 -0
  46. package/dist/types/ble-guards.js.map +1 -0
  47. package/dist/types/ble-guards.test.d.ts +2 -0
  48. package/dist/types/ble-guards.test.d.ts.map +1 -0
  49. package/dist/types/ble-guards.test.js +62 -0
  50. package/dist/types/ble-guards.test.js.map +1 -0
  51. package/dist/types/{bledevicestatus.d.ts → ble.d.ts} +97 -116
  52. package/dist/types/ble.d.ts.map +1 -0
  53. package/dist/types/ble.js +2 -0
  54. package/dist/types/ble.js.map +1 -0
  55. package/dist/types/openapi.d.ts +560 -0
  56. package/dist/types/openapi.d.ts.map +1 -0
  57. package/dist/types/openapi.js +3 -0
  58. package/dist/types/openapi.js.map +1 -0
  59. package/docs/assets/hierarchy.js +1 -1
  60. package/docs/assets/navigation.js +1 -1
  61. package/docs/assets/search.js +1 -1
  62. package/docs/classes/Advertising.html +4 -4
  63. package/docs/classes/ErrorUtils.html +25 -0
  64. package/docs/classes/ParameterChecker.html +69 -0
  65. package/docs/classes/SwitchBotBLE.html +8 -10
  66. package/docs/classes/SwitchBotOpenAPI.html +9 -9
  67. package/docs/classes/SwitchbotDevice.html +12 -12
  68. package/docs/classes/ValidationUtils.html +51 -0
  69. package/docs/classes/WoBlindTilt.html +22 -22
  70. package/docs/classes/WoBulb.html +20 -20
  71. package/docs/classes/WoCeilingLight.html +24 -24
  72. package/docs/classes/WoContact.html +14 -14
  73. package/docs/classes/WoCurtain.html +19 -19
  74. package/docs/classes/WoHand.html +19 -19
  75. package/docs/classes/WoHub2.html +14 -14
  76. package/docs/classes/WoHumi.html +21 -21
  77. package/docs/classes/WoHumi2.html +21 -21
  78. package/docs/classes/WoIOSensorTH.html +14 -14
  79. package/docs/classes/WoKeypad.html +14 -14
  80. package/docs/classes/WoLeak.html +14 -14
  81. package/docs/classes/WoPlugMiniJP.html +19 -19
  82. package/docs/classes/WoPlugMiniUS.html +19 -19
  83. package/docs/classes/WoPresence.html +14 -14
  84. package/docs/classes/WoRelaySwitch1.html +16 -16
  85. package/docs/classes/WoRelaySwitch1PM.html +16 -16
  86. package/docs/classes/WoRemote.html +14 -14
  87. package/docs/classes/WoSensorTH.html +12 -12
  88. package/docs/classes/WoSensorTHPlus.html +12 -12
  89. package/docs/classes/WoSensorTHPro.html +12 -12
  90. package/docs/classes/WoSensorTHProCO2.html +12 -12
  91. package/docs/classes/WoSmartLock.html +24 -24
  92. package/docs/classes/WoSmartLockPro.html +24 -24
  93. package/docs/classes/WoStrip.html +21 -21
  94. package/docs/enums/LogLevel.html +2 -2
  95. package/docs/enums/SwitchBotBLEModel.html +2 -2
  96. package/docs/enums/SwitchBotBLEModelFriendlyName.html +2 -2
  97. package/docs/enums/SwitchBotBLEModelName.html +2 -2
  98. package/docs/enums/SwitchBotModel.html +2 -2
  99. package/docs/functions/updateBaseURL.html +3 -0
  100. package/docs/hierarchy.html +1 -1
  101. package/docs/interfaces/AdvertisementData.html +2 -2
  102. package/docs/interfaces/Chars.html +2 -2
  103. package/docs/interfaces/ColorLightServiceDataBase.html +17 -0
  104. package/docs/interfaces/Device.html +7 -0
  105. package/docs/interfaces/DeviceList.html +2 -0
  106. package/docs/interfaces/ErrorObject.html +2 -2
  107. package/docs/interfaces/LockBaseServiceData.html +15 -0
  108. package/docs/interfaces/NobleTypes.html +2 -2
  109. package/docs/interfaces/Params.html +2 -2
  110. package/docs/interfaces/PlugMiniServiceDataBase.html +12 -0
  111. package/docs/interfaces/PushRequest.html +5 -0
  112. package/docs/interfaces/{pushResponse.html → PushResponse.html} +3 -2
  113. package/docs/interfaces/PushResponseBody.html +3 -0
  114. package/docs/interfaces/Rule.html +2 -2
  115. package/docs/interfaces/ServiceData.html +2 -2
  116. package/docs/interfaces/SwitchBotBLEDevice.html +2 -2
  117. package/docs/interfaces/SwitchBotScanner.html +6 -0
  118. package/docs/interfaces/TemperatureServiceDataBase.html +10 -0
  119. package/docs/interfaces/WebhookDetail.html +2 -2
  120. package/docs/interfaces/ad.html +2 -2
  121. package/docs/interfaces/body.html +2 -2
  122. package/docs/interfaces/deleteWebhookResponse.html +2 -2
  123. package/docs/interfaces/deviceStatus.html +2 -2
  124. package/docs/interfaces/deviceStatusRequest.html +2 -2
  125. package/docs/interfaces/deviceWebhook.html +2 -2
  126. package/docs/interfaces/deviceWebhookContext.html +2 -2
  127. package/docs/interfaces/devices.html +2 -2
  128. package/docs/interfaces/infraredRemoteList.html +2 -2
  129. package/docs/interfaces/irdevice.html +2 -2
  130. package/docs/interfaces/queryWebhookResponse.html +2 -2
  131. package/docs/interfaces/setupWebhookResponse.html +2 -2
  132. package/docs/interfaces/updateWebhookResponse.html +2 -2
  133. package/docs/interfaces/webhookRequest.html +2 -2
  134. package/docs/modules.html +1 -1
  135. package/docs/types/BLEDeviceServiceData.html +1 -0
  136. package/docs/types/BatteryCirculatorFan.html +1 -0
  137. package/docs/types/BatteryCirculatorFanServiceData.html +1 -0
  138. package/docs/types/{batteryCirculatorFanStatus.html → BatteryCirculatorFanStatus.html} +1 -1
  139. package/docs/types/{blindTilt.html → BlindTilt.html} +1 -1
  140. package/docs/types/BlindTiltServiceData.html +1 -0
  141. package/docs/types/{blindTiltStatus.html → BlindTiltStatus.html} +1 -1
  142. package/docs/types/{bot.html → Bot.html} +1 -1
  143. package/docs/types/BotServiceData.html +1 -0
  144. package/docs/types/{ceilingLight.html → CeilingLight.html} +1 -1
  145. package/docs/types/{ceilingLightPro.html → CeilingLightPro.html} +1 -1
  146. package/docs/types/CeilingLightProServiceData.html +1 -0
  147. package/docs/types/CeilingLightServiceData.html +1 -0
  148. package/docs/types/{circulatorFanStatus.html → CirculatorFanStatus.html} +1 -1
  149. package/docs/types/{colorBulb.html → ColorBulb.html} +1 -1
  150. package/docs/types/ColorBulbServiceData.html +1 -0
  151. package/docs/types/CommandType.html +2 -0
  152. package/docs/types/{contactSensor.html → ContactSensor.html} +1 -1
  153. package/docs/types/ContactSensorServiceData.html +1 -0
  154. package/docs/types/{curtain.html → Curtain.html} +1 -1
  155. package/docs/types/{curtain3.html → Curtain3.html} +1 -1
  156. package/docs/types/Curtain3ServiceData.html +1 -0
  157. package/docs/types/CurtainServiceData.html +1 -0
  158. package/docs/types/{floorCleaningRobotS10.html → FloorCleaningRobotS10.html} +1 -1
  159. package/docs/types/{hub2.html → Hub2.html} +1 -1
  160. package/docs/types/Hub2ServiceData.html +1 -0
  161. package/docs/types/{hub2Status.html → Hub2Status.html} +1 -1
  162. package/docs/types/{stripLight.html → Humidifier.html} +1 -1
  163. package/docs/types/Humidifier2ServiceData.html +1 -0
  164. package/docs/types/{humidifier2Status.html → Humidifier2Status.html} +1 -1
  165. package/docs/types/HumidifierServiceData.html +1 -0
  166. package/docs/types/{humidifierStatus.html → HumidifierStatus.html} +1 -1
  167. package/docs/types/{indoorCam.html → IndoorCam.html} +1 -1
  168. package/docs/types/{keypad.html → Keypad.html} +1 -1
  169. package/docs/types/KeypadDetectorServiceData.html +1 -0
  170. package/docs/types/{keypadTouch.html → KeypadTouch.html} +1 -1
  171. package/docs/types/{lock.html → Lock.html} +1 -1
  172. package/docs/types/{lockPro.html → LockPro.html} +1 -1
  173. package/docs/types/LockProServiceData.html +1 -0
  174. package/docs/types/LockServiceData.html +1 -0
  175. package/docs/types/MacAddress.html +1 -1
  176. package/docs/types/{meter.html → Meter.html} +1 -1
  177. package/docs/types/{meterPlus.html → MeterPlus.html} +1 -1
  178. package/docs/types/MeterPlusServiceData.html +1 -0
  179. package/docs/types/{meterPro.html → MeterPro.html} +1 -1
  180. package/docs/types/MeterProCO2ServiceData.html +1 -0
  181. package/docs/types/MeterProServiceData.html +1 -0
  182. package/docs/types/MeterServiceData.html +1 -0
  183. package/docs/types/{motionSensor.html → MotionSensor.html} +1 -1
  184. package/docs/types/MotionSensorServiceData.html +1 -0
  185. package/docs/types/{outdoorMeter.html → OutdoorMeter.html} +1 -1
  186. package/docs/types/OutdoorMeterServiceData.html +1 -0
  187. package/docs/types/{humidifier.html → PantiltCam.html} +1 -1
  188. package/docs/types/{pantiltCam2k.html → PantiltCam2k.html} +1 -1
  189. package/docs/types/{plug.html → Plug.html} +1 -1
  190. package/docs/types/{plugMini.html → PlugMini.html} +1 -1
  191. package/docs/types/PlugMiniJPServiceData.html +1 -0
  192. package/docs/types/PlugMiniUSServiceData.html +1 -0
  193. package/docs/types/RelaySwitch1PMServiceData.html +1 -0
  194. package/docs/types/RelaySwitch1ServiceData.html +1 -0
  195. package/docs/types/{remote.html → Remote.html} +1 -1
  196. package/docs/types/RemoteServiceData.html +1 -0
  197. package/docs/types/RobotVacuumCleanerS1.html +1 -0
  198. package/docs/types/{robotVacuumCleanerS1Plus.html → RobotVacuumCleanerS1Plus.html} +1 -1
  199. package/docs/types/RobotVacuumCleanerServiceData.html +1 -0
  200. package/docs/types/{pantiltCam.html → StripLight.html} +1 -1
  201. package/docs/types/StripLightServiceData.html +1 -0
  202. package/docs/types/{waterLeakDetector.html → WaterLeakDetector.html} +1 -1
  203. package/docs/types/WaterLeakDetectorServiceData.html +1 -0
  204. package/docs/types/batteryCirculatorFanWebhookContext.html +1 -1
  205. package/docs/types/blindTiltWebhookContext.html +1 -1
  206. package/docs/types/botStatus.html +1 -1
  207. package/docs/types/botWebhookContext.html +1 -1
  208. package/docs/types/ceilingLightProStatus.html +1 -1
  209. package/docs/types/ceilingLightProWebhookContext.html +1 -1
  210. package/docs/types/ceilingLightStatus.html +1 -1
  211. package/docs/types/ceilingLightWebhookContext.html +1 -1
  212. package/docs/types/circulatorFanWebhookContext.html +1 -1
  213. package/docs/types/colorBulbStatus.html +1 -1
  214. package/docs/types/colorBulbWebhookContext.html +1 -1
  215. package/docs/types/contactSensorStatus.html +1 -1
  216. package/docs/types/contactSensorWebhookContext.html +1 -1
  217. package/docs/types/curtain3WebhookContext.html +1 -1
  218. package/docs/types/curtainStatus.html +1 -1
  219. package/docs/types/curtainWebhookContext.html +1 -1
  220. package/docs/types/floorCleaningRobotS10Status.html +1 -1
  221. package/docs/types/floorCleaningRobotS10WebhookContext.html +1 -1
  222. package/docs/types/hub2WebhookContext.html +1 -1
  223. package/docs/types/humidifier2WebhookContext.html +1 -1
  224. package/docs/types/humidifierWebhookContext.html +1 -1
  225. package/docs/types/indoorCameraWebhookContext.html +1 -1
  226. package/docs/types/keypadTouchWebhookContext.html +1 -1
  227. package/docs/types/keypadWebhookContext.html +1 -1
  228. package/docs/types/lockProStatus.html +1 -1
  229. package/docs/types/lockProWebhookContext.html +1 -1
  230. package/docs/types/lockStatus.html +1 -1
  231. package/docs/types/lockWebhookContext.html +1 -1
  232. package/docs/types/meterPlusStatus.html +1 -1
  233. package/docs/types/meterPlusWebhookContext.html +1 -1
  234. package/docs/types/meterProCO2Status.html +1 -1
  235. package/docs/types/meterProCO2WebhookContext.html +1 -1
  236. package/docs/types/meterProStatus.html +1 -1
  237. package/docs/types/meterProWebhookContext.html +1 -1
  238. package/docs/types/meterStatus.html +1 -1
  239. package/docs/types/meterWebhookContext.html +1 -1
  240. package/docs/types/motionSensorStatus.html +1 -1
  241. package/docs/types/motionSensorWebhookContext.html +1 -1
  242. package/docs/types/onadvertisement.html +1 -1
  243. package/docs/types/ondiscover.html +1 -1
  244. package/docs/types/outdoorMeterStatus.html +1 -1
  245. package/docs/types/outdoorMeterWebhookContext.html +1 -1
  246. package/docs/types/panTiltCamWebhookContext.html +1 -1
  247. package/docs/types/plugMiniJPWebhookContext.html +1 -1
  248. package/docs/types/plugMiniStatus.html +1 -1
  249. package/docs/types/plugMiniUSWebhookContext.html +1 -1
  250. package/docs/types/plugStatus.html +1 -1
  251. package/docs/types/plugWebhookContext.html +1 -1
  252. package/docs/types/relaySwitch1Context.html +1 -1
  253. package/docs/types/relaySwitch1PMContext.html +1 -1
  254. package/docs/types/relaySwitch1PMStatus.html +1 -1
  255. package/docs/types/relaySwitch1Status.html +1 -1
  256. package/docs/types/robotVacuumCleanerS1PlusStatus.html +1 -1
  257. package/docs/types/robotVacuumCleanerS1PlusWebhookContext.html +1 -1
  258. package/docs/types/robotVacuumCleanerS1Status.html +1 -1
  259. package/docs/types/robotVacuumCleanerS1WebhookContext.html +1 -1
  260. package/docs/types/stripLightStatus.html +1 -1
  261. package/docs/types/stripLightWebhookContext.html +1 -1
  262. package/docs/types/waterLeakDetectorStatus.html +1 -1
  263. package/docs/types/waterLeakDetectorWebhookContext.html +1 -1
  264. package/docs/variables/parameterChecker.html +1 -0
  265. package/docs/variables/urls.html +1 -0
  266. package/package.json +6 -6
  267. package/dist/types/bledevicestatus.d.ts.map +0 -1
  268. package/dist/types/bledevicestatus.js +0 -2
  269. package/dist/types/bledevicestatus.js.map +0 -1
  270. package/dist/types/devicelist.d.ts +0 -90
  271. package/dist/types/devicelist.d.ts.map +0 -1
  272. package/dist/types/devicelist.js +0 -2
  273. package/dist/types/devicelist.js.map +0 -1
  274. package/dist/types/devicepush.d.ts +0 -13
  275. package/dist/types/devicepush.d.ts.map +0 -1
  276. package/dist/types/devicepush.js +0 -2
  277. package/dist/types/devicepush.js.map +0 -1
  278. package/dist/types/deviceresponse.d.ts +0 -12
  279. package/dist/types/deviceresponse.d.ts.map +0 -1
  280. package/dist/types/deviceresponse.js +0 -2
  281. package/dist/types/deviceresponse.js.map +0 -1
  282. package/dist/types/devicestatus.d.ts +0 -194
  283. package/dist/types/devicestatus.d.ts.map +0 -1
  284. package/dist/types/devicestatus.js +0 -3
  285. package/dist/types/devicestatus.js.map +0 -1
  286. package/dist/types/devicewebhookstatus.d.ts +0 -236
  287. package/dist/types/devicewebhookstatus.d.ts.map +0 -1
  288. package/dist/types/devicewebhookstatus.js +0 -2
  289. package/dist/types/devicewebhookstatus.js.map +0 -1
  290. package/dist/types/irdevicelist.d.ts +0 -10
  291. package/dist/types/irdevicelist.d.ts.map +0 -1
  292. package/dist/types/irdevicelist.js +0 -2
  293. package/dist/types/irdevicelist.js.map +0 -1
  294. package/docs/interfaces/bodyChange.html +0 -4
  295. package/docs/interfaces/device.html +0 -7
  296. package/docs/interfaces/deviceList.html +0 -2
  297. package/docs/interfaces/switchbot.html +0 -3
  298. package/docs/types/batteryCirculatorFan.html +0 -1
  299. package/docs/types/batteryCirculatorFanServiceData.html +0 -1
  300. package/docs/types/blindTiltServiceData.html +0 -1
  301. package/docs/types/botServiceData.html +0 -1
  302. package/docs/types/ceilingLightProServiceData.html +0 -1
  303. package/docs/types/ceilingLightServiceData.html +0 -1
  304. package/docs/types/colorBulbServiceData.html +0 -1
  305. package/docs/types/contactSensorServiceData.html +0 -1
  306. package/docs/types/curtain3ServiceData.html +0 -1
  307. package/docs/types/curtainServiceData.html +0 -1
  308. package/docs/types/hub2ServiceData.html +0 -1
  309. package/docs/types/humidifier2ServiceData.html +0 -1
  310. package/docs/types/humidifierServiceData.html +0 -1
  311. package/docs/types/keypadDetectorServiceData.html +0 -1
  312. package/docs/types/lockProServiceData.html +0 -1
  313. package/docs/types/lockServiceData.html +0 -1
  314. package/docs/types/meterPlusServiceData.html +0 -1
  315. package/docs/types/meterProCO2ServiceData.html +0 -1
  316. package/docs/types/meterProServiceData.html +0 -1
  317. package/docs/types/meterServiceData.html +0 -1
  318. package/docs/types/motionSensorServiceData.html +0 -1
  319. package/docs/types/outdoorMeterServiceData.html +0 -1
  320. package/docs/types/plugMiniJPServiceData.html +0 -1
  321. package/docs/types/plugMiniUSServiceData.html +0 -1
  322. package/docs/types/relaySwitch1PMServiceData.html +0 -1
  323. package/docs/types/relaySwitch1ServiceData.html +0 -1
  324. package/docs/types/remoteServiceData.html +0 -1
  325. package/docs/types/robotVacuumCleanerS1.html +0 -1
  326. package/docs/types/robotVacuumCleanerServiceData.html +0 -1
  327. package/docs/types/stripLightServiceData.html +0 -1
  328. package/docs/types/waterLeakDetectorServiceData.html +0 -1
  329. package/jest.config.js +0 -3
package/dist/device.js CHANGED
@@ -1,15 +1,52 @@
1
1
  import { Buffer } from 'node:buffer';
2
2
  import * as Crypto from 'node:crypto';
3
3
  import { EventEmitter } from 'node:events';
4
- import { parameterChecker } from './parameter-checker.js';
5
4
  import { CHAR_UUID_DEVICE, CHAR_UUID_NOTIFY, CHAR_UUID_WRITE, READ_TIMEOUT_MSEC, SERV_UUID_PRIMARY, WoSmartLockCommands, WoSmartLockProCommands, WRITE_TIMEOUT_MSEC } from './settings.js';
6
- const HUMIDIFIER_COMMAND_HEADER = '5701';
7
- const TURN_ON_KEY = `${HUMIDIFIER_COMMAND_HEADER}0101`;
8
- const TURN_OFF_KEY = `${HUMIDIFIER_COMMAND_HEADER}0102`;
9
- const INCREASE_KEY = `${HUMIDIFIER_COMMAND_HEADER}0103`;
10
- const DECREASE_KEY = `${HUMIDIFIER_COMMAND_HEADER}0104`;
11
- const SET_AUTO_MODE_KEY = `${HUMIDIFIER_COMMAND_HEADER}0105`;
12
- const SET_MANUAL_MODE_KEY = `${HUMIDIFIER_COMMAND_HEADER}0106`;
5
+ /**
6
+ * Command constants for various SwitchBot devices.
7
+ * Using readonly arrays to ensure immutability and better type safety.
8
+ */
9
+ const DEVICE_COMMANDS = {
10
+ BLIND_TILT: {
11
+ OPEN: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x32],
12
+ CLOSE_UP: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x64],
13
+ CLOSE_DOWN: [0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x00],
14
+ PAUSE: [0x57, 0x0F, 0x45, 0x01, 0x00, 0xFF],
15
+ },
16
+ BULB: {
17
+ BASE: [0x57, 0x0F, 0x47, 0x01],
18
+ READ_STATE: [0x57, 0x0F, 0x48, 0x01],
19
+ TURN_ON: [0x01, 0x01],
20
+ TURN_OFF: [0x01, 0x02],
21
+ SET_BRIGHTNESS: [0x02, 0x14],
22
+ SET_COLOR_TEMP: [0x02, 0x17],
23
+ SET_RGB: [0x02, 0x12],
24
+ },
25
+ HUMIDIFIER: {
26
+ HEADER: '5701',
27
+ TURN_ON: '570101',
28
+ TURN_OFF: '570102',
29
+ INCREASE: '570103',
30
+ DECREASE: '570104',
31
+ SET_AUTO_MODE: '570105',
32
+ SET_MANUAL_MODE: '570106',
33
+ },
34
+ // Common commands used across multiple devices
35
+ COMMON: {
36
+ POWER_ON: [0x57, 0x01, 0x01],
37
+ POWER_OFF: [0x57, 0x01, 0x02],
38
+ },
39
+ };
40
+ // Legacy constants for backward compatibility
41
+ const BLIND_TILT_COMMANDS = DEVICE_COMMANDS.BLIND_TILT;
42
+ const BULB_COMMANDS = DEVICE_COMMANDS.BULB;
43
+ const HUMIDIFIER_COMMAND_HEADER = DEVICE_COMMANDS.HUMIDIFIER.HEADER;
44
+ const TURN_ON_KEY = DEVICE_COMMANDS.HUMIDIFIER.TURN_ON;
45
+ const TURN_OFF_KEY = DEVICE_COMMANDS.HUMIDIFIER.TURN_OFF;
46
+ const INCREASE_KEY = DEVICE_COMMANDS.HUMIDIFIER.INCREASE;
47
+ const DECREASE_KEY = DEVICE_COMMANDS.HUMIDIFIER.DECREASE;
48
+ const SET_AUTO_MODE_KEY = DEVICE_COMMANDS.HUMIDIFIER.SET_AUTO_MODE;
49
+ const SET_MANUAL_MODE_KEY = DEVICE_COMMANDS.HUMIDIFIER.SET_MANUAL_MODE;
13
50
  export var SwitchBotModel;
14
51
  (function (SwitchBotModel) {
15
52
  SwitchBotModel["HubMini"] = "W0202200";
@@ -166,6 +203,176 @@ export var LogLevel;
166
203
  LogLevel["DEBUG"] = "debug";
167
204
  LogLevel["INFO"] = "info";
168
205
  })(LogLevel || (LogLevel = {}));
206
+ /**
207
+ * Utility class for comprehensive input validation with improved error messages.
208
+ */
209
+ export class ValidationUtils {
210
+ /**
211
+ * Validates percentage value (0-100).
212
+ * @param value - The value to validate
213
+ * @param paramName - The parameter name for error reporting
214
+ * @throws {RangeError} When value is not within valid range
215
+ * @throws {TypeError} When value is not a number
216
+ */
217
+ static validatePercentage(value, paramName = 'value') {
218
+ if (typeof value !== 'number' || Number.isNaN(value)) {
219
+ throw new TypeError(`${paramName} must be a valid number, got: ${value}`);
220
+ }
221
+ if (value < 0 || value > 100) {
222
+ throw new RangeError(`${paramName} must be between 0 and 100 inclusive, got: ${value}`);
223
+ }
224
+ }
225
+ /**
226
+ * Validates RGB color value (0-255).
227
+ * @param value - The color value to validate
228
+ * @param colorName - The color name for error reporting
229
+ * @throws {RangeError} When value is not within valid range
230
+ * @throws {TypeError} When value is not a number
231
+ */
232
+ static validateRGB(value, colorName = 'color') {
233
+ if (typeof value !== 'number' || Number.isNaN(value)) {
234
+ throw new TypeError(`${colorName} must be a valid number, got: ${value}`);
235
+ }
236
+ if (!Number.isInteger(value) || value < 0 || value > 255) {
237
+ throw new RangeError(`${colorName} must be an integer between 0 and 255 inclusive, got: ${value}`);
238
+ }
239
+ }
240
+ /**
241
+ * Validates buffer and throws descriptive error.
242
+ * @param buffer - The buffer to validate
243
+ * @param expectedLength - Optional expected length
244
+ * @param paramName - The parameter name for error reporting
245
+ * @throws {TypeError} When buffer is not a Buffer
246
+ * @throws {RangeError} When buffer length doesn't match expected
247
+ */
248
+ static validateBuffer(buffer, expectedLength, paramName = 'buffer') {
249
+ if (!Buffer.isBuffer(buffer)) {
250
+ throw new TypeError(`${paramName} must be a Buffer instance, got: ${typeof buffer}`);
251
+ }
252
+ if (expectedLength !== undefined && buffer.length !== expectedLength) {
253
+ throw new RangeError(`${paramName} must have exactly ${expectedLength} bytes, got: ${buffer.length} bytes`);
254
+ }
255
+ }
256
+ /**
257
+ * Validates string input with comprehensive checks.
258
+ * @param value - The value to validate
259
+ * @param paramName - The parameter name for error reporting
260
+ * @param minLength - Minimum required length
261
+ * @param maxLength - Optional maximum length
262
+ * @throws {TypeError} When value is not a string
263
+ * @throws {RangeError} When string length is invalid
264
+ */
265
+ static validateString(value, paramName = 'value', minLength = 1, maxLength) {
266
+ if (typeof value !== 'string') {
267
+ throw new TypeError(`${paramName} must be a string, got: ${typeof value}`);
268
+ }
269
+ if (value.length < minLength) {
270
+ throw new RangeError(`${paramName} must have at least ${minLength} character(s), got: ${value.length}`);
271
+ }
272
+ if (maxLength !== undefined && value.length > maxLength) {
273
+ throw new RangeError(`${paramName} must have at most ${maxLength} character(s), got: ${value.length}`);
274
+ }
275
+ }
276
+ /**
277
+ * Validates numeric range with enhanced checks.
278
+ * @param value - The value to validate
279
+ * @param min - Minimum allowed value
280
+ * @param max - Maximum allowed value
281
+ * @param paramName - The parameter name for error reporting
282
+ * @param mustBeInteger - Whether the value must be an integer
283
+ * @throws {TypeError} When value is not a number
284
+ * @throws {RangeError} When value is outside valid range
285
+ */
286
+ static validateRange(value, min, max, paramName = 'value', mustBeInteger = false) {
287
+ if (typeof value !== 'number' || Number.isNaN(value)) {
288
+ throw new TypeError(`${paramName} must be a valid number, got: ${value}`);
289
+ }
290
+ if (mustBeInteger && !Number.isInteger(value)) {
291
+ throw new TypeError(`${paramName} must be an integer, got: ${value}`);
292
+ }
293
+ if (value < min || value > max) {
294
+ throw new RangeError(`${paramName} must be between ${min} and ${max} inclusive, got: ${value}`);
295
+ }
296
+ }
297
+ /**
298
+ * Validates MAC address format.
299
+ * @param address - The MAC address to validate
300
+ * @param paramName - The parameter name for error reporting
301
+ * @throws {TypeError} When address is not a string
302
+ * @throws {Error} When address format is invalid
303
+ */
304
+ static validateMacAddress(address, paramName = 'address') {
305
+ if (typeof address !== 'string') {
306
+ throw new TypeError(`${paramName} must be a string`);
307
+ }
308
+ const macRegex = /^(?:[0-9A-F]{2}[:-]){5}[0-9A-F]{2}$|^[0-9A-F]{12}$/i;
309
+ if (!macRegex.test(address)) {
310
+ throw new Error(`${paramName} must be a valid MAC address format, got: ${address}`);
311
+ }
312
+ }
313
+ /**
314
+ * Validates that a value is one of the allowed enum values.
315
+ * @param value - The value to validate
316
+ * @param allowedValues - Array of allowed values
317
+ * @param paramName - The parameter name for error reporting
318
+ * @throws {Error} When value is not in allowed values
319
+ */
320
+ static validateEnum(value, allowedValues, paramName = 'value') {
321
+ if (!allowedValues.includes(value)) {
322
+ throw new Error(`${paramName} must be one of: ${allowedValues.join(', ')}, got: ${value}`);
323
+ }
324
+ }
325
+ }
326
+ /**
327
+ * Enhanced error handling utilities.
328
+ */
329
+ export class ErrorUtils {
330
+ /**
331
+ * Creates a timeout error with context.
332
+ * @param operation - The operation that timed out
333
+ * @param timeoutMs - The timeout duration in milliseconds
334
+ * @returns A descriptive timeout error
335
+ */
336
+ static createTimeoutError(operation, timeoutMs) {
337
+ return new Error(`Operation '${operation}' timed out after ${timeoutMs}ms`);
338
+ }
339
+ /**
340
+ * Creates a connection error with context.
341
+ * @param deviceId - The device ID that failed to connect
342
+ * @param cause - The underlying cause of the connection failure
343
+ * @returns A descriptive connection error
344
+ */
345
+ static createConnectionError(deviceId, cause) {
346
+ const message = `Failed to connect to device ${deviceId}`;
347
+ return cause ? new Error(`${message}: ${cause.message}`) : new Error(message);
348
+ }
349
+ /**
350
+ * Creates a command error with context.
351
+ * @param command - The command that failed
352
+ * @param deviceId - The device ID
353
+ * @param cause - The underlying cause
354
+ * @returns A descriptive command error
355
+ */
356
+ static createCommandError(command, deviceId, cause) {
357
+ const message = `Command '${command}' failed for device ${deviceId}`;
358
+ return cause ? new Error(`${message}: ${cause.message}`) : new Error(message);
359
+ }
360
+ /**
361
+ * Wraps an async operation with timeout and enhanced error handling.
362
+ * @param operation - The async operation to wrap
363
+ * @param timeoutMs - Timeout in milliseconds
364
+ * @param operationName - Name of the operation for error messages
365
+ * @returns Promise that resolves with the operation result or rejects with timeout
366
+ */
367
+ static async withTimeout(operation, timeoutMs, operationName) {
368
+ const timeoutPromise = new Promise((_, reject) => {
369
+ setTimeout(() => {
370
+ reject(this.createTimeoutError(operationName, timeoutMs));
371
+ }, timeoutMs);
372
+ });
373
+ return Promise.race([operation, timeoutPromise]);
374
+ }
375
+ }
169
376
  /**
170
377
  * Represents a Switchbot Device.
171
378
  */
@@ -345,8 +552,9 @@ export class SwitchbotDevice extends EventEmitter {
345
552
  * @param service The service to discover characteristics for.
346
553
  * @returns A Promise that resolves with the list of characteristics.
347
554
  */
348
- async discoverCharacteristics(service) {
349
- return await service.discoverCharacteristicsAsync([]);
555
+ // Discover characteristics without extra async/await
556
+ discoverCharacteristics(service) {
557
+ return service.discoverCharacteristicsAsync([]);
350
558
  }
351
559
  /**
352
560
  * Subscribes to the notify characteristic.
@@ -404,12 +612,20 @@ export class SwitchbotDevice extends EventEmitter {
404
612
  */
405
613
  async getDeviceName() {
406
614
  await this.internalConnect();
407
- if (!this.characteristics?.device) {
408
- throw new Error(`The device does not support the characteristic UUID 0x${CHAR_UUID_DEVICE}.`);
615
+ try {
616
+ if (!this.characteristics?.device) {
617
+ throw new Error(`Characteristic ${CHAR_UUID_DEVICE} not supported`);
618
+ }
619
+ const buf = await this.readCharacteristic(this.characteristics.device);
620
+ return buf.toString('utf8');
621
+ }
622
+ catch (error) {
623
+ const deviceContext = `device ${this.deviceId || 'unknown'}`;
624
+ throw ErrorUtils.createCommandError('getDeviceName', deviceContext, error);
625
+ }
626
+ finally {
627
+ await this.internalDisconnect();
409
628
  }
410
- const buf = await this.readCharacteristic(this.characteristics.device);
411
- await this.internalDisconnect();
412
- return buf.toString('utf8');
413
629
  }
414
630
  /**
415
631
  * Sets the device name.
@@ -417,17 +633,26 @@ export class SwitchbotDevice extends EventEmitter {
417
633
  * @returns A Promise that resolves when the name is set.
418
634
  */
419
635
  async setDeviceName(name) {
420
- const valid = parameterChecker.check({ name }, { name: { required: true, type: 'string', minBytes: 1, maxBytes: 100 } }, true);
421
- if (!valid) {
422
- throw new Error(parameterChecker.error.message);
636
+ ValidationUtils.validateString(name, 'name', 1);
637
+ // Additional validation for device name length
638
+ const nameBuffer = Buffer.from(name, 'utf8');
639
+ if (nameBuffer.length > 100) {
640
+ throw new RangeError('Device name cannot exceed 100 bytes when encoded as UTF-8');
423
641
  }
424
- const buf = Buffer.from(name, 'utf8');
425
642
  await this.internalConnect();
426
- if (!this.characteristics?.device) {
427
- throw new Error(`The device does not support the characteristic UUID 0x${CHAR_UUID_DEVICE}.`);
643
+ try {
644
+ if (!this.characteristics?.device) {
645
+ throw new Error(`Characteristic ${CHAR_UUID_DEVICE} not supported`);
646
+ }
647
+ await this.writeCharacteristic(this.characteristics.device, nameBuffer);
648
+ }
649
+ catch (error) {
650
+ const deviceContext = `device ${this.deviceId || 'unknown'}`;
651
+ throw ErrorUtils.createCommandError('setDeviceName', deviceContext, error);
652
+ }
653
+ finally {
654
+ await this.internalDisconnect();
428
655
  }
429
- await this.writeCharacteristic(this.characteristics.device, buf);
430
- await this.internalDisconnect();
431
656
  }
432
657
  /**
433
658
  * Sends a command to the device and awaits a response.
@@ -435,17 +660,24 @@ export class SwitchbotDevice extends EventEmitter {
435
660
  * @returns A Promise that resolves with the response buffer.
436
661
  */
437
662
  async command(reqBuf) {
438
- if (!Buffer.isBuffer(reqBuf)) {
439
- throw new TypeError('The specified data is not acceptable for writing.');
440
- }
663
+ ValidationUtils.validateBuffer(reqBuf, undefined, 'reqBuf');
441
664
  await this.internalConnect();
442
665
  if (!this.characteristics?.write) {
443
- throw new Error('No characteristics available.');
666
+ throw new Error('No write characteristic available for command execution');
667
+ }
668
+ try {
669
+ await this.writeCharacteristic(this.characteristics.write, reqBuf);
670
+ const resBuf = await this.waitForCommandResponse();
671
+ return resBuf;
672
+ }
673
+ catch (error) {
674
+ const deviceContext = `device ${this.deviceId || 'unknown'}`;
675
+ // Use ErrorUtils for enriched error context
676
+ throw ErrorUtils.createCommandError('execute command', deviceContext, error);
677
+ }
678
+ finally {
679
+ await this.internalDisconnect();
444
680
  }
445
- await this.writeCharacteristic(this.characteristics.write, reqBuf);
446
- const resBuf = await this.waitForCommandResponse();
447
- await this.internalDisconnect();
448
- return resBuf;
449
681
  }
450
682
  /**
451
683
  * Waits for a response from the device after sending a command.
@@ -468,41 +700,33 @@ export class SwitchbotDevice extends EventEmitter {
468
700
  return await Promise.race([readPromise, timeoutPromise]);
469
701
  }
470
702
  /**
471
- * Reads data from a characteristic with a timeout.
703
+ * Reads data from a characteristic with enhanced timeout and error handling.
472
704
  * @param char The characteristic to read from.
473
705
  * @returns A Promise that resolves with the data buffer.
474
706
  */
475
707
  async readCharacteristic(char) {
476
- const timer = setTimeout(() => {
477
- throw new Error('READ_TIMEOUT');
478
- }, READ_TIMEOUT_MSEC);
479
708
  try {
480
- const result = await char.readAsync();
481
- clearTimeout(timer);
482
- return result;
709
+ return await ErrorUtils.withTimeout(char.readAsync(), READ_TIMEOUT_MSEC, `read characteristic ${char.uuid}`);
483
710
  }
484
711
  catch (error) {
485
- clearTimeout(timer);
486
- throw error;
712
+ const deviceContext = `device ${this.deviceId || 'unknown'}`;
713
+ throw ErrorUtils.createCommandError(`read characteristic ${char.uuid}`, deviceContext, error);
487
714
  }
488
715
  }
489
716
  /**
490
- * Writes data to a characteristic with a timeout.
717
+ * Writes data to a characteristic with enhanced timeout and error handling.
491
718
  * @param char The characteristic to write to.
492
719
  * @param buf The data buffer.
493
720
  * @returns A Promise that resolves when the write is complete.
494
721
  */
495
722
  async writeCharacteristic(char, buf) {
496
- const timer = setTimeout(() => {
497
- throw new Error('WRITE_TIMEOUT');
498
- }, WRITE_TIMEOUT_MSEC);
723
+ ValidationUtils.validateBuffer(buf, undefined, 'write buffer');
499
724
  try {
500
- await char.writeAsync(buf, false);
501
- clearTimeout(timer);
725
+ return await ErrorUtils.withTimeout(char.writeAsync(buf, false), WRITE_TIMEOUT_MSEC, `write to characteristic ${char.uuid}`);
502
726
  }
503
727
  catch (error) {
504
- clearTimeout(timer);
505
- throw error;
728
+ const deviceContext = `device ${this.deviceId || 'unknown'}`;
729
+ throw ErrorUtils.createCommandError(`write to characteristic ${char.uuid}`, deviceContext, error);
506
730
  }
507
731
  }
508
732
  }
@@ -556,10 +780,11 @@ export class Advertising {
556
780
  * Validates if the buffer is a valid Buffer object with a minimum length.
557
781
  *
558
782
  * @param {any} buffer - The buffer to validate.
783
+ * @param {number} minLength - The minimum required length.
559
784
  * @returns {boolean} - True if the buffer is valid, false otherwise.
560
785
  */
561
- static validateBuffer(buffer) {
562
- return buffer && Buffer.isBuffer(buffer) && buffer.length >= 3;
786
+ static validateBuffer(buffer, minLength = 3) {
787
+ return buffer && Buffer.isBuffer(buffer) && buffer.length >= minLength;
563
788
  }
564
789
  /**
565
790
  * Parses the service data based on the device model.
@@ -660,7 +885,7 @@ export class WoBlindTilt extends SwitchbotDevice {
660
885
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
661
886
  * @param {Function} emitLog - The function to emit log messages.
662
887
  * @param {boolean} [reverse] - Whether to reverse the tilt percentage.
663
- * @returns {Promise<blindTiltServiceData | null>} - The parsed data object or null if the data is invalid.
888
+ * @returns {Promise<BlindTiltServiceData | null>} - The parsed data object or null if the data is invalid.
664
889
  */
665
890
  static async parseServiceData(serviceData, manufacturerData, emitLog, reverse = false) {
666
891
  if (![5, 6].includes(manufacturerData.length)) {
@@ -696,21 +921,21 @@ export class WoBlindTilt extends SwitchbotDevice {
696
921
  * @returns {Promise<void>}
697
922
  */
698
923
  async open() {
699
- await this.operateBlindTilt([0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x32]);
924
+ await this.operateBlindTilt([...BLIND_TILT_COMMANDS.OPEN]);
700
925
  }
701
926
  /**
702
927
  * Closes the blind tilt up to the nearest endpoint.
703
928
  * @returns {Promise<void>}
704
929
  */
705
930
  async closeUp() {
706
- await this.operateBlindTilt([0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x64]);
931
+ await this.operateBlindTilt([...BLIND_TILT_COMMANDS.CLOSE_UP]);
707
932
  }
708
933
  /**
709
934
  * Closes the blind tilt down to the nearest endpoint.
710
935
  * @returns {Promise<void>}
711
936
  */
712
937
  async closeDown() {
713
- await this.operateBlindTilt([0x57, 0x0F, 0x45, 0x01, 0x05, 0xFF, 0x00]);
938
+ await this.operateBlindTilt([...BLIND_TILT_COMMANDS.CLOSE_DOWN]);
714
939
  }
715
940
  /**
716
941
  * Closes the blind tilt to the nearest endpoint.
@@ -794,7 +1019,7 @@ export class WoBlindTilt extends SwitchbotDevice {
794
1019
  * @returns {Promise<void>}
795
1020
  */
796
1021
  async pause() {
797
- await this.operateBlindTilt([0x57, 0x0F, 0x45, 0x01, 0x00, 0xFF]);
1022
+ await this.operateBlindTilt([...BLIND_TILT_COMMANDS.PAUSE]);
798
1023
  }
799
1024
  /**
800
1025
  * Runs the blind tilt to the specified position.
@@ -803,13 +1028,10 @@ export class WoBlindTilt extends SwitchbotDevice {
803
1028
  * @returns {Promise<void>}
804
1029
  */
805
1030
  async runToPos(percent, mode) {
806
- if (typeof percent !== 'number' || percent < 0 || percent > 100) {
807
- throw new RangeError('Percent must be a number between 0 and 100');
808
- }
809
- if (typeof mode !== 'number' || mode < 0 || mode > 1) {
810
- throw new RangeError('Mode must be a number between 0 and 1');
811
- }
812
- await this.operateBlindTilt([0x57, 0x0F, 0x45, 0x01, 0x05, mode, percent]);
1031
+ ValidationUtils.validatePercentage(percent, 'percent');
1032
+ ValidationUtils.validateRange(mode, 0, 1, 'mode', true);
1033
+ const adjustedPercent = this.reverse ? 100 - percent : percent;
1034
+ await this.operateBlindTilt([0x57, 0x0F, 0x45, 0x01, 0x05, mode, adjustedPercent]);
813
1035
  }
814
1036
  /**
815
1037
  * Sends a command to operate the blind tilt and handles the response.
@@ -835,7 +1057,7 @@ export class WoBulb extends SwitchbotDevice {
835
1057
  * @param {Buffer} serviceData - The service data buffer.
836
1058
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
837
1059
  * @param {Function} emitLog - The function to emit log messages.
838
- * @returns {Promise<colorBulbServiceData | null>} - Parsed service data or null if invalid.
1060
+ * @returns {Promise<ColorBulbServiceData | null>} - Parsed service data or null if invalid.
839
1061
  */
840
1062
  static async parseServiceData(serviceData, manufacturerData,
841
1063
  // eslint-disable-next-line unused-imports/no-unused-vars
@@ -876,7 +1098,7 @@ export class WoBulb extends SwitchbotDevice {
876
1098
  * @returns {Promise<boolean>} - Resolves with a boolean indicating whether the bulb is ON (true) or OFF (false).
877
1099
  */
878
1100
  async readState() {
879
- return this.operateBulb([0x57, 0x0F, 0x48, 0x01]);
1101
+ return this.operateBulb([...BULB_COMMANDS.READ_STATE]);
880
1102
  }
881
1103
  /**
882
1104
  * Sets the state of the bulb.
@@ -885,22 +1107,21 @@ export class WoBulb extends SwitchbotDevice {
885
1107
  * @private
886
1108
  */
887
1109
  async setState(reqByteArray) {
888
- const base = [0x57, 0x0F, 0x47, 0x01];
889
- return this.operateBulb(base.concat(reqByteArray));
1110
+ return this.operateBulb([...BULB_COMMANDS.BASE, ...reqByteArray]);
890
1111
  }
891
1112
  /**
892
1113
  * Turns on the bulb.
893
1114
  * @returns {Promise<boolean>} - Resolves with a boolean indicating whether the bulb is ON (true).
894
1115
  */
895
1116
  async turnOn() {
896
- return this.setState([0x01, 0x01]);
1117
+ return this.setState([...BULB_COMMANDS.TURN_ON]);
897
1118
  }
898
1119
  /**
899
1120
  * Turns off the bulb.
900
1121
  * @returns {Promise<boolean>} - Resolves with a boolean indicating whether the bulb is OFF (false).
901
1122
  */
902
1123
  async turnOff() {
903
- return this.setState([0x01, 0x02]);
1124
+ return this.setState([...BULB_COMMANDS.TURN_OFF]);
904
1125
  }
905
1126
  /**
906
1127
  * Sets the brightness of the bulb.
@@ -908,10 +1129,8 @@ export class WoBulb extends SwitchbotDevice {
908
1129
  * @returns {Promise<boolean>} - Resolves with a boolean indicating whether the operation was successful.
909
1130
  */
910
1131
  async setBrightness(brightness) {
911
- if (brightness < 0 || brightness > 100) {
912
- throw new RangeError('Brightness must be between 0 and 100');
913
- }
914
- return this.setState([0x02, 0x14, brightness]);
1132
+ ValidationUtils.validatePercentage(brightness, 'brightness');
1133
+ return this.setState([...BULB_COMMANDS.SET_BRIGHTNESS, brightness]);
915
1134
  }
916
1135
  /**
917
1136
  * Sets the color temperature of the bulb.
@@ -919,10 +1138,8 @@ export class WoBulb extends SwitchbotDevice {
919
1138
  * @returns {Promise<boolean>} - Resolves with a boolean indicating whether the operation was successful.
920
1139
  */
921
1140
  async setColorTemperature(color_temperature) {
922
- if (color_temperature < 0 || color_temperature > 100) {
923
- throw new RangeError('Color temperature must be between 0 and 100');
924
- }
925
- return this.setState([0x02, 0x17, color_temperature]);
1141
+ ValidationUtils.validatePercentage(color_temperature, 'color_temperature');
1142
+ return this.setState([...BULB_COMMANDS.SET_COLOR_TEMP, color_temperature]);
926
1143
  }
927
1144
  /**
928
1145
  * Sets the RGB color of the bulb.
@@ -933,10 +1150,11 @@ export class WoBulb extends SwitchbotDevice {
933
1150
  * @returns {Promise<boolean>} - Resolves with a boolean indicating whether the operation was successful.
934
1151
  */
935
1152
  async setRGB(brightness, red, green, blue) {
936
- if (brightness < 0 || brightness > 100 || red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) {
937
- throw new RangeError('Invalid RGB or brightness values');
938
- }
939
- return this.setState([0x02, 0x12, brightness, red, green, blue]);
1153
+ ValidationUtils.validatePercentage(brightness, 'brightness');
1154
+ ValidationUtils.validateRGB(red, 'red');
1155
+ ValidationUtils.validateRGB(green, 'green');
1156
+ ValidationUtils.validateRGB(blue, 'blue');
1157
+ return this.setState([...BULB_COMMANDS.SET_RGB, brightness, red, green, blue]);
940
1158
  }
941
1159
  /**
942
1160
  * Sends a command to the bulb.
@@ -966,7 +1184,7 @@ export class WoCeilingLight extends SwitchbotDevice {
966
1184
  * Parses the service data for WoCeilingLight.
967
1185
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
968
1186
  * @param {Function} emitLog - The function to emit log messages.
969
- * @returns {Promise<ceilingLightServiceData | null>} - Parsed service data or null if invalid.
1187
+ * @returns {Promise<CeilingLightServiceData | null>} - Parsed service data or null if invalid.
970
1188
  */
971
1189
  static async parseServiceData(manufacturerData, emitLog) {
972
1190
  if (manufacturerData.length !== 13) {
@@ -997,7 +1215,7 @@ export class WoCeilingLight extends SwitchbotDevice {
997
1215
  * Parses the service data for WoCeilingLight Pro.
998
1216
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
999
1217
  * @param {Function} emitLog - The function to emit log messages.
1000
- * @returns {Promise<ceilingLightProServiceData | null>} - Parsed service data or null if invalid.
1218
+ * @returns {Promise<CeilingLightProServiceData | null>} - Parsed service data or null if invalid.
1001
1219
  */
1002
1220
  static async parseServiceData_Pro(manufacturerData, emitLog) {
1003
1221
  if (manufacturerData.length !== 13) {
@@ -1123,7 +1341,7 @@ export class WoContact extends SwitchbotDevice {
1123
1341
  * Parses the service data for WoContact.
1124
1342
  * @param {Buffer} serviceData - The service data buffer.
1125
1343
  * @param {Function} emitLog - The function to emit log messages.
1126
- * @returns {Promise<contactSensorServiceData | null>} - Parsed service data or null if invalid.
1344
+ * @returns {Promise<ContactSensorServiceData | null>} - Parsed service data or null if invalid.
1127
1345
  */
1128
1346
  static async parseServiceData(serviceData, emitLog) {
1129
1347
  if (serviceData.length !== 9) {
@@ -1171,7 +1389,7 @@ export class WoCurtain extends SwitchbotDevice {
1171
1389
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
1172
1390
  * @param {Function} emitLog - The function to emit log messages.
1173
1391
  * @param {boolean} [reverse] - Whether to reverse the position.
1174
- * @returns {Promise<curtainServiceData | curtain3ServiceData | null>} - Parsed service data or null if invalid.
1392
+ * @returns {Promise<CurtainServiceData | Curtain3ServiceData | null>} - Parsed service data or null if invalid.
1175
1393
  */
1176
1394
  static async parseServiceData(serviceData, manufacturerData, emitLog, reverse = false) {
1177
1395
  if (![5, 6].includes(serviceData.length)) {
@@ -1299,7 +1517,7 @@ export class WoHand extends SwitchbotDevice {
1299
1517
  * Parses the service data for WoHand.
1300
1518
  * @param {Buffer} serviceData - The service data buffer.
1301
1519
  * @param {Function} emitLog - The function to emit log messages.
1302
- * @returns {Promise<botServiceData | null>} - Parsed service data or null if invalid.
1520
+ * @returns {Promise<BotServiceData | null>} - Parsed service data or null if invalid.
1303
1521
  */
1304
1522
  static async parseServiceData(serviceData, emitLog) {
1305
1523
  if (!serviceData || serviceData.length < 3) {
@@ -1378,7 +1596,7 @@ export class WoHub2 extends SwitchbotDevice {
1378
1596
  * Parses the service data for WoHub2.
1379
1597
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
1380
1598
  * @param {Function} emitLog - The function to emit log messages.
1381
- * @returns {Promise<hub2ServiceData | null>} - Parsed service data or null if invalid.
1599
+ * @returns {Promise<Hub2ServiceData | null>} - Parsed service data or null if invalid.
1382
1600
  */
1383
1601
  static async parseServiceData(manufacturerData, emitLog) {
1384
1602
  if (manufacturerData.length !== 16) {
@@ -1418,7 +1636,7 @@ export class WoHumi extends SwitchbotDevice {
1418
1636
  * Parses the service data for WoHumi.
1419
1637
  * @param {Buffer} serviceData - The service data buffer.
1420
1638
  * @param {Function} emitLog - The function to emit log messages.
1421
- * @returns {Promise<humidifierServiceData | null>} - Parsed service data or null if invalid.
1639
+ * @returns {Promise<HumidifierServiceData | null>} - Parsed service data or null if invalid.
1422
1640
  */
1423
1641
  static async parseServiceData(serviceData, emitLog) {
1424
1642
  if (serviceData.length !== 8) {
@@ -1521,7 +1739,7 @@ export class WoHumi2 extends SwitchbotDevice {
1521
1739
  * Parses the service data for WoHumi.
1522
1740
  * @param {Buffer} serviceData - The service data buffer.
1523
1741
  * @param {Function} emitLog - The function to emit log messages.
1524
- * @returns {Promise<humidifier2ServiceData | null>} - Parsed service data or null if invalid.
1742
+ * @returns {Promise<Humidifier2ServiceData | null>} - Parsed service data or null if invalid.
1525
1743
  */
1526
1744
  static async parseServiceData(serviceData, emitLog) {
1527
1745
  if (serviceData.length !== 8) {
@@ -1644,7 +1862,7 @@ export class WoIOSensorTH extends SwitchbotDevice {
1644
1862
  * @param {Buffer} serviceData - The service data buffer.
1645
1863
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
1646
1864
  * @param {Function} emitLog - The function to emit log messages.
1647
- * @returns {Promise<outdoorMeterServiceData | null>} - Parsed service data or null if invalid.
1865
+ * @returns {Promise<OutdoorMeterServiceData | null>} - Parsed service data or null if invalid.
1648
1866
  */
1649
1867
  static async parseServiceData(serviceData, manufacturerData, emitLog) {
1650
1868
  if (serviceData.length !== 3) {
@@ -1689,7 +1907,7 @@ export class WoKeypad extends SwitchbotDevice {
1689
1907
  * @param {Buffer} serviceData - The service data buffer.
1690
1908
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
1691
1909
  * @param {Function} emitLog - The function to emit log messages.
1692
- * @returns {Promise<keypadDetectorServiceData | null>} - Parsed service data or null if invalid.
1910
+ * @returns {Promise<KeypadDetectorServiceData | null>} - Parsed service data or null if invalid.
1693
1911
  */
1694
1912
  static async parseServiceData(serviceData, manufacturerData, emitLog) {
1695
1913
  if (!serviceData || serviceData.length < 3) {
@@ -1738,7 +1956,7 @@ export class WoLeak extends SwitchbotDevice {
1738
1956
  * @param {Buffer} serviceData - The service data buffer.
1739
1957
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
1740
1958
  * @param {Function} emitLog - The function to emit log messages.
1741
- * @returns {Promise<waterLeakDetectorServiceData | null>} - Parsed service data or null if invalid.
1959
+ * @returns {Promise<WaterLeakDetectorServiceData | null>} - Parsed service data or null if invalid.
1742
1960
  */
1743
1961
  static async parseServiceData(serviceData, manufacturerData, emitLog) {
1744
1962
  if (!serviceData || serviceData.length < 3) {
@@ -1781,7 +1999,7 @@ export class WoPlugMiniJP extends SwitchbotDevice {
1781
1999
  * Parses the service data for WoPlugMini JP.
1782
2000
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
1783
2001
  * @param {Function} emitLog - The function to emit log messages.
1784
- * @returns {Promise<plugMiniJPServiceData | null>} - Parsed service data or null if invalid.
2002
+ * @returns {Promise<PlugMiniJPServiceData | null>} - Parsed service data or null if invalid.
1785
2003
  */
1786
2004
  static async parseServiceData(manufacturerData, emitLog) {
1787
2005
  if (manufacturerData.length !== 14) {
@@ -1887,7 +2105,7 @@ export class WoPlugMiniUS extends SwitchbotDevice {
1887
2105
  * Parses the service data for WoPlugMini US.
1888
2106
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
1889
2107
  * @param {Function} emitLog - The function to emit log messages.
1890
- * @returns {Promise<plugMiniUSServiceData | null>} - Parsed service data or null if invalid.
2108
+ * @returns {Promise<PlugMiniUSServiceData | null>} - Parsed service data or null if invalid.
1891
2109
  */
1892
2110
  static async parseServiceData(manufacturerData, emitLog) {
1893
2111
  if (manufacturerData.length !== 14) {
@@ -1990,7 +2208,7 @@ export class WoPresence extends SwitchbotDevice {
1990
2208
  * Parses the service data for WoPresence.
1991
2209
  * @param {Buffer} serviceData - The service data buffer.
1992
2210
  * @param {Function} emitLog - The function to emit log messages.
1993
- * @returns {Promise<motionSensorServiceData | null>} - Parsed service data or null if invalid.
2211
+ * @returns {Promise<MotionSensorServiceData | null>} - Parsed service data or null if invalid.
1994
2212
  */
1995
2213
  static async parseServiceData(serviceData, emitLog) {
1996
2214
  if (serviceData.length !== 6) {
@@ -2030,7 +2248,7 @@ export class WoRelaySwitch1 extends SwitchbotDevice {
2030
2248
  * @param {Buffer} serviceData - The service data buffer.
2031
2249
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
2032
2250
  * @param {Function} emitLog - The function to emit log messages.
2033
- * @returns {Promise<relaySwitch1ServiceData | null>} - Parsed service data or null if invalid.
2251
+ * @returns {Promise<RelaySwitch1ServiceData | null>} - Parsed service data or null if invalid.
2034
2252
  */
2035
2253
  static async parseServiceData(serviceData, manufacturerData, emitLog) {
2036
2254
  if (serviceData.length < 8 || manufacturerData.length === null) {
@@ -2087,7 +2305,7 @@ export class WoRelaySwitch1PM extends SwitchbotDevice {
2087
2305
  * @param {Buffer} serviceData - The service data buffer.
2088
2306
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
2089
2307
  * @param {Function} emitLog - The function to emit log messages.
2090
- * @returns {Promise<relaySwitch1PMServiceData | null>} - Parsed service data or null if invalid.
2308
+ * @returns {Promise<RelaySwitch1PMServiceData | null>} - Parsed service data or null if invalid.
2091
2309
  */
2092
2310
  static async parseServiceData(serviceData, manufacturerData, emitLog) {
2093
2311
  if (serviceData.length < 8 || manufacturerData.length === 0) {
@@ -2143,7 +2361,7 @@ export class WoRemote extends SwitchbotDevice {
2143
2361
  * Parses the service data for WoRemote.
2144
2362
  * @param {Buffer} serviceData - The service data buffer.
2145
2363
  * @param {Function} emitLog - The function to emit log messages.
2146
- * @returns {Promise<remoteServiceData | null>} - Parsed service data or null if invalid.
2364
+ * @returns {Promise<RemoteServiceData | null>} - Parsed service data or null if invalid.
2147
2365
  */
2148
2366
  static async parseServiceData(serviceData, emitLog) {
2149
2367
  if (serviceData.length !== 9) {
@@ -2368,7 +2586,7 @@ export class WoSmartLock extends SwitchbotDevice {
2368
2586
  * @param {Buffer} serviceData - The service data buffer.
2369
2587
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
2370
2588
  * @param {Function} emitLog - The function to emit log messages.
2371
- * @returns {Promise<lockServiceData | null>} - Parsed service data or null if invalid.
2589
+ * @returns {Promise<LockServiceData | null>} - Parsed service data or null if invalid.
2372
2590
  */
2373
2591
  static async parseServiceData(serviceData, manufacturerData, emitLog) {
2374
2592
  if (manufacturerData.length < 11) {
@@ -2560,7 +2778,7 @@ export class WoSmartLockPro extends SwitchbotDevice {
2560
2778
  * @param {Buffer} serviceData - The service data buffer.
2561
2779
  * @param {Buffer} manufacturerData - The manufacturer data buffer.
2562
2780
  * @param {Function} emitLog - The function to emit log messages.
2563
- * @returns {Promise<lockProServiceData | null>} - Parsed service data or null if invalid.
2781
+ * @returns {Promise<LockProServiceData | null>} - Parsed service data or null if invalid.
2564
2782
  */
2565
2783
  static async parseServiceData(serviceData, manufacturerData, emitLog) {
2566
2784
  if (manufacturerData.length < 11) {
@@ -2724,7 +2942,7 @@ export class WoStrip extends SwitchbotDevice {
2724
2942
  * Parses the service data from the SwitchBot Strip Light.
2725
2943
  * @param {Buffer} serviceData - The service data buffer.
2726
2944
  * @param {Function} emitLog - The function to emit log messages.
2727
- * @returns {Promise<stripLightServiceData | null>} - Parsed service data or null if invalid.
2945
+ * @returns {Promise<StripLightServiceData | null>} - Parsed service data or null if invalid.
2728
2946
  */
2729
2947
  static async parseServiceData(serviceData, emitLog) {
2730
2948
  if (serviceData.length !== 18) {
@@ -2750,6 +2968,7 @@ export class WoStrip extends SwitchbotDevice {
2750
2968
  red: byte3,
2751
2969
  green: byte4,
2752
2970
  blue: byte5,
2971
+ color_temperature: 0, // Add a default value or extract from serviceData if available
2753
2972
  delay: byte8 & 0b10000000,
2754
2973
  preset: byte8 & 0b00001000,
2755
2974
  color_mode: byte8 & 0b00000111,