@switchbot/homebridge-switchbot 4.3.2-beta.9 → 5.0.0-beta.1

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 (416) hide show
  1. package/.github/copilot-instructions.md +328 -0
  2. package/.github/workflows/beta-release.yml +8 -12
  3. package/.github/workflows/release.yml +57 -21
  4. package/README.md +13 -10
  5. package/config.schema.json +1 -12
  6. package/coverage/base.css +224 -0
  7. package/coverage/block-navigation.js +87 -0
  8. package/coverage/clover.xml +15847 -0
  9. package/coverage/coverage-final.json +42 -0
  10. package/coverage/docs/assets/dmt/dmt-component-data.js.html +85 -0
  11. package/coverage/docs/assets/dmt/dmt-components.js.html +286 -0
  12. package/coverage/docs/assets/dmt/index.html +131 -0
  13. package/coverage/docs/assets/hierarchy.js.html +85 -0
  14. package/coverage/docs/assets/icons.js.html +136 -0
  15. package/coverage/docs/assets/index.html +146 -0
  16. package/coverage/docs/assets/main.js.html +265 -0
  17. package/coverage/favicon.png +0 -0
  18. package/coverage/index.html +191 -0
  19. package/coverage/prettify.css +1 -0
  20. package/coverage/prettify.js +2 -0
  21. package/coverage/sort-arrow-sprite.png +0 -0
  22. package/coverage/sorter.js +196 -0
  23. package/coverage/src/device/blindtilt.ts.html +3238 -0
  24. package/coverage/src/device/bot.ts.html +2803 -0
  25. package/coverage/src/device/ceilinglight.ts.html +2338 -0
  26. package/coverage/src/device/colorbulb.ts.html +2824 -0
  27. package/coverage/src/device/contact.ts.html +1465 -0
  28. package/coverage/src/device/curtain.ts.html +2869 -0
  29. package/coverage/src/device/device.ts.html +2500 -0
  30. package/coverage/src/device/fan.ts.html +2242 -0
  31. package/coverage/src/device/hub.ts.html +1408 -0
  32. package/coverage/src/device/humidifier.ts.html +2116 -0
  33. package/coverage/src/device/index.html +416 -0
  34. package/coverage/src/device/iosensor.ts.html +1375 -0
  35. package/coverage/src/device/lightstrip.ts.html +2617 -0
  36. package/coverage/src/device/lock.ts.html +1963 -0
  37. package/coverage/src/device/meter.ts.html +1372 -0
  38. package/coverage/src/device/meterplus.ts.html +1384 -0
  39. package/coverage/src/device/meterpro.ts.html +1618 -0
  40. package/coverage/src/device/motion.ts.html +1264 -0
  41. package/coverage/src/device/plug.ts.html +1372 -0
  42. package/coverage/src/device/relayswitch.ts.html +2284 -0
  43. package/coverage/src/device/robotvacuumcleaner.ts.html +1810 -0
  44. package/coverage/src/device/waterdetector.ts.html +1294 -0
  45. package/coverage/src/homebridge-ui/index.html +116 -0
  46. package/coverage/src/homebridge-ui/server.ts.html +229 -0
  47. package/coverage/src/index.html +161 -0
  48. package/coverage/src/index.ts.html +124 -0
  49. package/coverage/src/irdevice/airconditioner.ts.html +1687 -0
  50. package/coverage/src/irdevice/airpurifier.ts.html +844 -0
  51. package/coverage/src/irdevice/camera.ts.html +475 -0
  52. package/coverage/src/irdevice/fan.ts.html +766 -0
  53. package/coverage/src/irdevice/index.html +251 -0
  54. package/coverage/src/irdevice/irdevice.ts.html +1117 -0
  55. package/coverage/src/irdevice/light.ts.html +826 -0
  56. package/coverage/src/irdevice/other.ts.html +2458 -0
  57. package/coverage/src/irdevice/tv.ts.html +1222 -0
  58. package/coverage/src/irdevice/vacuumcleaner.ts.html +466 -0
  59. package/coverage/src/irdevice/waterheater.ts.html +469 -0
  60. package/coverage/src/platform.ts.html +8776 -0
  61. package/coverage/src/settings.ts.html +934 -0
  62. package/coverage/src/utils.ts.html +2092 -0
  63. package/dist/{device → devices-hap}/airpurifier.d.ts +3 -3
  64. package/dist/devices-hap/airpurifier.d.ts.map +1 -0
  65. package/dist/devices-hap/airpurifier.js.map +1 -0
  66. package/dist/{device → devices-hap}/blindtilt.d.ts +3 -3
  67. package/dist/devices-hap/blindtilt.d.ts.map +1 -0
  68. package/dist/{device → devices-hap}/blindtilt.js +6 -1
  69. package/dist/devices-hap/blindtilt.js.map +1 -0
  70. package/dist/{device → devices-hap}/bot.d.ts +3 -3
  71. package/dist/devices-hap/bot.d.ts.map +1 -0
  72. package/dist/devices-hap/bot.js.map +1 -0
  73. package/dist/{device → devices-hap}/ceilinglight.d.ts +3 -3
  74. package/dist/devices-hap/ceilinglight.d.ts.map +1 -0
  75. package/dist/devices-hap/ceilinglight.js.map +1 -0
  76. package/dist/{device → devices-hap}/colorbulb.d.ts +3 -3
  77. package/dist/devices-hap/colorbulb.d.ts.map +1 -0
  78. package/dist/devices-hap/colorbulb.js.map +1 -0
  79. package/dist/{device → devices-hap}/contact.d.ts +3 -3
  80. package/dist/devices-hap/contact.d.ts.map +1 -0
  81. package/dist/devices-hap/contact.js.map +1 -0
  82. package/dist/{device → devices-hap}/curtain.d.ts +3 -3
  83. package/dist/devices-hap/curtain.d.ts.map +1 -0
  84. package/dist/{device → devices-hap}/curtain.js +32 -8
  85. package/dist/devices-hap/curtain.js.map +1 -0
  86. package/dist/{device → devices-hap}/device.d.ts +3 -3
  87. package/dist/devices-hap/device.d.ts.map +1 -0
  88. package/dist/{device → devices-hap}/device.js +10 -4
  89. package/dist/devices-hap/device.js.map +1 -0
  90. package/dist/{device → devices-hap}/fan.d.ts +3 -3
  91. package/dist/devices-hap/fan.d.ts.map +1 -0
  92. package/dist/devices-hap/fan.js.map +1 -0
  93. package/dist/{device → devices-hap}/hub.d.ts +5 -5
  94. package/dist/devices-hap/hub.d.ts.map +1 -0
  95. package/dist/{device → devices-hap}/hub.js +2 -1
  96. package/dist/devices-hap/hub.js.map +1 -0
  97. package/dist/{device → devices-hap}/humidifier.d.ts +3 -3
  98. package/dist/devices-hap/humidifier.d.ts.map +1 -0
  99. package/dist/devices-hap/humidifier.js.map +1 -0
  100. package/dist/{device → devices-hap}/iosensor.d.ts +3 -3
  101. package/dist/devices-hap/iosensor.d.ts.map +1 -0
  102. package/dist/devices-hap/iosensor.js.map +1 -0
  103. package/dist/{device → devices-hap}/lightstrip.d.ts +3 -3
  104. package/dist/devices-hap/lightstrip.d.ts.map +1 -0
  105. package/dist/devices-hap/lightstrip.js.map +1 -0
  106. package/dist/{device → devices-hap}/lock.d.ts +3 -3
  107. package/dist/devices-hap/lock.d.ts.map +1 -0
  108. package/dist/devices-hap/lock.js.map +1 -0
  109. package/dist/{device → devices-hap}/meter.d.ts +3 -3
  110. package/dist/devices-hap/meter.d.ts.map +1 -0
  111. package/dist/devices-hap/meter.js.map +1 -0
  112. package/dist/{device → devices-hap}/meterplus.d.ts +3 -3
  113. package/dist/devices-hap/meterplus.d.ts.map +1 -0
  114. package/dist/devices-hap/meterplus.js.map +1 -0
  115. package/dist/{device → devices-hap}/meterpro.d.ts +3 -3
  116. package/dist/devices-hap/meterpro.d.ts.map +1 -0
  117. package/dist/{device → devices-hap}/meterpro.js +16 -3
  118. package/dist/devices-hap/meterpro.js.map +1 -0
  119. package/dist/{device → devices-hap}/motion.d.ts +3 -3
  120. package/dist/devices-hap/motion.d.ts.map +1 -0
  121. package/dist/devices-hap/motion.js.map +1 -0
  122. package/dist/{device → devices-hap}/plug.d.ts +3 -3
  123. package/dist/devices-hap/plug.d.ts.map +1 -0
  124. package/dist/devices-hap/plug.js.map +1 -0
  125. package/dist/{device → devices-hap}/relayswitch.d.ts +3 -3
  126. package/dist/devices-hap/relayswitch.d.ts.map +1 -0
  127. package/dist/devices-hap/relayswitch.js.map +1 -0
  128. package/dist/{device → devices-hap}/robotvacuumcleaner.d.ts +3 -3
  129. package/dist/devices-hap/robotvacuumcleaner.d.ts.map +1 -0
  130. package/dist/devices-hap/robotvacuumcleaner.js.map +1 -0
  131. package/dist/{device → devices-hap}/waterdetector.d.ts +3 -3
  132. package/dist/devices-hap/waterdetector.d.ts.map +1 -0
  133. package/dist/devices-hap/waterdetector.js.map +1 -0
  134. package/dist/devices-matter/BaseMatterAccessory.d.ts +63 -0
  135. package/dist/devices-matter/BaseMatterAccessory.d.ts.map +1 -0
  136. package/dist/devices-matter/BaseMatterAccessory.js +100 -0
  137. package/dist/devices-matter/BaseMatterAccessory.js.map +1 -0
  138. package/dist/devices-matter/ColorLightAccessory.d.ts +18 -0
  139. package/dist/devices-matter/ColorLightAccessory.d.ts.map +1 -0
  140. package/dist/devices-matter/ColorLightAccessory.js +96 -0
  141. package/dist/devices-matter/ColorLightAccessory.js.map +1 -0
  142. package/dist/devices-matter/ColorTemperatureLightAccessory.d.ts +16 -0
  143. package/dist/devices-matter/ColorTemperatureLightAccessory.d.ts.map +1 -0
  144. package/dist/devices-matter/ColorTemperatureLightAccessory.js +83 -0
  145. package/dist/devices-matter/ColorTemperatureLightAccessory.js.map +1 -0
  146. package/dist/devices-matter/ContactSensorAccessory.d.ts +10 -0
  147. package/dist/devices-matter/ContactSensorAccessory.d.ts.map +1 -0
  148. package/dist/devices-matter/ContactSensorAccessory.js +31 -0
  149. package/dist/devices-matter/ContactSensorAccessory.js.map +1 -0
  150. package/dist/devices-matter/DimmableLightAccessory.d.ts +56 -0
  151. package/dist/devices-matter/DimmableLightAccessory.d.ts.map +1 -0
  152. package/dist/devices-matter/DimmableLightAccessory.js +170 -0
  153. package/dist/devices-matter/DimmableLightAccessory.js.map +1 -0
  154. package/dist/devices-matter/DoorLockAccessory.d.ts +12 -0
  155. package/dist/devices-matter/DoorLockAccessory.d.ts.map +1 -0
  156. package/dist/devices-matter/DoorLockAccessory.js +47 -0
  157. package/dist/devices-matter/DoorLockAccessory.js.map +1 -0
  158. package/dist/devices-matter/ExtendedColorLightAccessory.d.ts +19 -0
  159. package/dist/devices-matter/ExtendedColorLightAccessory.d.ts.map +1 -0
  160. package/dist/devices-matter/ExtendedColorLightAccessory.js +108 -0
  161. package/dist/devices-matter/ExtendedColorLightAccessory.js.map +1 -0
  162. package/dist/devices-matter/FanAccessory.d.ts +14 -0
  163. package/dist/devices-matter/FanAccessory.d.ts.map +1 -0
  164. package/dist/devices-matter/FanAccessory.js +73 -0
  165. package/dist/devices-matter/FanAccessory.js.map +1 -0
  166. package/dist/devices-matter/HumiditySensorAccessory.d.ts +10 -0
  167. package/dist/devices-matter/HumiditySensorAccessory.d.ts.map +1 -0
  168. package/dist/devices-matter/HumiditySensorAccessory.js +33 -0
  169. package/dist/devices-matter/HumiditySensorAccessory.js.map +1 -0
  170. package/dist/devices-matter/LeakSensorAccessory.d.ts +10 -0
  171. package/dist/devices-matter/LeakSensorAccessory.d.ts.map +1 -0
  172. package/dist/devices-matter/LeakSensorAccessory.js +30 -0
  173. package/dist/devices-matter/LeakSensorAccessory.js.map +1 -0
  174. package/dist/devices-matter/LightSensorAccessory.d.ts +10 -0
  175. package/dist/devices-matter/LightSensorAccessory.d.ts.map +1 -0
  176. package/dist/devices-matter/LightSensorAccessory.js +33 -0
  177. package/dist/devices-matter/LightSensorAccessory.js.map +1 -0
  178. package/dist/devices-matter/OccupancySensorAccessory.d.ts +10 -0
  179. package/dist/devices-matter/OccupancySensorAccessory.d.ts.map +1 -0
  180. package/dist/devices-matter/OccupancySensorAccessory.js +43 -0
  181. package/dist/devices-matter/OccupancySensorAccessory.js.map +1 -0
  182. package/dist/devices-matter/OnOffLightAccessory.d.ts +36 -0
  183. package/dist/devices-matter/OnOffLightAccessory.d.ts.map +1 -0
  184. package/dist/devices-matter/OnOffLightAccessory.js +117 -0
  185. package/dist/devices-matter/OnOffLightAccessory.js.map +1 -0
  186. package/dist/devices-matter/OnOffOutletAccessory.d.ts +12 -0
  187. package/dist/devices-matter/OnOffOutletAccessory.d.ts.map +1 -0
  188. package/dist/devices-matter/OnOffOutletAccessory.js +43 -0
  189. package/dist/devices-matter/OnOffOutletAccessory.js.map +1 -0
  190. package/dist/devices-matter/OnOffSwitchAccessory.d.ts +12 -0
  191. package/dist/devices-matter/OnOffSwitchAccessory.d.ts.map +1 -0
  192. package/dist/devices-matter/OnOffSwitchAccessory.js +43 -0
  193. package/dist/devices-matter/OnOffSwitchAccessory.js.map +1 -0
  194. package/dist/devices-matter/RoboticVacuumAccessory.d.ts +66 -0
  195. package/dist/devices-matter/RoboticVacuumAccessory.d.ts.map +1 -0
  196. package/dist/devices-matter/RoboticVacuumAccessory.js +402 -0
  197. package/dist/devices-matter/RoboticVacuumAccessory.js.map +1 -0
  198. package/dist/devices-matter/SmokeCOAlarmAccessory.d.ts +11 -0
  199. package/dist/devices-matter/SmokeCOAlarmAccessory.d.ts.map +1 -0
  200. package/dist/devices-matter/SmokeCOAlarmAccessory.js +49 -0
  201. package/dist/devices-matter/SmokeCOAlarmAccessory.js.map +1 -0
  202. package/dist/devices-matter/TemperatureSensorAccessory.d.ts +10 -0
  203. package/dist/devices-matter/TemperatureSensorAccessory.d.ts.map +1 -0
  204. package/dist/devices-matter/TemperatureSensorAccessory.js +33 -0
  205. package/dist/devices-matter/TemperatureSensorAccessory.js.map +1 -0
  206. package/dist/devices-matter/ThermostatAccessory.d.ts +17 -0
  207. package/dist/devices-matter/ThermostatAccessory.d.ts.map +1 -0
  208. package/dist/devices-matter/ThermostatAccessory.js +87 -0
  209. package/dist/devices-matter/ThermostatAccessory.js.map +1 -0
  210. package/dist/devices-matter/VenetianBlindAccessory.d.ts +17 -0
  211. package/dist/devices-matter/VenetianBlindAccessory.d.ts.map +1 -0
  212. package/dist/devices-matter/VenetianBlindAccessory.js +100 -0
  213. package/dist/devices-matter/VenetianBlindAccessory.js.map +1 -0
  214. package/dist/devices-matter/WindowBlindAccessory.d.ts +15 -0
  215. package/dist/devices-matter/WindowBlindAccessory.d.ts.map +1 -0
  216. package/dist/devices-matter/WindowBlindAccessory.js +81 -0
  217. package/dist/devices-matter/WindowBlindAccessory.js.map +1 -0
  218. package/dist/devices-matter/custom/PowerStripAccessory.d.ts +97 -0
  219. package/dist/devices-matter/custom/PowerStripAccessory.d.ts.map +1 -0
  220. package/dist/devices-matter/custom/PowerStripAccessory.js +265 -0
  221. package/dist/devices-matter/custom/PowerStripAccessory.js.map +1 -0
  222. package/dist/devices-matter/custom/index.d.ts +8 -0
  223. package/dist/devices-matter/custom/index.d.ts.map +1 -0
  224. package/dist/devices-matter/custom/index.js +8 -0
  225. package/dist/devices-matter/custom/index.js.map +1 -0
  226. package/dist/devices-matter/index.d.ts +29 -0
  227. package/dist/devices-matter/index.d.ts.map +1 -0
  228. package/dist/devices-matter/index.js +28 -0
  229. package/dist/devices-matter/index.js.map +1 -0
  230. package/dist/homebridge-ui/public/index.html +1 -1
  231. package/dist/index.d.ts.map +1 -1
  232. package/dist/index.js +7 -2
  233. package/dist/index.js.map +1 -1
  234. package/dist/index.test.js +2 -2
  235. package/dist/index.test.js.map +1 -1
  236. package/dist/irdevice/airconditioner.d.ts +3 -3
  237. package/dist/irdevice/airconditioner.d.ts.map +1 -1
  238. package/dist/irdevice/airconditioner.js.map +1 -1
  239. package/dist/irdevice/airpurifier.d.ts +3 -3
  240. package/dist/irdevice/airpurifier.d.ts.map +1 -1
  241. package/dist/irdevice/airpurifier.js.map +1 -1
  242. package/dist/irdevice/camera.d.ts +3 -3
  243. package/dist/irdevice/camera.d.ts.map +1 -1
  244. package/dist/irdevice/camera.js.map +1 -1
  245. package/dist/irdevice/fan.d.ts +3 -3
  246. package/dist/irdevice/fan.d.ts.map +1 -1
  247. package/dist/irdevice/fan.js.map +1 -1
  248. package/dist/irdevice/irdevice.d.ts +3 -3
  249. package/dist/irdevice/irdevice.d.ts.map +1 -1
  250. package/dist/irdevice/irdevice.js.map +1 -1
  251. package/dist/irdevice/light.d.ts +3 -3
  252. package/dist/irdevice/light.d.ts.map +1 -1
  253. package/dist/irdevice/light.js.map +1 -1
  254. package/dist/irdevice/other.d.ts +3 -3
  255. package/dist/irdevice/other.d.ts.map +1 -1
  256. package/dist/irdevice/other.js.map +1 -1
  257. package/dist/irdevice/tv.d.ts +3 -3
  258. package/dist/irdevice/tv.d.ts.map +1 -1
  259. package/dist/irdevice/tv.js.map +1 -1
  260. package/dist/irdevice/vacuumcleaner.d.ts +3 -3
  261. package/dist/irdevice/vacuumcleaner.d.ts.map +1 -1
  262. package/dist/irdevice/vacuumcleaner.js.map +1 -1
  263. package/dist/irdevice/waterheater.d.ts +3 -3
  264. package/dist/irdevice/waterheater.d.ts.map +1 -1
  265. package/dist/irdevice/waterheater.js.map +1 -1
  266. package/dist/{platform.d.ts → platform-hap.d.ts} +2 -2
  267. package/dist/platform-hap.d.ts.map +1 -0
  268. package/dist/{platform.js → platform-hap.js} +50 -32
  269. package/dist/platform-hap.js.map +1 -0
  270. package/dist/platform-matter.d.ts +75 -0
  271. package/dist/platform-matter.d.ts.map +1 -0
  272. package/dist/platform-matter.js +379 -0
  273. package/dist/platform-matter.js.map +1 -0
  274. package/dist/utils.d.ts +5 -0
  275. package/dist/utils.d.ts.map +1 -1
  276. package/dist/utils.js +43 -0
  277. package/dist/utils.js.map +1 -1
  278. package/dist/verifyconfig.test.d.ts +2 -0
  279. package/dist/verifyconfig.test.d.ts.map +1 -0
  280. package/dist/verifyconfig.test.js +167 -0
  281. package/dist/verifyconfig.test.js.map +1 -0
  282. package/docs/index.html +20 -11
  283. package/docs/variables/default.html +1 -1
  284. package/package.json +7 -7
  285. package/src/{device → devices-hap}/airpurifier.ts +2 -2
  286. package/src/{device → devices-hap}/blindtilt.ts +7 -3
  287. package/src/{device → devices-hap}/bot.ts +2 -2
  288. package/src/{device → devices-hap}/ceilinglight.ts +2 -2
  289. package/src/{device → devices-hap}/colorbulb.ts +2 -2
  290. package/src/{device → devices-hap}/contact.ts +2 -2
  291. package/src/{device → devices-hap}/curtain.ts +32 -10
  292. package/src/{device → devices-hap}/device.ts +12 -6
  293. package/src/{device → devices-hap}/fan.ts +2 -2
  294. package/src/{device → devices-hap}/hub.ts +7 -6
  295. package/src/{device → devices-hap}/humidifier.ts +2 -2
  296. package/src/{device → devices-hap}/iosensor.ts +2 -2
  297. package/src/{device → devices-hap}/lightstrip.ts +2 -2
  298. package/src/{device → devices-hap}/lock.ts +2 -2
  299. package/src/{device → devices-hap}/meter.ts +2 -2
  300. package/src/{device → devices-hap}/meterplus.ts +2 -2
  301. package/src/{device → devices-hap}/meterpro.ts +18 -5
  302. package/src/{device → devices-hap}/motion.ts +2 -2
  303. package/src/{device → devices-hap}/plug.ts +2 -2
  304. package/src/{device → devices-hap}/relayswitch.ts +2 -2
  305. package/src/{device → devices-hap}/robotvacuumcleaner.ts +2 -2
  306. package/src/{device → devices-hap}/waterdetector.ts +2 -2
  307. package/src/devices-matter/BaseMatterAccessory.ts +131 -0
  308. package/src/devices-matter/ColorLightAccessory.ts +113 -0
  309. package/src/devices-matter/ColorTemperatureLightAccessory.ts +98 -0
  310. package/src/devices-matter/ContactSensorAccessory.ts +37 -0
  311. package/src/devices-matter/DimmableLightAccessory.ts +196 -0
  312. package/src/devices-matter/DoorLockAccessory.ts +56 -0
  313. package/src/devices-matter/ExtendedColorLightAccessory.ts +127 -0
  314. package/src/devices-matter/FanAccessory.ts +87 -0
  315. package/src/devices-matter/HumiditySensorAccessory.ts +39 -0
  316. package/src/devices-matter/LeakSensorAccessory.ts +36 -0
  317. package/src/devices-matter/LightSensorAccessory.ts +39 -0
  318. package/src/devices-matter/OccupancySensorAccessory.ts +52 -0
  319. package/src/devices-matter/OnOffLightAccessory.ts +133 -0
  320. package/src/devices-matter/OnOffOutletAccessory.ts +52 -0
  321. package/src/devices-matter/OnOffSwitchAccessory.ts +52 -0
  322. package/src/devices-matter/RoboticVacuumAccessory.ts +484 -0
  323. package/src/devices-matter/SmokeCOAlarmAccessory.ts +59 -0
  324. package/src/devices-matter/TemperatureSensorAccessory.ts +39 -0
  325. package/src/devices-matter/ThermostatAccessory.ts +105 -0
  326. package/src/devices-matter/VenetianBlindAccessory.ts +118 -0
  327. package/src/devices-matter/WindowBlindAccessory.ts +94 -0
  328. package/src/devices-matter/custom/PowerStripAccessory.ts +309 -0
  329. package/src/devices-matter/custom/index.ts +8 -0
  330. package/src/devices-matter/index.ts +29 -0
  331. package/src/homebridge-ui/public/index.html +1 -1
  332. package/src/index.test.ts +2 -2
  333. package/src/index.ts +7 -2
  334. package/src/irdevice/airconditioner.ts +2 -2
  335. package/src/irdevice/airpurifier.ts +2 -2
  336. package/src/irdevice/camera.ts +2 -2
  337. package/src/irdevice/fan.ts +2 -2
  338. package/src/irdevice/irdevice.ts +2 -2
  339. package/src/irdevice/light.ts +2 -2
  340. package/src/irdevice/other.ts +2 -2
  341. package/src/irdevice/tv.ts +2 -2
  342. package/src/irdevice/vacuumcleaner.ts +2 -2
  343. package/src/irdevice/waterheater.ts +2 -2
  344. package/src/{platform.ts → platform-hap.ts} +47 -31
  345. package/src/platform-matter.ts +465 -0
  346. package/src/utils.ts +49 -0
  347. package/src/verifyconfig.test.ts +197 -0
  348. package/tsconfig.json +2 -1
  349. package/typedoc.json +1 -0
  350. package/.github/workflows/build.yml +0 -18
  351. package/.github/workflows/changerelease.yml +0 -11
  352. package/.github/workflows/labeler.yml +0 -16
  353. package/.github/workflows/release-drafter.yml +0 -14
  354. package/dist/device/airpurifier.d.ts.map +0 -1
  355. package/dist/device/airpurifier.js.map +0 -1
  356. package/dist/device/blindtilt.d.ts.map +0 -1
  357. package/dist/device/blindtilt.js.map +0 -1
  358. package/dist/device/bot.d.ts.map +0 -1
  359. package/dist/device/bot.js.map +0 -1
  360. package/dist/device/ceilinglight.d.ts.map +0 -1
  361. package/dist/device/ceilinglight.js.map +0 -1
  362. package/dist/device/colorbulb.d.ts.map +0 -1
  363. package/dist/device/colorbulb.js.map +0 -1
  364. package/dist/device/contact.d.ts.map +0 -1
  365. package/dist/device/contact.js.map +0 -1
  366. package/dist/device/curtain.d.ts.map +0 -1
  367. package/dist/device/curtain.js.map +0 -1
  368. package/dist/device/device.d.ts.map +0 -1
  369. package/dist/device/device.js.map +0 -1
  370. package/dist/device/fan.d.ts.map +0 -1
  371. package/dist/device/fan.js.map +0 -1
  372. package/dist/device/hub.d.ts.map +0 -1
  373. package/dist/device/hub.js.map +0 -1
  374. package/dist/device/humidifier.d.ts.map +0 -1
  375. package/dist/device/humidifier.js.map +0 -1
  376. package/dist/device/iosensor.d.ts.map +0 -1
  377. package/dist/device/iosensor.js.map +0 -1
  378. package/dist/device/lightstrip.d.ts.map +0 -1
  379. package/dist/device/lightstrip.js.map +0 -1
  380. package/dist/device/lock.d.ts.map +0 -1
  381. package/dist/device/lock.js.map +0 -1
  382. package/dist/device/meter.d.ts.map +0 -1
  383. package/dist/device/meter.js.map +0 -1
  384. package/dist/device/meterplus.d.ts.map +0 -1
  385. package/dist/device/meterplus.js.map +0 -1
  386. package/dist/device/meterpro.d.ts.map +0 -1
  387. package/dist/device/meterpro.js.map +0 -1
  388. package/dist/device/motion.d.ts.map +0 -1
  389. package/dist/device/motion.js.map +0 -1
  390. package/dist/device/plug.d.ts.map +0 -1
  391. package/dist/device/plug.js.map +0 -1
  392. package/dist/device/relayswitch.d.ts.map +0 -1
  393. package/dist/device/relayswitch.js.map +0 -1
  394. package/dist/device/robotvacuumcleaner.d.ts.map +0 -1
  395. package/dist/device/robotvacuumcleaner.js.map +0 -1
  396. package/dist/device/waterdetector.d.ts.map +0 -1
  397. package/dist/device/waterdetector.js.map +0 -1
  398. package/dist/platform.d.ts.map +0 -1
  399. package/dist/platform.js.map +0 -1
  400. /package/dist/{device → devices-hap}/airpurifier.js +0 -0
  401. /package/dist/{device → devices-hap}/bot.js +0 -0
  402. /package/dist/{device → devices-hap}/ceilinglight.js +0 -0
  403. /package/dist/{device → devices-hap}/colorbulb.js +0 -0
  404. /package/dist/{device → devices-hap}/contact.js +0 -0
  405. /package/dist/{device → devices-hap}/fan.js +0 -0
  406. /package/dist/{device → devices-hap}/humidifier.js +0 -0
  407. /package/dist/{device → devices-hap}/iosensor.js +0 -0
  408. /package/dist/{device → devices-hap}/lightstrip.js +0 -0
  409. /package/dist/{device → devices-hap}/lock.js +0 -0
  410. /package/dist/{device → devices-hap}/meter.js +0 -0
  411. /package/dist/{device → devices-hap}/meterplus.js +0 -0
  412. /package/dist/{device → devices-hap}/motion.js +0 -0
  413. /package/dist/{device → devices-hap}/plug.js +0 -0
  414. /package/dist/{device → devices-hap}/relayswitch.js +0 -0
  415. /package/dist/{device → devices-hap}/robotvacuumcleaner.js +0 -0
  416. /package/dist/{device → devices-hap}/waterdetector.js +0 -0
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicChange, CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { bodyChange, curtain3ServiceData, curtain3WebhookContext, curtainServiceData, curtainStatus, curtainWebhookContext, device, SwitchBotBLE, SwitchbotDevice, WoCurtain } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { curtainConfig, devicesConfig } from '../settings.js'
10
10
 
