node-switchbot 4.0.0-beta.0 → 4.0.0-beta.10

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 (247) hide show
  1. package/.github/copilot-instructions.md +19 -5
  2. package/BLE.md +117 -4
  3. package/CHANGELOG.md +45 -0
  4. package/README.md +7 -1
  5. package/dist/api.d.ts +3 -3
  6. package/dist/api.d.ts.map +1 -1
  7. package/dist/api.js +9 -6
  8. package/dist/api.js.map +1 -1
  9. package/dist/ble.d.ts +38 -4
  10. package/dist/ble.d.ts.map +1 -1
  11. package/dist/ble.js +409 -53
  12. package/dist/ble.js.map +1 -1
  13. package/dist/devices/base.d.ts +83 -5
  14. package/dist/devices/base.d.ts.map +1 -1
  15. package/dist/devices/base.js +371 -34
  16. package/dist/devices/base.js.map +1 -1
  17. package/dist/devices/device-override-state-during-connection.d.ts +27 -0
  18. package/dist/devices/device-override-state-during-connection.d.ts.map +1 -0
  19. package/dist/devices/device-override-state-during-connection.js +45 -0
  20. package/dist/devices/device-override-state-during-connection.js.map +1 -0
  21. package/dist/devices/index.d.ts +4 -0
  22. package/dist/devices/index.d.ts.map +1 -1
  23. package/dist/devices/index.js +4 -0
  24. package/dist/devices/index.js.map +1 -1
  25. package/dist/devices/sequence-device.d.ts +36 -0
  26. package/dist/devices/sequence-device.d.ts.map +1 -0
  27. package/dist/devices/sequence-device.js +75 -0
  28. package/dist/devices/sequence-device.js.map +1 -0
  29. package/dist/devices/wo-air-purifier.d.ts +2 -2
  30. package/dist/devices/wo-air-purifier.d.ts.map +1 -1
  31. package/dist/devices/wo-air-purifier.js +2 -2
  32. package/dist/devices/wo-air-purifier.js.map +1 -1
  33. package/dist/devices/wo-bulb.d.ts +10 -0
  34. package/dist/devices/wo-bulb.d.ts.map +1 -1
  35. package/dist/devices/wo-bulb.js +69 -0
  36. package/dist/devices/wo-bulb.js.map +1 -1
  37. package/dist/devices/wo-curtain.d.ts +3 -3
  38. package/dist/devices/wo-curtain.d.ts.map +1 -1
  39. package/dist/devices/wo-curtain.js +12 -9
  40. package/dist/devices/wo-curtain.js.map +1 -1
  41. package/dist/devices/wo-hand.d.ts +53 -2
  42. package/dist/devices/wo-hand.d.ts.map +1 -1
  43. package/dist/devices/wo-hand.js +121 -3
  44. package/dist/devices/wo-hand.js.map +1 -1
  45. package/dist/devices/wo-lock-pro.d.ts +11 -2
  46. package/dist/devices/wo-lock-pro.d.ts.map +1 -1
  47. package/dist/devices/wo-lock-pro.js +65 -3
  48. package/dist/devices/wo-lock-pro.js.map +1 -1
  49. package/dist/devices/wo-lock.d.ts +7 -2
  50. package/dist/devices/wo-lock.d.ts.map +1 -1
  51. package/dist/devices/wo-lock.js +58 -3
  52. package/dist/devices/wo-lock.js.map +1 -1
  53. package/dist/devices/wo-plug-mini-us.d.ts +2 -2
  54. package/dist/devices/wo-plug-mini-us.d.ts.map +1 -1
  55. package/dist/devices/wo-plug-mini-us.js +2 -2
  56. package/dist/devices/wo-plug-mini-us.js.map +1 -1
  57. package/dist/devices/wo-relay-switch-1.d.ts +4 -2
  58. package/dist/devices/wo-relay-switch-1.d.ts.map +1 -1
  59. package/dist/devices/wo-relay-switch-1.js +36 -4
  60. package/dist/devices/wo-relay-switch-1.js.map +1 -1
  61. package/dist/devices/wo-relay-switch-2pm.d.ts +21 -0
  62. package/dist/devices/wo-relay-switch-2pm.d.ts.map +1 -0
  63. package/dist/devices/wo-relay-switch-2pm.js +39 -0
  64. package/dist/devices/wo-relay-switch-2pm.js.map +1 -0
  65. package/dist/devices/wo-rgbic-bulb.d.ts +29 -0
  66. package/dist/devices/wo-rgbic-bulb.d.ts.map +1 -0
  67. package/dist/devices/wo-rgbic-bulb.js +84 -0
  68. package/dist/devices/wo-rgbic-bulb.js.map +1 -0
  69. package/dist/index.d.ts +2 -0
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +2 -0
  72. package/dist/index.js.map +1 -1
  73. package/dist/settings.d.ts +17 -0
  74. package/dist/settings.d.ts.map +1 -1
  75. package/dist/settings.js +18 -1
  76. package/dist/settings.js.map +1 -1
  77. package/dist/switchbot.d.ts +7 -0
  78. package/dist/switchbot.d.ts.map +1 -1
  79. package/dist/switchbot.js +109 -40
  80. package/dist/switchbot.js.map +1 -1
  81. package/dist/types/ble.d.ts +20 -1
  82. package/dist/types/ble.d.ts.map +1 -1
  83. package/dist/types/ble.js.map +1 -1
  84. package/dist/types/device.d.ts +30 -3
  85. package/dist/types/device.d.ts.map +1 -1
  86. package/dist/types/index.d.ts +22 -0
  87. package/dist/types/index.d.ts.map +1 -1
  88. package/dist/types/index.js.map +1 -1
  89. package/dist/utils/bot-ble.d.ts +36 -0
  90. package/dist/utils/bot-ble.d.ts.map +1 -0
  91. package/dist/utils/bot-ble.js +109 -0
  92. package/dist/utils/bot-ble.js.map +1 -0
  93. package/dist/utils/circuit-breaker.d.ts +98 -0
  94. package/dist/utils/circuit-breaker.d.ts.map +1 -0
  95. package/dist/utils/circuit-breaker.js +187 -0
  96. package/dist/utils/circuit-breaker.js.map +1 -0
  97. package/dist/utils/connection-tracker.d.ts +66 -0
  98. package/dist/utils/connection-tracker.d.ts.map +1 -0
  99. package/dist/utils/connection-tracker.js +184 -0
  100. package/dist/utils/connection-tracker.js.map +1 -0
  101. package/dist/utils/fallback-handler.d.ts +68 -0
  102. package/dist/utils/fallback-handler.d.ts.map +1 -0
  103. package/dist/utils/fallback-handler.js +131 -0
  104. package/dist/utils/fallback-handler.js.map +1 -0
  105. package/dist/utils/index.d.ts +10 -0
  106. package/dist/utils/index.d.ts.map +1 -1
  107. package/dist/utils/index.js +41 -4
  108. package/dist/utils/index.js.map +1 -1
  109. package/dist/utils/retry.d.ts +55 -0
  110. package/dist/utils/retry.d.ts.map +1 -0
  111. package/dist/utils/retry.js +95 -0
  112. package/dist/utils/retry.js.map +1 -0
  113. package/docs/assets/hierarchy.js +1 -1
  114. package/docs/assets/navigation.js +1 -1
  115. package/docs/assets/search.js +1 -1
  116. package/docs/classes/APIError.html +2 -2
  117. package/docs/classes/APINotAvailableError.html +2 -2
  118. package/docs/classes/BLEConnection.html +16 -10
  119. package/docs/classes/BLENotAvailableError.html +2 -2
  120. package/docs/classes/BLEScanner.html +11 -9
  121. package/docs/classes/CommandFailedError.html +2 -2
  122. package/docs/classes/ConnectionTimeoutError.html +2 -2
  123. package/docs/classes/DeviceManager.html +13 -13
  124. package/docs/classes/DeviceNotFoundError.html +2 -2
  125. package/docs/classes/DeviceOverrideStateDuringConnection.html +56 -0
  126. package/docs/classes/DiscoveryError.html +2 -2
  127. package/docs/classes/OpenAPIClient.html +24 -24
  128. package/docs/classes/SequenceDevice.html +58 -0
  129. package/docs/classes/SwitchBot.html +12 -11
  130. package/docs/classes/SwitchBotDevice.html +43 -15
  131. package/docs/classes/SwitchBotError.html +2 -2
  132. package/docs/classes/ValidationError.html +2 -2
  133. package/docs/classes/WoAirPurifier.html +48 -18
  134. package/docs/classes/WoAirPurifierTable.html +48 -18
  135. package/docs/classes/WoBlindTilt.html +48 -20
  136. package/docs/classes/WoBulb.html +52 -19
  137. package/docs/classes/WoCeilingLight.html +52 -19
  138. package/docs/classes/WoContact.html +42 -14
  139. package/docs/classes/WoCurtain.html +46 -18
  140. package/docs/classes/WoHand.html +63 -19
  141. package/docs/classes/WoHub2.html +42 -14
  142. package/docs/classes/WoHub3.html +42 -14
  143. package/docs/classes/WoHumi.html +46 -18
  144. package/docs/classes/WoHumi2.html +46 -18
  145. package/docs/classes/WoIOSensorTH.html +42 -14
  146. package/docs/classes/WoKeypad.html +42 -14
  147. package/docs/classes/WoLeak.html +42 -14
  148. package/docs/classes/WoPlugMiniJP.html +45 -17
  149. package/docs/classes/WoPlugMiniUS.html +45 -17
  150. package/docs/classes/WoPresence.html +42 -14
  151. package/docs/classes/WoRelaySwitch1.html +47 -17
  152. package/docs/classes/WoRelaySwitch1PM.html +47 -17
  153. package/docs/classes/WoRemote.html +42 -14
  154. package/docs/classes/WoSensorTH.html +42 -14
  155. package/docs/classes/WoSensorTHPlus.html +42 -14
  156. package/docs/classes/WoSensorTHPro.html +42 -14
  157. package/docs/classes/WoSensorTHProCO2.html +42 -14
  158. package/docs/classes/WoSmartLock.html +49 -16
  159. package/docs/classes/WoSmartLockPro.html +52 -17
  160. package/docs/classes/WoStrip.html +52 -19
  161. package/docs/enums/LogLevel.html +2 -2
  162. package/docs/enums/SwitchBotBLEModel.html +2 -2
  163. package/docs/enums/SwitchBotBLEModelName.html +2 -2
  164. package/docs/functions/updateBaseURL.html +1 -1
  165. package/docs/hierarchy.html +1 -1
  166. package/docs/index.html +2 -2
  167. package/docs/interfaces/APICommandRequest.html +2 -2
  168. package/docs/interfaces/APICommandResponse.html +2 -2
  169. package/docs/interfaces/APIDevice.html +2 -2
  170. package/docs/interfaces/APIDeviceStatus.html +2 -2
  171. package/docs/interfaces/APIErrorResponse.html +2 -2
  172. package/docs/interfaces/APIResponse.html +2 -2
  173. package/docs/interfaces/AirPurifierCommands.html +2 -2
  174. package/docs/interfaces/AirPurifierServiceData.html +20 -5
  175. package/docs/interfaces/AirPurifierStatus.html +7 -7
  176. package/docs/interfaces/BLEAdvertisement.html +3 -2
  177. package/docs/interfaces/BLEScanOptions.html +5 -5
  178. package/docs/interfaces/BLEServiceData.html +22 -5
  179. package/docs/interfaces/BlindTiltCommands.html +2 -2
  180. package/docs/interfaces/BlindTiltServiceData.html +21 -5
  181. package/docs/interfaces/BlindTiltStatus.html +6 -6
  182. package/docs/interfaces/BotCommands.html +6 -2
  183. package/docs/interfaces/BotServiceData.html +20 -5
  184. package/docs/interfaces/BotStatus.html +6 -6
  185. package/docs/interfaces/BulbCommands.html +4 -2
  186. package/docs/interfaces/BulbServiceData.html +21 -5
  187. package/docs/interfaces/BulbStatus.html +6 -6
  188. package/docs/interfaces/CeilingLightCommands.html +4 -2
  189. package/docs/interfaces/CeilingLightServiceData.html +21 -5
  190. package/docs/interfaces/CeilingLightStatus.html +6 -6
  191. package/docs/interfaces/CommandResult.html +6 -6
  192. package/docs/interfaces/ContactServiceData.html +22 -5
  193. package/docs/interfaces/ContactStatus.html +6 -6
  194. package/docs/interfaces/CurtainCommands.html +2 -2
  195. package/docs/interfaces/CurtainServiceData.html +22 -5
  196. package/docs/interfaces/CurtainStatus.html +6 -6
  197. package/docs/interfaces/DeviceInfo.html +23 -13
  198. package/docs/interfaces/DeviceListResponse.html +2 -2
  199. package/docs/interfaces/DeviceStatus.html +6 -6
  200. package/docs/interfaces/DiscoveryOptions.html +7 -7
  201. package/docs/interfaces/HubServiceData.html +22 -5
  202. package/docs/interfaces/HubStatus.html +6 -6
  203. package/docs/interfaces/HumidifierCommands.html +2 -2
  204. package/docs/interfaces/HumidifierServiceData.html +23 -6
  205. package/docs/interfaces/HumidifierStatus.html +6 -6
  206. package/docs/interfaces/KeypadStatus.html +6 -6
  207. package/docs/interfaces/LeakServiceData.html +22 -5
  208. package/docs/interfaces/LeakStatus.html +6 -6
  209. package/docs/interfaces/LockCommands.html +6 -2
  210. package/docs/interfaces/LockServiceData.html +20 -6
  211. package/docs/interfaces/LockStatus.html +6 -6
  212. package/docs/interfaces/MeterServiceData.html +22 -5
  213. package/docs/interfaces/MeterStatus.html +6 -6
  214. package/docs/interfaces/MotionServiceData.html +22 -5
  215. package/docs/interfaces/MotionStatus.html +6 -6
  216. package/docs/interfaces/PlugCommands.html +2 -2
  217. package/docs/interfaces/PlugServiceData.html +21 -5
  218. package/docs/interfaces/PlugStatus.html +6 -6
  219. package/docs/interfaces/PresenceServiceData.html +22 -5
  220. package/docs/interfaces/PresenceStatus.html +6 -6
  221. package/docs/interfaces/RelaySwitchCommands.html +2 -2
  222. package/docs/interfaces/RelaySwitchServiceData.html +21 -5
  223. package/docs/interfaces/RelaySwitchStatus.html +6 -6
  224. package/docs/interfaces/RemoteStatus.html +6 -6
  225. package/docs/interfaces/SceneListResponse.html +2 -2
  226. package/docs/interfaces/StripCommands.html +4 -2
  227. package/docs/interfaces/StripServiceData.html +21 -5
  228. package/docs/interfaces/StripStatus.html +6 -6
  229. package/docs/interfaces/SwitchBotConfig.html +21 -9
  230. package/docs/interfaces/WebhookConfig.html +2 -2
  231. package/docs/interfaces/WebhookDetails.html +2 -2
  232. package/docs/interfaces/WebhookQueryResponse.html +2 -2
  233. package/docs/interfaces/WebhookSetupResponse.html +2 -2
  234. package/docs/media/BLE.md +117 -4
  235. package/docs/modules.html +1 -1
  236. package/docs/types/ConnectionType.html +1 -1
  237. package/docs/types/PhysicalDeviceType.html +1 -1
  238. package/docs/types/VirtualDeviceType.html +1 -1
  239. package/docs/variables/urls.html +1 -1
  240. package/package.json +12 -8
  241. package/tmp-switchbot-scan.mjs +79 -0
  242. package/todo/PYSWITCHBOT_COMPARISON.md +484 -0
  243. package/todo/README.md +68 -0
  244. package/todo/completed.md +134 -0
  245. package/todo/todo.md +296 -0
  246. package/tsconfig.build.json +17 -0
  247. package/PRODUCTION_READY.md +0 -135
