@switchbot/homebridge-switchbot 5.0.0-beta.1 → 5.0.0-beta.100

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 (448) hide show
  1. package/.github/ISSUE_TEMPLATE/e2e-verification.md +36 -0
  2. package/.github/workflows/ci.yml +32 -0
  3. package/.github/workflows/manual-e2e.yml +115 -0
  4. package/.github/workflows/release.yml +0 -4
  5. package/CHANGELOG.md +35 -0
  6. package/E2E-VERIFICATION.md +121 -0
  7. package/MIGRATION.md +44 -0
  8. package/README.md +56 -3
  9. package/config.schema.json +91 -14787
  10. package/dist/deviceFactory.d.ts +13 -0
  11. package/dist/deviceFactory.d.ts.map +1 -0
  12. package/dist/deviceFactory.js +81 -0
  13. package/dist/deviceFactory.js.map +1 -0
  14. package/dist/devices/deviceBase.d.ts +50 -0
  15. package/dist/devices/deviceBase.d.ts.map +1 -0
  16. package/dist/devices/deviceBase.js +119 -0
  17. package/dist/devices/deviceBase.js.map +1 -0
  18. package/dist/devices/genericDevice.d.ts +298 -0
  19. package/dist/devices/genericDevice.d.ts.map +1 -0
  20. package/dist/devices/genericDevice.js +1065 -0
  21. package/dist/devices/genericDevice.js.map +1 -0
  22. package/dist/homebridge-ui/public/index.html +636 -246
  23. package/dist/homebridge-ui/server.d.ts +3 -1
  24. package/dist/homebridge-ui/server.d.ts.map +1 -1
  25. package/dist/homebridge-ui/server.js +467 -36
  26. package/dist/homebridge-ui/server.js.map +1 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +4 -7
  29. package/dist/index.js.map +1 -1
  30. package/dist/platform.d.ts +35 -0
  31. package/dist/platform.d.ts.map +1 -0
  32. package/dist/platform.js +1562 -0
  33. package/dist/platform.js.map +1 -0
  34. package/dist/settings.d.ts +10 -249
  35. package/dist/settings.d.ts.map +1 -1
  36. package/dist/settings.js +5 -30
  37. package/dist/settings.js.map +1 -1
  38. package/dist/switchbotClient.d.ts +32 -0
  39. package/dist/switchbotClient.d.ts.map +1 -0
  40. package/dist/switchbotClient.js +194 -0
  41. package/dist/switchbotClient.js.map +1 -0
  42. package/dist/utils.d.ts +39 -50
  43. package/dist/utils.d.ts.map +1 -1
  44. package/dist/utils.js +39 -688
  45. package/dist/utils.js.map +1 -1
  46. package/docs/assets/highlight.css +14 -0
  47. package/docs/assets/icons.js +1 -1
  48. package/docs/assets/icons.svg +1 -1
  49. package/docs/assets/main.js +2 -2
  50. package/docs/assets/style.css +3 -3
  51. package/docs/index.html +77 -13
  52. package/docs/variables/default.html +1 -1
  53. package/eslint.config.js +2 -8
  54. package/package.json +21 -28
  55. package/scripts/e2e/README.md +25 -0
  56. package/scripts/e2e/curtain-e2e.sh +70 -0
  57. package/scripts/e2e/fan-e2e.sh +75 -0
  58. package/scripts/e2e/light-advanced-e2e.sh +97 -0
  59. package/scripts/e2e/light-e2e.sh +75 -0
  60. package/scripts/e2e/list-accessories.sh +19 -0
  61. package/scripts/e2e/lock-e2e.sh +65 -0
  62. package/scripts/generate-matter-maps.js +60 -0
  63. package/scripts/run-e2e-local.sh +14 -0
  64. package/src/deviceFactory.ts +122 -0
  65. package/src/devices/deviceBase.ts +141 -0
  66. package/src/devices/genericDevice.ts +995 -0
  67. package/src/homebridge-ui/public/index.html +636 -246
  68. package/src/homebridge-ui/server.ts +552 -41
  69. package/src/index.ts +4 -7
  70. package/src/platform.ts +1561 -0
  71. package/src/settings.ts +12 -277
  72. package/src/switchbotClient.ts +203 -0
  73. package/src/utils.ts +45 -713
  74. package/test/accessory-restore.spec.ts +73 -0
  75. package/test/device-mapping.spec.ts +37 -0
  76. package/test/deviceFactory.spec.ts +18 -0
  77. package/test/e2e/run-e2e.spec.ts +50 -0
  78. package/test/fan-swing.spec.ts +29 -0
  79. package/test/helpers/matter-harness.ts +53 -0
  80. package/test/lock-users.spec.ts +44 -0
  81. package/test/matter-childbridge.spec.ts +55 -0
  82. package/test/matter-descriptors.spec.ts +97 -0
  83. package/test/matter-device-state.spec.ts +101 -0
  84. package/test/matter-integration.spec.ts +70 -0
  85. package/test/platform.integration.spec.ts +55 -0
  86. package/test/switchbot-client-debounce.spec.ts +131 -0
  87. package/test/switchbot-client-openapi.spec.ts +56 -0
  88. package/test/switchbotClient.spec.ts +10 -0
  89. package/test/utils.spec.ts +20 -0
  90. package/vitest.config.ts +7 -0
  91. package/coverage/base.css +0 -224
  92. package/coverage/block-navigation.js +0 -87
  93. package/coverage/clover.xml +0 -15847
  94. package/coverage/coverage-final.json +0 -42
  95. package/coverage/docs/assets/dmt/dmt-component-data.js.html +0 -85
  96. package/coverage/docs/assets/dmt/dmt-components.js.html +0 -286
  97. package/coverage/docs/assets/dmt/index.html +0 -131
  98. package/coverage/docs/assets/hierarchy.js.html +0 -85
  99. package/coverage/docs/assets/icons.js.html +0 -136
  100. package/coverage/docs/assets/index.html +0 -146
  101. package/coverage/docs/assets/main.js.html +0 -265
  102. package/coverage/favicon.png +0 -0
  103. package/coverage/index.html +0 -191
  104. package/coverage/prettify.css +0 -1
  105. package/coverage/prettify.js +0 -2
  106. package/coverage/sort-arrow-sprite.png +0 -0
  107. package/coverage/sorter.js +0 -196
  108. package/coverage/src/device/blindtilt.ts.html +0 -3238
  109. package/coverage/src/device/bot.ts.html +0 -2803
  110. package/coverage/src/device/ceilinglight.ts.html +0 -2338
  111. package/coverage/src/device/colorbulb.ts.html +0 -2824
  112. package/coverage/src/device/contact.ts.html +0 -1465
  113. package/coverage/src/device/curtain.ts.html +0 -2869
  114. package/coverage/src/device/device.ts.html +0 -2500
  115. package/coverage/src/device/fan.ts.html +0 -2242
  116. package/coverage/src/device/hub.ts.html +0 -1408
  117. package/coverage/src/device/humidifier.ts.html +0 -2116
  118. package/coverage/src/device/index.html +0 -416
  119. package/coverage/src/device/iosensor.ts.html +0 -1375
  120. package/coverage/src/device/lightstrip.ts.html +0 -2617
  121. package/coverage/src/device/lock.ts.html +0 -1963
  122. package/coverage/src/device/meter.ts.html +0 -1372
  123. package/coverage/src/device/meterplus.ts.html +0 -1384
  124. package/coverage/src/device/meterpro.ts.html +0 -1618
  125. package/coverage/src/device/motion.ts.html +0 -1264
  126. package/coverage/src/device/plug.ts.html +0 -1372
  127. package/coverage/src/device/relayswitch.ts.html +0 -2284
  128. package/coverage/src/device/robotvacuumcleaner.ts.html +0 -1810
  129. package/coverage/src/device/waterdetector.ts.html +0 -1294
  130. package/coverage/src/homebridge-ui/index.html +0 -116
  131. package/coverage/src/homebridge-ui/server.ts.html +0 -229
  132. package/coverage/src/index.html +0 -161
  133. package/coverage/src/index.ts.html +0 -124
  134. package/coverage/src/irdevice/airconditioner.ts.html +0 -1687
  135. package/coverage/src/irdevice/airpurifier.ts.html +0 -844
  136. package/coverage/src/irdevice/camera.ts.html +0 -475
  137. package/coverage/src/irdevice/fan.ts.html +0 -766
  138. package/coverage/src/irdevice/index.html +0 -251
  139. package/coverage/src/irdevice/irdevice.ts.html +0 -1117
  140. package/coverage/src/irdevice/light.ts.html +0 -826
  141. package/coverage/src/irdevice/other.ts.html +0 -2458
  142. package/coverage/src/irdevice/tv.ts.html +0 -1222
  143. package/coverage/src/irdevice/vacuumcleaner.ts.html +0 -466
  144. package/coverage/src/irdevice/waterheater.ts.html +0 -469
  145. package/coverage/src/platform.ts.html +0 -8776
  146. package/coverage/src/settings.ts.html +0 -934
  147. package/coverage/src/utils.ts.html +0 -2092
  148. package/dist/devices-hap/airpurifier.d.ts +0 -54
  149. package/dist/devices-hap/airpurifier.d.ts.map +0 -1
  150. package/dist/devices-hap/airpurifier.js +0 -527
  151. package/dist/devices-hap/airpurifier.js.map +0 -1
  152. package/dist/devices-hap/blindtilt.d.ts +0 -90
  153. package/dist/devices-hap/blindtilt.d.ts.map +0 -1
  154. package/dist/devices-hap/blindtilt.js +0 -974
  155. package/dist/devices-hap/blindtilt.js.map +0 -1
  156. package/dist/devices-hap/bot.d.ts +0 -102
  157. package/dist/devices-hap/bot.d.ts.map +0 -1
  158. package/dist/devices-hap/bot.js +0 -811
  159. package/dist/devices-hap/bot.js.map +0 -1
  160. package/dist/devices-hap/ceilinglight.d.ts +0 -85
  161. package/dist/devices-hap/ceilinglight.d.ts.map +0 -1
  162. package/dist/devices-hap/ceilinglight.js +0 -701
  163. package/dist/devices-hap/ceilinglight.js.map +0 -1
  164. package/dist/devices-hap/colorbulb.d.ts +0 -88
  165. package/dist/devices-hap/colorbulb.d.ts.map +0 -1
  166. package/dist/devices-hap/colorbulb.js +0 -881
  167. package/dist/devices-hap/colorbulb.js.map +0 -1
  168. package/dist/devices-hap/contact.d.ts +0 -44
  169. package/dist/devices-hap/contact.d.ts.map +0 -1
  170. package/dist/devices-hap/contact.js +0 -409
  171. package/dist/devices-hap/contact.js.map +0 -1
  172. package/dist/devices-hap/curtain.d.ts +0 -73
  173. package/dist/devices-hap/curtain.d.ts.map +0 -1
  174. package/dist/devices-hap/curtain.js +0 -869
  175. package/dist/devices-hap/curtain.js.map +0 -1
  176. package/dist/devices-hap/device.d.ts +0 -98
  177. package/dist/devices-hap/device.d.ts.map +0 -1
  178. package/dist/devices-hap/device.js +0 -749
  179. package/dist/devices-hap/device.js.map +0 -1
  180. package/dist/devices-hap/fan.d.ts +0 -69
  181. package/dist/devices-hap/fan.d.ts.map +0 -1
  182. package/dist/devices-hap/fan.js +0 -649
  183. package/dist/devices-hap/fan.js.map +0 -1
  184. package/dist/devices-hap/hub.d.ts +0 -37
  185. package/dist/devices-hap/hub.d.ts.map +0 -1
  186. package/dist/devices-hap/hub.js +0 -392
  187. package/dist/devices-hap/hub.js.map +0 -1
  188. package/dist/devices-hap/humidifier.d.ts +0 -68
  189. package/dist/devices-hap/humidifier.d.ts.map +0 -1
  190. package/dist/devices-hap/humidifier.js +0 -628
  191. package/dist/devices-hap/humidifier.js.map +0 -1
  192. package/dist/devices-hap/iosensor.d.ts +0 -42
  193. package/dist/devices-hap/iosensor.d.ts.map +0 -1
  194. package/dist/devices-hap/iosensor.js +0 -382
  195. package/dist/devices-hap/iosensor.js.map +0 -1
  196. package/dist/devices-hap/lightstrip.d.ts +0 -79
  197. package/dist/devices-hap/lightstrip.d.ts.map +0 -1
  198. package/dist/devices-hap/lightstrip.js +0 -797
  199. package/dist/devices-hap/lightstrip.js.map +0 -1
  200. package/dist/devices-hap/lock.d.ts +0 -53
  201. package/dist/devices-hap/lock.d.ts.map +0 -1
  202. package/dist/devices-hap/lock.js +0 -561
  203. package/dist/devices-hap/lock.js.map +0 -1
  204. package/dist/devices-hap/meter.d.ts +0 -37
  205. package/dist/devices-hap/meter.d.ts.map +0 -1
  206. package/dist/devices-hap/meter.js +0 -379
  207. package/dist/devices-hap/meter.js.map +0 -1
  208. package/dist/devices-hap/meterplus.d.ts +0 -42
  209. package/dist/devices-hap/meterplus.d.ts.map +0 -1
  210. package/dist/devices-hap/meterplus.js +0 -384
  211. package/dist/devices-hap/meterplus.js.map +0 -1
  212. package/dist/devices-hap/meterpro.d.ts +0 -43
  213. package/dist/devices-hap/meterpro.d.ts.map +0 -1
  214. package/dist/devices-hap/meterpro.js +0 -468
  215. package/dist/devices-hap/meterpro.js.map +0 -1
  216. package/dist/devices-hap/motion.d.ts +0 -42
  217. package/dist/devices-hap/motion.d.ts.map +0 -1
  218. package/dist/devices-hap/motion.js +0 -345
  219. package/dist/devices-hap/motion.js.map +0 -1
  220. package/dist/devices-hap/plug.d.ts +0 -49
  221. package/dist/devices-hap/plug.d.ts.map +0 -1
  222. package/dist/devices-hap/plug.js +0 -395
  223. package/dist/devices-hap/plug.js.map +0 -1
  224. package/dist/devices-hap/relayswitch.d.ts +0 -96
  225. package/dist/devices-hap/relayswitch.d.ts.map +0 -1
  226. package/dist/devices-hap/relayswitch.js +0 -642
  227. package/dist/devices-hap/relayswitch.js.map +0 -1
  228. package/dist/devices-hap/robotvacuumcleaner.d.ts +0 -54
  229. package/dist/devices-hap/robotvacuumcleaner.d.ts.map +0 -1
  230. package/dist/devices-hap/robotvacuumcleaner.js +0 -523
  231. package/dist/devices-hap/robotvacuumcleaner.js.map +0 -1
  232. package/dist/devices-hap/waterdetector.d.ts +0 -41
  233. package/dist/devices-hap/waterdetector.d.ts.map +0 -1
  234. package/dist/devices-hap/waterdetector.js +0 -356
  235. package/dist/devices-hap/waterdetector.js.map +0 -1
  236. package/dist/devices-matter/BaseMatterAccessory.d.ts +0 -63
  237. package/dist/devices-matter/BaseMatterAccessory.d.ts.map +0 -1
  238. package/dist/devices-matter/BaseMatterAccessory.js +0 -100
  239. package/dist/devices-matter/BaseMatterAccessory.js.map +0 -1
  240. package/dist/devices-matter/ColorLightAccessory.d.ts +0 -18
  241. package/dist/devices-matter/ColorLightAccessory.d.ts.map +0 -1
  242. package/dist/devices-matter/ColorLightAccessory.js +0 -96
  243. package/dist/devices-matter/ColorLightAccessory.js.map +0 -1
  244. package/dist/devices-matter/ColorTemperatureLightAccessory.d.ts +0 -16
  245. package/dist/devices-matter/ColorTemperatureLightAccessory.d.ts.map +0 -1
  246. package/dist/devices-matter/ColorTemperatureLightAccessory.js +0 -83
  247. package/dist/devices-matter/ColorTemperatureLightAccessory.js.map +0 -1
  248. package/dist/devices-matter/ContactSensorAccessory.d.ts +0 -10
  249. package/dist/devices-matter/ContactSensorAccessory.d.ts.map +0 -1
  250. package/dist/devices-matter/ContactSensorAccessory.js +0 -31
  251. package/dist/devices-matter/ContactSensorAccessory.js.map +0 -1
  252. package/dist/devices-matter/DimmableLightAccessory.d.ts +0 -56
  253. package/dist/devices-matter/DimmableLightAccessory.d.ts.map +0 -1
  254. package/dist/devices-matter/DimmableLightAccessory.js +0 -170
  255. package/dist/devices-matter/DimmableLightAccessory.js.map +0 -1
  256. package/dist/devices-matter/DoorLockAccessory.d.ts +0 -12
  257. package/dist/devices-matter/DoorLockAccessory.d.ts.map +0 -1
  258. package/dist/devices-matter/DoorLockAccessory.js +0 -47
  259. package/dist/devices-matter/DoorLockAccessory.js.map +0 -1
  260. package/dist/devices-matter/ExtendedColorLightAccessory.d.ts +0 -19
  261. package/dist/devices-matter/ExtendedColorLightAccessory.d.ts.map +0 -1
  262. package/dist/devices-matter/ExtendedColorLightAccessory.js +0 -108
  263. package/dist/devices-matter/ExtendedColorLightAccessory.js.map +0 -1
  264. package/dist/devices-matter/FanAccessory.d.ts +0 -14
  265. package/dist/devices-matter/FanAccessory.d.ts.map +0 -1
  266. package/dist/devices-matter/FanAccessory.js +0 -73
  267. package/dist/devices-matter/FanAccessory.js.map +0 -1
  268. package/dist/devices-matter/HumiditySensorAccessory.d.ts +0 -10
  269. package/dist/devices-matter/HumiditySensorAccessory.d.ts.map +0 -1
  270. package/dist/devices-matter/HumiditySensorAccessory.js +0 -33
  271. package/dist/devices-matter/HumiditySensorAccessory.js.map +0 -1
  272. package/dist/devices-matter/LeakSensorAccessory.d.ts +0 -10
  273. package/dist/devices-matter/LeakSensorAccessory.d.ts.map +0 -1
  274. package/dist/devices-matter/LeakSensorAccessory.js +0 -30
  275. package/dist/devices-matter/LeakSensorAccessory.js.map +0 -1
  276. package/dist/devices-matter/LightSensorAccessory.d.ts +0 -10
  277. package/dist/devices-matter/LightSensorAccessory.d.ts.map +0 -1
  278. package/dist/devices-matter/LightSensorAccessory.js +0 -33
  279. package/dist/devices-matter/LightSensorAccessory.js.map +0 -1
  280. package/dist/devices-matter/OccupancySensorAccessory.d.ts +0 -10
  281. package/dist/devices-matter/OccupancySensorAccessory.d.ts.map +0 -1
  282. package/dist/devices-matter/OccupancySensorAccessory.js +0 -43
  283. package/dist/devices-matter/OccupancySensorAccessory.js.map +0 -1
  284. package/dist/devices-matter/OnOffLightAccessory.d.ts +0 -36
  285. package/dist/devices-matter/OnOffLightAccessory.d.ts.map +0 -1
  286. package/dist/devices-matter/OnOffLightAccessory.js +0 -117
  287. package/dist/devices-matter/OnOffLightAccessory.js.map +0 -1
  288. package/dist/devices-matter/OnOffOutletAccessory.d.ts +0 -12
  289. package/dist/devices-matter/OnOffOutletAccessory.d.ts.map +0 -1
  290. package/dist/devices-matter/OnOffOutletAccessory.js +0 -43
  291. package/dist/devices-matter/OnOffOutletAccessory.js.map +0 -1
  292. package/dist/devices-matter/OnOffSwitchAccessory.d.ts +0 -12
  293. package/dist/devices-matter/OnOffSwitchAccessory.d.ts.map +0 -1
  294. package/dist/devices-matter/OnOffSwitchAccessory.js +0 -43
  295. package/dist/devices-matter/OnOffSwitchAccessory.js.map +0 -1
  296. package/dist/devices-matter/RoboticVacuumAccessory.d.ts +0 -66
  297. package/dist/devices-matter/RoboticVacuumAccessory.d.ts.map +0 -1
  298. package/dist/devices-matter/RoboticVacuumAccessory.js +0 -402
  299. package/dist/devices-matter/RoboticVacuumAccessory.js.map +0 -1
  300. package/dist/devices-matter/SmokeCOAlarmAccessory.d.ts +0 -11
  301. package/dist/devices-matter/SmokeCOAlarmAccessory.d.ts.map +0 -1
  302. package/dist/devices-matter/SmokeCOAlarmAccessory.js +0 -49
  303. package/dist/devices-matter/SmokeCOAlarmAccessory.js.map +0 -1
  304. package/dist/devices-matter/TemperatureSensorAccessory.d.ts +0 -10
  305. package/dist/devices-matter/TemperatureSensorAccessory.d.ts.map +0 -1
  306. package/dist/devices-matter/TemperatureSensorAccessory.js +0 -33
  307. package/dist/devices-matter/TemperatureSensorAccessory.js.map +0 -1
  308. package/dist/devices-matter/ThermostatAccessory.d.ts +0 -17
  309. package/dist/devices-matter/ThermostatAccessory.d.ts.map +0 -1
  310. package/dist/devices-matter/ThermostatAccessory.js +0 -87
  311. package/dist/devices-matter/ThermostatAccessory.js.map +0 -1
  312. package/dist/devices-matter/VenetianBlindAccessory.d.ts +0 -17
  313. package/dist/devices-matter/VenetianBlindAccessory.d.ts.map +0 -1
  314. package/dist/devices-matter/VenetianBlindAccessory.js +0 -100
  315. package/dist/devices-matter/VenetianBlindAccessory.js.map +0 -1
  316. package/dist/devices-matter/WindowBlindAccessory.d.ts +0 -15
  317. package/dist/devices-matter/WindowBlindAccessory.d.ts.map +0 -1
  318. package/dist/devices-matter/WindowBlindAccessory.js +0 -81
  319. package/dist/devices-matter/WindowBlindAccessory.js.map +0 -1
  320. package/dist/devices-matter/custom/PowerStripAccessory.d.ts +0 -97
  321. package/dist/devices-matter/custom/PowerStripAccessory.d.ts.map +0 -1
  322. package/dist/devices-matter/custom/PowerStripAccessory.js +0 -265
  323. package/dist/devices-matter/custom/PowerStripAccessory.js.map +0 -1
  324. package/dist/devices-matter/custom/index.d.ts +0 -8
  325. package/dist/devices-matter/custom/index.d.ts.map +0 -1
  326. package/dist/devices-matter/custom/index.js +0 -8
  327. package/dist/devices-matter/custom/index.js.map +0 -1
  328. package/dist/devices-matter/index.d.ts +0 -29
  329. package/dist/devices-matter/index.d.ts.map +0 -1
  330. package/dist/devices-matter/index.js +0 -28
  331. package/dist/devices-matter/index.js.map +0 -1
  332. package/dist/index.test.d.ts +0 -2
  333. package/dist/index.test.d.ts.map +0 -1
  334. package/dist/index.test.js +0 -14
  335. package/dist/index.test.js.map +0 -1
  336. package/dist/irdevice/airconditioner.d.ts +0 -61
  337. package/dist/irdevice/airconditioner.d.ts.map +0 -1
  338. package/dist/irdevice/airconditioner.js +0 -472
  339. package/dist/irdevice/airconditioner.js.map +0 -1
  340. package/dist/irdevice/airpurifier.d.ts +0 -50
  341. package/dist/irdevice/airpurifier.d.ts.map +0 -1
  342. package/dist/irdevice/airpurifier.js +0 -213
  343. package/dist/irdevice/airpurifier.js.map +0 -1
  344. package/dist/irdevice/camera.d.ts +0 -32
  345. package/dist/irdevice/camera.d.ts.map +0 -1
  346. package/dist/irdevice/camera.js +0 -107
  347. package/dist/irdevice/camera.js.map +0 -1
  348. package/dist/irdevice/fan.d.ts +0 -36
  349. package/dist/irdevice/fan.d.ts.map +0 -1
  350. package/dist/irdevice/fan.js +0 -200
  351. package/dist/irdevice/fan.js.map +0 -1
  352. package/dist/irdevice/irdevice.d.ts +0 -68
  353. package/dist/irdevice/irdevice.d.ts.map +0 -1
  354. package/dist/irdevice/irdevice.js +0 -298
  355. package/dist/irdevice/irdevice.js.map +0 -1
  356. package/dist/irdevice/light.d.ts +0 -36
  357. package/dist/irdevice/light.d.ts.map +0 -1
  358. package/dist/irdevice/light.js +0 -206
  359. package/dist/irdevice/light.js.map +0 -1
  360. package/dist/irdevice/other.d.ts +0 -57
  361. package/dist/irdevice/other.d.ts.map +0 -1
  362. package/dist/irdevice/other.js +0 -778
  363. package/dist/irdevice/other.js.map +0 -1
  364. package/dist/irdevice/tv.d.ts +0 -45
  365. package/dist/irdevice/tv.d.ts.map +0 -1
  366. package/dist/irdevice/tv.js +0 -327
  367. package/dist/irdevice/tv.js.map +0 -1
  368. package/dist/irdevice/vacuumcleaner.d.ts +0 -28
  369. package/dist/irdevice/vacuumcleaner.d.ts.map +0 -1
  370. package/dist/irdevice/vacuumcleaner.js +0 -104
  371. package/dist/irdevice/vacuumcleaner.js.map +0 -1
  372. package/dist/irdevice/waterheater.d.ts +0 -30
  373. package/dist/irdevice/waterheater.d.ts.map +0 -1
  374. package/dist/irdevice/waterheater.js +0 -105
  375. package/dist/irdevice/waterheater.js.map +0 -1
  376. package/dist/platform-hap.d.ts +0 -149
  377. package/dist/platform-hap.d.ts.map +0 -1
  378. package/dist/platform-hap.js +0 -2849
  379. package/dist/platform-hap.js.map +0 -1
  380. package/dist/platform-matter.d.ts +0 -75
  381. package/dist/platform-matter.d.ts.map +0 -1
  382. package/dist/platform-matter.js +0 -379
  383. package/dist/platform-matter.js.map +0 -1
  384. package/dist/verifyconfig.test.d.ts +0 -2
  385. package/dist/verifyconfig.test.d.ts.map +0 -1
  386. package/dist/verifyconfig.test.js +0 -167
  387. package/dist/verifyconfig.test.js.map +0 -1
  388. package/src/custom.d.ts +0 -7
  389. package/src/devices-hap/airpurifier.ts +0 -563
  390. package/src/devices-hap/blindtilt.ts +0 -1049
  391. package/src/devices-hap/bot.ts +0 -900
  392. package/src/devices-hap/ceilinglight.ts +0 -742
  393. package/src/devices-hap/colorbulb.ts +0 -904
  394. package/src/devices-hap/contact.ts +0 -457
  395. package/src/devices-hap/curtain.ts +0 -944
  396. package/src/devices-hap/device.ts +0 -811
  397. package/src/devices-hap/fan.ts +0 -711
  398. package/src/devices-hap/hub.ts +0 -439
  399. package/src/devices-hap/humidifier.ts +0 -669
  400. package/src/devices-hap/iosensor.ts +0 -427
  401. package/src/devices-hap/lightstrip.ts +0 -836
  402. package/src/devices-hap/lock.ts +0 -620
  403. package/src/devices-hap/meter.ts +0 -426
  404. package/src/devices-hap/meterplus.ts +0 -430
  405. package/src/devices-hap/meterpro.ts +0 -522
  406. package/src/devices-hap/motion.ts +0 -390
  407. package/src/devices-hap/plug.ts +0 -423
  408. package/src/devices-hap/relayswitch.ts +0 -727
  409. package/src/devices-hap/robotvacuumcleaner.ts +0 -568
  410. package/src/devices-hap/waterdetector.ts +0 -400
  411. package/src/devices-matter/BaseMatterAccessory.ts +0 -131
  412. package/src/devices-matter/ColorLightAccessory.ts +0 -113
  413. package/src/devices-matter/ColorTemperatureLightAccessory.ts +0 -98
  414. package/src/devices-matter/ContactSensorAccessory.ts +0 -37
  415. package/src/devices-matter/DimmableLightAccessory.ts +0 -196
  416. package/src/devices-matter/DoorLockAccessory.ts +0 -56
  417. package/src/devices-matter/ExtendedColorLightAccessory.ts +0 -127
  418. package/src/devices-matter/FanAccessory.ts +0 -87
  419. package/src/devices-matter/HumiditySensorAccessory.ts +0 -39
  420. package/src/devices-matter/LeakSensorAccessory.ts +0 -36
  421. package/src/devices-matter/LightSensorAccessory.ts +0 -39
  422. package/src/devices-matter/OccupancySensorAccessory.ts +0 -52
  423. package/src/devices-matter/OnOffLightAccessory.ts +0 -133
  424. package/src/devices-matter/OnOffOutletAccessory.ts +0 -52
  425. package/src/devices-matter/OnOffSwitchAccessory.ts +0 -52
  426. package/src/devices-matter/RoboticVacuumAccessory.ts +0 -484
  427. package/src/devices-matter/SmokeCOAlarmAccessory.ts +0 -59
  428. package/src/devices-matter/TemperatureSensorAccessory.ts +0 -39
  429. package/src/devices-matter/ThermostatAccessory.ts +0 -105
  430. package/src/devices-matter/VenetianBlindAccessory.ts +0 -118
  431. package/src/devices-matter/WindowBlindAccessory.ts +0 -94
  432. package/src/devices-matter/custom/PowerStripAccessory.ts +0 -309
  433. package/src/devices-matter/custom/index.ts +0 -8
  434. package/src/devices-matter/index.ts +0 -29
  435. package/src/index.test.ts +0 -19
  436. package/src/irdevice/airconditioner.ts +0 -533
  437. package/src/irdevice/airpurifier.ts +0 -252
  438. package/src/irdevice/camera.ts +0 -129
  439. package/src/irdevice/fan.ts +0 -226
  440. package/src/irdevice/irdevice.ts +0 -344
  441. package/src/irdevice/light.ts +0 -246
  442. package/src/irdevice/other.ts +0 -790
  443. package/src/irdevice/tv.ts +0 -378
  444. package/src/irdevice/vacuumcleaner.ts +0 -126
  445. package/src/irdevice/waterheater.ts +0 -127
  446. package/src/platform-hap.ts +0 -2986
  447. package/src/platform-matter.ts +0 -465
  448. package/src/verifyconfig.test.ts +0 -197