11
11
  import { hostname } from 'node:os'
@@ -77,7 +77,7 @@ export class Curtain extends deviceBase {
77
77
  doCurtainUpdate!: Subject<void>
78
78
 
79
79
  constructor(
80
- readonly platform: SwitchBotPlatform,
80
+ readonly platform: SwitchBotHAPPlatform,
81
81
  accessory: PlatformAccessory,
82
82
  device: device & devicesConfig,
83
83
  ) {
@@ -378,9 +378,11 @@ export class Curtain extends deviceBase {
378
378
  this.debugLog('BLEparseStatus')
379
379
  this.debugLog(`(position, battery) = BLE:(${this.serviceData.position}, ${this.serviceData.battery}), current:(${this.WindowCovering.CurrentPosition}, ${this.Battery.BatteryLevel})`)
380
380
  // CurrentPosition
381
- if ('position' in this.serviceData) {
382
- this.WindowCovering.CurrentPosition = 100 - this.serviceData.position
381
+ if ('position' in this.serviceData && this.serviceData.position !== undefined && this.serviceData.position !== null && !Number.isNaN(Number(this.serviceData.position))) {
382
+ this.WindowCovering.CurrentPosition = 100 - Number(this.serviceData.position)
383
383
  await this.getCurrentPostion()
384
+ } else {
385
+ this.warnLog(`Invalid position data from BLE: ${this.serviceData.position}`)
384
386
  }
385
387
  // CurrentAmbientLightLevel
386
388
  if (!(this.device as curtainConfig).hide_lightsensor && this.LightSensor?.Service && 'lightLevel' in this.serviceData) {
@@ -489,10 +491,10 @@ export class Curtain extends deviceBase {
489
491
  // Start to monitor advertisement packets
490
492
  const serviceData = await this.monitorAdvertisementPackets(switchBotBLE) as curtainServiceData | curtain3ServiceData
491
493
  // Update HomeKit
492
- if ((serviceData.model === SwitchBotBLEModel.Curtain || SwitchBotBLEModel.Curtain3)
493
- && (serviceData.modelName === SwitchBotBLEModelName.Curtain || SwitchBotBLEModelName.Curtain3)) {
494
+ if ((serviceData.model === SwitchBotBLEModel.Curtain || serviceData.model === SwitchBotBLEModel.Curtain3)
495
+ && (serviceData.modelName === SwitchBotBLEModelName.Curtain || serviceData.modelName === SwitchBotBLEModelName.Curtain3)) {
494
496
  this.serviceData = serviceData
495
- if (serviceData !== undefined || serviceData !== null) {
497
+ if (serviceData !== undefined && serviceData !== null) {
496
498
  await this.BLEparseStatus()
497
499
  await this.updateHomeKitCharacteristics()
498
500
  } else {
@@ -559,7 +561,7 @@ export class Curtain extends deviceBase {
559
561
  this.platform.bleEventHandler[this.device.bleMac] = async (context: curtainServiceData | curtain3ServiceData) => {
560
562
  try {
561
563
  this.serviceData = context
562
- if (context !== undefined || context !== null) {
564
+ if (context !== undefined && context !== null) {
563
565
  this.debugLog(`received BLE: ${JSON.stringify(context)}`)
564
566
  await this.BLEparseStatus()
565
567
  await this.updateHomeKitCharacteristics()
@@ -619,7 +621,11 @@ export class Curtain extends deviceBase {
619
621
  return await this.retryBLE({
620
622
  max: this.maxRetryBLE(),
621
623
  fn: async () => {
622
- return await deviceList[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode)
624
+ if (deviceList && Array.isArray(deviceList) && deviceList.length > 0) {
625
+ return await deviceList[0].runToPos(100 - Number(this.WindowCovering.TargetPosition), adjustedMode)
626
+ } else {
627
+ throw new Error('No device found')
628
+ }
623
629
  },
624
630
  })
625
631
  })
@@ -777,6 +783,17 @@ export class Curtain extends deviceBase {
777
783
 
778
784
  async updateHomeKitCharacteristics(): Promise<void> {
779
785
  await this.setMinMax()
786
+
787
+ // Validate position values to prevent NaN
788
+ if (Number.isNaN(Number(this.WindowCovering.CurrentPosition))) {
789
+ this.warnLog(`CurrentPosition is NaN, keeping previous value`)
790
+ this.WindowCovering.CurrentPosition = this.accessory.context.CurrentPosition ?? 100
791
+ }
792
+ if (Number.isNaN(Number(this.WindowCovering.TargetPosition))) {
793
+ this.warnLog(`TargetPosition is NaN, keeping previous value`)
794
+ this.WindowCovering.TargetPosition = this.accessory.context.TargetPosition ?? 100
795
+ }
796
+
780
797
  // CurrentPosition
781
798
  await this.updateCharacteristic(this.WindowCovering.Service, this.hap.Characteristic.CurrentPosition, this.WindowCovering.CurrentPosition, 'CurrentPosition')
782
799
  // PositionState
@@ -799,17 +816,22 @@ export class Curtain extends deviceBase {
799
816
  }
800
817
 
801
818
  async BLEPushConnection() {
819
+ this.warnLog('BLE connection failed for push operation')
802
820
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
803
821
  this.warnLog('Using OpenAPI Connection to Push Changes')
804
822
  await this.openAPIpushChanges()
823
+ } else {
824
+ this.errorLog('No fallback available for BLE push failure. Consider using BLE/OpenAPI connection type.')
805
825
  }
806
826
  }
807
827
 
808
828
  async BLERefreshConnection(switchbot: SwitchBotBLE): Promise<void> {
809
- this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${switchbot}`)
829
+ this.warnLog(`BLE connection failed for refresh operation, node-switchbot: ${switchbot}`)
810
830
  if (this.platform.config.credentials?.token && this.device.connectionType === 'BLE/OpenAPI') {
811
831
  this.warnLog('Using OpenAPI Connection to Refresh Status')
812
832
  await this.openAPIRefreshStatus()
833
+ } else {
834
+ this.errorLog('No fallback available for BLE refresh failure. Consider using BLE/OpenAPI connection type.')
813
835
  }
814
836
  }
815
837
 
@@ -7,7 +7,7 @@ import type { API, CharacteristicValue, HAP, Logging, PlatformAccessory, Service
7
7
  import type { MqttClient } from 'mqtt'
8
8
  import type { ad, bodyChange, device, deviceStatus, deviceStatusRequest, pushResponse, SwitchBotBLE } from 'node-switchbot'
9
9
 
10
- import type { SwitchBotPlatform } from '../platform.js'
10
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
11
11
  import type { blindTiltConfig, botConfig, ceilingLightConfig, colorBulbConfig, contactConfig, curtainConfig, devicesConfig, hubConfig, humidifierConfig, indoorOutdoorSensorConfig, lockConfig, meterConfig, motionConfig, plugConfig, relaySwitch1Config, relaySwitch1PMConfig, stripLightConfig, SwitchBotPlatformConfig, waterDetectorConfig } from '../settings.js'
12
12
 
13
13
  import { hostname } from 'node:os'
@@ -53,7 +53,7 @@ export abstract class deviceBase {
53
53
  protected mqttClient: MqttClient | null = null
54
54
 
55
55
  constructor(
56
- protected readonly platform: SwitchBotPlatform,
56
+ protected readonly platform: SwitchBotHAPPlatform,
57
57
  protected accessory: PlatformAccessory,
58
58
  protected device: device & devicesConfig,
59
59
  ) {
@@ -318,7 +318,7 @@ export abstract class deviceBase {
318
318
  try {
319
319
  await switchbot.startScan({ model: this.device.bleModel, id: this.device.bleMac })
320
320
  } catch (e: any) {
321
- this.errorLog(`Failed to start BLE scanning. Error:${e.message ?? e}`)
321
+ this.errorLog(`Failed to start BLE scanning. Error: ${e.message ?? e}`)
322
322
  }
323
323
  // Set an event handler
324
324
  let serviceData = { model: this.device.bleModel, modelName: this.device.bleModelName } as ad['serviceData']
@@ -337,7 +337,7 @@ export abstract class deviceBase {
337
337
  try {
338
338
  await switchbot.stopScan()
339
339
  } catch (e: any) {
340
- this.errorLog(`Failed to stop BLE scanning. Error:${e.message ?? e}`)
340
+ this.errorLog(`Failed to stop BLE scanning. Error: ${e.message ?? e}`)
341
341
  }
342
342
  return serviceData
343
343
  }
@@ -350,7 +350,7 @@ export abstract class deviceBase {
350
350
  try {
351
351
  await switchbot.startScan({ model: this.device.bleModel })
352
352
  } catch (e: any) {
353
- this.errorLog(`Failed to start BLE scanning. Error:${e.message ?? e}`)
353
+ this.errorLog(`Failed to start BLE scanning. Error: ${e.message ?? e}`)
354
354
  }
355
355
  // Set an event handler
356
356
  switchbot.onadvertisement = (ad: ad) => {
@@ -361,7 +361,7 @@ export abstract class deviceBase {
361
361
  try {
362
362
  switchbot.stopScan()
363
363
  } catch (e: any) {
364
- this.errorLog(`Failed to stop BLE scanning. Error:${e.message ?? e}`)
364
+ this.errorLog(`Failed to stop BLE scanning. Error: ${e.message ?? e}`)
365
365
  }
366
366
  })()
367
367
  }
@@ -446,6 +446,12 @@ export abstract class deviceBase {
446
446
  bleModelName: SwitchBotBLEModelName.Hub2,
447
447
  bleModelFriendlyName: SwitchBotBLEModelFriendlyName.Hub2,
448
448
  },
449
+ 'Hub 3': {
450
+ model: SwitchBotModel.Hub3,
451
+ bleModel: SwitchBotBLEModel.Hub3,
452
+ bleModelName: SwitchBotBLEModelName.Hub3,
453
+ bleModelFriendlyName: SwitchBotBLEModelFriendlyName.Hub3,
454
+ },
449
455
  'Bot': {
450
456
  model: SwitchBotModel.Bot,
451
457
  bleModel: SwitchBotBLEModel.Bot,
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { batteryCirculatorFanServiceData, batteryCirculatorFanStatus, batteryCirculatorFanWebhookContext, bodyChange, device, SwitchBotBLE, SwitchbotDevice } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig } from '../settings.js'
10
10
 
11
11
  /*
@@ -57,7 +57,7 @@ export class Fan extends deviceBase {
57
57
  doFanUpdate!: Subject<void>
58
58
 
59
59
  constructor(
60
- readonly platform: SwitchBotPlatform,
60
+ readonly platform: SwitchBotHAPPlatform,
61
61
  accessory: PlatformAccessory,
62
62
  device: device & devicesConfig,
63
63
  ) {
@@ -3,9 +3,9 @@
3
3
  * hub.ts: @switchbot/homebridge-switchbot.
4
4
  */
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
- import type { device, hub2ServiceData, hub2Status, hub2WebhookContext, SwitchBotBLE } from 'node-switchbot'
6
+ import type { device, hub2ServiceData, hub2Status, hub2WebhookContext, hub3ServiceData, SwitchBotBLE } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, hubConfig } from '../settings.js'
10
10
 
11
11
  import { Units } from 'homebridge'
@@ -46,14 +46,14 @@ export class Hub extends deviceBase {
46
46
  webhookContext!: hub2WebhookContext
47
47
 
48
48
  // BLE
49
- serviceData!: hub2ServiceData
49
+ serviceData!: hub2ServiceData | hub3ServiceData
50
50
 
51
51
  // Updates
52
52
  hubUpdateInProgress!: boolean
53
53
  doHubUpdate!: Subject<void>
54
54
 
55
55
  constructor(
56
- readonly platform: SwitchBotPlatform,
56
+ readonly platform: SwitchBotHAPPlatform,
57
57
  accessory: PlatformAccessory,
58
58
  device: device & devicesConfig,
59
59
  ) {
@@ -292,9 +292,10 @@ export class Hub extends deviceBase {
292
292
  // Start to monitor advertisement packets
293
293
  (async () => {
294
294
  // Start to monitor advertisement packets
295
- const serviceData = await this.monitorAdvertisementPackets(switchBotBLE) as hub2ServiceData
295
+ const serviceData = await this.monitorAdvertisementPackets(switchBotBLE) as hub2ServiceData | hub3ServiceData
296
296
  // Update HomeKit
297
- if (serviceData.model === SwitchBotBLEModel.Hub2 && serviceData.modelName === SwitchBotBLEModelName.Hub2) {
297
+ if ((serviceData.model === SwitchBotBLEModel.Hub2 && serviceData.modelName === SwitchBotBLEModelName.Hub2)
298
+ || (serviceData.model === SwitchBotBLEModel.Hub3 && serviceData.modelName === SwitchBotBLEModelName.Hub3)) {
298
299
  this.serviceData = serviceData
299
300
  if (serviceData !== undefined || serviceData !== null) {
300
301
  await this.BLEparseStatus()
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { bodyChange, device, humidifier2ServiceData, humidifier2Status, humidifier2WebhookContext, humidifierServiceData, humidifierStatus, humidifierWebhookContext, SwitchBotBLE, SwitchbotDevice, WoHumi } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, humidifierConfig } from '../settings.js'
10
10
 
11
11
  /*
@@ -56,7 +56,7 @@ export class Humidifier extends deviceBase {
56
56
  doHumidifierUpdate!: Subject<void>
57
57
 
58
58
  constructor(
59
- readonly platform: SwitchBotPlatform,
59
+ readonly platform: SwitchBotHAPPlatform,
60
60
  accessory: PlatformAccessory,
61
61
  device: device & devicesConfig,
62
62
  ) {
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { device, outdoorMeterServiceData, outdoorMeterStatus, outdoorMeterWebhookContext, SwitchBotBLE } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, indoorOutdoorSensorConfig } from '../settings.js'
10
10
 
11
11
  import { Units } from 'homebridge'
@@ -59,7 +59,7 @@ export class IOSensor extends deviceBase {
59
59
  doIOSensorUpdate: Subject<void>
60
60
 
61
61
  constructor(
62
- readonly platform: SwitchBotPlatform,
62
+ readonly platform: SwitchBotHAPPlatform,
63
63
  accessory: PlatformAccessory,
64
64
  device: device & devicesConfig,
65
65
  ) {
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, Controller, ControllerConstructor, ControllerServiceMap, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { bodyChange, device, stripLightServiceData, stripLightStatus, stripLightWebhookContext, SwitchBotBLE, SwitchbotDevice, WoStrip } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, stripLightConfig } from '../settings.js'
10
10
 
11
11
  /*
@@ -54,7 +54,7 @@ export class StripLight extends deviceBase {
54
54
  doStripLightUpdate!: Subject<void>
55
55
 
56
56
  constructor(
57
- readonly platform: SwitchBotPlatform,
57
+ readonly platform: SwitchBotHAPPlatform,
58
58
  accessory: PlatformAccessory,
59
59
  device: device & devicesConfig,
60
60
  ) {
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { bodyChange, device, lockProServiceData, lockProStatus, lockProWebhookContext, lockServiceData, lockStatus, lockWebhookContext, SwitchBotBLE, SwitchbotDevice, WoSmartLock } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, lockConfig } from '../settings.js'
10
10
 
11
11
  /*
@@ -60,7 +60,7 @@ export class Lock extends deviceBase {
60
60
  doLockUpdate!: Subject<void>
61
61
 
62
62
  constructor(
63
- readonly platform: SwitchBotPlatform,
63
+ readonly platform: SwitchBotHAPPlatform,
64
64
  accessory: PlatformAccessory,
65
65
  device: device & devicesConfig,
66
66
  ) {
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { device, meterServiceData, meterStatus, meterWebhookContext, SwitchBotBLE } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, meterConfig } from '../settings.js'
10
10
 
11
11
  import { Units } from 'homebridge'
@@ -54,7 +54,7 @@ export class Meter extends deviceBase {
54
54
  doMeterUpdate: Subject<void>
55
55
 
56
56
  constructor(
57
- readonly platform: SwitchBotPlatform,
57
+ readonly platform: SwitchBotHAPPlatform,
58
58
  accessory: PlatformAccessory,
59
59
  device: device & devicesConfig,
60
60
  ) {
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { device, meterPlusServiceData, meterPlusStatus, meterPlusWebhookContext, SwitchBotBLE } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, meterConfig } from '../settings.js'
10
10
 
11
11
  import { Units } from 'homebridge'
@@ -59,7 +59,7 @@ export class MeterPlus extends deviceBase {
59
59
  doMeterUpdate: Subject<void>
60
60
 
61
61
  constructor(
62
- readonly platform: SwitchBotPlatform,
62
+ readonly platform: SwitchBotHAPPlatform,
63
63
  accessory: PlatformAccessory,
64
64
  device: device & devicesConfig,
65
65
  ) {
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { device, meterProCO2ServiceData, meterProCO2Status, meterProCO2WebhookContext, meterProServiceData, meterProStatus, meterProWebhookContext, SwitchBotBLE } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, meterProConfig } from '../settings.js'
10
10
 
11
11
  import { Units } from 'homebridge'
@@ -66,7 +66,7 @@ export class MeterPro extends deviceBase {
66
66
  doMeterUpdate: Subject<void>
67
67
 
68
68
  constructor(
69
- readonly platform: SwitchBotPlatform,
69
+ readonly platform: SwitchBotHAPPlatform,
70
70
  accessory: PlatformAccessory,
71
71
  device: device & devicesConfig,
72
72
  ) {
@@ -237,7 +237,6 @@ export class MeterPro extends deviceBase {
237
237
  ? this.hap.Characteristic.CarbonDioxideDetected.CO2_LEVELS_ABNORMAL
238
238
  : this.hap.Characteristic.CarbonDioxideDetected.CO2_LEVELS_NORMAL
239
239
  this.debugLog(`CarbonDioxideDetected: ${this.CarbonDioxideSensor.CarbonDioxideDetected}`)
240
- this.warnLog('Carbon Dioxide Sensor is not supported yet.')
241
240
  }
242
241
  // Battery Info
243
242
  if ('battery' in this.serviceData) {
@@ -277,7 +276,6 @@ export class MeterPro extends deviceBase {
277
276
  ? this.hap.Characteristic.CarbonDioxideDetected.CO2_LEVELS_ABNORMAL
278
277
  : this.hap.Characteristic.CarbonDioxideDetected.CO2_LEVELS_NORMAL
279
278
  this.debugLog(`CarbonDioxideDetected: ${this.CarbonDioxideSensor.CarbonDioxideDetected}`)
280
- this.warnLog('Carbon Dioxide Sensor is not supported yet.')
281
279
  }
282
280
 
283
281
  // Battery Info
@@ -338,7 +336,6 @@ export class MeterPro extends deviceBase {
338
336
  ? this.hap.Characteristic.CarbonDioxideDetected.CO2_LEVELS_ABNORMAL
339
337
  : this.hap.Characteristic.CarbonDioxideDetected.CO2_LEVELS_NORMAL
340
338
  this.debugLog(`CarbonDioxideDetected: ${this.CarbonDioxideSensor.CarbonDioxideDetected}`)
341
- this.warnLog('Carbon Dioxide Sensor is not supported yet.')
342
339
  }
343
340
  }
344
341
 
@@ -469,6 +466,14 @@ export class MeterPro extends deviceBase {
469
466
  if (!(this.device as meterProConfig).hide_temperature && this.TemperatureSensor?.Service) {
470
467
  await this.updateCharacteristic(this.TemperatureSensor.Service, this.hap.Characteristic.CurrentTemperature, this.TemperatureSensor.CurrentTemperature, 'CurrentTemperature')
471
468
  }
469
+ // CarbonDioxideDetected
470
+ if (!(this.device as meterProConfig).hide_co2 && this.CarbonDioxideSensor?.Service && this.device.deviceType === 'MeterPro(CO2)') {
471
+ await this.updateCharacteristic(this.CarbonDioxideSensor.Service, this.hap.Characteristic.CarbonDioxideDetected, this.CarbonDioxideSensor.CarbonDioxideDetected, 'CarbonDioxideDetected')
472
+ }
473
+ // CarbonDioxideLevel
474
+ if (!(this.device as meterProConfig).hide_co2 && this.CarbonDioxideSensor?.Service && this.device.deviceType === 'MeterPro(CO2)') {
475
+ await this.updateCharacteristic(this.CarbonDioxideSensor.Service, this.hap.Characteristic.CarbonDioxideLevel, this.CarbonDioxideSensor.CarbonDioxideLevel, 'CarbonDioxideLevel')
476
+ }
472
477
  // BatteryLevel
473
478
  await this.updateCharacteristic(this.Battery.Service, this.hap.Characteristic.BatteryLevel, this.Battery.BatteryLevel, 'BatteryLevel')
474
479
  // StatusLowBattery
@@ -491,6 +496,10 @@ export class MeterPro extends deviceBase {
491
496
  if (!(this.device as meterProConfig).hide_temperature && this.TemperatureSensor?.Service) {
492
497
  this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, 30)
493
498
  }
499
+ if (!(this.device as meterProConfig).hide_co2 && this.CarbonDioxideSensor?.Service && this.device.deviceType === 'MeterPro(CO2)') {
500
+ this.CarbonDioxideSensor.Service.updateCharacteristic(this.hap.Characteristic.CarbonDioxideDetected, this.hap.Characteristic.CarbonDioxideDetected.CO2_LEVELS_NORMAL)
501
+ this.CarbonDioxideSensor.Service.updateCharacteristic(this.hap.Characteristic.CarbonDioxideLevel, 0)
502
+ }
494
503
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, 100)
495
504
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, this.hap.Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL)
496
505
  }
@@ -503,6 +512,10 @@ export class MeterPro extends deviceBase {
503
512
  if (!(this.device as meterProConfig).hide_temperature && this.TemperatureSensor?.Service) {
504
513
  this.TemperatureSensor.Service.updateCharacteristic(this.hap.Characteristic.CurrentTemperature, e)
505
514
  }
515
+ if (!(this.device as meterProConfig).hide_co2 && this.CarbonDioxideSensor?.Service && this.device.deviceType === 'MeterPro(CO2)') {
516
+ this.CarbonDioxideSensor.Service.updateCharacteristic(this.hap.Characteristic.CarbonDioxideDetected, e)
517
+ this.CarbonDioxideSensor.Service.updateCharacteristic(this.hap.Characteristic.CarbonDioxideLevel, e)
518
+ }
506
519
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.BatteryLevel, e)
507
520
  this.Battery.Service.updateCharacteristic(this.hap.Characteristic.StatusLowBattery, e)
508
521
  }
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { device, motionSensorServiceData, motionSensorStatus, motionSensorWebhookContext, SwitchBotBLE } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, motionConfig } from '../settings.js'
10
10
 
11
11
  /*
@@ -58,7 +58,7 @@ export class Motion extends deviceBase {
58
58
  doMotionUpdate!: Subject<void>
59
59
 
60
60
  constructor(
61
- readonly platform: SwitchBotPlatform,
61
+ readonly platform: SwitchBotHAPPlatform,
62
62
  accessory: PlatformAccessory,
63
63
  device: device & devicesConfig,
64
64
  ) {
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { bodyChange, device, plugMiniJPServiceData, plugMiniJPWebhookContext, plugMiniStatus, plugMiniUSServiceData, plugMiniUSWebhookContext, plugStatus, plugWebhookContext, SwitchBotBLE, SwitchbotDevice, WoPlugMiniUS } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig } from '../settings.js'
10
10
 
11
11
  /*
@@ -40,7 +40,7 @@ export class Plug extends deviceBase {
40
40
  doPlugUpdate!: Subject<void>
41
41
 
42
42
  constructor(
43
- readonly platform: SwitchBotPlatform,
43
+ readonly platform: SwitchBotHAPPlatform,
44
44
  accessory: PlatformAccessory,
45
45
  device: device & devicesConfig,
46
46
  ) {
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { bodyChange, device, relaySwitch1Context, relaySwitch1PMContext, relaySwitch1PMServiceData, relaySwitch1PMStatus, relaySwitch1ServiceData, relaySwitch1Status, SwitchBotBLE, SwitchbotDevice, WoRelaySwitch1, WoRelaySwitch1PM } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, relaySwitch1Config, relaySwitch1PMConfig } from '../settings.js'
10
10
 
11
11
  /*
@@ -107,7 +107,7 @@ export class RelaySwitch extends deviceBase {
107
107
  * @constructor
108
108
  */
109
109
  constructor(
110
- readonly platform: SwitchBotPlatform,
110
+ readonly platform: SwitchBotHAPPlatform,
111
111
  accessory: PlatformAccessory,
112
112
  device: device & devicesConfig,
113
113
  ) {
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { bodyChange, device, floorCleaningRobotS10Status, floorCleaningRobotS10WebhookContext, robotVacuumCleanerS1PlusStatus, robotVacuumCleanerS1PlusWebhookContext, robotVacuumCleanerS1Status, robotVacuumCleanerS1WebhookContext, robotVacuumCleanerServiceData, SwitchBotBLE, SwitchbotDevice } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig } from '../settings.js'
10
10
 
11
11
  /*
@@ -49,7 +49,7 @@ export class RobotVacuumCleaner extends deviceBase {
49
49
  doRobotVacuumCleanerUpdate!: Subject<void>
50
50
 
51
51
  constructor(
52
- readonly platform: SwitchBotPlatform,
52
+ readonly platform: SwitchBotHAPPlatform,
53
53
  accessory: PlatformAccessory,
54
54
  device: device & devicesConfig,
55
55
  ) {
@@ -5,7 +5,7 @@
5
5
  import type { CharacteristicValue, PlatformAccessory, Service } from 'homebridge'
6
6
  import type { device, SwitchBotBLE, waterLeakDetectorServiceData, waterLeakDetectorStatus, waterLeakDetectorWebhookContext } from 'node-switchbot'
7
7
 
8
- import type { SwitchBotPlatform } from '../platform.js'
8
+ import type { SwitchBotHAPPlatform } from '../platform-hap.js'
9
9
  import type { devicesConfig, waterDetectorConfig } from '../settings.js'
10
10
 
11
11
  /*
@@ -54,7 +54,7 @@ export class WaterDetector extends deviceBase {
54
54
  doWaterDetectorUpdate: Subject<void>
55
55
 
56
56
  constructor(
57
- readonly platform: SwitchBotPlatform,
57
+ readonly platform: SwitchBotHAPPlatform,
58
58
  accessory: PlatformAccessory,
59
59
  device: device & devicesConfig,
60
60
  ) {
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Base Matter Accessory Class
3
+ *
4
+ * This base class implements the MatterAccessory interface and provides
5
+ * common functionality that all Matter devices can use.
6
+ *
7
+ * Individual device types should extend this class and call super() with
8
+ * the required configuration.
9
+ */
10
+
11
+ import type { API, EndpointType, Logger, MatterAccessory } from 'homebridge'
12
+
13
+ export interface BaseMatterAccessoryConfig {
14
+ uuid: string
15
+ displayName: string
16
+ deviceType: EndpointType
17
+ serialNumber: string
18
+ manufacturer: string
19
+ model: string
20
+ firmwareRevision: string
21
+ hardwareRevision: string
22
+ context?: Record<string, unknown>
23
+ clusters?: MatterAccessory['clusters']
24
+ handlers?: MatterAccessory['handlers']
25
+ parts?: MatterAccessory['parts']
26
+ }
27
+
28
+ /**
29
+ * Base class for all Matter accessories
30
+ * Implements the MatterAccessory interface and provides common methods
31
+ */
32
+ export abstract class BaseMatterAccessory implements MatterAccessory {
33
+ // Required MatterAccessory properties
34
+ public readonly uuid: string
35
+ public readonly displayName: string
36
+ public readonly deviceType: EndpointType
37
+ public readonly serialNumber: string
38
+ public readonly manufacturer: string
39
+ public readonly model: string
40
+ public readonly firmwareRevision: string
41
+ public readonly hardwareRevision: string
42
+ public readonly context: Record<string, unknown>
43
+ public readonly clusters?: MatterAccessory['clusters']
44
+ public readonly handlers?: MatterAccessory['handlers']
45
+ public readonly parts?: MatterAccessory['parts']
46
+
47
+ // Protected properties available to child classes
48
+ protected readonly api: API
49
+ protected readonly log: Logger
50
+
51
+ constructor(
52
+ api: API,
53
+ log: Logger,
54
+ config: BaseMatterAccessoryConfig,
55
+ ) {
56
+ this.api = api
57
+ this.log = log
58
+
59
+ // Set all required properties
60
+ this.uuid = config.uuid
61
+ this.displayName = config.displayName
62
+ this.deviceType = config.deviceType
63
+ this.serialNumber = config.serialNumber
64
+ this.manufacturer = config.manufacturer
65
+ this.model = config.model
66
+ this.firmwareRevision = config.firmwareRevision
67
+ this.hardwareRevision = config.hardwareRevision
68
+ this.clusters = config.clusters
69
+ this.handlers = config.handlers
70
+ this.parts = config.parts
71
+
72
+ // Set context with all metadata
73
+ this.context = {
74
+ serialNumber: this.serialNumber,
75
+ manufacturer: this.manufacturer,
76
+ model: this.model,
77
+ firmwareRevision: this.firmwareRevision,
78
+ hardwareRevision: this.hardwareRevision,
79
+ ...config.context,
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Update the accessory state
85
+ * Helper method to update cluster attributes
86
+ */
87
+ protected async updateState(cluster: string, attributes: Record<string, unknown>): Promise<void> {
88
+ await this.api.matter.updateAccessoryState(this.uuid, cluster, attributes)
89
+ this.log.debug(`[${this.displayName}] Updated ${cluster} state:`, attributes)
90
+ }
91
+
92
+ /**
93
+ * Log helper methods
94
+ */
95
+ protected logInfo(message: string, ...args: unknown[]): void {
96
+ this.log.info(`[${this.displayName}] ${message}`, ...args)
97
+ }
98
+
99
+ protected logError(message: string, ...args: unknown[]): void {
100
+ this.log.error(`[${this.displayName}] ${message}`, ...args)
101
+ }
102
+
103
+ protected logDebug(message: string, ...args: unknown[]): void {
104
+ this.log.debug(`[${this.displayName}] ${message}`, ...args)
105
+ }
106
+
107
+ protected logWarn(message: string, ...args: unknown[]): void {
108
+ this.log.warn(`[${this.displayName}] ${message}`, ...args)
109
+ }
110
+
111
+ /**
112
+ * Convert this class instance to a plain MatterAccessory object
113
+ * This is what gets registered with Homebridge
114
+ */
115
+ public toAccessory(): MatterAccessory {
116
+ return {
117
+ uuid: this.uuid,
118
+ displayName: this.displayName,
119
+ deviceType: this.deviceType,
120
+ serialNumber: this.serialNumber,
121
+ manufacturer: this.manufacturer,
122
+ model: this.model,
123
+ firmwareRevision: this.firmwareRevision,
124
+ hardwareRevision: this.hardwareRevision,
125
+ context: this.context,
126
+ clusters: this.clusters,
127
+ handlers: this.handlers,
128
+ parts: this.parts,
129
+ }
130
+ }
131
+ }