@@ -0,0 +1,39 @@
1
+ /* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
+ *
3
+ * devices/wo-relay-switch-2pm.ts: SwitchBot v4.0.0 - Relay Switch 2PM Device
4
+ */
5
+ import { DEVICE_COMMANDS } from '../settings.js';
6
+ import { WoRelaySwitch1 } from './wo-relay-switch-1.js';
7
+ /**
8
+ * Relay Switch 2PM Device (2-channel with power monitoring)
9
+ * Extends Relay Switch 1 with channel-specific control
10
+ */
11
+ export class WoRelaySwitch2PM extends WoRelaySwitch1 {
12
+ /**
13
+ * Set channel 1 state
14
+ */
15
+ async setChannel1(state) {
16
+ const command = state
17
+ ? DEVICE_COMMANDS.RELAY.CHANNEL1_ON
18
+ : DEVICE_COMMANDS.RELAY.CHANNEL1_OFF;
19
+ const result = await this.sendCommand(command, `setChannel1:${state}`);
20
+ return result.success;
21
+ }
22
+ /**
23
+ * Set channel 2 state
24
+ */
25
+ async setChannel2(state) {
26
+ const command = state
27
+ ? DEVICE_COMMANDS.RELAY.CHANNEL2_ON
28
+ : DEVICE_COMMANDS.RELAY.CHANNEL2_OFF;
29
+ const result = await this.sendCommand(command, `setChannel2:${state}`);
30
+ return result.success;
31
+ }
32
+ /**
33
+ * Get device status (inherited, same as 1PM)
34
+ */
35
+ async getStatus() {
36
+ return super.getStatus();
37
+ }
38
+ }
39
+ //# sourceMappingURL=wo-relay-switch-2pm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wo-relay-switch-2pm.js","sourceRoot":"","sources":["../../src/devices/wo-relay-switch-2pm.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAEvD;;;GAGG;AACH,MAAM,OAAO,gBAAiB,SAAQ,cAAc;IAClD;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,KAAc;QAC9B,MAAM,OAAO,GAAG,KAAK;YACnB,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW;YACnC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,YAAY,CAAA;QAEtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,eAAe,KAAK,EAAE,CAAC,CAAA;QACtE,OAAO,MAAM,CAAC,OAAO,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,KAAc;QAC9B,MAAM,OAAO,GAAG,KAAK;YACnB,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW;YACnC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,YAAY,CAAA;QAEtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,eAAe,KAAK,EAAE,CAAC,CAAA;QACtE,OAAO,MAAM,CAAC,OAAO,CAAA;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,OAAO,KAAK,CAAC,SAAS,EAAE,CAAA;IAC1B,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ import type { RGBICBulbCommands, RGBICBulbStatus } from '../types/device.js';
2
+ import { WoBulb } from './wo-bulb.js';
3
+ /**
4
+ * RGBIC Bulb Device with segmented/multi-zone color control
5
+ * Supports individual LED segment control for addressable RGB+IC strips
6
+ */
7
+ export declare class WoRGBICBulb extends WoBulb implements RGBICBulbCommands {
8
+ private static readonly RGBIC_EFFECTS;
9
+ /**
10
+ * Set color for individual LED segment
11
+ * @param segmentId - Segment identifier (0-based index)
12
+ * @param red - Red value (0-255)
13
+ * @param green - Green value (0-255)
14
+ * @param blue - Blue value (0-255)
15
+ */
16
+ setSegmentColor(segmentId: number, red: number, green: number, blue: number): Promise<boolean>;
17
+ /**
18
+ * Set effect for individual LED segment
19
+ * @param segmentId - Segment identifier (0-based index)
20
+ * @param effectName - Effect name from RGBIC_EFFECTS
21
+ * @param speed - Effect speed (1-100, default: 50)
22
+ */
23
+ setSegmentEffect(segmentId: number, effectName: string, speed?: number): Promise<boolean>;
24
+ /**
25
+ * Get device status (inherited from WoBulb)
26
+ */
27
+ getStatus(): Promise<RGBICBulbStatus>;
28
+ }
29
+ //# sourceMappingURL=wo-rgbic-bulb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wo-rgbic-bulb.d.ts","sourceRoot":"","sources":["../../src/devices/wo-rgbic-bulb.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAG5E,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC;;;GAGG;AACH,qBAAa,WAAY,SAAQ,MAAO,YAAW,iBAAiB;IAClE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CA4BpC;IAED;;;;;;OAMG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAkBpG;;;;;OAKG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAoB3F;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;CAG5C"}
@@ -0,0 +1,84 @@
1
+ /* Copyright(C) 2024-2026, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
+ *
3
+ * devices/wo-rgbic-bulb.ts: SwitchBot v4.0.0 - RGBIC Color Bulb with Segmented Control
4
+ */
5
+ import { clamp } from '../utils/index.js';
6
+ import { WoBulb } from './wo-bulb.js';
7
+ /**
8
+ * RGBIC Bulb Device with segmented/multi-zone color control
9
+ * Supports individual LED segment control for addressable RGB+IC strips
10
+ */
11
+ export class WoRGBICBulb extends WoBulb {
12
+ static RGBIC_EFFECTS = {
13
+ // Standard effects (compatible with WoBulb)
14
+ christmas: 0x00,
15
+ candle: 0x01,
16
+ halloween: 0x02,
17
+ sunset: 0x03,
18
+ party: 0x04,
19
+ reading: 0x05,
20
+ rainbow: 0x06,
21
+ forest: 0x07,
22
+ ocean: 0x08,
23
+ spring: 0x09,
24
+ summer: 0x0A,
25
+ autumn: 0x0B,
26
+ winter: 0x0C,
27
+ aurora: 0x0D,
28
+ meteor: 0x0E,
29
+ firework: 0x0F,
30
+ breathe: 0x10,
31
+ pulse: 0x11,
32
+ flicker: 0x12,
33
+ pet: 0x13,
34
+ // RGBIC-specific effects
35
+ segment_cycle: 0x20,
36
+ segment_wave: 0x21,
37
+ segment_chase: 0x22,
38
+ segment_strobe: 0x23,
39
+ segment_twinkle: 0x24,
40
+ };
41
+ /**
42
+ * Set color for individual LED segment
43
+ * @param segmentId - Segment identifier (0-based index)
44
+ * @param red - Red value (0-255)
45
+ * @param green - Green value (0-255)
46
+ * @param blue - Blue value (0-255)
47
+ */
48
+ async setSegmentColor(segmentId, red, green, blue) {
49
+ const segId = clamp(segmentId, 0, 255);
50
+ const r = clamp(red, 0, 255);
51
+ const g = clamp(green, 0, 255);
52
+ const b = clamp(blue, 0, 255);
53
+ // Command format for segment color: varies by device
54
+ // Using extended command format: 0x57 0x0F 0x47 0x01 0x13 SEG_ID R G B
55
+ const bleCommand = [0x57, 0x0F, 0x47, 0x01, 0x13, segId, r, g, b];
56
+ const result = await this.sendCommand(bleCommand, 'setSegmentColor', `seg${segId}:${r}:${g}:${b}`);
57
+ return result.success;
58
+ }
59
+ /**
60
+ * Set effect for individual LED segment
61
+ * @param segmentId - Segment identifier (0-based index)
62
+ * @param effectName - Effect name from RGBIC_EFFECTS
63
+ * @param speed - Effect speed (1-100, default: 50)
64
+ */
65
+ async setSegmentEffect(segmentId, effectName, speed = 50) {
66
+ const effectId = WoRGBICBulb.RGBIC_EFFECTS[effectName.toLowerCase()];
67
+ if (effectId === undefined) {
68
+ throw new Error(`Unsupported RGBIC effect: ${effectName}`);
69
+ }
70
+ const segId = clamp(segmentId, 0, 255);
71
+ const effectSpeed = clamp(speed, 1, 100);
72
+ // Command format for segment effect: 0x57 0x0F 0x47 0x01 0x14 SEG_ID EFFECT_ID SPEED
73
+ const bleCommand = [0x57, 0x0F, 0x47, 0x01, 0x14, segId, effectId, effectSpeed];
74
+ const result = await this.sendCommand(bleCommand, 'setSegmentEffect', `seg${segId}:${effectName}:${effectSpeed}`);
75
+ return result.success;
76
+ }
77
+ /**
78
+ * Get device status (inherited from WoBulb)
79
+ */
80
+ async getStatus() {
81
+ return super.getStatus();
82
+ }
83
+ }
84
+ //# sourceMappingURL=wo-rgbic-bulb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wo-rgbic-bulb.js","sourceRoot":"","sources":["../../src/devices/wo-rgbic-bulb.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export { OpenAPIClient } from './api.js';
2
2
  export { BLEConnection, BLEScanner } from './ble.js';
