@switchbot/homebridge-switchbot 5.0.0-beta.8 → 5.0.0-beta.80

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