@@ -1,2986 +0,0 @@
1
- /* Copyright(C) 2017-2024, donavanbecker (https://github.com/donavanbecker). All rights reserved.
2
- *
3
- * platform.ts: @switchbot/homebridge-switchbot platform class.
4
- */
5
- import type { Server } from 'node:http'
6
-
7
- import type { API, DynamicPlatformPlugin, Logging, PlatformAccessory } from 'homebridge'
8
- import type { MqttClient } from 'mqtt'
9
- /*
10
- * For Testing Locally:
11
- * import type { blindTilt, curtain, curtain3, device, irdevice } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
12
- * import { LogLevel, SwitchBotBLE, SwitchBotModel, SwitchBotOpenAPI } from '/Users/Shared/GitHub/OpenWonderLabs/node-switchbot/dist/index.js';
13
- */
14
- import type { blindTilt, bodyChange, curtain, curtain3, device, deviceStatusRequest, irdevice } from 'node-switchbot'
15
-
16
- import type { blindTiltConfig, curtainConfig, devicesConfig, irDevicesConfig, options, SwitchBotPlatformConfig } from './settings.js'
17
-
18
- import { readFileSync } from 'node:fs'
19
- import { argv } from 'node:process'
20
-
21
- import asyncmqtt from 'async-mqtt'
22
- import fakegato from 'fakegato-history'
23
- import { EveHomeKitTypes } from 'homebridge-lib/EveHomeKitTypes'
24
- import { LogLevel, SwitchBotBLE, SwitchBotModel, SwitchBotOpenAPI } from 'node-switchbot'
25
- import { queueScheduler } from 'rxjs'
26
-
27
- import { AirPurifier } from './devices-hap/airpurifier.js'
28
- import { BlindTilt } from './devices-hap/blindtilt.js'
29
- import { Bot } from './devices-hap/bot.js'
30
- import { CeilingLight } from './devices-hap/ceilinglight.js'
31
- import { ColorBulb } from './devices-hap/colorbulb.js'
32
- import { Contact } from './devices-hap/contact.js'
33
- import { Curtain } from './devices-hap/curtain.js'
34
- import { Fan } from './devices-hap/fan.js'
35
- import { Hub } from './devices-hap/hub.js'
36
- import { Humidifier } from './devices-hap/humidifier.js'
37
- import { IOSensor } from './devices-hap/iosensor.js'
38
- import { StripLight } from './devices-hap/lightstrip.js'
39
- import { Lock } from './devices-hap/lock.js'
40
- import { Meter } from './devices-hap/meter.js'
41
- import { MeterPlus } from './devices-hap/meterplus.js'
42
- import { MeterPro } from './devices-hap/meterpro.js'
43
- import { Motion } from './devices-hap/motion.js'
44
- import { Plug } from './devices-hap/plug.js'
45
- import { RelaySwitch } from './devices-hap/relayswitch.js'
46
- import { RobotVacuumCleaner } from './devices-hap/robotvacuumcleaner.js'
47
- import { WaterDetector } from './devices-hap/waterdetector.js'
48
- import { AirConditioner } from './irdevice/airconditioner.js'
49
- import { AirPurifierIR } from './irdevice/airpurifier.js'
50
- import { Camera } from './irdevice/camera.js'
51
- import { IRFan } from './irdevice/fan.js'
52
- import { Light } from './irdevice/light.js'
53
- import { Others } from './irdevice/other.js'
54
- import { TV } from './irdevice/tv.js'
55
- import { VacuumCleaner } from './irdevice/vacuumcleaner.js'
56
- import { WaterHeater } from './irdevice/waterheater.js'
57
- import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js'
58
- import { cleanDeviceConfig, formatDeviceIdAsMac, isBlindTiltDevice, isCurtainDevice, safeStringify, sleep } from './utils.js'
59
-
60
- /**
61
- * HomebridgePlatform
62
- * This class is the main constructor for your plugin, this is where you should
63
- * parse the user config and discover/register accessories with Homebridge.
64
- */
65
- export class SwitchBotHAPPlatform implements DynamicPlatformPlugin {
66
- // Platform properties
67
- public accessories: PlatformAccessory[] = []
68
- public readonly api: API
69
- public readonly log: Logging
70
-
71
- // Configuration properties
72
- platformConfig!: SwitchBotPlatformConfig
73
- platformLogging!: options['logging']
74
- platformRefreshRate!: options['refreshRate']
75
- platformPushRate!: options['pushRate']
76
- platformUpdateRate!: options['updateRate']
77
- platformMaxRetries!: options['maxRetries']
78
- platformDelayBetweenRetries!: options['delayBetweenRetries']
79
- config!: SwitchBotPlatformConfig
80
- debugMode!: boolean
81
- version!: string
82
-
83
- // MQTT and Webhook properties
84
- mqttClient: MqttClient | null = null
85
- webhookEventListener: Server | null = null
86
-
87
- // SwitchBot APIs
88
- switchBotAPI!: SwitchBotOpenAPI
89
- switchBotBLE!: SwitchBotBLE
90
-
91
- // External APIs
92
- public readonly eve: any
93
- public readonly fakegatoAPI: any
94
-
95
- // Event Handlers
96
- public readonly webhookEventHandler: { [x: string]: (context: any) => void } = {}
97
- public readonly bleEventHandler: { [x: string]: (context: any) => void } = {}
98
-
99
- constructor(
100
- log: Logging,
101
- config: SwitchBotPlatformConfig,
102
- api: API,
103
- ) {
104
- this.api = api
105
- this.log = log
106
-
107
- // only load if configured
108
- if (!config) {
109
- this.log.error('No configuration found for the plugin, please check your config.')
110
- return
111
- }
112
-
113
- // Plugin options into our config variables.
114
- this.config = {
115
- platform: 'SwitchBotPlatform',
116
- name: config.name,
117
- credentials: config.credentials as object,
118
- options: config.options as object,
119
- devices: config.devices as { deviceId: string }[],
120
- }
121
-
122
- // Normalize deviceConfig to remove UI-inserted defaults (lots of false/empty values)
123
- try {
124
- if ((this.config as any).options) {
125
- const cleaned = cleanDeviceConfig((this.config as any).options.deviceConfig)
126
- if (cleaned) {
127
- ;(this.config as any).options.deviceConfig = cleaned
128
- } else {
129
- // remove the empty deviceConfig so downstream checks treat it as absent
130
- delete (this.config as any).options.deviceConfig
131
- }
132
- }
133
- } catch (e) {
134
- this.debugErrorLog(`Failed to clean deviceConfig: ${e}`)
135
- }
136
-
137
- // Plugin Configuration
138
- this.getPlatformLogSettings()
139
- this.getPlatformRateSettings()
140
- this.getPlatformConfigSettings()
141
- this.getVersion()
142
-
143
- // Finish initializing the platform
144
- this.debugLog(`Finished initializing platform: ${config.name}`)
145
-
146
- // verify the config
147
- try {
148
- this.verifyConfig()
149
- this.debugLog('Config OK')
150
- } catch (e: any) {
151
- this.errorLog(`Verify Config, Error Message: ${e.message ?? e}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug')
152
- this.debugErrorLog(`Verify Config, Error: ${e.message ?? e}`)
153
- return
154
- }
155
-
156
- // SwitchBot OpenAPI
157
- if (this.config.credentials?.token && this.config.credentials?.secret) {
158
- this.switchBotAPI = new SwitchBotOpenAPI(this.config.credentials.token, this.config.credentials.secret, this.config.options?.hostname)
159
- } else {
160
- this.debugErrorLog('Missing SwitchBot API credentials (token or secret).')
161
- }
162
- // Listen for log events
163
- if (!this.config.options?.disableLogsforOpenAPI && this.switchBotAPI) {
164
- this.switchBotAPI.on('log', (log) => {
165
- switch (log.level) {
166
- case LogLevel.SUCCESS:
167
- this.successLog(log.message)
168
- break
169
- case LogLevel.DEBUGSUCCESS:
170
- this.debugSuccessLog(log.message)
171
- break
172
- case LogLevel.WARN:
173
- this.warnLog(log.message)
174
- break
175
- case LogLevel.DEBUGWARN:
176
- this.debugWarnLog(log.message)
177
- break
178
- case LogLevel.ERROR:
179
- this.errorLog(log.message)
180
- break
181
- case LogLevel.DEBUGERROR:
182
- this.debugErrorLog(log.message)
183
- break
184
- case LogLevel.DEBUG:
185
- this.debugLog(log.message)
186
- break
187
- case LogLevel.INFO:
188
- default:
189
- this.infoLog(log.message)
190
- }
191
- })
192
- } else {
193
- this.debugErrorLog(`SwitchBot OpenAPI logs are disabled, enable it by setting disableLogsforOpenAPI to false.`)
194
- this.debugLog(`SwitchBot OpenAPI: ${JSON.stringify(this.switchBotAPI)}, disableLogsforOpenAPI: ${this.config.options?.disableLogsforOpenAPI}`)
195
- }
196
- // import fakegato-history module and EVE characteristics
197
- this.fakegatoAPI = fakegato(api)
198
- this.eve = new EveHomeKitTypes(api)
199
-
200
- // When this event is fired it means Homebridge has restored all cached accessories from disk.
201
- // Dynamic Platform plugins should only register new accessories after this event was fired,
202
- // in order to ensure they weren't added to homebridge already. This event can also be used
203
- // to start discovery of new accessories.
204
- this.api.on('didFinishLaunching', async () => {
205
- this.debugLog('Executed didFinishLaunching callback')
206
- // run the method to discover / register your devices as accessories
207
- try {
208
- await this.discoverDevices()
209
- } catch (e: any) {
210
- this.errorLog(`Failed to Discover, Error Message: ${e.message ?? e}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug')
211
- this.debugErrorLog(`Failed to Discover, Error: ${e.message ?? e}`)
212
- }
213
- })
214
-
215
- try {
216
- this.setupMqtt()
217
- } catch (e: any) {
218
- this.errorLog(`Setup MQTT, Error Message: ${e.message ?? e}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug')
219
- }
220
- try {
221
- this.setupwebhook()
222
- } catch (e: any) {
223
- this.errorLog(`Setup Webhook, Error Message: ${e.message ?? e}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug')
224
- }
225
- try {
226
- this.setupBlE()
227
- } catch (e: any) {
228
- this.errorLog(`Setup Platform BLE, Error Message: ${e.message ?? e}, Submit Bugs Here: ` + 'https://tinyurl.com/SwitchBotBug')
229
- }
230
- }
231
-
232
- async setupMqtt(): Promise<void> {
233
- if (this.config.options?.mqttURL) {
234
- try {
235
- const { connectAsync } = asyncmqtt
236
- this.mqttClient = await connectAsync(this.config.options?.mqttURL, this.config.options.mqttOptions || {})
237
- this.debugLog('MQTT connection has been established successfully.')
238
- this.mqttClient.on('error', async (e: Error) => {
239
- this.errorLog(`Failed to publish MQTT messages. ${e.message ?? e}`)
240
- })
241
- if (!this.config.options?.webhookURL) {
242
- // receive webhook events via MQTT
243
- this.infoLog(`Webhook is configured to be received through ${this.config.options.mqttURL}/homebridge-switchbot/webhook.`)
244
- this.mqttClient.subscribe('homebridge-switchbot/webhook/+')
245
- this.mqttClient.on('message', async (topic: string, message) => {
246
- try {
247
- this.debugLog(`Received Webhook via MQTT: ${topic}=${message}`)
248
- const context = JSON.parse(message.toString())
249
- this.webhookEventHandler[context.deviceMac]?.(context)
250
- } catch (e: any) {
251
- this.errorLog(`Failed to handle webhook event. Error: ${e.message ?? e}`)
252
- }
253
- })
254
- }
255
- } catch (e: any) {
256
- this.mqttClient = null
257
- this.errorLog(`Failed to establish MQTT connection. ${e.message ?? e}`)
258
- }
259
- }
260
- }
261
-
262
- async setupwebhook() {
263
- // webhook configuration
264
- if (this.config.options?.webhookURL) {
265
- const url = this.config.options?.webhookURL
266
- try {
267
- this.switchBotAPI.setupWebhook(url)
268
- // Listen for webhook events
269
- this.switchBotAPI.on('webhookEvent', (body) => {
270
- if (this.config.options?.mqttURL) {
271
- const mac = body.context.deviceMac?.toLowerCase().match(/[\s\S]{1,2}/g)?.join(':')
272
- const options = this.config.options?.mqttPubOptions || {}
273
- this.mqttClient?.publish(`homebridge-switchbot/webhook/${mac}`, `${JSON.stringify(body.context)}`, options)
274
- }
275
- this.webhookEventHandler[body.context.deviceMac]?.(body.context)
276
- })
277
- } catch (e: any) {
278
- this.errorLog(`Failed to setup webhook. Error: ${e.message ?? e}`)
279
- }
280
-
281
- this.api.on('shutdown', async () => {
282
- try {
283
- this.switchBotAPI.deleteWebhook(url)
284
- } catch (e: any) {
285
- this.errorLog(`Failed to delete webhook. Error: ${e.message ?? e}`)
286
- }
287
- })
288
- }
289
- }
290
-
291
- async setupBlE() {
292
- this.switchBotBLE = new SwitchBotBLE()
293
- // Listen for log events
294
- if (!this.config.options?.disableLogsforBLE) {
295
- this.switchBotBLE.on('log', (log) => {
296
- switch (log.level) {
297
- case LogLevel.SUCCESS:
298
- this.successLog(log.message)
299
- break
300
- case LogLevel.DEBUGSUCCESS:
301
- this.debugSuccessLog(log.message)
302
- break
303
- case LogLevel.WARN:
304
- this.warnLog(log.message)
305
- break
306
- case LogLevel.DEBUGWARN:
307
- this.debugWarnLog(log.message)
308
- break
309
- case LogLevel.ERROR:
310
- this.errorLog(log.message)
311
- break
312
- case LogLevel.DEBUGERROR:
313
- this.debugErrorLog(log.message)
314
- break
315
- case LogLevel.DEBUG:
316
- this.debugLog(log.message)
317
- break
318
- case LogLevel.INFO:
319
- default:
320
- this.infoLog(log.message)
321
- }
322
- })
323
- }
324
- if (this.config.options?.BLE) {
325
- this.debugLog('setupBLE')
326
- if (this.switchBotBLE === undefined) {
327
- this.errorLog(`wasn't able to establish BLE Connection, node-switchbot: ${JSON.stringify(this.switchBotBLE)}`)
328
- } else {
329
- // Start to monitor advertisement packets
330
- (async () => {
331
- // Start to monitor advertisement packets
332
- this.debugLog('Scanning for BLE SwitchBot devices...')
333
- try {
334
- await this.switchBotBLE.startScan()
335
- } catch (e: any) {
336
- this.errorLog(`Failed to start BLE scanning. Error: ${e.message ?? e}`)
337
- }
338
- // Set an event handler to monitor advertisement packets
339
- this.switchBotBLE.onadvertisement = async (ad: any) => {
340
- try {
341
- this.bleEventHandler[ad.address]?.(ad.serviceData)
342
- } catch (e: any) {
343
- this.errorLog(`Failed to handle BLE event. Error: ${e.message ?? e}`)
344
- }
345
- }
346
- })()
347
-
348
- this.api.on('shutdown', async () => {
349
- try {
350
- // this.switchBotBLE.stopScan()
351
- this.infoLog('Stopped BLE scanning to close listening.')
352
- } catch (e: any) {
353
- this.errorLog(`Failed to stop Platform BLE scanning. Error: ${e.message ?? e}`)
354
- }
355
- })
356
- }
357
- } else {
358
- this.debugLog('Platform BLE is not enabled')
359
- }
360
- }
361
-
362
- /**
363
- * This function is invoked when homebridge restores cached accessories from disk at startup.
364
- * It should be used to setup event handlers for characteristics and update respective values.
365
- */
366
- async configureAccessory(accessory: PlatformAccessory) {
367
- const { displayName } = accessory
368
- this.debugLog(`Loading accessory from cache: ${displayName}`)
369
-
370
- // add the restored accessory to the accessories cache so we can track if it has already been registered
371
- this.accessories.push(accessory)
372
- }
373
-
374
- /**
375
- * Verify the config passed to the plugin is valid
376
- */
377
- async verifyConfig() {
378
- this.debugLog('Verifying Config')
379
- this.config = this.config || {}
380
- this.config.options = this.config.options || {}
381
-
382
- if (this.config.options) {
383
- // Device Config
384
- if (this.config.options.devices) {
385
- for (const deviceConfig of this.config.options.devices) {
386
- if (!deviceConfig.hide_device) {
387
- if (!deviceConfig.deviceId) {
388
- this.errorLog('The devices config section is missing the *Device ID* in the config. Please check your config.')
389
- }
390
- if (!deviceConfig.configDeviceType && (deviceConfig as devicesConfig).connectionType) {
391
- this.errorLog('The devices config section is missing the *Device Type* in the config. Please check your config.')
392
- }
393
- }
394
- }
395
- }
396
-
397
- // IR Device Config
398
- if (this.config.options.irdevices) {
399
- for (const irDeviceConfig of this.config.options.irdevices) {
400
- if (!irDeviceConfig.hide_device) {
401
- if (!irDeviceConfig.deviceId) {
402
- this.errorLog('The devices config section is missing the *Device ID* in the config. Please check your config.')
403
- }
404
- if (!irDeviceConfig.deviceId && !irDeviceConfig.configRemoteType) {
405
- this.errorLog('The devices config section is missing the *Device Type* in the config. Please check your config.')
406
- }
407
- }
408
- }
409
- }
410
- }
411
-
412
- if (!this.config.credentials && !this.config.options) {
413
- this.debugWarnLog('Missing Credentials')
414
- } else if (this.config.credentials && !this.config.credentials.notice) {
415
- if (!this.config.credentials?.token) {
416
- this.debugErrorLog('Missing token')
417
- this.debugWarnLog('Cloud Enabled SwitchBot Devices & IR Devices will not work')
418
- }
419
- if (this.config.credentials?.token) {
420
- if (!this.config.credentials?.secret) {
421
- this.debugErrorLog('Missing secret')
422
- this.debugWarnLog('Cloud Enabled SwitchBot Devices & IR Devices will not work')
423
- }
424
- }
425
- }
426
- }
427
-
428
- async discoverDevices() {
429
- if (!this.config.credentials?.token) {
430
- return this.handleManualConfig()
431
- }
432
-
433
- let retryCount = 0
434
- const maxRetries = this.platformMaxRetries ?? 5
435
- const delayBetweenRetries = this.platformDelayBetweenRetries || 5000
436
-
437
- this.debugWarnLog(`Retry Count: ${retryCount}`)
438
- this.debugWarnLog(`Max Retries: ${this.platformMaxRetries}`)
439
- this.debugWarnLog(`Delay Between Retries: ${this.platformDelayBetweenRetries}`)
440
-
441
- while (retryCount < maxRetries) {
442
- try {
443
- const { response, statusCode } = await this.switchBotAPI.getDevices()
444
- this.debugLog(`response: ${JSON.stringify(response)}`)
445
- if (this.isSuccessfulResponse(statusCode)) {
446
- await this.handleDevices(Array.isArray(response.body.deviceList) ? response.body.deviceList : [])
447
- await this.handleIRDevices(Array.isArray(response.body.infraredRemoteList) ? response.body.infraredRemoteList : [])
448
- break
449
- } else {
450
- await this.handleErrorResponse(statusCode, retryCount, maxRetries, delayBetweenRetries)
451
- retryCount++
452
- }
453
- } catch (e: any) {
454
- retryCount++
455
- this.debugErrorLog(`Failed to Discover Devices, Error Message: ${JSON.stringify(e.message)}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`)
456
- this.debugErrorLog(`Failed to Discover Devices, Error: ${e.message ?? e}`)
457
- }
458
- }
459
- }
460
-
461
- private async handleManualConfig() {
462
- if (this.config.options?.devices) {
463
- this.debugLog(`SwitchBot Device Manual Config Set: ${JSON.stringify(this.config.options?.devices)}`)
464
- const devices = this.config.options.devices.map((v: any) => v)
465
- for (const device of devices) {
466
- device.deviceType = device.configDeviceType !== undefined ? device.configDeviceType : 'Unknown'
467
- device.deviceName = device.configDeviceName !== undefined ? device.configDeviceName : 'Unknown'
468
- try {
469
- device.deviceId = formatDeviceIdAsMac(device.deviceId, true)
470
- this.debugLog(`deviceId: ${device.deviceId}`)
471
- if (device.deviceType) {
472
- await this.createDevice(device)
473
- }
474
- } catch (error) {
475
- this.errorLog(`failed to format device ID as MAC, Error: ${error}`)
476
- }
477
- }
478
- } else {
479
- this.errorLog('Neither SwitchBot Token or Device Config are set.')
480
- }
481
- }
482
-
483
- private isSuccessfulResponse(apiStatusCode: number): boolean {
484
- return (apiStatusCode === 200 || apiStatusCode === 100)
485
- }
486
-
487
- private async handleDevices(deviceLists: any[]) {
488
- if (!this.config.options?.devices && !this.config.options?.deviceConfig) {
489
- this.debugLog(`SwitchBot Device Config Not Set: ${JSON.stringify(this.config.options?.devices)}`)
490
- if (deviceLists.length === 0) {
491
- this.debugLog('SwitchBot API Has No Devices With Cloud Services Enabled')
492
- } else {
493
- for (const device of deviceLists) {
494
- if (device.deviceType) {
495
- if (device.configDeviceName) {
496
- device.deviceName = device.configDeviceName
497
- }
498
- await this.createDevice(device)
499
- }
500
- }
501
- }
502
- } else if (this.config.options?.devices || this.config.options?.deviceConfig) {
503
- this.debugLog(`SwitchBot Device Config Set: ${JSON.stringify(this.config.options?.devices)}`)
504
-
505
- // Step 1: Check and assign configDeviceType to deviceType if deviceType is not present
506
- const devicesWithTypeConfigPromises = deviceLists.map(async (device) => {
507
- if (!device.deviceType) {
508
- device.deviceType = device.configDeviceType !== undefined ? device.configDeviceType : 'Unknown'
509
- this.warnLog(`API is displaying no deviceType: ${device.deviceType}, So using configDeviceType: ${device.configDeviceType}`)
510
- }
511
-
512
- // Retrieve deviceTypeConfig for each device and merge it
513
- const deviceTypeConfig = this.config.options?.deviceConfig?.[device.deviceType] || {}
514
- return Object.assign({}, device, deviceTypeConfig)
515
- })
516
-
517
- // Wait for all promises to resolve
518
- const devicesWithTypeConfig = (await Promise.all(devicesWithTypeConfigPromises)).filter(device => device !== null) // Filter out skipped devices
519
-
520
- const devices = this.mergeByDeviceId(this.config.options.devices ?? [], devicesWithTypeConfig ?? [])
521
-
522
- this.debugLog(`SwitchBot Devices: ${JSON.stringify(devices)}`)
523
-
524
- for (const device of devices) {
525
- const deviceIdConfig = this.config.options?.devices?.[device.deviceId] || {}
526
- const deviceWithConfig = Object.assign({}, device, deviceIdConfig)
527
-
528
- if (device.configDeviceName) {
529
- device.deviceName = device.configDeviceName
530
- }
531
- // Pass the merged device object to createDevice
532
- await this.createDevice(deviceWithConfig)
533
- }
534
- }
535
- }
536
-
537
- private async handleIRDevices(irDeviceLists: any[]) {
538
- if (!this.config.options?.irdevices && !this.config.options?.irdeviceConfig) {
539
- this.debugLog(`IR Device Config Not Set: ${JSON.stringify(this.config.options?.irdevices)}`)
540
- for (const device of irDeviceLists) {
541
- if (device.remoteType) {
542
- await this.createIRDevice(device)
543
- }
544
- }
545
- } else if (this.config.options?.irdevices || this.config.options?.irdeviceConfig) {
546
- this.debugLog(`IR Device Config Set: ${JSON.stringify(this.config.options?.irdevices)}`)
547
-
548
- // Step 1: Check and assign configRemoteType to remoteType if remoteType is not present
549
- const devicesWithTypeConfigPromises = irDeviceLists.map(async (device) => {
550
- if (!device.remoteType && device.configRemoteType) {
551
- device.remoteType = device.configRemoteType
552
- this.warnLog(`API is displaying no remoteType: ${device.remoteType}, So using configRemoteType: ${device.configRemoteType}`)
553
- } else if (!device.remoteType && !device.configDeviceName) {
554
- this.errorLog('No remoteType or configRemoteType for device. No device will be created.')
555
- return null // Skip this device
556
- }
557
-
558
- // Retrieve remoteTypeConfig for each device and merge it
559
- const remoteTypeConfig = this.config.options?.irdeviceConfig?.[device.remoteType] || {}
560
- return Object.assign({}, device, remoteTypeConfig)
561
- })
562
- // Wait for all promises to resolve
563
- const devicesWithRemoteTypeConfig = (await Promise.all(devicesWithTypeConfigPromises)).filter(device => device !== null) // Filter out skipped devices
564
-
565
- const devices = this.mergeByDeviceId(this.config.options.irdevices ?? [], devicesWithRemoteTypeConfig ?? [])
566
-
567
- this.debugLog(`IR Devices: ${JSON.stringify(devices)}`)
568
- for (const device of devices) {
569
- const irdeviceIdConfig = this.config.options?.irdevices?.[device.deviceId] || {}
570
- const irdeviceWithConfig = Object.assign({}, device, irdeviceIdConfig)
571
-
572
- if (device.configDeviceName) {
573
- device.deviceName = device.configDeviceName
574
- }
575
- await this.createIRDevice(irdeviceWithConfig)
576
- }
577
- }
578
- }
579
-
580
- private mergeByDeviceId(a1: { deviceId: string }[], a2: any[]) {
581
- const normalizeDeviceId = (deviceId: string) => deviceId.toUpperCase().replace(/[^A-Z0-9]+/g, '')
582
- return a1.map((itm) => {
583
- const matchingItem = a2.find(item => normalizeDeviceId(item.deviceId) === normalizeDeviceId(itm.deviceId))
584
- return { ...matchingItem, ...itm }
585
- })
586
- }
587
-
588
- private async handleErrorResponse(apiStatusCode: number, retryCount: number, maxRetries: number, delayBetweenRetries: number) {
589
- await this.statusCode(apiStatusCode)
590
- if (apiStatusCode === 500) {
591
- this.infoLog(`statusCode: ${apiStatusCode} Attempt ${retryCount + 1} of ${maxRetries}`)
592
- await sleep(delayBetweenRetries)
593
- }
594
- }
595
-
596
- private async createDevice(device: device & devicesConfig) {
597
- const deviceTypeHandlers: { [key: string]: (device: device & devicesConfig) => Promise<void> } = {
598
- 'Humidifier': this.createHumidifier.bind(this),
599
- 'Humidifier2': this.createHumidifier.bind(this),
600
- 'Hub 2': this.createHub2.bind(this),
601
- 'Hub 3': this.createHub2.bind(this),
602
- 'Bot': this.createBot.bind(this),
603
- 'Relay Switch 1': this.createRelaySwitch.bind(this),
604
- 'Relay Switch 1PM': this.createRelaySwitch.bind(this),
605
- 'Meter': this.createMeter.bind(this),
606
- 'MeterPlus': this.createMeterPlus.bind(this),
607
- 'Meter Plus (JP)': this.createMeterPlus.bind(this),
608
- 'MeterPro': this.createMeterPro.bind(this),
609
- 'MeterPro(CO2)': this.createMeterPro.bind(this),
610
- 'WoIOSensor': this.createIOSensor.bind(this),
611
- 'Water Detector': this.createWaterDetector.bind(this),
612
- 'Motion Sensor': this.createMotion.bind(this),
613
- 'Contact Sensor': this.createContact.bind(this),
614
- 'Curtain': this.createCurtain.bind(this),
615
- 'Curtain3': this.createCurtain.bind(this),
616
- 'WoRollerShade': this.createCurtain.bind(this),
617
- 'Roller Shade': this.createCurtain.bind(this),
618
- 'Blind Tilt': this.createBlindTilt.bind(this),
619
- 'Plug': this.createPlug.bind(this),
620
- 'Plug Mini (US)': this.createPlug.bind(this),
621
- 'Plug Mini (JP)': this.createPlug.bind(this),
622
- 'Smart Lock': this.createLock.bind(this),
623
- 'Smart Lock Pro': this.createLock.bind(this),
624
- 'Color Bulb': this.createColorBulb.bind(this),
625
- 'K10+': this.createRobotVacuumCleaner.bind(this),
626
- 'K10+ Pro': this.createRobotVacuumCleaner.bind(this),
627
- 'WoSweeper': this.createRobotVacuumCleaner.bind(this),
628
- 'WoSweeperMini': this.createRobotVacuumCleaner.bind(this),
629
- 'Robot Vacuum Cleaner S1': this.createRobotVacuumCleaner.bind(this),
630
- 'Robot Vacuum Cleaner S1 Plus': this.createRobotVacuumCleaner.bind(this),
631
- 'Robot Vacuum Cleaner S10': this.createRobotVacuumCleaner.bind(this),
632
- 'Ceiling Light': this.createCeilingLight.bind(this),
633
- 'Ceiling Light Pro': this.createCeilingLight.bind(this),
634
- 'Strip Light': this.createStripLight.bind(this),
635
- 'Battery Circulator Fan': this.createFan.bind(this),
636
- 'Air Purifier PM2.5': this.createAirPurifier.bind(this),
637
- 'Air Purifier Table PM2.5': this.createAirPurifier.bind(this),
638
- 'Air Purifier VOC': this.createAirPurifier.bind(this),
639
- 'Air Purifier Table VOC': this.createAirPurifier.bind(this),
640
- }
641
-
642
- if (deviceTypeHandlers[device.deviceType!]) {
643
- this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}`)
644
- await deviceTypeHandlers[device.deviceType!](device)
645
- } else if (['Hub Mini', 'Hub Plus', 'Remote', 'Indoor Cam', 'remote with screen'].includes(device.deviceType!)) {
646
- this.debugLog(`Discovered ${device.deviceType}: ${device.deviceId}, is currently not supported, device: ${JSON.stringify(device)}`)
647
- } else {
648
- this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.deviceType}, is currently not supported. Submit Feature Requests Here: https://tinyurl.com/SwitchBotFeatureRequest, device: ${JSON.stringify(device)}`)
649
- }
650
- }
651
-
652
- private async createIRDevice(device: irdevice & irDevicesConfig) {
653
- device.connectionType = device.connectionType ?? 'OpenAPI'
654
- const deviceTypeHandlers: { [key: string]: (device: irdevice & irDevicesConfig) => Promise<void> } = {
655
- 'TV': this.createTV.bind(this),
656
- 'DIY TV': this.createTV.bind(this),
657
- 'Projector': this.createTV.bind(this),
658
- 'DIY Projector': this.createTV.bind(this),
659
- 'Set Top Box': this.createTV.bind(this),
660
- 'DIY Set Top Box': this.createTV.bind(this),
661
- 'IPTV': this.createTV.bind(this),
662
- 'DIY IPTV': this.createTV.bind(this),
663
- 'DVD': this.createTV.bind(this),
664
- 'DIY DVD': this.createTV.bind(this),
665
- 'Speaker': this.createTV.bind(this),
666
- 'DIY Speaker': this.createTV.bind(this),
667
- 'Fan': this.createIRFan.bind(this),
668
- 'DIY Fan': this.createIRFan.bind(this),
669
- 'Air Conditioner': this.createAirConditioner.bind(this),
670
- 'DIY Air Conditioner': this.createAirConditioner.bind(this),
671
- 'Light': this.createLight.bind(this),
672
- 'DIY Light': this.createLight.bind(this),
673
- 'Air Purifier': this.createAirPurifierIR.bind(this),
674
- 'DIY Air Purifier': this.createAirPurifierIR.bind(this),
675
- 'Water Heater': this.createWaterHeater.bind(this),
676
- 'DIY Water Heater': this.createWaterHeater.bind(this),
677
- 'Vacuum Cleaner': this.createVacuumCleaner.bind(this),
678
- 'DIY Vacuum Cleaner': this.createVacuumCleaner.bind(this),
679
- 'Camera': this.createCamera.bind(this),
680
- 'DIY Camera': this.createCamera.bind(this),
681
- 'Others': this.createOthers.bind(this),
682
- }
683
-
684
- if (deviceTypeHandlers[device.remoteType!]) {
685
- this.debugLog(`Discovered ${device.remoteType}: ${device.deviceId}`)
686
- if (device.remoteType.startsWith('DIY') && device.external === undefined) {
687
- device.external = true
688
- }
689
- await deviceTypeHandlers[device.remoteType!](device)
690
- } else {
691
- this.warnLog(`Device: ${device.deviceName} with Device Type: ${device.remoteType}, is currently not supported. Submit Feature Requests Here: https://tinyurl.com/SwitchBotFeatureRequest, device: ${JSON.stringify(device)}`)
692
- }
693
- }
694
-
695
- private async createHumidifier(device: device & devicesConfig) {
696
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
697
-
698
- // see if an accessory with the same uuid has already been registered and restored from
699
- // the cached devices we stored in the `configureAccessory` method above
700
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
701
-
702
- if (existingAccessory) {
703
- // the accessory already exists
704
- if (await this.registerDevice(device)) {
705
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
706
- existingAccessory.context.device = device
707
- existingAccessory.context.deviceId = device.deviceId
708
- existingAccessory.context.deviceType = device.deviceType
709
- existingAccessory.context.model = device.deviceType === 'Humidifier2' ? SwitchBotModel.Humidifier2 : SwitchBotModel.Humidifier
710
- existingAccessory.displayName = device.configDeviceName
711
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
712
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
713
- existingAccessory.context.connectionType = await this.connectionType(device)
714
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
715
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
716
- this.api.updatePlatformAccessories([existingAccessory])
717
- // create the accessory handler for the restored accessory
718
- // this is imported from `platformAccessory.ts`
719
- new Humidifier(this, existingAccessory, device)
720
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
721
- } else {
722
- this.unregisterPlatformAccessories(existingAccessory)
723
- }
724
- } else if (await this.registerDevice(device)) {
725
- // create a new accessory
726
- const accessory = new this.api.platformAccessory(device.configDeviceName
727
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
728
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
729
-
730
- // store a copy of the device object in the `accessory.context`
731
- // the `context` property can be used to store any data about the accessory you may need
732
- accessory.context.device = device
733
- accessory.context.deviceId = device.deviceId
734
- accessory.context.deviceType = device.deviceType
735
- accessory.context.model = device.deviceType === 'Humidifier2' ? SwitchBotModel.Humidifier2 : SwitchBotModel.Humidifier
736
- accessory.displayName = device.configDeviceName
737
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
738
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
739
- accessory.context.connectionType = await this.connectionType(device)
740
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
741
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
742
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
743
- // create the accessory handler for the newly create accessory
744
- // this is imported from `platformAccessory.ts`
745
- new Humidifier(this, accessory, device)
746
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
747
-
748
- // publish device externally or link the accessory to your platform
749
- this.externalOrPlatform(device, accessory)
750
- this.accessories.push(accessory)
751
- } else {
752
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
753
- }
754
- }
755
-
756
- private async createBot(device: device & devicesConfig) {
757
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
758
-
759
- // see if an accessory with the same uuid has already been registered and restored from
760
- // the cached devices we stored in the `configureAccessory` method above
761
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
762
-
763
- if (existingAccessory) {
764
- // the accessory already exists
765
- if (await this.registerDevice(device)) {
766
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
767
- existingAccessory.context.device = device
768
- existingAccessory.context.deviceId = device.deviceId
769
- existingAccessory.context.deviceType = device.deviceType
770
- existingAccessory.context.model = SwitchBotModel.Bot
771
- existingAccessory.displayName = device.configDeviceName
772
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
773
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
774
- existingAccessory.context.connectionType = await this.connectionType(device)
775
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
776
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
777
- this.api.updatePlatformAccessories([existingAccessory])
778
- // create the accessory handler for the restored accessory
779
- // this is imported from `platformAccessory.ts`
780
- new Bot(this, existingAccessory, device)
781
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
782
- } else {
783
- this.unregisterPlatformAccessories(existingAccessory)
784
- }
785
- } else if (await this.registerDevice(device)) {
786
- // create a new accessory
787
- const accessory = new this.api.platformAccessory(device.configDeviceName
788
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
789
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
790
-
791
- // store a copy of the device object in the `accessory.context`
792
- // the `context` property can be used to store any data about the accessory you may need
793
- accessory.context.device = device
794
- accessory.context.deviceId = device.deviceId
795
- accessory.context.deviceType = device.deviceType
796
- accessory.context.model = SwitchBotModel.Bot
797
- accessory.displayName = device.configDeviceName
798
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
799
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
800
- accessory.context.connectionType = await this.connectionType(device)
801
- accessory.context.connectionType = await this.connectionType(device)
802
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
803
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
804
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
805
- // accessory.context.version = findaccessories.accessoryAttribute.softwareRevision;
806
- // create the accessory handler for the newly create accessory
807
- // this is imported from `platformAccessory.ts`
808
- new Bot(this, accessory, device)
809
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
810
-
811
- // publish device externally or link the accessory to your platform
812
- this.externalOrPlatform(device, accessory)
813
- this.accessories.push(accessory)
814
- } else {
815
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
816
- }
817
- }
818
-
819
- private async createRelaySwitch(device: device & devicesConfig) {
820
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
821
-
822
- // see if an accessory with the same uuid has already been registered and restored from
823
- // the cached devices we stored in the `configureAccessory` method above
824
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
825
-
826
- if (existingAccessory) {
827
- // the accessory already exists
828
- if (await this.registerDevice(device)) {
829
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
830
- existingAccessory.context.device = device
831
- existingAccessory.context.deviceId = device.deviceId
832
- existingAccessory.context.deviceType = device.deviceType
833
- existingAccessory.context.model = device.deviceType === 'Relay Switch 1' ? SwitchBotModel.RelaySwitch1 : SwitchBotModel.RelaySwitch1PM
834
- existingAccessory.displayName = device.configDeviceName
835
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
836
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
837
- existingAccessory.context.connectionType = await this.connectionType(device)
838
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
839
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
840
- this.api.updatePlatformAccessories([existingAccessory])
841
- // create the accessory handler for the restored accessory
842
- // this is imported from `platformAccessory.ts`
843
- new RelaySwitch(this, existingAccessory, device)
844
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
845
- } else {
846
- this.unregisterPlatformAccessories(existingAccessory)
847
- }
848
- } else if (await this.registerDevice(device)) {
849
- // create a new accessory
850
- const accessory = new this.api.platformAccessory(device.configDeviceName
851
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
852
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
853
-
854
- // store a copy of the device object in the `accessory.context`
855
- // the `context` property can be used to store any data about the accessory you may need
856
- accessory.context.device = device
857
- accessory.context.deviceId = device.deviceId
858
- accessory.context.deviceType = device.deviceType
859
- accessory.context.model = device.deviceType === 'Relay Switch 1' ? SwitchBotModel.RelaySwitch1 : SwitchBotModel.RelaySwitch1PM
860
- accessory.displayName = device.configDeviceName
861
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
862
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
863
- accessory.context.connectionType = await this.connectionType(device)
864
- accessory.context.connectionType = await this.connectionType(device)
865
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
866
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
867
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
868
- // accessory.context.version = findaccessories.accessoryAttribute.softwareRevision;
869
- // create the accessory handler for the newly create accessory
870
- // this is imported from `platformAccessory.ts`
871
- new RelaySwitch(this, accessory, device)
872
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
873
-
874
- // publish device externally or link the accessory to your platform
875
- this.externalOrPlatform(device, accessory)
876
- this.accessories.push(accessory)
877
- } else {
878
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
879
- }
880
- }
881
-
882
- private async createMeter(device: device & devicesConfig) {
883
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
884
-
885
- // see if an accessory with the same uuid has already been registered and restored from
886
- // the cached devices we stored in the `configureAccessory` method above
887
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
888
-
889
- if (existingAccessory) {
890
- // the accessory already exists
891
- if (await this.registerDevice(device)) {
892
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
893
- existingAccessory.context.device = device
894
- existingAccessory.context.model = SwitchBotModel.Meter
895
- existingAccessory.context.deviceId = device.deviceId
896
- existingAccessory.context.deviceType = device.deviceType
897
- existingAccessory.displayName = device.configDeviceName
898
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
899
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
900
- existingAccessory.context.connectionType = await this.connectionType(device)
901
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
902
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
903
- this.api.updatePlatformAccessories([existingAccessory])
904
- // create the accessory handler for the restored accessory
905
- // this is imported from `platformAccessory.ts`
906
- new Meter(this, existingAccessory, device)
907
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
908
- } else {
909
- this.unregisterPlatformAccessories(existingAccessory)
910
- }
911
- } else if (await this.registerDevice(device)) {
912
- // create a new accessory
913
- const accessory = new this.api.platformAccessory(device.configDeviceName
914
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
915
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
916
-
917
- // store a copy of the device object in the `accessory.context`
918
- // the `context` property can be used to store any data about the accessory you may need
919
- accessory.context.device = device
920
- accessory.context.model = SwitchBotModel.Meter
921
- accessory.context.deviceId = device.deviceId
922
- accessory.context.deviceType = device.deviceType
923
- accessory.displayName = device.configDeviceName
924
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
925
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
926
- accessory.context.connectionType = await this.connectionType(device)
927
- accessory.context.connectionType = await this.connectionType(device)
928
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
929
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
930
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
931
- // create the accessory handler for the newly create accessory
932
- // this is imported from `platformAccessory.ts`
933
- new Meter(this, accessory, device)
934
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
935
-
936
- // publish device externally or link the accessory to your platform
937
- this.externalOrPlatform(device, accessory)
938
- this.accessories.push(accessory)
939
- } else {
940
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
941
- }
942
- }
943
-
944
- private async createMeterPlus(device: device & devicesConfig) {
945
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
946
-
947
- // see if an accessory with the same uuid has already been registered and restored from
948
- // the cached devices we stored in the `configureAccessory` method above
949
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
950
-
951
- if (existingAccessory) {
952
- // the accessory already exists
953
- if (await this.registerDevice(device)) {
954
- // console.log("existingAccessory", existingAccessory);
955
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
956
- existingAccessory.context.device = device
957
- existingAccessory.context.model = SwitchBotModel.MeterPlusUS ?? SwitchBotModel.MeterPlusJP
958
- existingAccessory.context.deviceId = device.deviceId
959
- existingAccessory.context.deviceType = device.deviceType
960
- existingAccessory.displayName = device.configDeviceName
961
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
962
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
963
- existingAccessory.context.connectionType = await this.connectionType(device)
964
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
965
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
966
- this.api.updatePlatformAccessories([existingAccessory])
967
- // create the accessory handler for the restored accessory
968
- // this is imported from `platformAccessory.ts`
969
- new MeterPlus(this, existingAccessory, device)
970
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
971
- } else {
972
- this.unregisterPlatformAccessories(existingAccessory)
973
- }
974
- } else if (await this.registerDevice(device)) {
975
- // create a new accessory
976
- const accessory = new this.api.platformAccessory(device.configDeviceName
977
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
978
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
979
-
980
- // store a copy of the device object in the `accessory.context`
981
- // the `context` property can be used to store any data about the accessory you may need
982
- accessory.context.device = device
983
- accessory.context.model = SwitchBotModel.MeterPlusUS ?? SwitchBotModel.MeterPlusJP
984
- accessory.context.deviceId = device.deviceId
985
- accessory.context.deviceType = device.deviceType
986
- accessory.displayName = device.configDeviceName
987
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
988
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
989
- accessory.context.connectionType = await this.connectionType(device)
990
- accessory.context.connectionType = await this.connectionType(device)
991
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
992
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
993
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
994
- // create the accessory handler for the newly create accessory
995
- // this is imported from `platformAccessory.ts`
996
- new MeterPlus(this, accessory, device)
997
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
998
-
999
- // publish device externally or link the accessory to your platform
1000
- this.externalOrPlatform(device, accessory)
1001
- this.accessories.push(accessory)
1002
- } else {
1003
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1004
- }
1005
- }
1006
-
1007
- private async createMeterPro(device: device & devicesConfig) {
1008
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1009
-
1010
- // see if an accessory with the same uuid has already been registered and restored from
1011
- // the cached devices we stored in the `configureAccessory` method above
1012
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1013
-
1014
- if (existingAccessory) {
1015
- // the accessory already exists
1016
- if (await this.registerDevice(device)) {
1017
- // console.log("existingAccessory", existingAccessory);
1018
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1019
- existingAccessory.context.device = device
1020
- existingAccessory.context.model = SwitchBotModel.MeterPro ?? SwitchBotModel.MeterProCO2
1021
- existingAccessory.context.deviceId = device.deviceId
1022
- existingAccessory.context.deviceType = device.deviceType
1023
- existingAccessory.displayName = device.configDeviceName
1024
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1025
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1026
- existingAccessory.context.connectionType = await this.connectionType(device)
1027
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1028
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1029
- this.api.updatePlatformAccessories([existingAccessory])
1030
- // create the accessory handler for the restored accessory
1031
- // this is imported from `platformAccessory.ts`
1032
- new MeterPro(this, existingAccessory, device)
1033
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1034
- } else {
1035
- this.unregisterPlatformAccessories(existingAccessory)
1036
- }
1037
- } else if (await this.registerDevice(device)) {
1038
- // create a new accessory
1039
- const accessory = new this.api.platformAccessory(device.configDeviceName
1040
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1041
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1042
-
1043
- // store a copy of the device object in the `accessory.context`
1044
- // the `context` property can be used to store any data about the accessory you may need
1045
- accessory.context.device = device
1046
- accessory.context.model = SwitchBotModel.MeterPro ?? SwitchBotModel.MeterProCO2
1047
- accessory.context.deviceId = device.deviceId
1048
- accessory.context.deviceType = device.deviceType
1049
- accessory.displayName = device.configDeviceName
1050
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1051
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1052
- accessory.context.connectionType = await this.connectionType(device)
1053
- accessory.context.connectionType = await this.connectionType(device)
1054
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1055
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1056
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1057
- // create the accessory handler for the newly create accessory
1058
- // this is imported from `platformAccessory.ts`
1059
- new MeterPro(this, accessory, device)
1060
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1061
-
1062
- // publish device externally or link the accessory to your platform
1063
- this.externalOrPlatform(device, accessory)
1064
- this.accessories.push(accessory)
1065
- } else {
1066
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1067
- }
1068
- }
1069
-
1070
- private async createHub2(device: device & devicesConfig) {
1071
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1072
-
1073
- // see if an accessory with the same uuid has already been registered and restored from
1074
- // the cached devices we stored in the `configureAccessory` method above
1075
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1076
-
1077
- if (existingAccessory) {
1078
- // the accessory already exists
1079
- if (await this.registerDevice(device)) {
1080
- // console.log("existingAccessory", existingAccessory);
1081
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1082
- existingAccessory.context.device = device
1083
- existingAccessory.context.model = SwitchBotModel.Hub2
1084
- existingAccessory.context.deviceId = device.deviceId
1085
- existingAccessory.context.deviceType = device.deviceType
1086
- existingAccessory.displayName = device.configDeviceName
1087
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1088
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1089
- existingAccessory.context.connectionType = await this.connectionType(device)
1090
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1091
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1092
- this.api.updatePlatformAccessories([existingAccessory])
1093
- // create the accessory handler for the restored accessory
1094
- // this is imported from `platformAccessory.ts`
1095
- new Hub(this, existingAccessory, device)
1096
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1097
- } else {
1098
- this.unregisterPlatformAccessories(existingAccessory)
1099
- }
1100
- } else if (await this.registerDevice(device)) {
1101
- // create a new accessory
1102
- const accessory = new this.api.platformAccessory(device.configDeviceName
1103
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1104
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1105
-
1106
- // store a copy of the device object in the `accessory.context`
1107
- // the `context` property can be used to store any data about the accessory you may need
1108
- accessory.context.device = device
1109
- accessory.context.model = SwitchBotModel.Hub2
1110
- accessory.context.deviceId = device.deviceId
1111
- accessory.context.deviceType = device.deviceType
1112
- accessory.displayName = device.configDeviceName
1113
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1114
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1115
- accessory.context.connectionType = await this.connectionType(device)
1116
- accessory.context.connectionType = await this.connectionType(device)
1117
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1118
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1119
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1120
- // create the accessory handler for the newly create accessory
1121
- // this is imported from `platformAccessory.ts`
1122
- new Hub(this, accessory, device)
1123
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1124
-
1125
- // publish device externally or link the accessory to your platform
1126
- this.externalOrPlatform(device, accessory)
1127
- this.accessories.push(accessory)
1128
- } else {
1129
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1130
- }
1131
- }
1132
-
1133
- private async createIOSensor(device: device & devicesConfig) {
1134
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1135
-
1136
- // see if an accessory with the same uuid has already been registered and restored from
1137
- // the cached devices we stored in the `configureAccessory` method above
1138
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1139
-
1140
- if (existingAccessory) {
1141
- // the accessory already exists
1142
- if (await this.registerDevice(device)) {
1143
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1144
- existingAccessory.context.device = device
1145
- existingAccessory.context.model = SwitchBotModel.OutdoorMeter
1146
- existingAccessory.context.deviceId = device.deviceId
1147
- existingAccessory.context.deviceType = device.deviceType
1148
- existingAccessory.displayName = device.configDeviceName
1149
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1150
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1151
- existingAccessory.context.connectionType = await this.connectionType(device)
1152
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1153
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1154
- this.api.updatePlatformAccessories([existingAccessory])
1155
- // create the accessory handler for the restored accessory
1156
- // this is imported from `platformAccessory.ts`
1157
- new IOSensor(this, existingAccessory, device)
1158
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1159
- } else {
1160
- this.unregisterPlatformAccessories(existingAccessory)
1161
- }
1162
- } else if (await this.registerDevice(device)) {
1163
- // create a new accessory
1164
- const accessory = new this.api.platformAccessory(device.configDeviceName
1165
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1166
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1167
-
1168
- // store a copy of the device object in the `accessory.context`
1169
- // the `context` property can be used to store any data about the accessory you may need
1170
- accessory.context.device = device
1171
- accessory.context.model = SwitchBotModel.OutdoorMeter
1172
- accessory.context.deviceId = device.deviceId
1173
- accessory.context.deviceType = device.deviceType
1174
- accessory.displayName = device.configDeviceName
1175
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1176
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1177
- accessory.context.connectionType = await this.connectionType(device)
1178
- accessory.context.connectionType = await this.connectionType(device)
1179
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1180
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1181
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1182
- // create the accessory handler for the newly create accessory
1183
- // this is imported from `platformAccessory.ts`
1184
- new IOSensor(this, accessory, device)
1185
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1186
-
1187
- // publish device externally or link the accessory to your platform
1188
- this.externalOrPlatform(device, accessory)
1189
- this.accessories.push(accessory)
1190
- } else {
1191
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1192
- }
1193
- }
1194
-
1195
- private async createWaterDetector(device: device & devicesConfig) {
1196
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1197
-
1198
- // see if an accessory with the same uuid has already been registered and restored from
1199
- // the cached devices we stored in the `configureAccessory` method above
1200
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1201
-
1202
- if (existingAccessory) {
1203
- // the accessory already exists
1204
- if (await this.registerDevice(device)) {
1205
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1206
- existingAccessory.context.device = device
1207
- existingAccessory.context.deviceId = device.deviceId
1208
- existingAccessory.context.deviceType = device.deviceType
1209
- existingAccessory.context.model = SwitchBotModel.WaterDetector
1210
- existingAccessory.displayName = device.configDeviceName
1211
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1212
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1213
- existingAccessory.context.connectionType = await this.connectionType(device)
1214
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1215
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1216
- this.api.updatePlatformAccessories([existingAccessory])
1217
- // create the accessory handler for the restored accessory
1218
- // this is imported from `platformAccessory.ts`
1219
- new WaterDetector(this, existingAccessory, device)
1220
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1221
- } else {
1222
- this.unregisterPlatformAccessories(existingAccessory)
1223
- }
1224
- } else if (await this.registerDevice(device)) {
1225
- // create a new accessory
1226
- const accessory = new this.api.platformAccessory(device.configDeviceName
1227
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1228
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1229
-
1230
- // store a copy of the device object in the `accessory.context`
1231
- // the `context` property can be used to store any data about the accessory you may need
1232
- accessory.context.device = device
1233
- accessory.context.deviceId = device.deviceId
1234
- accessory.context.deviceType = device.deviceType
1235
- accessory.context.model = SwitchBotModel.WaterDetector
1236
- accessory.displayName = device.configDeviceName
1237
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1238
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1239
- accessory.context.connectionType = await this.connectionType(device)
1240
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1241
- accessory.context.connectionType = await this.connectionType(device)
1242
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1243
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1244
- // create the accessory handler for the newly create accessory
1245
- // this is imported from `platformAccessory.ts`
1246
- new WaterDetector(this, accessory, device)
1247
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1248
-
1249
- // publish device externally or link the accessory to your platform
1250
- this.externalOrPlatform(device, accessory)
1251
- this.accessories.push(accessory)
1252
- } else {
1253
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1254
- }
1255
- }
1256
-
1257
- private async createMotion(device: device & devicesConfig) {
1258
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1259
-
1260
- // see if an accessory with the same uuid has already been registered and restored from
1261
- // the cached devices we stored in the `configureAccessory` method above
1262
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1263
-
1264
- if (existingAccessory) {
1265
- // the accessory already exists
1266
- if (await this.registerDevice(device)) {
1267
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1268
- existingAccessory.context.device = device
1269
- existingAccessory.context.deviceId = device.deviceId
1270
- existingAccessory.context.deviceType = device.deviceType
1271
- existingAccessory.context.model = SwitchBotModel.MotionSensor
1272
- existingAccessory.displayName = device.configDeviceName
1273
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1274
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1275
- existingAccessory.context.connectionType = await this.connectionType(device)
1276
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1277
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1278
- this.api.updatePlatformAccessories([existingAccessory])
1279
- // create the accessory handler for the restored accessory
1280
- // this is imported from `platformAccessory.ts`
1281
- new Motion(this, existingAccessory, device)
1282
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1283
- } else {
1284
- this.unregisterPlatformAccessories(existingAccessory)
1285
- }
1286
- } else if (await this.registerDevice(device)) {
1287
- // create a new accessory
1288
- const accessory = new this.api.platformAccessory(device.configDeviceName
1289
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1290
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1291
-
1292
- // store a copy of the device object in the `accessory.context`
1293
- // the `context` property can be used to store any data about the accessory you may need
1294
- accessory.context.device = device
1295
- accessory.context.deviceId = device.deviceId
1296
- accessory.context.deviceType = device.deviceType
1297
- accessory.context.model = SwitchBotModel.MotionSensor
1298
- accessory.displayName = device.configDeviceName
1299
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1300
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1301
- accessory.context.connectionType = await this.connectionType(device)
1302
- accessory.context.connectionType = await this.connectionType(device)
1303
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1304
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1305
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1306
- // create the accessory handler for the newly create accessory
1307
- // this is imported from `platformAccessory.ts`
1308
- new Motion(this, accessory, device)
1309
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1310
-
1311
- // publish device externally or link the accessory to your platform
1312
- this.externalOrPlatform(device, accessory)
1313
- this.accessories.push(accessory)
1314
- } else {
1315
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1316
- }
1317
- }
1318
-
1319
- private async createContact(device: device & devicesConfig) {
1320
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1321
-
1322
- // see if an accessory with the same uuid has already been registered and restored from
1323
- // the cached devices we stored in the `configureAccessory` method above
1324
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1325
-
1326
- if (existingAccessory) {
1327
- // the accessory already exists
1328
- if (await this.registerDevice(device)) {
1329
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1330
- existingAccessory.context.device = device
1331
- existingAccessory.context.deviceId = device.deviceId
1332
- existingAccessory.context.deviceType = device.deviceType
1333
- existingAccessory.context.model = SwitchBotModel.ContactSensor
1334
- existingAccessory.displayName = device.configDeviceName
1335
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1336
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1337
- existingAccessory.context.connectionType = await this.connectionType(device)
1338
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1339
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1340
- this.api.updatePlatformAccessories([existingAccessory])
1341
- // create the accessory handler for the restored accessory
1342
- // this is imported from `platformAccessory.ts`
1343
- new Contact(this, existingAccessory, device)
1344
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1345
- } else {
1346
- this.unregisterPlatformAccessories(existingAccessory)
1347
- }
1348
- } else if (await this.registerDevice(device)) {
1349
- // create a new accessory
1350
- const accessory = new this.api.platformAccessory(device.configDeviceName
1351
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1352
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1353
-
1354
- // store a copy of the device object in the `accessory.context`
1355
- // the `context` property can be used to store any data about the accessory you may need
1356
- accessory.context.device = device
1357
- accessory.context.deviceId = device.deviceId
1358
- accessory.context.deviceType = device.deviceType
1359
- accessory.context.model = SwitchBotModel.ContactSensor
1360
- accessory.displayName = device.configDeviceName
1361
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1362
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1363
- accessory.context.connectionType = await this.connectionType(device)
1364
- accessory.context.connectionType = await this.connectionType(device)
1365
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1366
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1367
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1368
- // create the accessory handler for the newly create accessory
1369
- // this is imported from `platformAccessory.ts`
1370
- new Contact(this, accessory, device)
1371
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1372
-
1373
- // publish device externally or link the accessory to your platform
1374
- this.externalOrPlatform(device, accessory)
1375
- this.accessories.push(accessory)
1376
- } else {
1377
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1378
- }
1379
- }
1380
-
1381
- private async createBlindTilt(device: device & devicesConfig) {
1382
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1383
-
1384
- // see if an accessory with the same uuid has already been registered and restored from
1385
- // the cached devices we stored in the `configureAccessory` method above
1386
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1387
-
1388
- if (existingAccessory) {
1389
- // the accessory already exists
1390
- if (await this.registerDevice(device)) {
1391
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1392
- existingAccessory.context.device = device
1393
- existingAccessory.context.deviceId = device.deviceId
1394
- existingAccessory.context.deviceType = device.deviceType
1395
- existingAccessory.context.model = SwitchBotModel.BlindTilt
1396
- existingAccessory.displayName = device.configDeviceName
1397
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1398
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1399
- existingAccessory.context.connectionType = await this.connectionType(device)
1400
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1401
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1402
- this.api.updatePlatformAccessories([existingAccessory])
1403
- // create the accessory handler for the restored accessory
1404
- // this is imported from `platformAccessory.ts`
1405
- new BlindTilt(this, existingAccessory, device as blindTiltConfig)
1406
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1407
- } else {
1408
- this.unregisterPlatformAccessories(existingAccessory)
1409
- }
1410
- } else if (await this.registerDevice(device)) {
1411
- if (isBlindTiltDevice(device)) {
1412
- if (device.group && !(device as blindTiltConfig | curtainConfig).disable_group) {
1413
- this.debugLog(
1414
- 'Your Curtains are grouped, '
1415
- + `, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`,
1416
- )
1417
- } else {
1418
- if (device.master) {
1419
- this.warnLog(`Main Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`)
1420
- } else {
1421
- this.errorLog(`Secondary Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`)
1422
- }
1423
- }
1424
- }
1425
-
1426
- // create a new accessory
1427
- const accessory = new this.api.platformAccessory(device.configDeviceName
1428
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1429
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1430
-
1431
- // store a copy of the device object in the `accessory.context`
1432
- // the `context` property can be used to store any data about the accessory you may need
1433
- accessory.context.device = device
1434
- accessory.context.deviceId = device.deviceId
1435
- accessory.context.deviceType = device.deviceType
1436
- accessory.context.model = SwitchBotModel.BlindTilt
1437
- accessory.displayName = device.configDeviceName
1438
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1439
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1440
- accessory.context.connectionType = await this.connectionType(device)
1441
- accessory.context.connectionType = await this.connectionType(device)
1442
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1443
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1444
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1445
- // create the accessory handler for the newly create accessory
1446
- // this is imported from `platformAccessory.ts`
1447
- new BlindTilt(this, accessory, device as blindTiltConfig)
1448
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1449
-
1450
- // publish device externally or link the accessory to your platform
1451
- this.externalOrPlatform(device, accessory)
1452
- this.accessories.push(accessory)
1453
- } else {
1454
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1455
- }
1456
- }
1457
-
1458
- private async createCurtain(device: device & devicesConfig) {
1459
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1460
-
1461
- // see if an accessory with the same uuid has already been registered and restored from
1462
- // the cached devices we stored in the `configureAccessory` method above
1463
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1464
-
1465
- if (existingAccessory) {
1466
- // the accessory already exists
1467
- if (await this.registerDevice(device)) {
1468
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1469
- existingAccessory.context.device = device
1470
- existingAccessory.context.deviceId = device.deviceId
1471
- existingAccessory.context.deviceType = device.deviceType
1472
- existingAccessory.context.model = device.deviceType === 'Curtain3' ? SwitchBotModel.Curtain3 : SwitchBotModel.Curtain
1473
- existingAccessory.displayName = device.configDeviceName
1474
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1475
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1476
- existingAccessory.context.connectionType = await this.connectionType(device)
1477
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1478
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1479
- this.api.updatePlatformAccessories([existingAccessory])
1480
- // create the accessory handler for the restored accessory
1481
- // this is imported from `platformAccessory.ts`
1482
- new Curtain(this, existingAccessory, device as curtainConfig)
1483
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1484
- } else {
1485
- this.unregisterPlatformAccessories(existingAccessory)
1486
- }
1487
- } else if (await this.registerDevice(device)) {
1488
- if (isCurtainDevice(device)) {
1489
- if (device.group && !(device as blindTiltConfig | curtainConfig).disable_group) {
1490
- this.debugLog(
1491
- 'Your Curtains are grouped, '
1492
- + `, Secondary curtain automatically hidden. Main Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`,
1493
- )
1494
- } else {
1495
- if (device.master) {
1496
- this.warnLog(`Main Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`)
1497
- } else {
1498
- this.errorLog(`Secondary Curtain: ${device.deviceName}, deviceId: ${device.deviceId}`)
1499
- }
1500
- }
1501
- }
1502
-
1503
- // create a new accessory
1504
- const accessory = new this.api.platformAccessory(device.configDeviceName
1505
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1506
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1507
-
1508
- // store a copy of the device object in the `accessory.context`
1509
- // the `context` property can be used to store any data about the accessory you may need
1510
- accessory.context.device = device
1511
- accessory.context.deviceId = device.deviceId
1512
- accessory.context.deviceType = device.deviceType
1513
- accessory.context.model = device.deviceType === 'Curtain3' ? SwitchBotModel.Curtain3 : SwitchBotModel.Curtain
1514
- accessory.displayName = device.configDeviceName
1515
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1516
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1517
- accessory.context.connectionType = await this.connectionType(device)
1518
- accessory.context.connectionType = await this.connectionType(device)
1519
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1520
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1521
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1522
- // create the accessory handler for the newly create accessory
1523
- // this is imported from `platformAccessory.ts`
1524
- new Curtain(this, accessory, device as curtainConfig)
1525
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1526
-
1527
- // publish device externally or link the accessory to your platform
1528
- this.externalOrPlatform(device, accessory)
1529
- this.accessories.push(accessory)
1530
- } else {
1531
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1532
- }
1533
- }
1534
-
1535
- private async createPlug(device: device & devicesConfig) {
1536
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1537
-
1538
- // see if an accessory with the same uuid has already been registered and restored from
1539
- // the cached devices we stored in the `configureAccessory` method above
1540
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1541
-
1542
- if (existingAccessory) {
1543
- // the accessory already exists
1544
- if (await this.registerDevice(device)) {
1545
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1546
- existingAccessory.context.device = device
1547
- existingAccessory.context.deviceId = device.deviceId
1548
- existingAccessory.context.deviceType = device.deviceType
1549
- existingAccessory.context.model = device.deviceType === 'Plug Mini (US)'
1550
- ? SwitchBotModel.PlugMiniUS
1551
- : device.deviceType === 'Plug Mini (JP)'
1552
- ? SwitchBotModel.PlugMiniJP
1553
- : SwitchBotModel.Plug
1554
- existingAccessory.displayName = device.configDeviceName
1555
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1556
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1557
- existingAccessory.context.connectionType = await this.connectionType(device)
1558
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1559
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1560
- this.api.updatePlatformAccessories([existingAccessory])
1561
- // create the accessory handler for the restored accessory
1562
- // this is imported from `platformAccessory.ts`
1563
- new Plug(this, existingAccessory, device)
1564
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1565
- } else {
1566
- this.unregisterPlatformAccessories(existingAccessory)
1567
- }
1568
- } else if (await this.registerDevice(device)) {
1569
- // create a new accessory
1570
- const accessory = new this.api.platformAccessory(device.configDeviceName
1571
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1572
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1573
-
1574
- // store a copy of the device object in the `accessory.context`
1575
- // the `context` property can be used to store any data about the accessory you may need
1576
- accessory.context.device = device
1577
- accessory.context.deviceId = device.deviceId
1578
- accessory.context.deviceType = device.deviceType
1579
- accessory.context.model = device.deviceType === 'Plug Mini (US)'
1580
- ? SwitchBotModel.PlugMiniUS
1581
- : device.deviceType === 'Plug Mini (JP)'
1582
- ? SwitchBotModel.PlugMiniJP
1583
- : SwitchBotModel.Plug
1584
- accessory.displayName = device.configDeviceName
1585
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1586
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1587
- accessory.context.connectionType = await this.connectionType(device)
1588
- accessory.context.connectionType = await this.connectionType(device)
1589
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1590
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1591
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1592
- // create the accessory handler for the newly create accessory
1593
- // this is imported from `platformAccessory.ts`
1594
- new Plug(this, accessory, device)
1595
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1596
-
1597
- // publish device externally or link the accessory to your platform
1598
- this.externalOrPlatform(device, accessory)
1599
- this.accessories.push(accessory)
1600
- } else {
1601
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1602
- }
1603
- }
1604
-
1605
- private async createLock(device: device & devicesConfig) {
1606
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1607
-
1608
- // see if an accessory with the same uuid has already been registered and restored from
1609
- // the cached devices we stored in the `configureAccessory` method above
1610
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1611
-
1612
- if (existingAccessory) {
1613
- // the accessory already exists
1614
- if (await this.registerDevice(device)) {
1615
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1616
- existingAccessory.context.device = device
1617
- existingAccessory.context.deviceId = device.deviceId
1618
- existingAccessory.context.deviceType = device.deviceType
1619
- existingAccessory.context.model = device.deviceType === 'Smart Lock Pro' ? SwitchBotModel.LockPro : SwitchBotModel.Lock
1620
- existingAccessory.displayName = device.configDeviceName
1621
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1622
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1623
- existingAccessory.context.connectionType = await this.connectionType(device)
1624
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1625
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1626
- this.api.updatePlatformAccessories([existingAccessory])
1627
- // create the accessory handler for the restored accessory
1628
- // this is imported from `platformAccessory.ts`
1629
- new Lock(this, existingAccessory, device)
1630
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1631
- } else {
1632
- this.unregisterPlatformAccessories(existingAccessory)
1633
- }
1634
- } else if (await this.registerDevice(device)) {
1635
- // create a new accessory
1636
- const accessory = new this.api.platformAccessory(device.configDeviceName
1637
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1638
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1639
-
1640
- // store a copy of the device object in the `accessory.context`
1641
- // the `context` property can be used to store any data about the accessory you may need
1642
- accessory.context.device = device
1643
- accessory.context.deviceId = device.deviceId
1644
- accessory.context.deviceType = device.deviceType
1645
- accessory.context.model = device.deviceType === 'Smart Lock Pro' ? SwitchBotModel.LockPro : SwitchBotModel.Lock
1646
- accessory.displayName = device.configDeviceName
1647
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1648
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1649
- accessory.context.connectionType = await this.connectionType(device)
1650
- accessory.context.connectionType = await this.connectionType(device)
1651
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1652
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1653
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1654
- // create the accessory handler for the newly create accessory
1655
- // this is imported from `platformAccessory.ts`
1656
- new Lock(this, accessory, device)
1657
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1658
-
1659
- // publish device externally or link the accessory to your platform
1660
- this.externalOrPlatform(device, accessory)
1661
- this.accessories.push(accessory)
1662
- } else {
1663
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1664
- }
1665
- }
1666
-
1667
- private async createColorBulb(device: device & devicesConfig) {
1668
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1669
-
1670
- // see if an accessory with the same uuid has already been registered and restored from
1671
- // the cached devices we stored in the `configureAccessory` method above
1672
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1673
-
1674
- if (existingAccessory) {
1675
- // the accessory already exists
1676
- if (await this.registerDevice(device)) {
1677
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1678
- existingAccessory.context.device = device
1679
- existingAccessory.context.deviceId = device.deviceId
1680
- existingAccessory.context.deviceType = device.deviceType
1681
- existingAccessory.context.model = SwitchBotModel.ColorBulb
1682
- existingAccessory.displayName = device.configDeviceName
1683
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1684
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1685
- existingAccessory.context.connectionType = await this.connectionType(device)
1686
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1687
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1688
- this.api.updatePlatformAccessories([existingAccessory])
1689
- // create the accessory handler for the restored accessory
1690
- // this is imported from `platformAccessory.ts`
1691
- new ColorBulb(this, existingAccessory, device)
1692
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1693
- } else {
1694
- this.unregisterPlatformAccessories(existingAccessory)
1695
- }
1696
- } else if (await this.registerDevice(device)) {
1697
- // create a new accessory
1698
- const accessory = new this.api.platformAccessory(device.configDeviceName
1699
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1700
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1701
-
1702
- // store a copy of the device object in the `accessory.context`
1703
- // the `context` property can be used to store any data about the accessory you may need
1704
- accessory.context.device = device
1705
- accessory.context.deviceId = device.deviceId
1706
- accessory.context.deviceType = device.deviceType
1707
- accessory.context.model = SwitchBotModel.ColorBulb
1708
- accessory.displayName = device.configDeviceName
1709
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1710
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1711
- accessory.context.connectionType = await this.connectionType(device)
1712
- accessory.context.connectionType = await this.connectionType(device)
1713
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1714
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1715
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1716
- // create the accessory handler for the newly create accessory
1717
- // this is imported from `platformAccessory.ts`
1718
- new ColorBulb(this, accessory, device)
1719
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1720
-
1721
- // publish device externally or link the accessory to your platform
1722
- this.externalOrPlatform(device, accessory)
1723
- this.accessories.push(accessory)
1724
- } else {
1725
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1726
- }
1727
- }
1728
-
1729
- private async createCeilingLight(device: device & devicesConfig) {
1730
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1731
-
1732
- // see if an accessory with the same uuid has already been registered and restored from
1733
- // the cached devices we stored in the `configureAccessory` method above
1734
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1735
-
1736
- if (existingAccessory) {
1737
- // the accessory already exists
1738
- if (await this.registerDevice(device)) {
1739
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1740
- existingAccessory.context.device = device
1741
- existingAccessory.context.deviceId = device.deviceId
1742
- existingAccessory.context.deviceType = device.deviceType
1743
- existingAccessory.context.model = device.deviceType === 'Ceiling Light Pro' ? SwitchBotModel.CeilingLightPro : SwitchBotModel.CeilingLight
1744
- existingAccessory.displayName = device.configDeviceName
1745
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1746
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1747
- existingAccessory.context.connectionType = await this.connectionType(device)
1748
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1749
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1750
- this.api.updatePlatformAccessories([existingAccessory])
1751
- // create the accessory handler for the restored accessory
1752
- // this is imported from `platformAccessory.ts`
1753
- new CeilingLight(this, existingAccessory, device)
1754
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1755
- } else {
1756
- this.unregisterPlatformAccessories(existingAccessory)
1757
- }
1758
- } else if (await this.registerDevice(device)) {
1759
- // create a new accessory
1760
- const accessory = new this.api.platformAccessory(device.configDeviceName
1761
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1762
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1763
-
1764
- // store a copy of the device object in the `accessory.context`
1765
- // the `context` property can be used to store any data about the accessory you may need
1766
- accessory.context.device = device
1767
- accessory.context.deviceId = device.deviceId
1768
- accessory.context.deviceType = device.deviceType
1769
- accessory.context.model = device.deviceType === 'Ceiling Light Pro' ? SwitchBotModel.CeilingLightPro : SwitchBotModel.CeilingLight
1770
- accessory.displayName = device.configDeviceName
1771
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1772
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1773
- accessory.context.connectionType = await this.connectionType(device)
1774
- accessory.context.connectionType = await this.connectionType(device)
1775
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1776
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1777
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1778
- // create the accessory handler for the newly create accessory
1779
- // this is imported from `platformAccessory.ts`
1780
- new CeilingLight(this, accessory, device)
1781
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1782
-
1783
- // publish device externally or link the accessory to your platform
1784
- this.externalOrPlatform(device, accessory)
1785
- this.accessories.push(accessory)
1786
- } else {
1787
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1788
- }
1789
- }
1790
-
1791
- private async createStripLight(device: device & devicesConfig) {
1792
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1793
-
1794
- // see if an accessory with the same uuid has already been registered and restored from
1795
- // the cached devices we stored in the `configureAccessory` method above
1796
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1797
-
1798
- if (existingAccessory) {
1799
- // the accessory already exists
1800
- if (await this.registerDevice(device)) {
1801
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1802
- existingAccessory.context.device = device
1803
- existingAccessory.context.deviceId = device.deviceId
1804
- existingAccessory.context.deviceType = device.deviceType
1805
- existingAccessory.context.model = SwitchBotModel.StripLight
1806
- existingAccessory.displayName = device.configDeviceName
1807
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1808
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1809
- existingAccessory.context.connectionType = await this.connectionType(device)
1810
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1811
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1812
- this.api.updatePlatformAccessories([existingAccessory])
1813
- // create the accessory handler for the restored accessory
1814
- // this is imported from `platformAccessory.ts`
1815
- new StripLight(this, existingAccessory, device)
1816
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1817
- } else {
1818
- this.unregisterPlatformAccessories(existingAccessory)
1819
- }
1820
- } else if (await this.registerDevice(device)) {
1821
- // create a new accessory
1822
- const accessory = new this.api.platformAccessory(device.configDeviceName
1823
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1824
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1825
-
1826
- // store a copy of the device object in the `accessory.context`
1827
- // the `context` property can be used to store any data about the accessory you may need
1828
- accessory.context.device = device
1829
- accessory.context.deviceId = device.deviceId
1830
- accessory.context.deviceType = device.deviceType
1831
- accessory.context.model = SwitchBotModel.StripLight
1832
- accessory.displayName = device.configDeviceName
1833
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1834
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1835
- accessory.context.connectionType = await this.connectionType(device)
1836
- accessory.context.connectionType = await this.connectionType(device)
1837
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1838
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1839
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1840
- // create the accessory handler for the newly create accessory
1841
- // this is imported from `platformAccessory.ts`
1842
- new StripLight(this, accessory, device)
1843
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1844
-
1845
- // publish device externally or link the accessory to your platform
1846
- this.externalOrPlatform(device, accessory)
1847
- this.accessories.push(accessory)
1848
- } else {
1849
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1850
- }
1851
- }
1852
-
1853
- private async createFan(device: device & devicesConfig) {
1854
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1855
-
1856
- // see if an accessory with the same uuid has already been registered and restored from
1857
- // the cached devices we stored in the `configureAccessory` method above
1858
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1859
-
1860
- if (existingAccessory) {
1861
- // the accessory already exists
1862
- if (await this.registerDevice(device)) {
1863
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1864
- existingAccessory.context.device = device
1865
- existingAccessory.context.deviceId = device.deviceId
1866
- existingAccessory.context.deviceType = device.deviceType
1867
- existingAccessory.context.model = SwitchBotModel.BatteryCirculatorFan
1868
- existingAccessory.displayName = device.configDeviceName
1869
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1870
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1871
- existingAccessory.context.connectionType = await this.connectionType(device)
1872
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1873
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1874
- this.api.updatePlatformAccessories([existingAccessory])
1875
- // create the accessory handler for the restored accessory
1876
- // this is imported from `platformAccessory.ts`
1877
- new Fan(this, existingAccessory, device)
1878
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1879
- } else {
1880
- this.unregisterPlatformAccessories(existingAccessory)
1881
- }
1882
- } else if (await this.registerDevice(device)) {
1883
- // create a new accessory
1884
- const accessory = new this.api.platformAccessory(device.configDeviceName
1885
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1886
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1887
-
1888
- // store a copy of the device object in the `accessory.context`
1889
- // the `context` property can be used to store any data about the accessory you may need
1890
- accessory.context.device = device
1891
- accessory.context.deviceId = device.deviceId
1892
- accessory.context.deviceType = device.deviceType
1893
- accessory.context.model = SwitchBotModel.BatteryCirculatorFan
1894
- accessory.displayName = device.configDeviceName
1895
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1896
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1897
- accessory.context.connectionType = await this.connectionType(device)
1898
- accessory.context.connectionType = await this.connectionType(device)
1899
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1900
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1901
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1902
- // create the accessory handler for the newly create accessory
1903
- // this is imported from `platformAccessory.ts`
1904
- new Fan(this, accessory, device)
1905
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1906
-
1907
- // publish device externally or link the accessory to your platform
1908
- this.externalOrPlatform(device, accessory)
1909
- this.accessories.push(accessory)
1910
- } else {
1911
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1912
- }
1913
- }
1914
-
1915
- private async createAirPurifier(device: device & devicesConfig) {
1916
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1917
-
1918
- // see if an accessory with the same uuid has already been registered and restored from
1919
- // the cached devices we stored in the `configureAccessory` method above
1920
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1921
-
1922
- if (existingAccessory) {
1923
- // the accessory already exists
1924
- if (await this.registerDevice(device)) {
1925
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1926
- existingAccessory.context.device = device
1927
- existingAccessory.context.deviceId = device.deviceId
1928
- existingAccessory.context.deviceType = device.deviceType
1929
- existingAccessory.context.model = SwitchBotModel.BatteryCirculatorFan
1930
- existingAccessory.displayName = device.configDeviceName
1931
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1932
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1933
- existingAccessory.context.connectionType = await this.connectionType(device)
1934
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1935
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
1936
- this.api.updatePlatformAccessories([existingAccessory])
1937
- // create the accessory handler for the restored accessory
1938
- // this is imported from `platformAccessory.ts`
1939
- new AirPurifier(this, existingAccessory, device)
1940
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
1941
- } else {
1942
- this.unregisterPlatformAccessories(existingAccessory)
1943
- }
1944
- } else if (await this.registerDevice(device)) {
1945
- // create a new accessory
1946
- const accessory = new this.api.platformAccessory(device.configDeviceName
1947
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1948
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
1949
-
1950
- // store a copy of the device object in the `accessory.context`
1951
- // the `context` property can be used to store any data about the accessory you may need
1952
- accessory.context.device = device
1953
- accessory.context.deviceId = device.deviceId
1954
- accessory.context.deviceType = device.deviceType
1955
- accessory.context.model = SwitchBotModel.BatteryCirculatorFan
1956
- accessory.displayName = device.configDeviceName
1957
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
1958
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
1959
- accessory.context.connectionType = await this.connectionType(device)
1960
- accessory.context.connectionType = await this.connectionType(device)
1961
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
1962
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
1963
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
1964
- // create the accessory handler for the newly create accessory
1965
- // this is imported from `platformAccessory.ts`
1966
- new AirPurifier(this, accessory, device)
1967
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
1968
-
1969
- // publish device externally or link the accessory to your platform
1970
- this.externalOrPlatform(device, accessory)
1971
- this.accessories.push(accessory)
1972
- } else {
1973
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
1974
- }
1975
- }
1976
-
1977
- private async createRobotVacuumCleaner(device: device & devicesConfig) {
1978
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.deviceType}`)
1979
-
1980
- // see if an accessory with the same uuid has already been registered and restored from
1981
- // the cached devices we stored in the `configureAccessory` method above
1982
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
1983
-
1984
- if (existingAccessory) {
1985
- // the accessory already exists
1986
- if (await this.registerDevice(device)) {
1987
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
1988
- existingAccessory.context.device = device
1989
- existingAccessory.context.deviceId = device.deviceId
1990
- existingAccessory.context.deviceType = device.deviceType
1991
- existingAccessory.context.model = device.deviceType === 'Robot Vacuum Cleaner S1'
1992
- ? SwitchBotModel.RobotVacuumCleanerS1
1993
- : device.deviceType === 'Robot Vacuum Cleaner S1 Plus'
1994
- ? SwitchBotModel.RobotVacuumCleanerS1Plus
1995
- : device.deviceType === 'Robot Vacuum Cleaner S10'
1996
- ? SwitchBotModel.RobotVacuumCleanerS10
1997
- : device.deviceType === 'WoSweeper'
1998
- ? SwitchBotModel.WoSweeper
1999
- : device.deviceType === 'WoSweeperMini'
2000
- ? SwitchBotModel.WoSweeperMini
2001
- : SwitchBotModel.Unknown
2002
- existingAccessory.displayName = device.configDeviceName
2003
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2004
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2005
- existingAccessory.context.connectionType = await this.connectionType(device)
2006
- existingAccessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
2007
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
2008
- this.api.updatePlatformAccessories([existingAccessory])
2009
- // create the accessory handler for the restored accessory
2010
- // this is imported from `platformAccessory.ts`
2011
- new RobotVacuumCleaner(this, existingAccessory, device)
2012
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${existingAccessory.UUID})`)
2013
- } else {
2014
- this.unregisterPlatformAccessories(existingAccessory)
2015
- }
2016
- } else if (await this.registerDevice(device)) {
2017
- // create a new accessory
2018
- const accessory = new this.api.platformAccessory(device.configDeviceName
2019
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2020
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
2021
-
2022
- // store a copy of the device object in the `accessory.context`
2023
- // the `context` property can be used to store any data about the accessory you may need
2024
- accessory.context.device = device
2025
- accessory.context.deviceId = device.deviceId
2026
- accessory.context.deviceType = device.deviceType
2027
- accessory.context.model = device.deviceType === 'Robot Vacuum Cleaner S1'
2028
- ? SwitchBotModel.RobotVacuumCleanerS1
2029
- : device.deviceType === 'Robot Vacuum Cleaner S1 Plus'
2030
- ? SwitchBotModel.RobotVacuumCleanerS1Plus
2031
- : device.deviceType === 'Robot Vacuum Cleaner S10'
2032
- ? SwitchBotModel.RobotVacuumCleanerS10
2033
- : device.deviceType === 'WoSweeper'
2034
- ? SwitchBotModel.WoSweeper
2035
- : device.deviceType === 'WoSweeperMini'
2036
- ? SwitchBotModel.WoSweeperMini
2037
- : SwitchBotModel.Unknown
2038
- accessory.displayName = device.configDeviceName
2039
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2040
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2041
- accessory.context.connectionType = await this.connectionType(device)
2042
- accessory.context.connectionType = await this.connectionType(device)
2043
- accessory.context.version = device.firmware ?? device.version ?? this.version ?? '0.0.0'
2044
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
2045
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
2046
- // create the accessory handler for the newly create accessory
2047
- // this is imported from `platformAccessory.ts`
2048
- new RobotVacuumCleaner(this, accessory, device)
2049
- this.debugLog(`${device.deviceType} uuid: ${device.deviceId}-${device.deviceType}, (${accessory.UUID})`)
2050
-
2051
- // publish device externally or link the accessory to your platform
2052
- this.externalOrPlatform(device, accessory)
2053
- this.accessories.push(accessory)
2054
- } else {
2055
- this.debugLog(`Device not registered: ${device.deviceName} ${device.deviceType} deviceId: ${device.deviceId}`)
2056
- }
2057
- }
2058
-
2059
- private async createTV(device: irdevice & irDevicesConfig) {
2060
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`)
2061
-
2062
- // see if an accessory with the same uuid has already been registered and restored from
2063
- // the cached devices we stored in the `configureAccessory` method above
2064
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
2065
-
2066
- if (!device.hide_device && existingAccessory) {
2067
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
2068
- existingAccessory.context.device = device
2069
- existingAccessory.context.deviceId = device.deviceId
2070
- existingAccessory.context.deviceType = `IR: ${device.remoteType}`
2071
- existingAccessory.context.model = device.remoteType
2072
- existingAccessory.displayName = device.configDeviceName
2073
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2074
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2075
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
2076
- existingAccessory.context.connectionType = device.connectionType
2077
- this.api.updatePlatformAccessories([existingAccessory])
2078
- // create the accessory handler for the restored accessory
2079
- // this is imported from `platformAccessory.ts`
2080
- new TV(this, existingAccessory, device)
2081
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`)
2082
- } else if (!device.hide_device && device.hubDeviceId) {
2083
- // create a new accessory
2084
- const accessory = new this.api.platformAccessory(device.configDeviceName
2085
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2086
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
2087
-
2088
- // store a copy of the device object in the `accessory.context`
2089
- // the `context` property can be used to store any data about the accessory you may need
2090
- accessory.context.device = device
2091
- accessory.context.deviceId = device.deviceId
2092
- accessory.context.deviceType = `IR: ${device.remoteType}`
2093
- accessory.context.model = device.remoteType
2094
- accessory.displayName = device.configDeviceName
2095
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2096
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2097
- accessory.context.connectionType = await this.connectionType(device)
2098
- accessory.context.version = device.firmware ?? this.version ?? '0.0.0'
2099
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
2100
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
2101
- // create the accessory handler for the newly create accessory
2102
- // this is imported from `platformAccessory.ts`
2103
- new TV(this, accessory, device)
2104
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`)
2105
-
2106
- this.externalOrPlatform(device, accessory)
2107
- this.accessories.push(accessory)
2108
- } else {
2109
- this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} deviceId: ${device.deviceId}`)
2110
- }
2111
- }
2112
-
2113
- private async createIRFan(device: irdevice & irDevicesConfig) {
2114
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`)
2115
-
2116
- // see if an accessory with the same uuid has already been registered and restored from
2117
- // the cached devices we stored in the `configureAccessory` method above
2118
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
2119
-
2120
- if (existingAccessory) {
2121
- // the accessory already exists
2122
- if (!device.hide_device && device.hubDeviceId) {
2123
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
2124
- existingAccessory.context.device = device
2125
- existingAccessory.context.deviceId = device.deviceId
2126
- existingAccessory.context.deviceType = `IR: ${device.remoteType}`
2127
- existingAccessory.context.model = device.remoteType
2128
- existingAccessory.displayName = device.configDeviceName
2129
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2130
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2131
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
2132
- existingAccessory.context.connectionType = device.connectionType
2133
- this.api.updatePlatformAccessories([existingAccessory])
2134
- // create the accessory handler for the restored accessory
2135
- // this is imported from `platformAccessory.ts`
2136
- new IRFan(this, existingAccessory, device)
2137
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`)
2138
- } else {
2139
- this.unregisterPlatformAccessories(existingAccessory)
2140
- }
2141
- } else if (!device.hide_device && device.hubDeviceId) {
2142
- // create a new accessory
2143
- const accessory = new this.api.platformAccessory(device.configDeviceName
2144
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2145
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
2146
-
2147
- // store a copy of the device object in the `accessory.context`
2148
- // the `context` property can be used to store any data about the accessory you may need
2149
- accessory.context.device = device
2150
- accessory.context.deviceId = device.deviceId
2151
- accessory.context.deviceType = `IR: ${device.remoteType}`
2152
- accessory.context.model = device.remoteType
2153
- accessory.displayName = device.configDeviceName
2154
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2155
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2156
- accessory.context.connectionType = await this.connectionType(device)
2157
- accessory.context.version = device.firmware ?? this.version ?? '0.0.0'
2158
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
2159
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
2160
- // create the accessory handler for the newly create accessory
2161
- // this is imported from `platformAccessory.ts`
2162
- new IRFan(this, accessory, device)
2163
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`)
2164
-
2165
- // publish device externally or link the accessory to your platform
2166
- this.externalOrPlatform(device, accessory)
2167
- this.accessories.push(accessory)
2168
- } else {
2169
- this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} deviceId: ${device.deviceId}`)
2170
- }
2171
- }
2172
-
2173
- private async createLight(device: irdevice & irDevicesConfig) {
2174
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`)
2175
-
2176
- // see if an accessory with the same uuid has already been registered and restored from
2177
- // the cached devices we stored in the `configureAccessory` method above
2178
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
2179
-
2180
- if (existingAccessory) {
2181
- // the accessory already exists
2182
- if (!device.hide_device && device.hubDeviceId) {
2183
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
2184
- existingAccessory.context.device = device
2185
- existingAccessory.context.deviceId = device.deviceId
2186
- existingAccessory.context.deviceType = `IR: ${device.remoteType}`
2187
- existingAccessory.context.model = device.remoteType
2188
- existingAccessory.displayName = device.configDeviceName
2189
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2190
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2191
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
2192
- existingAccessory.context.connectionType = device.connectionType
2193
- this.api.updatePlatformAccessories([existingAccessory])
2194
- // create the accessory handler for the restored accessory
2195
- // this is imported from `platformAccessory.ts`
2196
- new Light(this, existingAccessory, device)
2197
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`)
2198
- } else {
2199
- this.unregisterPlatformAccessories(existingAccessory)
2200
- }
2201
- } else if (!device.hide_device && device.hubDeviceId) {
2202
- // create a new accessory
2203
- const accessory = new this.api.platformAccessory(device.configDeviceName
2204
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2205
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
2206
-
2207
- // store a copy of the device object in the `accessory.context`
2208
- // the `context` property can be used to store any data about the accessory you may need
2209
- accessory.context.device = device
2210
- accessory.context.deviceId = device.deviceId
2211
- accessory.context.deviceType = `IR: ${device.remoteType}`
2212
- accessory.context.model = device.remoteType
2213
- accessory.displayName = device.configDeviceName
2214
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2215
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2216
- accessory.context.connectionType = await this.connectionType(device)
2217
- accessory.context.version = device.firmware ?? this.version ?? '0.0.0'
2218
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
2219
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
2220
- // create the accessory handler for the newly create accessory
2221
- // this is imported from `platformAccessory.ts`
2222
- new Light(this, accessory, device)
2223
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`)
2224
-
2225
- // publish device externally or link the accessory to your platform
2226
- this.externalOrPlatform(device, accessory)
2227
- this.accessories.push(accessory)
2228
- } else {
2229
- this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} deviceId: ${device.deviceId}`)
2230
- }
2231
- }
2232
-
2233
- private async createAirConditioner(device: irdevice & irDevicesConfig) {
2234
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`)
2235
-
2236
- // see if an accessory with the same uuid has already been registered and restored from
2237
- // the cached devices we stored in the `configureAccessory` method above
2238
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
2239
-
2240
- if (existingAccessory) {
2241
- // the accessory already exists
2242
- if (!device.hide_device && device.hubDeviceId) {
2243
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
2244
- existingAccessory.context.device = device
2245
- existingAccessory.context.deviceId = device.deviceId
2246
- existingAccessory.context.deviceType = `IR: ${device.remoteType}`
2247
- existingAccessory.context.model = device.remoteType
2248
- existingAccessory.displayName = device.configDeviceName
2249
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2250
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2251
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
2252
- existingAccessory.context.connectionType = device.connectionType
2253
- this.api.updatePlatformAccessories([existingAccessory])
2254
- // create the accessory handler for the restored accessory
2255
- // this is imported from `platformAccessory.ts`
2256
- new AirConditioner(this, existingAccessory, device)
2257
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`)
2258
- } else {
2259
- this.unregisterPlatformAccessories(existingAccessory)
2260
- }
2261
- } else if (!device.hide_device && device.hubDeviceId) {
2262
- // create a new accessory
2263
- const accessory = new this.api.platformAccessory(device.configDeviceName
2264
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2265
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
2266
-
2267
- // store a copy of the device object in the `accessory.context`
2268
- // the `context` property can be used to store any data about the accessory you may need
2269
- accessory.context.device = device
2270
- accessory.context.deviceId = device.deviceId
2271
- accessory.context.deviceType = `IR: ${device.remoteType}`
2272
- accessory.context.model = device.remoteType
2273
- accessory.displayName = device.configDeviceName
2274
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2275
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2276
- accessory.context.connectionType = await this.connectionType(device)
2277
- accessory.context.version = device.firmware ?? this.version ?? '0.0.0'
2278
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
2279
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
2280
- // create the accessory handler for the newly create accessory
2281
- // this is imported from `platformAccessory.ts`
2282
- new AirConditioner(this, accessory, device)
2283
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`)
2284
-
2285
- // publish device externally or link the accessory to your platform
2286
- this.externalOrPlatform(device, accessory)
2287
- this.accessories.push(accessory)
2288
- } else {
2289
- this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} deviceId: ${device.deviceId}`)
2290
- }
2291
- }
2292
-
2293
- private async createAirPurifierIR(device: irdevice & irDevicesConfig) {
2294
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`)
2295
-
2296
- // see if an accessory with the same uuid has already been registered and restored from
2297
- // the cached devices we stored in the `configureAccessory` method above
2298
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
2299
-
2300
- if (existingAccessory) {
2301
- // the accessory already exists
2302
- if (!device.hide_device && device.hubDeviceId) {
2303
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
2304
- existingAccessory.context.device = device
2305
- existingAccessory.context.deviceId = device.deviceId
2306
- existingAccessory.context.deviceType = `IR: ${device.remoteType}`
2307
- existingAccessory.context.model = device.remoteType
2308
- existingAccessory.displayName = device.configDeviceName
2309
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2310
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2311
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
2312
- existingAccessory.context.connectionType = device.connectionType
2313
- this.api.updatePlatformAccessories([existingAccessory])
2314
- // create the accessory handler for the restored accessory
2315
- // this is imported from `platformAccessory.ts`
2316
- new AirPurifierIR(this, existingAccessory, device)
2317
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`)
2318
- } else {
2319
- this.unregisterPlatformAccessories(existingAccessory)
2320
- }
2321
- } else if (!device.hide_device && device.hubDeviceId) {
2322
- // create a new accessory
2323
- const accessory = new this.api.platformAccessory(device.configDeviceName
2324
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2325
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
2326
-
2327
- // store a copy of the device object in the `accessory.context`
2328
- // the `context` property can be used to store any data about the accessory you may need
2329
- accessory.context.device = device
2330
- accessory.context.deviceId = device.deviceId
2331
- accessory.context.deviceType = `IR: ${device.remoteType}`
2332
- accessory.context.model = device.remoteType
2333
- accessory.displayName = device.configDeviceName
2334
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2335
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2336
- accessory.context.connectionType = await this.connectionType(device)
2337
- accessory.context.version = device.firmware ?? this.version ?? '0.0.0'
2338
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
2339
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
2340
- // create the accessory handler for the newly create accessory
2341
- // this is imported from `platformAccessory.ts`
2342
- new AirPurifierIR(this, accessory, device)
2343
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`)
2344
-
2345
- // publish device externally or link the accessory to your platform
2346
- this.externalOrPlatform(device, accessory)
2347
- this.accessories.push(accessory)
2348
- } else {
2349
- this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} deviceId: ${device.deviceId}`)
2350
- }
2351
- }
2352
-
2353
- private async createWaterHeater(device: irdevice & irDevicesConfig) {
2354
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`)
2355
-
2356
- // see if an accessory with the same uuid has already been registered and restored from
2357
- // the cached devices we stored in the `configureAccessory` method above
2358
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
2359
-
2360
- if (existingAccessory) {
2361
- // the accessory already exists
2362
- if (!device.hide_device && device.hubDeviceId) {
2363
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
2364
- existingAccessory.context.device = device
2365
- existingAccessory.context.deviceId = device.deviceId
2366
- existingAccessory.context.deviceType = `IR: ${device.remoteType}`
2367
- existingAccessory.context.model = device.remoteType
2368
- existingAccessory.displayName = device.configDeviceName
2369
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2370
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2371
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
2372
- existingAccessory.context.connectionType = device.connectionType
2373
- this.api.updatePlatformAccessories([existingAccessory])
2374
- // create the accessory handler for the restored accessory
2375
- // this is imported from `platformAccessory.ts`
2376
- new WaterHeater(this, existingAccessory, device)
2377
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`)
2378
- } else {
2379
- this.unregisterPlatformAccessories(existingAccessory)
2380
- }
2381
- } else if (!device.hide_device && device.hubDeviceId) {
2382
- // create a new accessory
2383
- const accessory = new this.api.platformAccessory(device.configDeviceName
2384
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2385
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
2386
-
2387
- // store a copy of the device object in the `accessory.context`
2388
- // the `context` property can be used to store any data about the accessory you may need
2389
- accessory.context.device = device
2390
- accessory.context.deviceId = device.deviceId
2391
- accessory.context.deviceType = `IR: ${device.remoteType}`
2392
- accessory.context.model = device.remoteType
2393
- accessory.displayName = device.configDeviceName
2394
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2395
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2396
- accessory.context.connectionType = await this.connectionType(device)
2397
- accessory.context.version = device.firmware ?? this.version ?? '0.0.0'
2398
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
2399
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
2400
- // create the accessory handler for the newly create accessory
2401
- // this is imported from `platformAccessory.ts`
2402
- new WaterHeater(this, accessory, device)
2403
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`)
2404
-
2405
- // publish device externally or link the accessory to your platform
2406
- this.externalOrPlatform(device, accessory)
2407
- this.accessories.push(accessory)
2408
- } else {
2409
- this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} deviceId: ${device.deviceId}`)
2410
- }
2411
- }
2412
-
2413
- private async createVacuumCleaner(device: irdevice & irDevicesConfig) {
2414
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`)
2415
-
2416
- // see if an accessory with the same uuid has already been registered and restored from
2417
- // the cached devices we stored in the `configureAccessory` method above
2418
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
2419
-
2420
- if (existingAccessory) {
2421
- // the accessory already exists
2422
- if (!device.hide_device && device.hubDeviceId) {
2423
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
2424
- existingAccessory.context.device = device
2425
- existingAccessory.context.deviceId = device.deviceId
2426
- existingAccessory.context.deviceType = `IR: ${device.remoteType}`
2427
- existingAccessory.context.model = device.remoteType
2428
- existingAccessory.displayName = device.configDeviceName
2429
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2430
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2431
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
2432
- existingAccessory.context.connectionType = device.connectionType
2433
- this.api.updatePlatformAccessories([existingAccessory])
2434
- // create the accessory handler for the restored accessory
2435
- // this is imported from `platformAccessory.ts`
2436
- new VacuumCleaner(this, existingAccessory, device)
2437
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`)
2438
- } else {
2439
- this.unregisterPlatformAccessories(existingAccessory)
2440
- }
2441
- } else if (!device.hide_device && device.hubDeviceId) {
2442
- // create a new accessory
2443
- const accessory = new this.api.platformAccessory(device.configDeviceName
2444
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2445
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
2446
-
2447
- // store a copy of the device object in the `accessory.context`
2448
- // the `context` property can be used to store any data about the accessory you may need
2449
- accessory.context.device = device
2450
- accessory.context.deviceId = device.deviceId
2451
- accessory.context.deviceType = `IR: ${device.remoteType}`
2452
- accessory.context.model = device.remoteType
2453
- accessory.displayName = device.configDeviceName
2454
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2455
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2456
- accessory.context.connectionType = await this.connectionType(device)
2457
- accessory.context.version = device.firmware ?? this.version ?? '0.0.0'
2458
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
2459
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
2460
- // create the accessory handler for the newly create accessory
2461
- // this is imported from `platformAccessory.ts`
2462
- new VacuumCleaner(this, accessory, device)
2463
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`)
2464
-
2465
- // publish device externally or link the accessory to your platform
2466
- this.externalOrPlatform(device, accessory)
2467
- this.accessories.push(accessory)
2468
- } else {
2469
- this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} deviceId: ${device.deviceId}`)
2470
- }
2471
- }
2472
-
2473
- private async createCamera(device: irdevice & irDevicesConfig) {
2474
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`)
2475
-
2476
- // see if an accessory with the same uuid has already been registered and restored from
2477
- // the cached devices we stored in the `configureAccessory` method above
2478
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
2479
-
2480
- if (existingAccessory) {
2481
- // the accessory already exists
2482
- if (!device.hide_device && device.hubDeviceId) {
2483
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
2484
- existingAccessory.context.device = device
2485
- existingAccessory.context.deviceId = device.deviceId
2486
- existingAccessory.context.deviceType = `IR: ${device.remoteType}`
2487
- existingAccessory.context.model = device.remoteType
2488
- existingAccessory.displayName = device.configDeviceName
2489
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2490
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2491
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
2492
- existingAccessory.context.connectionType = device.connectionType
2493
- this.api.updatePlatformAccessories([existingAccessory])
2494
- // create the accessory handler for the restored accessory
2495
- // this is imported from `platformAccessory.ts`
2496
- new Camera(this, existingAccessory, device)
2497
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`)
2498
- } else {
2499
- this.unregisterPlatformAccessories(existingAccessory)
2500
- }
2501
- } else if (!device.hide_device && device.hubDeviceId) {
2502
- // create a new accessory
2503
- const accessory = new this.api.platformAccessory(device.configDeviceName
2504
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2505
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
2506
-
2507
- // store a copy of the device object in the `accessory.context`
2508
- // the `context` property can be used to store any data about the accessory you may need
2509
- accessory.context.device = device
2510
- accessory.context.deviceId = device.deviceId
2511
- accessory.context.deviceType = `IR: ${device.remoteType}`
2512
- accessory.context.model = device.remoteType
2513
- accessory.displayName = device.configDeviceName
2514
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2515
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2516
- accessory.context.connectionType = await this.connectionType(device)
2517
- accessory.context.version = device.firmware ?? this.version ?? '0.0.0'
2518
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
2519
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
2520
- // create the accessory handler for the newly create accessory
2521
- // this is imported from `platformAccessory.ts`
2522
- new Camera(this, accessory, device)
2523
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`)
2524
-
2525
- // publish device externally or link the accessory to your platform
2526
- this.externalOrPlatform(device, accessory)
2527
- this.accessories.push(accessory)
2528
- } else {
2529
- this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} deviceId: ${device.deviceId}`)
2530
- }
2531
- }
2532
-
2533
- private async createOthers(device: irdevice & irDevicesConfig) {
2534
- const uuid = this.api.hap.uuid.generate(`${device.deviceId}-${device.remoteType}`)
2535
-
2536
- // see if an accessory with the same uuid has already been registered and restored from
2537
- // the cached devices we stored in the `configureAccessory` method above
2538
- const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid)
2539
-
2540
- if (existingAccessory) {
2541
- // the accessory already exists
2542
- if (!device.hide_device && device.hubDeviceId) {
2543
- // if you need to update the accessory.context then you should run `api.updatePlatformAccessories`. eg.:
2544
- existingAccessory.context.device = device
2545
- existingAccessory.context.deviceId = device.deviceId
2546
- existingAccessory.context.deviceType = `IR: ${device.remoteType}`
2547
- existingAccessory.context.model = device.remoteType
2548
- existingAccessory.displayName = device.configDeviceName
2549
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2550
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2551
- this.infoLog(`Restoring existing accessory from cache: ${existingAccessory.displayName} deviceId: ${device.deviceId}`)
2552
- existingAccessory.context.connectionType = device.connectionType
2553
- this.api.updatePlatformAccessories([existingAccessory])
2554
- // create the accessory handler for the restored accessory
2555
- // this is imported from `platformAccessory.ts`
2556
- new Others(this, existingAccessory, device)
2557
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${existingAccessory.UUID})`)
2558
- } else {
2559
- this.unregisterPlatformAccessories(existingAccessory)
2560
- }
2561
- } else if (!device.hide_device && device.hubDeviceId) {
2562
- // create a new accessory
2563
- const accessory = new this.api.platformAccessory(device.configDeviceName
2564
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2565
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName), uuid)
2566
-
2567
- // store a copy of the device object in the `accessory.context`
2568
- // the `context` property can be used to store any data about the accessory you may need
2569
- accessory.context.device = device
2570
- accessory.context.deviceId = device.deviceId
2571
- accessory.context.deviceType = `IR: ${device.remoteType}`
2572
- accessory.context.model = device.remoteType
2573
- accessory.displayName = device.configDeviceName
2574
- ? await this.validateAndCleanDisplayName(device.configDeviceName, 'configDeviceName', device.configDeviceName)
2575
- : await this.validateAndCleanDisplayName(device.deviceName, 'deviceName', device.deviceName)
2576
- accessory.context.connectionType = await this.connectionType(device)
2577
- accessory.context.version = device.firmware ?? this.version ?? '0.0.0'
2578
- const newOrExternal = !device.external ? 'Adding new' : 'Loading external'
2579
- this.infoLog(`${newOrExternal} accessory: ${accessory.displayName} deviceId: ${device.deviceId}`)
2580
- // create the accessory handler for the newly create accessory
2581
- // this is imported from `platformAccessory.ts`
2582
- new Others(this, accessory, device)
2583
- this.debugLog(`${device.remoteType} uuid: ${device.deviceId}-${device.remoteType}, (${accessory.UUID})`)
2584
-
2585
- // publish device externally or link the accessory to your platform
2586
- this.externalOrPlatform(device, accessory)
2587
- this.accessories.push(accessory)
2588
- } else {
2589
- this.debugLog(`Device not registered: ${device.deviceName} ${device.remoteType} deviceId: ${device.deviceId}`)
2590
- }
2591
- }
2592
-
2593
- async registerCurtains(device: device & devicesConfig): Promise<boolean> {
2594
- let registerWindowCovering: boolean
2595
- if (isCurtainDevice(device)) {
2596
- this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, curtainDevicesIds: ${device.curtainDevicesIds},x master: ${device.master}, group: ${device.group}, disable_group: ${(device as blindTiltConfig | curtainConfig).disable_group}, connectionType: ${device.connectionType}`)
2597
- registerWindowCovering = await this.registerWindowCovering(device)
2598
- } else if (isBlindTiltDevice(device)) {
2599
- this.debugWarnLog(`deviceName: ${device.deviceName} deviceId: ${device.deviceId}, blindTiltDevicesIds: ${device.blindTiltDevicesIds}, master: ${device.master}, group: ${device.group}, disable_group: ${(device as blindTiltConfig | curtainConfig).disable_group}, connectionType: ${device.connectionType}`)
2600
- registerWindowCovering = await this.registerWindowCovering(device)
2601
- } else {
2602
- registerWindowCovering = false
2603
- }
2604
- return registerWindowCovering
2605
- }
2606
-
2607
- async registerWindowCovering(device: (curtain | curtain3 | blindTilt) & devicesConfig) {
2608
- this.debugLog(`master: ${device.master}`)
2609
- let registerCurtain: boolean
2610
- if (device.master && device.group) {
2611
- // OpenAPI: Master Curtains/Blind Tilt in Group
2612
- registerCurtain = true
2613
- this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group} connectionType; ${device.connectionType}`)
2614
- this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`)
2615
- } else if (!device.master && (device as blindTiltConfig | curtainConfig).disable_group) {
2616
- registerCurtain = true
2617
- this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, disable_group: ${(device as blindTiltConfig | curtainConfig).disable_group}, connectionType; ${device.connectionType}`)
2618
- this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`)
2619
- } else if (device.master && !device.group) {
2620
- // OpenAPI: Master Curtains/Blind Tilts not in Group
2621
- registerCurtain = true
2622
- this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] device.master: ${device.master}, device.group: ${device.group} connectionType; ${device.connectionType}`)
2623
- this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`)
2624
- } else if (device.connectionType === 'BLE') {
2625
- // BLE: Curtains/Blind Tilt
2626
- registerCurtain = true
2627
- this.debugLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] connectionType: ${device.connectionType}, group: ${device.group}`)
2628
- this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}`)
2629
- } else {
2630
- registerCurtain = false
2631
- this.debugErrorLog(`deviceName: ${device.deviceName} [${device.deviceType} Config] disable_group: ${(device as blindTiltConfig | curtainConfig).disable_group}, device.master: ${device.master}, device.group: ${device.group}`)
2632
- this.debugWarnLog(`Device: ${device.deviceName} registerCurtains: ${registerCurtain}, device.connectionType: ${device.connectionType}`)
2633
- }
2634
- return registerCurtain
2635
- }
2636
-
2637
- async connectionType(device: (device & devicesConfig) | (irdevice & irDevicesConfig)): Promise<any> {
2638
- let connectionType: string
2639
- if (!device.connectionType && this.config.credentials?.token && this.config.credentials.secret) {
2640
- connectionType = 'OpenAPI'
2641
- } else {
2642
- connectionType = device.connectionType!
2643
- }
2644
- return connectionType
2645
- }
2646
-
2647
- async registerDevice(device: device & devicesConfig) {
2648
- device.connectionType = await this.connectionType(device)
2649
- let registerDevice: boolean
2650
-
2651
- const shouldRegister = !device.hide_device && (device.connectionType === 'BLE/OpenAPI' || (device.deviceId && device.configDeviceType && device.configDeviceName && device.connectionType === 'BLE') || device.connectionType === 'OpenAPI' || device.connectionType === 'Disabled')
2652
-
2653
- if (shouldRegister) {
2654
- registerDevice = await this.handleDeviceRegistration(device)
2655
- } else {
2656
- registerDevice = false
2657
- this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, hide_device: ${device.hide_device}, will not display in HomeKit`)
2658
- }
2659
-
2660
- return registerDevice
2661
- }
2662
-
2663
- async handleDeviceRegistration(device: device & devicesConfig): Promise<boolean> {
2664
- let registerDevice: boolean
2665
-
2666
- switch (device.deviceType) {
2667
- case 'Curtain':
2668
- case 'Curtain3':
2669
- case 'Blind Tilt':
2670
- registerDevice = await this.registerCurtains(device)
2671
- this.debugWarnLog(`Device: ${device.deviceName} ${device.deviceType} registerDevice: ${registerDevice}`)
2672
- break
2673
- default:
2674
- registerDevice = true
2675
- this.debugWarnLog(`Device: ${device.deviceName} registerDevice: ${registerDevice}`)
2676
- }
2677
-
2678
- if (registerDevice) {
2679
- this.debugWarnLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will display in HomeKit`)
2680
- } else {
2681
- this.debugErrorLog(`Device: ${device.deviceName} connectionType: ${device.connectionType}, will not display in HomeKit`)
2682
- }
2683
-
2684
- return registerDevice
2685
- }
2686
-
2687
- public async externalOrPlatform(device: (device & devicesConfig) | (irdevice & irDevicesConfig), accessory: PlatformAccessory) {
2688
- const { displayName } = accessory
2689
- const isExternal = device.external ?? false
2690
-
2691
- if (isExternal) {
2692
- this.debugWarnLog(`${displayName} External Accessory Mode`)
2693
- this.api.publishExternalAccessories(PLUGIN_NAME, [accessory])
2694
- } else {
2695
- this.debugLog(`${displayName} External Accessory Mode: ${isExternal}`)
2696
- this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory])
2697
- }
2698
- }
2699
-
2700
- public unregisterPlatformAccessories(existingAccessory: PlatformAccessory) {
2701
- const { displayName } = existingAccessory
2702
- // remove platform accessories when no longer present
2703
- this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [existingAccessory])
2704
- this.warnLog(`Removing existing accessory from cache: ${displayName}`)
2705
- }
2706
-
2707
- /**
2708
- * Handles the status codes returned by the device and logs appropriate messages.
2709
- *
2710
- * @param statusCode - The status code returned by the device.
2711
- * @returns A promise that resolves when the logging is complete.
2712
- */
2713
- async statusCode(statusCode: number): Promise<void> {
2714
- const messages: { [key: number]: string } = {
2715
- 151: `Command not supported by this device type, statusCode: ${statusCode}, Submit Feature Request Here:
2716
- https://tinyurl.com/SwitchBotFeatureRequest`,
2717
- 152: `Device not found, statusCode: ${statusCode}`,
2718
- 160: `Command is not supported, statusCode: ${statusCode}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`,
2719
- 161: `Device is offline, statusCode: ${statusCode}`,
2720
- 171: `is offline, statusCode: ${statusCode}`,
2721
- 190: `Requests reached the daily limit, statusCode: ${statusCode}`,
2722
- 100: `Command successfully sent, statusCode: ${statusCode}`,
2723
- 200: `Request successful, statusCode: ${statusCode}`,
2724
- 400: `Bad Request, The client has issued an invalid request. This is commonly used to specify validation errors in a request payload,
2725
- statusCode: ${statusCode}`,
2726
- 401: `Unauthorized, Authorization for the API is required, but the request has not been authenticated, statusCode: ${statusCode}`,
2727
- 403: `Forbidden, The request has been authenticated but does not have appropriate permissions, or a requested resource is not found,
2728
- statusCode: ${statusCode}`,
2729
- 404: `Not Found, Specifies the requested path does not exist, statusCode: ${statusCode}`,
2730
- 406: `Not Acceptable, The client has requested a MIME type via the Accept header for a value not supported by the server,
2731
- statusCode: ${statusCode}`,
2732
- 415: `Unsupported Media Type, The client has defined a contentType header that is not supported by the server, statusCode: ${statusCode}`,
2733
- 422: `Unprocessable Entity, The client has made a valid request, but the server cannot process it. This is often used for APIs for which
2734
- certain limits have been exceeded, statusCode: ${statusCode}`,
2735
- 429: `Too Many Requests, The client has exceeded the number of requests allowed for a given time window, statusCode: ${statusCode}`,
2736
- 500: `Internal Server Error, An unexpected error on the SmartThings servers has occurred. These errors should be rare,
2737
- statusCode: ${statusCode}`,
2738
- }
2739
-
2740
- const message = messages[statusCode] ?? `Unknown statusCode, statusCode: ${statusCode}, Submit Bugs Here: https://tinyurl.com/SwitchBotBug`
2741
-
2742
- if ([100, 200].includes(statusCode)) {
2743
- this.debugLog(message)
2744
- } else {
2745
- this.errorLog(message)
2746
- }
2747
- }
2748
-
2749
- async retryRequest(device: (device & devicesConfig) | (irdevice & irDevicesConfig), deviceMaxRetries: number, deviceDelayBetweenRetries: number): Promise<{ response: any, statusCode: deviceStatusRequest['statusCode'] }> {
2750
- let retryCount = 0
2751
- const maxRetries = deviceMaxRetries
2752
- const delayBetweenRetries = deviceDelayBetweenRetries
2753
- while (retryCount < maxRetries) {
2754
- try {
2755
- const { response, statusCode } = await this.switchBotAPI.getDeviceStatus(device.deviceId, this.config.credentials?.token, this.config.credentials?.secret)
2756
- this.debugLog(`response: ${JSON.stringify(response)}`)
2757
- return { response, statusCode }
2758
- } catch (error: any) {
2759
- this.errorLog(`Error making request: ${error.message}`)
2760
- }
2761
- retryCount++
2762
- this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`)
2763
- await sleep(delayBetweenRetries)
2764
- }
2765
- return { response: {
2766
- deviceId: '',
2767
- deviceType: '',
2768
- hubDeviceId: '',
2769
- version: 0,
2770
- deviceName: '',
2771
- }, statusCode: 500 }
2772
- }
2773
-
2774
- async retryCommand(device: (device & devicesConfig) | (irdevice & irDevicesConfig), bodyChange: bodyChange, deviceMaxRetries?: number, deviceDelayBetweenRetries?: number): Promise<{ response: any, statusCode: number }> {
2775
- let retryCount = 0
2776
- const maxRetries = deviceMaxRetries ?? 1
2777
- const delayBetweenRetries = deviceDelayBetweenRetries ?? 1000
2778
- while (retryCount < maxRetries) {
2779
- try {
2780
- const { response, statusCode } = await this.switchBotAPI.controlDevice(
2781
- device.deviceId,
2782
- bodyChange.command,
2783
- bodyChange.parameter,
2784
- bodyChange.commandType as import('node-switchbot').commandType,
2785
- this.config.credentials?.token,
2786
- this.config.credentials?.secret,
2787
- )
2788
- this.debugLog(`response: ${JSON.stringify(response)}`)
2789
- return { response, statusCode }
2790
- } catch (error: any) {
2791
- this.errorLog(`Error making request: ${error.message}`)
2792
- }
2793
- retryCount++
2794
- this.debugLog(`Retry attempt ${retryCount} of ${maxRetries}`)
2795
- await sleep(delayBetweenRetries)
2796
- }
2797
- return { response: {}, statusCode: 500 }
2798
- }
2799
-
2800
- // BLE Connection
2801
- async connectBLE(accessory: PlatformAccessory, device: device & devicesConfig): Promise<any> {
2802
- try {
2803
- queueScheduler.schedule(async () => this.switchBotBLE)
2804
- this.debugLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' found: ${safeStringify(this.switchBotBLE)}`)
2805
- return this.switchBotBLE
2806
- } catch (e: any) {
2807
- this.errorLog(`${device.deviceType}: ${accessory.displayName} 'node-switchbot' not found, Error: ${e.message ?? e}`)
2808
- return false
2809
- }
2810
- }
2811
-
2812
- async getPlatformConfigSettings() {
2813
- if (this.config.options) {
2814
- const platformConfig: SwitchBotPlatformConfig = {
2815
- platform: 'Resideo',
2816
- }
2817
- platformConfig.logging = this.config.options.logging ? this.config.options.logging : undefined
2818
- platformConfig.refreshRate = this.config.options.refreshRate ? this.config.options.refreshRate : undefined
2819
- platformConfig.updateRate = this.config.options.updateRate ? this.config.options.updateRate : undefined
2820
- platformConfig.pushRate = this.config.options.pushRate ? this.config.options.pushRate : undefined
2821
- platformConfig.maxRetries = this.config.options.maxRetries ? this.config.options.maxRetries : undefined
2822
- platformConfig.delayBetweenRetries = this.config.options.delayBetweenRetries ? this.config.options.delayBetweenRetries : undefined
2823
- if (Object.entries(platformConfig).length !== 0) {
2824
- await this.debugLog(`Platform Config: ${JSON.stringify(platformConfig)}`)
2825
- }
2826
- this.platformConfig = platformConfig
2827
- }
2828
- }
2829
-
2830
- async getPlatformRateSettings() {
2831
- // RefreshRate
2832
- this.platformRefreshRate = this.config.options?.refreshRate ? this.config.options.refreshRate : undefined
2833
- const refreshRate = this.config.options?.refreshRate ? 'Using Platform Config refreshRate' : 'Platform Config refreshRate Not Set'
2834
- await this.debugLog(`${refreshRate}: ${this.platformRefreshRate}`)
2835
- // UpdateRate
2836
- this.platformUpdateRate = this.config.options?.updateRate ? this.config.options.updateRate : undefined
2837
- const updateRate = this.config.options?.updateRate ? 'Using Platform Config updateRate' : 'Platform Config updateRate Not Set'
2838
- await this.debugLog(`${updateRate}: ${this.platformUpdateRate}`)
2839
- // PushRate
2840
- this.platformPushRate = this.config.options?.pushRate ? this.config.options.pushRate : undefined
2841
- const pushRate = this.config.options?.pushRate ? 'Using Platform Config pushRate' : 'Platform Config pushRate Not Set'
2842
- await this.debugLog(`${pushRate}: ${this.platformPushRate}`)
2843
- // MaxRetries
2844
- this.platformMaxRetries = this.config.options?.maxRetries ? this.config.options.maxRetries : undefined
2845
- const maxRetries = this.config.options?.maxRetries ? 'Using Platform Config maxRetries' : 'Platform Config maxRetries Not Set'
2846
- await this.debugLog(`${maxRetries}: ${this.platformMaxRetries}`)
2847
- // DelayBetweenRetries
2848
- this.platformDelayBetweenRetries = this.config.options?.delayBetweenRetries ? this.config.options.delayBetweenRetries : undefined
2849
- const delayBetweenRetries = this.config.options?.delayBetweenRetries ? 'Using Platform Config delayBetweenRetries' : 'Platform Config delayBetweenRetries Not Set'
2850
- await this.debugLog(`${delayBetweenRetries}: ${this.platformDelayBetweenRetries}`)
2851
- }
2852
-
2853
- async getPlatformLogSettings() {
2854
- this.debugMode = argv.includes('-D') ?? argv.includes('--debug')
2855
- this.platformLogging = (this.config.options?.logging === 'debug' || this.config.options?.logging === 'standard'
2856
- || this.config.options?.logging === 'none')
2857
- ? this.config.options.logging
2858
- : this.debugMode ? 'debugMode' : 'standard'
2859
- const logging = this.config.options?.logging ? 'Platform Config' : this.debugMode ? 'debugMode' : 'Default'
2860
- await this.debugLog(`Using ${logging} Logging: ${this.platformLogging}`)
2861
- }
2862
-
2863
- /**
2864
- * Asynchronously retrieves the version of the plugin from the package.json file.
2865
- *
2866
- * This method reads the package.json file located in the parent directory,
2867
- * parses its content to extract the version, and logs the version using the debug logger.
2868
- * The extracted version is then assigned to the `version` property of the class.
2869
- *
2870
- * @returns {Promise<void>} A promise that resolves when the version has been retrieved and logged.
2871
- */
2872
- async getVersion(): Promise<void> {
2873
- const { version } = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf-8'))
2874
- this.debugLog(`Plugin Version: ${version}`)
2875
- this.version = version
2876
- }
2877
-
2878
- /**
2879
- * Validate and clean a string value for a Name Characteristic.
2880
- * @param displayName - The display name of the accessory.
2881
- * @param name - The name of the characteristic.
2882
- * @param value - The value to be validated and cleaned.
2883
- * @returns The cleaned string value.
2884
- */
2885
- async validateAndCleanDisplayName(displayName: string, name: string, value: string): Promise<string> {
2886
- if (this.config.options?.allowInvalidCharacters) {
2887
- return value
2888
- } else {
2889
- const validPattern = /^[\p{L}\p{N}][\p{L}\p{N} ']*[\p{L}\p{N}]$/u
2890
- const invalidCharsPattern = /[^\p{L}\p{N} ']/gu
2891
- const invalidStartEndPattern = /^[^\p{L}\p{N}]+|[^\p{L}\p{N}]+$/gu
2892
-
2893
- if (typeof value === 'string' && !validPattern.test(value)) {
2894
- this.warnLog(`WARNING: The accessory '${displayName}' has an invalid '${name}' characteristic ('${value}'). Please use only alphanumeric, space, and apostrophe characters. Ensure it starts and ends with an alphabetic or numeric character, and avoid emojis. This may prevent the accessory from being added in the Home App or cause unresponsiveness.`)
2895
-
2896
- // Remove invalid characters
2897
- if (invalidCharsPattern.test(value)) {
2898
- const before = value
2899
- this.warnLog(`Removing invalid characters from '${name}' characteristic, if you feel this is incorrect, please enable \'allowInvalidCharacter\' in the config to allow all characters`)
2900
- value = value.replace(invalidCharsPattern, '')
2901
- this.warnLog(`${name} Before: '${before}' After: '${value}'`)
2902
- }
2903
-
2904
- // Ensure it starts and ends with an alphanumeric character
2905
- if (invalidStartEndPattern.test(value)) {
2906
- const before = value
2907
- this.warnLog(`Removing invalid starting or ending characters from '${name}' characteristic, if you feel this is incorrect, please enable \'allowInvalidCharacter\' in the config to allow all characters`)
2908
- value = value.replace(invalidStartEndPattern, '')
2909
- this.warnLog(`${name} Before: '${before}' After: '${value}'`)
2910
- }
2911
- }
2912
-
2913
- return value
2914
- }
2915
- }
2916
-
2917
- /**
2918
- * If device level logging is turned on, log to log.warn
2919
- * Otherwise send debug logs to log.debug
2920
- */
2921
- async infoLog(...log: any[]): Promise<void> {
2922
- if (await this.enablingPlatformLogging()) {
2923
- this.log.info(String(...log))
2924
- }
2925
- }
2926
-
2927
- async successLog(...log: any[]): Promise<void> {
2928
- if (await this.enablingPlatformLogging()) {
2929
- this.log.success(String(...log))
2930
- }
2931
- }
2932
-
2933
- async debugSuccessLog(...log: any[]): Promise<void> {
2934
- if (await this.enablingPlatformLogging()) {
2935
- if (await this.loggingIsDebug()) {
2936
- this.log.success('[DEBUG]', String(...log))
2937
- }
2938
- }
2939
- }
2940
-
2941
- async warnLog(...log: any[]): Promise<void> {
2942
- if (await this.enablingPlatformLogging()) {
2943
- this.log.warn(String(...log))
2944
- }
2945
- }
2946
-
2947
- async debugWarnLog(...log: any[]): Promise<void> {
2948
- if (await this.enablingPlatformLogging()) {
2949
- if (await this.loggingIsDebug()) {
2950
- this.log.warn('[DEBUG]', String(...log))
2951
- }
2952
- }
2953
- }
2954
-
2955
- async errorLog(...log: any[]): Promise<void> {
2956
- if (await this.enablingPlatformLogging()) {
2957
- this.log.error(String(...log))
2958
- }
2959
- }
2960
-
2961
- async debugErrorLog(...log: any[]): Promise<void> {
2962
- if (await this.enablingPlatformLogging()) {
2963
- if (await this.loggingIsDebug()) {
2964
- this.log.error('[DEBUG]', String(...log))
2965
- }
2966
- }
2967
- }
2968
-
2969
- async debugLog(...log: any[]): Promise<void> {
2970
- if (await this.enablingPlatformLogging()) {
2971
- if (this.platformLogging === 'debug') {
2972
- this.log.info('[DEBUG]', String(...log))
2973
- } else if (this.platformLogging === 'debugMode') {
2974
- this.log.debug(String(...log))
2975
- }
2976
- }
2977
- }
2978
-
2979
- async loggingIsDebug(): Promise<boolean> {
2980
- return this.platformLogging === 'debugMode' || this.platformLogging === 'debug'
2981
- }
2982
-
2983
- async enablingPlatformLogging(): Promise<boolean> {
2984
- return this.platformLogging === 'debugMode' || this.platformLogging === 'debug' || this.platformLogging === 'standard'
2985
- }
2986
- }