3
3
  export { DeviceManager, SwitchBotDevice } from './devices/base.js';
4
+ export { DeviceOverrideStateDuringConnection } from './devices/device-override-state-during-connection.js';
5
+ export { SequenceDevice } from './devices/sequence-device.js';
4
6
  export { WoAirPurifier, WoAirPurifierTable, WoBlindTilt, WoBulb, WoCeilingLight, WoContact, WoCurtain, WoHand, WoHub2, WoHub3, WoHumi, WoHumi2, WoIOSensorTH, WoKeypad, WoLeak, WoPlugMiniJP, WoPlugMiniUS, WoPresence, WoRelaySwitch1, WoRelaySwitch1PM, WoRemote, WoSensorTH, WoSensorTHPlus, WoSensorTHPro, WoSensorTHProCO2, WoSmartLock, WoSmartLockPro, WoStrip, } from './devices/index.js';
5
7
  export { APIError, APINotAvailableError, BLENotAvailableError, CommandFailedError, ConnectionTimeoutError, DeviceNotFoundError, DiscoveryError, SwitchBotError, ValidationError, } from './errors.js';
6
8
  export { updateBaseURL, urls } from './settings.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,EACN,cAAc,EACd,SAAS,EACT,SAAS,EACT,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,OAAO,GACR,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG1C,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,aAAa,EACb,cAAc,EACd,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,QAAQ,EACR,eAAe,GAChB,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAE,mCAAmC,EAAE,MAAM,sDAAsD,CAAA;AAC1G,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,EACN,cAAc,EACd,SAAS,EACT,SAAS,EACT,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,OAAO,GACR,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG1C,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,aAAa,EACb,cAAc,EACd,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,QAAQ,EACR,eAAe,GAChB,MAAM,kBAAkB,CAAA"}
