@switchbot/homebridge-switchbot 5.0.0-beta.98 → 5.0.0
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.
- package/.changeset/config.json +14 -0
- package/.github/copilot-instructions.md +39 -0
- package/.github/workflows/ci.yml +4 -1
- package/.github/workflows/manual-e2e.yml +6 -3
- package/.github/workflows/release.yml +64 -15
- package/.github/workflows/stale.yml +2 -4
- package/.husky/pre-push +15 -0
- package/CHANGELOG.md +126 -134
- package/MIGRATION.md +16 -6
- package/README.md +84 -3
- package/TODO.md +263 -0
- package/config.schema.json +229 -36
- package/dist/SwitchBotHAPPlatform.d.ts +133 -0
- package/dist/SwitchBotHAPPlatform.d.ts.map +1 -0
- package/dist/SwitchBotHAPPlatform.js +555 -0
- package/dist/SwitchBotHAPPlatform.js.map +1 -0
- package/dist/SwitchBotMatterPlatform.d.ts +141 -0
- package/dist/SwitchBotMatterPlatform.d.ts.map +1 -0
- package/dist/SwitchBotMatterPlatform.js +536 -0
- package/dist/SwitchBotMatterPlatform.js.map +1 -0
- package/dist/device-types.d.ts +31 -0
- package/dist/device-types.d.ts.map +1 -0
- package/dist/device-types.js +246 -0
- package/dist/device-types.js.map +1 -0
- package/dist/deviceCommandMapper.d.ts +10 -0
- package/dist/deviceCommandMapper.d.ts.map +1 -0
- package/dist/deviceCommandMapper.js +319 -0
- package/dist/deviceCommandMapper.js.map +1 -0
- package/dist/deviceFactory.d.ts +3 -2
- package/dist/deviceFactory.d.ts.map +1 -1
- package/dist/deviceFactory.js +107 -29
- package/dist/deviceFactory.js.map +1 -1
- package/dist/devices/genericDevice.d.ts +59 -37
- package/dist/devices/genericDevice.d.ts.map +1 -1
- package/dist/devices/genericDevice.js +376 -78
- package/dist/devices/genericDevice.js.map +1 -1
- package/dist/errors.d.ts +38 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +32 -0
- package/dist/errors.js.map +1 -0
- package/dist/homebridge-ui/device-types.js +246 -0
- package/dist/homebridge-ui/device-types.js.map +1 -0
- package/dist/homebridge-ui/deviceCommandMapper.js +319 -0
- package/dist/homebridge-ui/deviceCommandMapper.js.map +1 -0
- package/dist/homebridge-ui/endpoints/config.d.ts +3 -0
- package/dist/homebridge-ui/endpoints/config.d.ts.map +1 -0
- package/dist/homebridge-ui/endpoints/config.js +90 -0
- package/dist/homebridge-ui/endpoints/config.js.map +1 -0
- package/dist/homebridge-ui/endpoints/devices.d.ts +6 -0
- package/dist/homebridge-ui/endpoints/devices.d.ts.map +1 -0
- package/dist/homebridge-ui/endpoints/devices.js +144 -0
- package/dist/homebridge-ui/endpoints/devices.js.map +1 -0
- package/dist/homebridge-ui/endpoints/discovery.d.ts +7 -0
- package/dist/homebridge-ui/endpoints/discovery.d.ts.map +1 -0
- package/dist/homebridge-ui/endpoints/discovery.js +219 -0
- package/dist/homebridge-ui/endpoints/discovery.js.map +1 -0
- package/dist/homebridge-ui/errors.js +32 -0
- package/dist/homebridge-ui/errors.js.map +1 -0
- package/dist/homebridge-ui/homebridge-ui/endpoints/config.js +90 -0
- package/dist/homebridge-ui/homebridge-ui/endpoints/config.js.map +1 -0
- package/dist/homebridge-ui/homebridge-ui/endpoints/devices.js +144 -0
- package/dist/homebridge-ui/homebridge-ui/endpoints/devices.js.map +1 -0
- package/dist/homebridge-ui/homebridge-ui/endpoints/discovery.js +219 -0
- package/dist/homebridge-ui/homebridge-ui/endpoints/discovery.js.map +1 -0
- package/dist/homebridge-ui/homebridge-ui/server.js +11 -0
- package/dist/homebridge-ui/homebridge-ui/server.js.map +1 -0
- package/dist/homebridge-ui/homebridge-ui/utils/config-parser.js +108 -0
- package/dist/homebridge-ui/homebridge-ui/utils/config-parser.js.map +1 -0
- package/dist/homebridge-ui/homebridge-ui/utils/device-migration.js +111 -0
- package/dist/homebridge-ui/homebridge-ui/utils/device-migration.js.map +1 -0
- package/dist/homebridge-ui/homebridge-ui/utils/logger.js +17 -0
- package/dist/homebridge-ui/homebridge-ui/utils/logger.js.map +1 -0
- package/dist/homebridge-ui/public/css/styles.css +483 -0
- package/dist/homebridge-ui/public/index.html +197 -621
- package/dist/homebridge-ui/public/js/advanced-settings.d.ts +3 -0
- package/dist/homebridge-ui/public/js/advanced-settings.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/advanced-settings.js +95 -0
- package/dist/homebridge-ui/public/js/advanced-settings.js.map +1 -0
- package/dist/homebridge-ui/public/js/advanced-settings.ts +94 -0
- package/dist/homebridge-ui/public/js/api.d.ts +66 -0
- package/dist/homebridge-ui/public/js/api.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/api.js +295 -0
- package/dist/homebridge-ui/public/js/api.js.map +1 -0
- package/dist/homebridge-ui/public/js/api.ts +355 -0
- package/dist/homebridge-ui/public/js/app.d.ts +2 -0
- package/dist/homebridge-ui/public/js/app.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/app.js +3722 -0
- package/dist/homebridge-ui/public/js/app.js.map +7 -0
- package/dist/homebridge-ui/public/js/app.ts +22 -0
- package/dist/homebridge-ui/public/js/constants.d.ts +2 -0
- package/dist/homebridge-ui/public/js/constants.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/constants.js +2 -0
- package/dist/homebridge-ui/public/js/constants.js.map +1 -0
- package/dist/homebridge-ui/public/js/constants.ts +1 -0
- package/dist/homebridge-ui/public/js/credentials.d.ts +3 -0
- package/dist/homebridge-ui/public/js/credentials.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/credentials.js +99 -0
- package/dist/homebridge-ui/public/js/credentials.js.map +1 -0
- package/dist/homebridge-ui/public/js/credentials.ts +105 -0
- package/dist/homebridge-ui/public/js/devices-delete.d.ts +3 -0
- package/dist/homebridge-ui/public/js/devices-delete.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/devices-delete.js +199 -0
- package/dist/homebridge-ui/public/js/devices-delete.js.map +1 -0
- package/dist/homebridge-ui/public/js/devices-delete.ts +227 -0
- package/dist/homebridge-ui/public/js/devices.d.ts +9 -0
- package/dist/homebridge-ui/public/js/devices.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/devices.js +98 -0
- package/dist/homebridge-ui/public/js/devices.js.map +1 -0
- package/dist/homebridge-ui/public/js/devices.ts +106 -0
- package/dist/homebridge-ui/public/js/discovery.d.ts +9 -0
- package/dist/homebridge-ui/public/js/discovery.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/discovery.js +1201 -0
- package/dist/homebridge-ui/public/js/discovery.js.map +1 -0
- package/dist/homebridge-ui/public/js/discovery.ts +1335 -0
- package/dist/homebridge-ui/public/js/logger.d.ts +7 -0
- package/dist/homebridge-ui/public/js/logger.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/logger.js +17 -0
- package/dist/homebridge-ui/public/js/logger.js.map +1 -0
- package/dist/homebridge-ui/public/js/logger.ts +17 -0
- package/dist/homebridge-ui/public/js/modal.d.ts +5 -0
- package/dist/homebridge-ui/public/js/modal.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/modal.js +35 -0
- package/dist/homebridge-ui/public/js/modal.js.map +1 -0
- package/dist/homebridge-ui/public/js/modal.ts +35 -0
- package/dist/homebridge-ui/public/js/modals.d.ts +15 -0
- package/dist/homebridge-ui/public/js/modals.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/modals.js +675 -0
- package/dist/homebridge-ui/public/js/modals.js.map +1 -0
- package/dist/homebridge-ui/public/js/modals.ts +765 -0
- package/dist/homebridge-ui/public/js/render.d.ts +71 -0
- package/dist/homebridge-ui/public/js/render.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/render.js +960 -0
- package/dist/homebridge-ui/public/js/render.js.map +1 -0
- package/dist/homebridge-ui/public/js/render.ts +1084 -0
- package/dist/homebridge-ui/public/js/toast.d.ts +6 -0
- package/dist/homebridge-ui/public/js/toast.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/toast.js +38 -0
- package/dist/homebridge-ui/public/js/toast.js.map +1 -0
- package/dist/homebridge-ui/public/js/toast.ts +44 -0
- package/dist/homebridge-ui/public/js/types.d.ts +23 -0
- package/dist/homebridge-ui/public/js/types.d.ts.map +1 -0
- package/dist/homebridge-ui/public/js/types.js +2 -0
- package/dist/homebridge-ui/public/js/types.js.map +1 -0
- package/dist/homebridge-ui/public/js/types.ts +26 -0
- package/dist/homebridge-ui/server.d.ts +1 -3
- package/dist/homebridge-ui/server.d.ts.map +1 -1
- package/dist/homebridge-ui/server.js +8 -450
- package/dist/homebridge-ui/server.js.map +1 -1
- package/dist/homebridge-ui/settings.js +8 -0
- package/dist/homebridge-ui/settings.js.map +1 -0
- package/dist/homebridge-ui/switchbotClient.js +247 -0
- package/dist/homebridge-ui/switchbotClient.js.map +1 -0
- package/dist/homebridge-ui/utils/config-parser.d.ts +39 -0
- package/dist/homebridge-ui/utils/config-parser.d.ts.map +1 -0
- package/dist/homebridge-ui/utils/config-parser.js +108 -0
- package/dist/homebridge-ui/utils/config-parser.js.map +1 -0
- package/dist/homebridge-ui/utils/device-migration.d.ts +35 -0
- package/dist/homebridge-ui/utils/device-migration.d.ts.map +1 -0
- package/dist/homebridge-ui/utils/device-migration.js +111 -0
- package/dist/homebridge-ui/utils/device-migration.js.map +1 -0
- package/dist/homebridge-ui/utils/logger.d.ts +7 -0
- package/dist/homebridge-ui/utils/logger.d.ts.map +1 -0
- package/dist/homebridge-ui/utils/logger.js +17 -0
- package/dist/homebridge-ui/utils/logger.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/settings.d.ts +1 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +1 -0
- package/dist/settings.js.map +1 -1
- package/dist/switchbotClient.d.ts +12 -10
- package/dist/switchbotClient.d.ts.map +1 -1
- package/dist/switchbotClient.js +156 -103
- package/dist/switchbotClient.js.map +1 -1
- package/dist/utils.d.ts +76 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1121 -4
- package/dist/utils.js.map +1 -1
- package/docs/assets/highlight.css +16 -2
- package/docs/assets/main.js +1 -1
- package/docs/index.html +82 -5
- package/docs/variables/default.html +3 -1
- package/eslint.config.js +9 -5
- package/nodemon.json +2 -2
- package/package.json +34 -21
- package/scripts/build-ui.js +37 -0
- package/scripts/free-dev-ports.mjs +105 -0
- package/scripts/generate-matter-maps.js +34 -17
- package/scripts/sync-device-types.mjs +31 -0
- package/src/SwitchBotHAPPlatform.ts +558 -0
- package/src/SwitchBotMatterPlatform.ts +538 -0
- package/src/device-types.js +246 -0
- package/src/device-types.js.map +1 -0
- package/src/device-types.ts +261 -0
- package/src/deviceCommandMapper.js +319 -0
- package/src/deviceCommandMapper.js.map +1 -0
- package/src/deviceCommandMapper.ts +333 -0
- package/src/deviceFactory.ts +125 -45
- package/src/devices/genericDevice.ts +411 -69
- package/src/errors.js +32 -0
- package/src/errors.js.map +1 -0
- package/src/errors.ts +35 -0
- package/src/homebridge-ui/endpoints/config.ts +110 -0
- package/src/homebridge-ui/endpoints/devices.ts +153 -0
- package/src/homebridge-ui/endpoints/discovery.ts +240 -0
- package/src/homebridge-ui/public/css/styles.css +483 -0
- package/src/homebridge-ui/public/index.html +197 -621
- package/src/homebridge-ui/public/js/advanced-settings.ts +94 -0
- package/src/homebridge-ui/public/js/api.ts +355 -0
- package/src/homebridge-ui/public/js/app.ts +22 -0
- package/src/homebridge-ui/public/js/constants.ts +1 -0
- package/src/homebridge-ui/public/js/credentials.ts +105 -0
- package/src/homebridge-ui/public/js/devices-delete.ts +227 -0
- package/src/homebridge-ui/public/js/devices.ts +106 -0
- package/src/homebridge-ui/public/js/discovery.ts +1335 -0
- package/src/homebridge-ui/public/js/logger.ts +17 -0
- package/src/homebridge-ui/public/js/modal.ts +35 -0
- package/src/homebridge-ui/public/js/modals.ts +765 -0
- package/src/homebridge-ui/public/js/render.ts +1084 -0
- package/src/homebridge-ui/public/js/toast.ts +44 -0
- package/src/homebridge-ui/public/js/types.ts +26 -0
- package/src/homebridge-ui/server.ts +9 -526
- package/src/homebridge-ui/utils/config-parser.ts +125 -0
- package/src/homebridge-ui/utils/device-migration.ts +144 -0
- package/src/homebridge-ui/utils/logger.ts +17 -0
- package/src/index.ts +12 -2
- package/src/settings.js +8 -0
- package/src/settings.js.map +1 -0
- package/src/settings.ts +2 -0
- package/src/switchbotClient.js +247 -0
- package/src/switchbotClient.js.map +1 -0
- package/src/switchbotClient.ts +177 -114
- package/src/utils.ts +1133 -5
- package/test/client/switchbot-client-debounce.spec.ts +35 -0
- package/test/client/switchbot-client-openapi.spec.ts +19 -0
- package/test/client/switchbotClient.spec.ts +64 -0
- package/test/device/device-mapping.spec.ts +23 -0
- package/test/device/deviceBase.spec.ts +26 -0
- package/test/device/deviceFactory-edge.spec.ts +15 -0
- package/test/device/deviceFactory.spec.ts +33 -0
- package/test/device/fan-swing.spec.ts +34 -0
- package/test/device/genericDevice-blepoll.spec.ts +47 -0
- package/test/device/irdevice.spec.ts +9 -0
- package/test/device/lock-users.spec.ts +35 -0
- package/test/device/matter-descriptors.spec.ts +22 -0
- package/test/device/matter-device-state.spec.ts +37 -0
- package/test/e2e/run-e2e.spec.ts +18 -19
- package/test/errors/errors.spec.ts +10 -0
- package/test/helpers/matter-harness.ts +20 -9
- package/test/homebridge-ui/server.spec.ts +9 -0
- package/test/platform/accessory-restore.spec.ts +37 -0
- package/test/platform/matter-childbridge.spec.ts +34 -0
- package/test/platform/matter-integration.spec.ts +33 -0
- package/test/platform/platform-edge.spec.ts +73 -0
- package/test/platform/platform.integration.spec.ts +34 -0
- package/test/utils/utils-extra.spec.ts +10 -0
- package/test/utils/utils.spec.ts +53 -0
- package/todo/TODO.md +80 -0
- package/tsconfig.ui.json +11 -0
- package/.github/npm-version-script-esm.js +0 -97
- package/.github/workflows/beta-release.yml +0 -52
- package/dist/platform.d.ts +0 -35
- package/dist/platform.d.ts.map +0 -1
- package/dist/platform.js +0 -850
- package/dist/platform.js.map +0 -1
- package/src/platform.ts +0 -867
- package/test/accessory-restore.spec.ts +0 -73
- package/test/device-mapping.spec.ts +0 -37
- package/test/deviceFactory.spec.ts +0 -18
- package/test/fan-swing.spec.ts +0 -29
- package/test/lock-users.spec.ts +0 -44
- package/test/matter-childbridge.spec.ts +0 -55
- package/test/matter-descriptors.spec.ts +0 -97
- package/test/matter-device-state.spec.ts +0 -101
- package/test/matter-integration.spec.ts +0 -70
- package/test/platform.integration.spec.ts +0 -55
- package/test/switchbot-client-debounce.spec.ts +0 -131
- package/test/switchbot-client-openapi.spec.ts +0 -56
- package/test/switchbotClient.spec.ts +0 -10
- package/test/utils.spec.ts +0 -20
|
@@ -1 +1,3 @@
|
|
|
1
|
-
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>default | @switchbot/homebridge-switchbot</title><meta name="description" content="Documentation for @switchbot/homebridge-switchbot"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">@switchbot/homebridge-switchbot</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">default</a></li></ul><h1>Variable default</h1></div><div class="tsd-signature"><span class="tsd-kind-variable">default</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">api</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">API</span><span class="tsd-signature-symbol">)</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span></div><div class="tsd-
|
|
1
|
+
<!DOCTYPE html><html class="default" lang="en" data-base="../"><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>default | @switchbot/homebridge-switchbot</title><meta name="description" content="Documentation for @switchbot/homebridge-switchbot"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><a href="../index.html" class="title">@switchbot/homebridge-switchbot</a><div id="tsd-toolbar-links"></div><button id="tsd-search-trigger" class="tsd-widget" aria-label="Search"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></button><dialog id="tsd-search" aria-label="Search"><input role="combobox" id="tsd-search-input" aria-controls="tsd-search-results" aria-autocomplete="list" aria-expanded="true" autocapitalize="off" autocomplete="off" placeholder="Search the docs" maxLength="100"/><ul role="listbox" id="tsd-search-results"></ul><div id="tsd-search-status" aria-live="polite" aria-atomic="true"><div>Preparing search index...</div></div></dialog><a href="#" class="tsd-widget menu" id="tsd-toolbar-menu-trigger" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb" aria-label="Breadcrumb"><li><a href="" aria-current="page">default</a></li></ul><h1>Variable default</h1></div><div class="tsd-signature"><span class="tsd-kind-variable">default</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">api</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">API</span><span class="tsd-signature-symbol">)</span> <span class="tsd-signature-symbol">=></span> <span class="tsd-signature-type">void</span></div><div class="tsd-comment tsd-typography"><p>Registers the SwitchBot platform with Homebridge.</p>
|
|
2
|
+
</div><div class="tsd-type-declaration"><h4>Type Declaration</h4><ul class="tsd-parameters"><li class="tsd-parameter-signature"><ul class="tsd-signatures"><li class="tsd-signature" id="__type"><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">api</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">API</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">void</span></li><li class="tsd-description"><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">api</span>: <span class="tsd-signature-type">API</span></span><div class="tsd-comment tsd-typography"><p>The Homebridge API instance.</p>
|
|
3
|
+
</div></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">void</span></h4></li></ul></li></ul></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/OpenWonderLabs/homebridge-switchbot/blob/50cea4b3bf59e48befc35e5599a830888265844b/src/index.ts#L22">index.ts:22</a></li></ul></aside></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg><h3>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">@switchbot/homebridge-switchbot</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer></footer><div class="overlay"></div></body></html>
|
package/eslint.config.js
CHANGED
|
@@ -10,15 +10,22 @@ export default antfu(
|
|
|
10
10
|
},
|
|
11
11
|
rules: {
|
|
12
12
|
'curly': ['error', 'multi-line'],
|
|
13
|
+
'import/order': 0,
|
|
13
14
|
'jsdoc/check-alignment': 'error',
|
|
14
15
|
'jsdoc/check-line-alignment': 'error',
|
|
16
|
+
'no-new': 0,
|
|
17
|
+
'no-undef': 0,
|
|
15
18
|
'perfectionist/sort-exports': 'error',
|
|
16
19
|
'perfectionist/sort-imports': [
|
|
17
20
|
'error',
|
|
18
21
|
{
|
|
19
22
|
groups: [
|
|
20
|
-
'type',
|
|
21
|
-
|
|
23
|
+
'type-builtin',
|
|
24
|
+
'type-external',
|
|
25
|
+
'type-internal',
|
|
26
|
+
['type-parent', 'type-sibling', 'type-index'],
|
|
27
|
+
'builtin',
|
|
28
|
+
'external',
|
|
22
29
|
'internal',
|
|
23
30
|
['parent', 'sibling', 'index'],
|
|
24
31
|
'unknown',
|
|
@@ -35,9 +42,6 @@ export default antfu(
|
|
|
35
42
|
'test/no-only-tests': 'error',
|
|
36
43
|
'unicorn/no-useless-spread': 'error',
|
|
37
44
|
'unused-imports/no-unused-vars': ['error', { caughtErrors: 'none' }],
|
|
38
|
-
'no-new': 0, // Disable the no-new rule
|
|
39
|
-
'new-cap': 0, // Disable the new-cap rule
|
|
40
|
-
'no-undef': 0, // Disable the no-undef rule
|
|
41
45
|
},
|
|
42
46
|
},
|
|
43
47
|
)
|
package/nodemon.json
CHANGED
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@switchbot/homebridge-switchbot",
|
|
3
3
|
"displayName": "SwitchBot",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "5.0.0
|
|
5
|
+
"version": "5.0.0",
|
|
6
6
|
"description": "The SwitchBot plugin allows you to access your SwitchBot device(s) from HomeKit.",
|
|
7
7
|
"author": "SwitchBot <support@wondertechlabs.com> (https://github.com/SwitchBot)",
|
|
8
8
|
"contributors": [
|
|
@@ -56,20 +56,29 @@
|
|
|
56
56
|
"icon": "https://raw.githubusercontent.com/OpenWonderLabs/homebridge-switchbot/latest/branding/icon.png",
|
|
57
57
|
"engineStrict": true,
|
|
58
58
|
"engines": {
|
|
59
|
-
"homebridge": "^2.0.0-beta.
|
|
60
|
-
"node": "^
|
|
59
|
+
"homebridge": "^2.0.0-beta.86",
|
|
60
|
+
"node": "^22 || ^24"
|
|
61
61
|
},
|
|
62
62
|
"directories": {
|
|
63
63
|
"doc": "docs"
|
|
64
64
|
},
|
|
65
65
|
"scripts": {
|
|
66
|
+
"sync:device-types": "node scripts/sync-device-types.mjs",
|
|
66
67
|
"check": "npm install && npm outdated",
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
68
|
+
"ports:free": "node scripts/free-dev-ports.mjs",
|
|
69
|
+
"typecheck": "tsc --noEmit",
|
|
70
|
+
"lint": "eslint --no-warn-ignored src/**/*.ts test/**/*.ts src/homebridge-ui/**/*.html src/homebridge-ui/public/js/*.ts && npm run typecheck",
|
|
71
|
+
"lint:src": "eslint --no-warn-ignored src/**/*.ts",
|
|
72
|
+
"lint:test": "eslint --no-warn-ignored test/**/*.ts",
|
|
73
|
+
"lint:ui": "eslint --no-warn-ignored src/homebridge-ui/**/*.html",
|
|
74
|
+
"lint:fix": "eslint --no-warn-ignored src/**/*.ts test/**/*.ts src/homebridge-ui/**/*.html src/homebridge-ui/public/js/*.ts --fix && npm run typecheck",
|
|
75
|
+
"watch": "npm run ports:free && npm run build && npm run build:ui && npm run plugin-ui && npm link && nodemon",
|
|
76
|
+
"watch:ui": "npm run ports:free && bash -c 'npx homebridge -I -U -D ~/.homebridge-dev & HB_PID=$!; sleep 6; UIX_STORAGE_PATH=~/.homebridge-dev node ./node_modules/homebridge-config-ui-x/dist/bin/standalone.js & npm run watch:files'",
|
|
77
|
+
"watch:files": "nodemon",
|
|
78
|
+
"plugin-ui": "mkdir -p ./dist/homebridge-ui/public && if [ -d ./src/homebridge-ui/public ]; then rsync -a ./src/homebridge-ui/public/ ./dist/homebridge-ui/public/; fi && node scripts/build-ui.js",
|
|
79
|
+
"build": "npm run sync:device-types && npm run clean && tsc && npm run plugin-ui",
|
|
80
|
+
"build:ui": "tsc --project tsconfig.ui.json",
|
|
81
|
+
"prepublishOnly": "npm run lint && npm run build && npm run build:ui && npm run plugin-ui && npm run docs && npm run docs:lint",
|
|
73
82
|
"postpublish": "npm run clean && npm ci",
|
|
74
83
|
"clean": "shx rm -rf ./dist",
|
|
75
84
|
"test": "vitest run",
|
|
@@ -82,25 +91,29 @@
|
|
|
82
91
|
"access": "public"
|
|
83
92
|
},
|
|
84
93
|
"dependencies": {
|
|
85
|
-
"@homebridge/plugin-ui-utils": "^2.2.
|
|
86
|
-
"
|
|
94
|
+
"@homebridge/plugin-ui-utils": "^2.2.3",
|
|
95
|
+
"class-validator": "^0.15.1",
|
|
96
|
+
"node-switchbot": "^4.0.0"
|
|
87
97
|
},
|
|
88
98
|
"devDependencies": {
|
|
89
|
-
"@antfu/eslint-config": "^
|
|
90
|
-
"@types/debug": "^4.1.
|
|
99
|
+
"@antfu/eslint-config": "^8.1.1",
|
|
100
|
+
"@types/debug": "^4.1.13",
|
|
91
101
|
"@types/fs-extra": "^11.0.4",
|
|
92
|
-
"@types/node": "^25.
|
|
102
|
+
"@types/node": "^25.6.0",
|
|
93
103
|
"@types/semver": "^7.7.1",
|
|
94
104
|
"@types/source-map-support": "^0.5.10",
|
|
95
|
-
"@vitest/coverage-v8": "^4.
|
|
96
|
-
"
|
|
105
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
106
|
+
"esbuild": "^0.28.0",
|
|
107
|
+
"eslint": "^10.2.0",
|
|
97
108
|
"eslint-plugin-format": "^2.0.1",
|
|
98
|
-
"
|
|
99
|
-
"
|
|
109
|
+
"eslint-plugin-html": "^8.1.4",
|
|
110
|
+
"eslint-plugin-perfectionist": "^5.8.0",
|
|
111
|
+
"homebridge": "^2.0.0-beta.86",
|
|
112
|
+
"homebridge-config-ui-x": "^5.21.0",
|
|
100
113
|
"nodemon": "^3.1.14",
|
|
101
114
|
"shx": "^0.4.0",
|
|
102
|
-
"typedoc": "^0.28.
|
|
103
|
-
"typescript": "^
|
|
104
|
-
"vitest": "^4.
|
|
115
|
+
"typedoc": "^0.28.18",
|
|
116
|
+
"typescript": "^6.0.2",
|
|
117
|
+
"vitest": "^4.1.4"
|
|
105
118
|
}
|
|
106
119
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import esbuild from 'esbuild'
|
|
4
|
+
import fs from 'node:fs'
|
|
5
|
+
import path from 'node:path'
|
|
6
|
+
import process from 'node:process'
|
|
7
|
+
import { fileURLToPath } from 'node:url'
|
|
8
|
+
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
10
|
+
|
|
11
|
+
const srcDir = path.resolve(__dirname, '../src/homebridge-ui/public/js')
|
|
12
|
+
const outputDir = path.resolve(__dirname, '../dist/homebridge-ui/public/js')
|
|
13
|
+
|
|
14
|
+
// Ensure output directory exists
|
|
15
|
+
fs.mkdirSync(outputDir, { recursive: true })
|
|
16
|
+
|
|
17
|
+
// Transpile TypeScript to JavaScript with esbuild
|
|
18
|
+
esbuild
|
|
19
|
+
.build({
|
|
20
|
+
entryPoints: [path.join(srcDir, 'app.ts')],
|
|
21
|
+
outfile: path.join(outputDir, 'app.js'),
|
|
22
|
+
bundle: true,
|
|
23
|
+
target: 'es2020',
|
|
24
|
+
platform: 'browser',
|
|
25
|
+
format: 'esm',
|
|
26
|
+
sourcemap: true,
|
|
27
|
+
external: [],
|
|
28
|
+
minify: false,
|
|
29
|
+
logLevel: 'info',
|
|
30
|
+
})
|
|
31
|
+
.then(() => {
|
|
32
|
+
console.log('✓ UI bundling complete')
|
|
33
|
+
})
|
|
34
|
+
.catch((error) => {
|
|
35
|
+
console.error('✗ UI bundling failed:', error)
|
|
36
|
+
process.exit(1)
|
|
37
|
+
})
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import { readFileSync } from 'node:fs'
|
|
3
|
+
import { homedir } from 'node:os'
|
|
4
|
+
import { resolve } from 'node:path'
|
|
5
|
+
|
|
6
|
+
function resolvePorts() {
|
|
7
|
+
let bridgePort = 51829
|
|
8
|
+
let uiPort = 8581
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
const configPath = resolve(homedir(), '.homebridge-dev', 'config.json')
|
|
12
|
+
const config = JSON.parse(readFileSync(configPath, 'utf8'))
|
|
13
|
+
|
|
14
|
+
if (typeof config?.bridge?.port === 'number') {
|
|
15
|
+
bridgePort = config.bridge.port
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const configUiPlatform = Array.isArray(config?.platforms)
|
|
19
|
+
? config.platforms.find(platform => platform?.platform === 'config')
|
|
20
|
+
: undefined
|
|
21
|
+
|
|
22
|
+
if (typeof configUiPlatform?.port === 'number') {
|
|
23
|
+
uiPort = configUiPlatform.port
|
|
24
|
+
}
|
|
25
|
+
} catch {}
|
|
26
|
+
|
|
27
|
+
return [...new Set([bridgePort, uiPort])]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function pidsForPort(port) {
|
|
31
|
+
try {
|
|
32
|
+
const output = execSync(`lsof -ti tcp:${port}`, { stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim()
|
|
33
|
+
return output ? output.split('\n').filter(Boolean) : []
|
|
34
|
+
} catch {
|
|
35
|
+
return []
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function freePort(port) {
|
|
40
|
+
const initialPids = pidsForPort(port)
|
|
41
|
+
if (initialPids.length === 0) {
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
execSync(`lsof -ti tcp:${port} | xargs -r kill -TERM`, { stdio: ['ignore', 'ignore', 'ignore'] })
|
|
47
|
+
} catch {}
|
|
48
|
+
|
|
49
|
+
const remainingPids = pidsForPort(port)
|
|
50
|
+
if (remainingPids.length > 0) {
|
|
51
|
+
try {
|
|
52
|
+
execSync(`lsof -ti tcp:${port} | xargs -r kill -KILL`, { stdio: ['ignore', 'ignore', 'ignore'] })
|
|
53
|
+
} catch {}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function cleanupDevProcesses() {
|
|
58
|
+
let output = ''
|
|
59
|
+
try {
|
|
60
|
+
output = execSync('ps -axo pid=,command=', { stdio: ['ignore', 'pipe', 'ignore'] }).toString()
|
|
61
|
+
} catch {
|
|
62
|
+
return
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const targetPids = output
|
|
66
|
+
.split('\n')
|
|
67
|
+
.map(line => line.trim())
|
|
68
|
+
.filter(Boolean)
|
|
69
|
+
.map((line) => {
|
|
70
|
+
const firstSpace = line.indexOf(' ')
|
|
71
|
+
if (firstSpace === -1) {
|
|
72
|
+
return null
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const pid = Number(line.slice(0, firstSpace).trim())
|
|
76
|
+
const command = line.slice(firstSpace + 1)
|
|
77
|
+
return Number.isFinite(pid) ? { pid, command } : null
|
|
78
|
+
})
|
|
79
|
+
.filter((entry) => {
|
|
80
|
+
if (!entry) {
|
|
81
|
+
return false
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (entry.pid === process.pid || entry.pid === process.ppid) {
|
|
85
|
+
return false
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const isNodemonProcess = entry.command.includes('homebridge-switchbot/node_modules/.bin/nodemon')
|
|
89
|
+
const isConfigUiProcess = entry.command.trim().startsWith('homebridge-config-ui-x')
|
|
90
|
+
return isNodemonProcess || isConfigUiProcess
|
|
91
|
+
})
|
|
92
|
+
.map(entry => entry.pid)
|
|
93
|
+
|
|
94
|
+
for (const pid of targetPids) {
|
|
95
|
+
try {
|
|
96
|
+
process.kill(pid, 'SIGTERM')
|
|
97
|
+
} catch {}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
cleanupDevProcesses()
|
|
102
|
+
|
|
103
|
+
for (const port of resolvePorts()) {
|
|
104
|
+
freePort(port)
|
|
105
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
const
|
|
1
|
+
const fs = require('node:fs')
|
|
2
|
+
const path = require('node:path')
|
|
3
|
+
const process = require('node:process')
|
|
4
4
|
|
|
5
5
|
function usage() {
|
|
6
6
|
console.error('Usage: node scripts/generate-matter-maps.js <input-json> [output-file]')
|
|
@@ -10,39 +10,50 @@ function usage() {
|
|
|
10
10
|
const input = process.argv[2]
|
|
11
11
|
const outFile = process.argv[3] || path.join(__dirname, '..', 'src', 'matter-maps.generated.ts')
|
|
12
12
|
|
|
13
|
-
if (!input)
|
|
13
|
+
if (!input) {
|
|
14
|
+
usage()
|
|
15
|
+
}
|
|
14
16
|
if (!fs.existsSync(input)) {
|
|
15
17
|
console.error('Input file not found:', input)
|
|
16
18
|
process.exit(2)
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
let json
|
|
22
|
+
try {
|
|
23
|
+
json = JSON.parse(fs.readFileSync(input, 'utf8'))
|
|
24
|
+
} catch (e) {
|
|
25
|
+
console.error('Failed to parse input JSON:', e.message)
|
|
26
|
+
process.exit(2)
|
|
27
|
+
}
|
|
20
28
|
|
|
21
29
|
// Expecting structure: { clusters: [{ name, id, attributes: [{ name, id }, ...] }, ...] }
|
|
22
|
-
const clusters = json.clusters
|
|
30
|
+
const clusters = Array.isArray(json.clusters) ? json.clusters : []
|
|
23
31
|
|
|
24
32
|
const clusterMapEntries = []
|
|
25
33
|
const attrGroups = {}
|
|
26
34
|
|
|
27
35
|
for (const c of clusters) {
|
|
28
|
-
if (!c.name || typeof c.id === 'undefined')
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
if (!c.name || typeof c.id === 'undefined') {
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
const key = c.name.replace(/\W/g, '')
|
|
40
|
+
clusterMapEntries.push(` ${key}: 0x${Number.parseInt(String(c.id), 10).toString(16)}`)
|
|
31
41
|
const attrs = {}
|
|
32
42
|
if (Array.isArray(c.attributes)) {
|
|
33
43
|
for (const a of c.attributes) {
|
|
34
|
-
if (!a.name || typeof a.id === 'undefined')
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
if (!a.name || typeof a.id === 'undefined') {
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
47
|
+
const an = a.name.replace(/\W/g, '')
|
|
48
|
+
attrs[an] = `0x${Number.parseInt(String(a.id), 10).toString(16)}`
|
|
37
49
|
}
|
|
38
50
|
}
|
|
39
|
-
if (Object.keys(attrs).length)
|
|
51
|
+
if (Object.keys(attrs).length) {
|
|
52
|
+
attrGroups[key] = attrs
|
|
53
|
+
}
|
|
40
54
|
}
|
|
41
55
|
|
|
42
|
-
const clusterMap = `export const MATTER_CLUSTER_IDS = {
|
|
43
|
-
${clusterMapEntries.join(',\n')}
|
|
44
|
-
} as const
|
|
45
|
-
\n`
|
|
56
|
+
const clusterMap = `export const MATTER_CLUSTER_IDS = {\n${clusterMapEntries.join(',\n')}\n} as const\n\n`
|
|
46
57
|
|
|
47
58
|
let attrText = 'export const MATTER_ATTRIBUTE_IDS = {\n'
|
|
48
59
|
for (const [k, v] of Object.entries(attrGroups)) {
|
|
@@ -56,5 +67,11 @@ attrText += `} as const\n`
|
|
|
56
67
|
|
|
57
68
|
const fileContent = `// GENERATED FILE - do not edit by hand.\n// Run: node scripts/generate-matter-maps.js <zap-matter.json>\n\n${clusterMap}\n${attrText}`
|
|
58
69
|
|
|
70
|
+
// Ensure output directory exists
|
|
71
|
+
const outDir = path.dirname(outFile)
|
|
72
|
+
if (!fs.existsSync(outDir)) {
|
|
73
|
+
fs.mkdirSync(outDir, { recursive: true })
|
|
74
|
+
}
|
|
75
|
+
|
|
59
76
|
fs.writeFileSync(outFile, fileContent, 'utf8')
|
|
60
77
|
console.log('Wrote', outFile)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import process from 'node:process'
|
|
4
|
+
|
|
5
|
+
const root = process.cwd()
|
|
6
|
+
const sourcePath = path.join(root, 'src/device-types.ts')
|
|
7
|
+
const schemaPath = path.join(root, 'config.schema.json')
|
|
8
|
+
|
|
9
|
+
const source = fs.readFileSync(sourcePath, 'utf8')
|
|
10
|
+
const schemaRaw = fs.readFileSync(schemaPath, 'utf8')
|
|
11
|
+
const schema = JSON.parse(schemaRaw)
|
|
12
|
+
|
|
13
|
+
const match = source.match(/export const DEVICE_TYPES = (\{[\s\S]*?\}) as const/)
|
|
14
|
+
if (!match) {
|
|
15
|
+
throw new Error('Could not find DEVICE_TYPES in src/device-types.ts')
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// WARNING: This uses eval via new Function. Only safe if device-types.ts is trusted.
|
|
19
|
+
// eslint-disable-next-line no-new-func -- device-types.ts is trusted and controlled
|
|
20
|
+
const deviceTypesByCategory = (new Function(`return (${match[1]})`))()
|
|
21
|
+
const enumValues = [...new Set(Object.values(deviceTypesByCategory).flat())]
|
|
22
|
+
|
|
23
|
+
const configDeviceType = schema?.schema?.properties?.devices?.items?.properties?.configDeviceType
|
|
24
|
+
if (!configDeviceType) {
|
|
25
|
+
throw new Error('Could not locate schema.properties.devices.items.properties.configDeviceType')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
configDeviceType.enum = enumValues
|
|
29
|
+
|
|
30
|
+
fs.writeFileSync(schemaPath, `${JSON.stringify(schema, null, 2)}\n`, 'utf8')
|
|
31
|
+
console.log(`Synchronized ${enumValues.length} device types into config.schema.json`)
|