package/dist/index.js CHANGED
@@ -6,6 +6,8 @@
6
6
  export { OpenAPIClient } from './api.js';
7
7
  export { BLEConnection, BLEScanner } from './ble.js';
8
8
  export { DeviceManager, SwitchBotDevice } from './devices/base.js';
9
+ export { DeviceOverrideStateDuringConnection } from './devices/device-override-state-during-connection.js';
10
+ export { SequenceDevice } from './devices/sequence-device.js';
9
11
  export { WoAirPurifier, WoAirPurifierTable, WoBlindTilt, WoBulb, WoCeilingLight, WoContact, WoCurtain, WoHand, WoHub2, WoHub3, WoHumi, WoHumi2, WoIOSensorTH, WoKeypad, WoLeak, WoPlugMiniJP, WoPlugMiniUS, WoPresence, WoRelaySwitch1, WoRelaySwitch1PM, WoRemote, WoSensorTH, WoSensorTHPlus, WoSensorTHPro, WoSensorTHProCO2, WoSmartLock, WoSmartLockPro, WoStrip, } from './devices/index.js';
10
12
  export { APIError, APINotAvailableError, BLENotAvailableError, CommandFailedError, ConnectionTimeoutError, DeviceNotFoundError, DiscoveryError, SwitchBotError, ValidationError, } from './errors.js';
11
13
  export { updateBaseURL, urls } from './settings.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,EACN,cAAc,EACd,SAAS,EACT,SAAS,EACT,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,OAAO,GACR,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,EAAE,mCAAmC,EAAE,MAAM,sDAAsD,CAAA;AAC1G,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA;AAC7D,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,WAAW,EACX,MAAM,EACN,cAAc,EACd,SAAS,EACT,SAAS,EACT,MAAM,EACN,MAAM,EACN,MAAM,EACN,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,cAAc,EACd,OAAO,GACR,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA"}
@@ -42,6 +42,8 @@ export declare const DEVICE_COMMANDS: {
42
42
  readonly TURN_OFF: readonly [87, 1, 2];
43
43
  readonly DOWN: readonly [87, 1, 1];
44
44
  readonly UP: readonly [87, 1, 2];
45
+ readonly SET_MODE: readonly [87, 15, 71, 1];
46
+ readonly SET_LONG_PRESS: readonly [87, 15, 71, 3];
45
47
  };
46
48
  readonly CURTAIN: {
47
49
  readonly OPEN: readonly [87, 15, 69, 1, 5, 255, 0];
@@ -63,6 +65,7 @@ export declare const DEVICE_COMMANDS: {
63
65
  readonly SET_BRIGHTNESS: readonly [2, 20];
64
66
  readonly SET_COLOR_TEMP: readonly [2, 23];
65
67
  readonly SET_RGB: readonly [2, 18];
68
+ readonly SET_EFFECT: readonly [3];
66
69
  };
67
70
  readonly HUMIDIFIER: {
68
71
  readonly HEADER: "5701";
@@ -84,6 +87,13 @@ export declare const DEVICE_COMMANDS: {
84
87
  readonly TURN_OFF: readonly [87, 15, 80, 1, 2];
85
88
  readonly TOGGLE: readonly [87, 15, 80, 1, 0];
86
89
  };
90
+ readonly RELAY: {
91
+ readonly GET_BASIC_INFO: readonly [87, 2];
92
+ readonly CHANNEL1_ON: readonly [87, 15, 80, 1, 1];
93
+ readonly CHANNEL1_OFF: readonly [87, 15, 80, 1, 2];
94
+ readonly CHANNEL2_ON: readonly [87, 15, 80, 2, 1];
95
+ readonly CHANNEL2_OFF: readonly [87, 15, 80, 2, 2];
96
+ };
87
97
  readonly COMMON: {
88
98
  readonly POWER_ON: readonly [87, 1, 1];
89
99
  readonly POWER_OFF: readonly [87, 1, 2];
@@ -123,10 +133,17 @@ export declare const DEFAULTS: {
123
133
  readonly enableBLE: true;
124
134
  readonly enableFallback: true;
125
135
  readonly baseURL: "https://api.switch-bot.com";
136
+ readonly enableConnectionIntelligence: true;
137
+ readonly enableCircuitBreaker: true;
138
+ readonly enableRetry: true;
139
+ readonly maxRetryAttempts: 3;
140
+ readonly retryInitialDelayMs: 100;
141
+ readonly retryMaxDelayMs: 5000;
126
142
  };
127
143
  /**
128
144
  * Platform detection
129
145
  */
130
146
  export declare const IS_LINUX: boolean;
147
+ export declare const IS_MACOS: boolean;
131
148
  export declare const BLE_SUPPORTED: boolean;
132
149
  //# sourceMappingURL=settings.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,eAAO,MAAM,gBAAgB,+BAA+B,CAAA;AAC5D,eAAO,MAAM,WAAW,SAAS,CAAA;AAEjC,eAAO,MAAM,IAAI,EAAE;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAMhB,CAAA;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAKtD;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,qCAAqC,CAAA;AAClE,eAAO,MAAM,6BAA6B,qCAAqC,CAAA;AAC/E,eAAO,MAAM,8BAA8B,qCAAqC,CAAA;AAGhF,eAAO,MAAM,iBAAiB,yCAAyC,CAAA;AACvE,eAAO,MAAM,eAAe,yCAAyC,CAAA;AACrE,eAAO,MAAM,gBAAgB,yCAAyC,CAAA;AACtE,eAAO,MAAM,gBAAgB,yCAAyC,CAAA;AAEtE;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAQ,CAAA;AACrC,eAAO,MAAM,mBAAmB,QAAQ,CAAA;AACxC,eAAO,MAAM,mBAAmB,OAAO,CAAA;AACvC,eAAO,MAAM,iBAAiB,QAAQ,CAAA;AACtC,eAAO,MAAM,kBAAkB,QAAQ,CAAA;AAEvC;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoElB,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;CAGtB,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAqC1C,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA0C1C,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;;;CAQX,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,QAAQ,SAA+B,CAAA;AACpD,eAAO,MAAM,aAAa,SAAW,CAAA"}
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,eAAO,MAAM,gBAAgB,+BAA+B,CAAA;AAC5D,eAAO,MAAM,WAAW,SAAS,CAAA;AAEjC,eAAO,MAAM,IAAI,EAAE;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAMhB,CAAA;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAKtD;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,qCAAqC,CAAA;AAClE,eAAO,MAAM,6BAA6B,qCAAqC,CAAA;AAC/E,eAAO,MAAM,8BAA8B,qCAAqC,CAAA;AAGhF,eAAO,MAAM,iBAAiB,yCAAyC,CAAA;AACvE,eAAO,MAAM,eAAe,yCAAyC,CAAA;AACrE,eAAO,MAAM,gBAAgB,yCAAyC,CAAA;AACtE,eAAO,MAAM,gBAAgB,yCAAyC,CAAA;AAEtE;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAQ,CAAA;AACrC,eAAO,MAAM,mBAAmB,QAAQ,CAAA;AACxC,eAAO,MAAM,mBAAmB,OAAO,CAAA;AACvC,eAAO,MAAM,iBAAiB,QAAQ,CAAA;AACtC,eAAO,MAAM,kBAAkB,QAAQ,CAAA;AAEvC;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+ElB,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;CAGtB,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;CAIzB,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAqC1C,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA0C1C,CAAA;AAEV;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;CAaa,CAAA;AAElC;;GAEG;AACH,eAAO,MAAM,QAAQ,SAA+B,CAAA;AACpD,eAAO,MAAM,QAAQ,SAAgC,CAAA;AACrD,eAAO,MAAM,aAAa,SAAuB,CAAA"}
package/dist/settings.js CHANGED
@@ -54,6 +54,8 @@ export const DEVICE_COMMANDS = {
54
54
  TURN_OFF: [0x57, 0x01, 0x02],
55
55
  DOWN: [0x57, 0x01, 0x01],
56
56
  UP: [0x57, 0x01, 0x02],
57
+ SET_MODE: [0x57, 0x0F, 0x47, 0x01],
58
+ SET_LONG_PRESS: [0x57, 0x0F, 0x47, 0x03],
57
59
  },
58
60
  // Curtain (WoCurtain)
59
61
  CURTAIN: {
@@ -78,6 +80,7 @@ export const DEVICE_COMMANDS = {
78
80
  SET_BRIGHTNESS: [0x02, 0x14], // Add brightness byte
79
81
  SET_COLOR_TEMP: [0x02, 0x17], // Add temp bytes
80
82
  SET_RGB: [0x02, 0x12], // Add RGB bytes
83
+ SET_EFFECT: [0x03],
81
84
  },
82
85
  // Humidifier
83
86
  HUMIDIFIER: {
@@ -102,6 +105,13 @@ export const DEVICE_COMMANDS = {
102
105
  TURN_OFF: [0x57, 0x0F, 0x50, 0x01, 0x02],
103
106
  TOGGLE: [0x57, 0x0F, 0x50, 0x01, 0x00],
104
107
  },
108
+ RELAY: {
109
+ GET_BASIC_INFO: [0x57, 0x02],
110
+ CHANNEL1_ON: [0x57, 0x0F, 0x50, 0x01, 0x01],
111
+ CHANNEL1_OFF: [0x57, 0x0F, 0x50, 0x01, 0x02],
112
+ CHANNEL2_ON: [0x57, 0x0F, 0x50, 0x02, 0x01],
113
+ CHANNEL2_OFF: [0x57, 0x0F, 0x50, 0x02, 0x02],
114
+ },
105
115
  // Common commands
106
116
  COMMON: {
107
117
  POWER_ON: [0x57, 0x01, 0x01],
@@ -221,10 +231,17 @@ export const DEFAULTS = {
221
231
  enableBLE: true,
222
232
  enableFallback: true,
223
233
  baseURL: DEFAULT_BASE_URL,
234
+ enableConnectionIntelligence: true,
235
+ enableCircuitBreaker: true,
236
+ enableRetry: true,
237
+ maxRetryAttempts: 3,
238
+ retryInitialDelayMs: 100,
239
+ retryMaxDelayMs: 5000,
224
240
  };
225
241
  /**
226
242
  * Platform detection
227
243
  */
228
244
  export const IS_LINUX = process.platform === 'linux';
229
- export const BLE_SUPPORTED = IS_LINUX;
245
+ export const IS_MACOS = process.platform === 'darwin';
246
+ export const BLE_SUPPORTED = IS_LINUX || IS_MACOS;
230
247
  //# sourceMappingURL=settings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,7 @@ export declare class SwitchBot extends EventEmitter {
22
22
  private initialize;
23
23
  /**
24
24
  * Discover devices (BLE + OpenAPI)
25
+ * BLE discovery runs first, then API discovery to enable proper device matching
25
26
  */
26
27
  discover(options?: DiscoveryOptions): Promise<SwitchBotDevice[]>;
27
28
  /**
@@ -38,8 +39,14 @@ export declare class SwitchBot extends EventEmitter {
38
39
  private discoverAPI;
39
40
  /**
40
41
  * Handle API device discovery
42
+ * Tries to match with existing BLE devices and combines them into one entry
41
43
  */
42
44
  private handleAPIDiscovery;
45
+ /**
46
+ * Find matching BLE device for an API device
47
+ * Returns a BLE device if a good match is found
48
+ */
49
+ private findMatchingBLEDevice;
43
50
  /**
44
51
  * Create device instance
45
52
  */
@@ -1 +1 @@
1
- {"version":3,"file":"switchbot.d.ts","sourceRoot":"","sources":["../src/switchbot.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAkB,gBAAgB,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAEnG,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAiB,UAAU,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAwEjD;;GAEG;AACH,qBAAa,SAAU,SAAQ,YAAY;IACzC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,aAAa,CAAC,CAAe;IACrC,OAAO,CAAC,SAAS,CAAC,CAAe;IACjC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,WAAW,CAAQ;gBAEf,MAAM,GAAE,eAAoB;IAsBxC;;OAEG;IACH,OAAO,CAAC,UAAU;IAgDlB;;OAEG;IACG,QAAQ,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAmC1E;;OAEG;YACW,WAAW;IAuBzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwC1B;;OAEG;YACW,WAAW;IAkBzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAwC1B;;OAEG;IACH,OAAO,CAAC,YAAY;IA4BpB;;OAEG;IACH,IAAI,OAAO,IAAI,aAAa,CAE3B;IAED;;OAEG;IACH,aAAa,IAAI,UAAU,GAAG,SAAS;IAIvC;;OAEG;IACH,YAAY,IAAI,aAAa,GAAG,SAAS;IAIzC;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,eAAe,CAAC;IAItC;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAUlC;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAc/B"}
1
+ {"version":3,"file":"switchbot.d.ts","sourceRoot":"","sources":["../src/switchbot.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,KAAK,EAAkB,gBAAgB,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAEnG,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAiB,UAAU,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAwEjD;;GAEG;AACH,qBAAa,SAAU,SAAQ,YAAY;IACzC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,UAAU,CAAC,CAAY;IAC/B,OAAO,CAAC,aAAa,CAAC,CAAe;IACrC,OAAO,CAAC,SAAS,CAAC,CAAe;IACjC,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,WAAW,CAAQ;gBAEf,MAAM,GAAE,eAAoB;IA4BxC;;OAEG;IACH,OAAO,CAAC,UAAU;IAgDlB;;;OAGG;IACG,QAAQ,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAkC1E;;OAEG;YACW,WAAW;IAuBzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkD1B;;OAEG;YACW,WAAW;IAkBzB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAiD1B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAuC7B;;OAEG;IACH,OAAO,CAAC,YAAY;IAoCpB;;OAEG;IACH,IAAI,OAAO,IAAI,aAAa,CAE3B;IAED;;OAEG;IACH,aAAa,IAAI,UAAU,GAAG,SAAS;IAIvC;;OAEG;IACH,YAAY,IAAI,aAAa,GAAG,SAAS;IAIzC;;OAEG;IACH,SAAS,IAAI,QAAQ,CAAC,eAAe,CAAC;IAItC;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAUlC;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAc/B"}
package/dist/switchbot.js CHANGED
@@ -35,7 +35,7 @@ import { WoSensorTHPro } from './devices/wo-sensor-th-pro.js';
35
35
  import { WoSensorTH } from './devices/wo-sensor-th.js';
36
36
  import { WoStrip } from './devices/wo-strip.js';
37
37
  import { BLE_SUPPORTED, DEFAULTS, DEVICE_CLASS_MAP } from './settings.js';
38
- import { Logger } from './utils/index.js';
38
+ import { Logger, macToDeviceId } from './utils/index.js';
39
39
  /**
40
40
  * Device class registry
41
41
  */
@@ -93,6 +93,12 @@ export class SwitchBot extends EventEmitter {
93
93
  enableFallback: config.enableFallback ?? DEFAULTS.enableFallback,
94
94
  logLevel: config.logLevel ?? DEFAULTS.logLevel,
95
95
  noble: config.noble,
96
+ enableConnectionIntelligence: config.enableConnectionIntelligence ?? true,
97
+ enableCircuitBreaker: config.enableCircuitBreaker ?? true,
98
+ enableRetry: config.enableRetry ?? true,
99
+ maxRetryAttempts: config.maxRetryAttempts ?? 3,
100
+ retryInitialDelayMs: config.retryInitialDelayMs ?? 100,
101
+ retryMaxDelayMs: config.retryMaxDelayMs ?? 5000,
96
102
  };
97
103
  this.logger = new Logger('SwitchBot', this.config.logLevel);
98
104
  this.deviceManager = new DeviceManager(this.config.logLevel);
@@ -106,7 +112,7 @@ export class SwitchBot extends EventEmitter {
106
112
  // Initialize BLE if enabled and supported
107
113
  if (this.config.enableBLE) {
108
114
  if (!BLE_SUPPORTED) {
109
- this.logger.warn('BLE not supported on this platform (Linux only)');
115
+ this.logger.warn('BLE not supported on this platform (Linux/macOS only)');
110
116
  }
111
117
  else {
112
118
  try {
@@ -143,6 +149,7 @@ export class SwitchBot extends EventEmitter {
143
149
  }
144
150
  /**
145
151
  * Discover devices (BLE + OpenAPI)
152
+ * BLE discovery runs first, then API discovery to enable proper device matching
146
153
  */
147
154
  async discover(options = {}) {
148
155
  if (!this.initialized) {
@@ -150,19 +157,20 @@ export class SwitchBot extends EventEmitter {
150
157
  }
151
158
  const { scanBLE = !!this.bleScanner, fetchAPI = !!this.apiClient, timeout = this.config.scanTimeout, } = options;
152
159
  this.logger.info('Starting device discovery', { scanBLE, fetchAPI });
153
- const discoveries = [];
154
- // BLE discovery
160
+ // BLE discovery first (sequential)
155
161
  if (scanBLE && this.bleScanner) {
156
- discoveries.push(this.discoverBLE(timeout));
162
+ this.logger.info('Step 1: Starting BLE discovery...');
163
+ await this.discoverBLE(timeout);
164
+ this.logger.info('Step 1: BLE discovery complete');
157
165
  }
158
- // API discovery
166
+ // API discovery second (sequential)
159
167
  if (fetchAPI && this.apiClient) {
160
- discoveries.push(this.discoverAPI());
168
+ this.logger.info('Step 2: Starting API discovery...');
169
+ await this.discoverAPI();
170
+ this.logger.info('Step 2: API discovery complete');
161
171
  }
162
- // Wait for all discoveries
163
- await Promise.allSettled(discoveries);
164
172
  const devices = this.deviceManager.list();
165
- this.logger.info(`Discovery complete: ${devices.length} devices found`);
173
+ this.logger.info(`Discovery complete: ${devices.length} unique devices found`);
166
174
  this.emit('discovery-complete', devices);
167
175
  return devices;
168
176
  }
@@ -192,17 +200,25 @@ export class SwitchBot extends EventEmitter {
192
200
  * Handle BLE device discovery
193
201
  */
194
202
  handleBLEDiscovery(advertisement) {
195
- const { address, serviceData, rssi } = advertisement;
203
+ const { id: advertisementId, address, serviceData, rssi } = advertisement;
196
204
  const deviceType = serviceData.modelName;
205
+ const mac = typeof address === 'string' && address.length > 0 ? address : undefined;
206
+ const deviceId = mac ? macToDeviceId(mac) : advertisementId;
207
+ if (!deviceId) {
208
+ this.logger.warn(`Skipping ${deviceType} BLE discovery: no address or advertisement id`);
209
+ return;
210
+ }
197
211
  // Create device info
198
212
  const info = {
199
- id: address.replace(/:/g, '').toUpperCase(),
213
+ id: deviceId,
200
214
  name: deviceType,
201
215
  deviceType,
202
- mac: address,
216
+ mac,
217
+ bleId: advertisementId,
203
218
  connectionTypes: ['ble'],
204
219
  activeConnection: undefined,
205
220
  battery: serviceData.battery,
221
+ bleServiceData: serviceData,
206
222
  rssi,
207
223
  };
208
224
  // Check if device already exists (may have been discovered via API)
@@ -210,9 +226,10 @@ export class SwitchBot extends EventEmitter {
210
226
  if (device) {
211
227
  // Update existing device info
212
228
  device.updateInfo({
213
- mac: address,
229
+ mac: mac ?? device.getInfo().mac,
214
230
  connectionTypes: [...new Set([...device.getInfo().connectionTypes, 'ble'])],
215
231
  battery: serviceData.battery,
232
+ bleServiceData: serviceData,
216
233
  rssi,
217
234
  });
218
235
  this.logger.debug(`Updated device: ${info.name} (${info.id})`);
@@ -247,42 +264,86 @@ export class SwitchBot extends EventEmitter {
247
264
  }
248
265
  /**
249
266
  * Handle API device discovery
267
+ * Tries to match with existing BLE devices and combines them into one entry
250
268
  */
251
269
  handleAPIDiscovery(apiDevice) {
252
270
  const { deviceId, deviceName, deviceType, enableCloudService, hubDeviceId, version } = apiDevice;
253
- // Create device info
254
- const info = {
255
- id: deviceId,
256
- name: deviceName,
257
- deviceType,
258
- connectionTypes: ['api'],
259
- activeConnection: undefined,
260
- hubDeviceId,
261
- version,
262
- cloudServiceEnabled: enableCloudService,
263
- };
264
- // Check if device already exists (may have been discovered via BLE)
265
- let device = this.deviceManager.get(info.id);
266
- if (device) {
267
- // Update existing device info
268
- device.updateInfo({
271
+ this.logger.debug(`Processing API device: ${deviceName} (${deviceId}, type: ${deviceType})`);
272
+ // Try to find matching BLE device
273
+ // Strategy: look for BLE devices of the same type that haven't been fully populated yet
274
+ const matchedBLEDevice = this.findMatchingBLEDevice(deviceType, deviceName);
275
+ if (matchedBLEDevice) {
276
+ // Update existing BLE device with API information
277
+ const deviceId_internal = matchedBLEDevice.getId();
278
+ matchedBLEDevice.updateInfo({
269
279
  name: deviceName,
270
- connectionTypes: [...new Set([...device.getInfo().connectionTypes, 'api'])],
280
+ connectionTypes: [...new Set([...matchedBLEDevice.getInfo().connectionTypes, 'api'])],
271
281
  hubDeviceId,
272
282
  version,
273
283
  cloudServiceEnabled: enableCloudService,
274
284
  });
275
- this.logger.debug(`Updated device: ${info.name} (${info.id})`);
285
+ this.logger.info(`Matched API device to existing BLE device: ${deviceName} (${deviceId_internal})`);
286
+ this.emit('device-updated', matchedBLEDevice);
276
287
  }
277
288
  else {
278
- // Create new device
279
- device = this.createDevice(info);
280
- if (device) {
281
- this.deviceManager.add(device);
282
- this.emit('device-discovered', device);
283
- this.logger.info(`Discovered ${info.name} via API (${info.id})`);
289
+ // No matching BLE device found, create new API-only device
290
+ const info = {
291
+ id: deviceId,
292
+ name: deviceName,
293
+ deviceType,
294
+ connectionTypes: ['api'],
295
+ activeConnection: undefined,
296
+ hubDeviceId,
297
+ version,
298
+ cloudServiceEnabled: enableCloudService,
299
+ };
300
+ // Check if device already exists (shouldn't happen but safety check)
301
+ let device = this.deviceManager.get(info.id);
302
+ if (!device) {
303
+ device = this.createDevice(info);
304
+ if (device) {
305
+ this.deviceManager.add(device);
306
+ this.emit('device-discovered', device);
307
+ this.logger.info(`Discovered ${deviceName} via API only (${deviceId})`);
308
+ }
309
+ }
310
+ }
311
+ }
312
+ /**
313
+ * Find matching BLE device for an API device
314
+ * Returns a BLE device if a good match is found
315
+ */
316
+ findMatchingBLEDevice(apiDeviceType, apiDeviceName) {
317
+ // Get all BLE devices
318
+ const bleDevices = this.deviceManager.list().filter((device) => {
319
+ const info = device.getInfo();
320
+ return info.connectionTypes.includes('ble') && !info.connectionTypes.includes('api');
321
+ });
322
+ // Try exact device type match first
323
+ const typeMatches = bleDevices.filter(device => device.getDeviceType() === apiDeviceType);
324
+ if (typeMatches.length === 1) {
325
+ // If only one device of this type, it's likely a match
326
+ this.logger.debug(`Found exact type match for ${apiDeviceType}`);
327
+ return typeMatches[0];
328
+ }
329
+ if (typeMatches.length > 1) {
330
+ // If multiple devices of same type, try to match by name similarity
331
+ const nameMatch = typeMatches.find((device) => {
332
+ const devName = device.getName();
333
+ // Simple name comparison (could be enhanced)
334
+ return devName === apiDeviceName || devName.includes(apiDeviceName) || apiDeviceName.includes(devName);
335
+ });
336
+ if (nameMatch) {
337
+ this.logger.debug(`Found name match for ${apiDeviceName}`);
338
+ return nameMatch;
339
+ }
340
+ // No good name match, return the first one as fallback for single device
341
+ // (better to merge than to duplicate)
342
+ if (typeMatches.length === 1) {
343
+ return typeMatches[0];
284
344
  }
285
345
  }
346
+ return undefined;
286
347
  }
287
348
  /**
288
349
  * Create device instance
@@ -303,6 +364,14 @@ export class SwitchBot extends EventEmitter {
303
364
  bleConnection: this.bleConnection,
304
365
  apiClient: this.apiClient,
305
366
  enableFallback: this.config.enableFallback,
367
+ enableConnectionIntelligence: this.config.enableConnectionIntelligence,
368
+ enableCircuitBreaker: this.config.enableCircuitBreaker,
369
+ enableRetry: this.config.enableRetry,
370
+ retryConfig: {
371
+ maxAttempts: this.config.maxRetryAttempts,
372
+ initialDelayMs: this.config.retryInitialDelayMs,
373
+ maxDelayMs: this.config.retryMaxDelayMs,
374
+ },
306
375
  logLevel: this.config.logLevel,
307
376
  });
308
377
  }
@@ -363,8 +432,8 @@ export class SwitchBot extends EventEmitter {
363
432
  */
364
433
  async cleanup() {
365
434
  this.logger.info('Cleaning up');
366
- if (this.bleScanner?.isScanning()) {
367
- this.bleScanner.stopScan();
435
+ if (this.bleScanner) {
436
+ this.bleScanner.destroy();
368
437
  }
369
438
  if (this.bleConnection) {
370
439
  await this.bleConnection.disconnectAll();