@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
package/MIGRATION.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Migration notes — v4.3.x →
|
|
1
|
+
# Migration notes — v4.3.x → v5.x
|
|
2
2
|
|
|
3
|
-
This document highlights important changes and recommended actions before upgrading to the
|
|
3
|
+
This document highlights important changes and recommended actions before upgrading to the release that includes Matter and stable `node-switchbot@4` support.
|
|
4
4
|
|
|
5
5
|
1. Matter-first behavior
|
|
6
6
|
- The plugin will prefer registering accessories with Homebridge's Matter child-bridge when `enableMatter: true` and the Homebridge Matter API is available.
|
|
@@ -9,13 +9,13 @@ This document highlights important changes and recommended actions before upgrad
|
|
|
9
9
|
2. Configuration keys
|
|
10
10
|
- `enableMatter` (boolean) — enable Matter child-bridge registration.
|
|
11
11
|
- `preferMatter` (boolean) — prefer Matter for devices that support Matter descriptors; HAP fallback still available.
|
|
12
|
-
- `openApiToken` (string) —
|
|
12
|
+
- `openApiToken` + `openApiSecret` (string) — both are required for OpenAPI discovery/calls for cloud-reachable devices.
|
|
13
13
|
- `perDeviceMaxRetries`, `requestTimeout`, `maxRetries` — network retry/timing options for OpenAPI fallback.
|
|
14
14
|
|
|
15
15
|
- `writeDebounceMs` (number, milliseconds, default 100) — global write coalescing debounce window. Commands sent to the same device within this window are coalesced (last-write-wins) to reduce duplicate network/API commands. Set to `0` to disable coalescing if you require immediate, per-command delivery.
|
|
16
16
|
|
|
17
17
|
3. Hybrid client
|
|
18
|
-
- The plugin dynamically imports `node-switchbot` when available and
|
|
18
|
+
- The plugin dynamically imports `node-switchbot` when available and uses OpenAPI fallback when both `openApiToken` and `openApiSecret` are configured.
|
|
19
19
|
- If you rely on BLE-only operation, ensure devices and the host have BLE available.
|
|
20
20
|
|
|
21
21
|
4. UI changes
|
|
@@ -28,8 +28,18 @@ This document highlights important changes and recommended actions before upgrad
|
|
|
28
28
|
- Run the local test suite before upgrading to confirm TypeScript and unit tests pass: `npm run build && npm run test`.
|
|
29
29
|
|
|
30
30
|
6. Rollback plan
|
|
31
|
-
- If the
|
|
31
|
+
- If the upgrade causes issues, revert to the previous plugin version by reinstalling the prior package version.
|
|
32
32
|
|
|
33
|
+
|
|
34
|
+
8. BLE encryption key and keyId fields
|
|
35
|
+
|
|
36
|
+
- The plugin now supports BLE encryption for devices that require it (e.g., SwitchBot Lock, Curtain 3, and some sensors).
|
|
37
|
+
- New config fields: `encryptionKey` and `keyId` can be set per-device in the Homebridge UI or config.json.
|
|
38
|
+
- To upgrade, obtain your device's BLE encryption key and keyId from the SwitchBot app (see README for instructions) and add them to your device config if required.
|
|
39
|
+
- Devices that do not require encryption can leave these fields blank.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
33
43
|
7. Regenerating Matter ID maps
|
|
34
44
|
|
|
35
45
|
- A helper script `scripts/generate-matter-maps.js` is included to generate `src/matter-maps.generated.ts` from official zap/matter JSON metadata. The script expects a JSON input with a `clusters` array and will write mapped `MATTER_CLUSTER_IDS` and `MATTER_ATTRIBUTE_IDS` constants.
|
|
@@ -41,4 +51,4 @@ node scripts/generate-matter-maps.js ./zap-matter.json
|
|
|
41
51
|
|
|
42
52
|
Place the official metadata JSON as `zap-matter.json` at the repo root (or pass a path) and commit the generated `src/matter-maps.generated.ts` to keep maps up to date.
|
|
43
53
|
|
|
44
|
-
|
|
54
|
+
These notes should be kept in sync with README and CHANGELOG updates for each release.
|
package/README.md
CHANGED
|
@@ -21,8 +21,31 @@
|
|
|
21
21
|
- See noble [prerequisites](https://github.com/abandonware/noble#prerequisites) for your OS. (This is used for BLE connection.)
|
|
22
22
|
3. Click **Install**
|
|
23
23
|
|
|
24
|
+
|
|
24
25
|
## Configuration
|
|
25
26
|
|
|
27
|
+
### OpenAPI Polling/Rate Advanced Settings (UI)
|
|
28
|
+
|
|
29
|
+
You can now configure global OpenAPI polling and rate-limiting options directly from the Homebridge UI:
|
|
30
|
+
|
|
31
|
+
- Go to the SwitchBot plugin settings in Homebridge Config UI X.
|
|
32
|
+
- Scroll to the **Advanced Settings** section at the bottom of the page.
|
|
33
|
+
- Adjust the following options as needed:
|
|
34
|
+
- **OpenAPI Polling Interval (seconds):** How often to poll devices via OpenAPI for status. Default: 300 (5 min). Min: 30. Can be overridden per device.
|
|
35
|
+
- **Enable Batched OpenAPI Polling:** Poll all OpenAPI devices in a single batch at the configured interval. Devices with per-device refreshRate are excluded from the batch.
|
|
36
|
+
- **OpenAPI Batch Polling Interval (seconds):** Interval for batched OpenAPI polling. Falls back to OpenAPI Polling Interval if not set. Default: 300.
|
|
37
|
+
- **OpenAPI Daily Request Limit:** Maximum OpenAPI requests per day allowed by the plugin. Default: 10000.
|
|
38
|
+
- **OpenAPI Reserve for Commands:** Requests reserved for user actions. When remaining budget reaches this value, background polling pauses. Default: 1000.
|
|
39
|
+
- **Reset OpenAPI Counter at Local Midnight:** If true, resets the daily OpenAPI request counter at local midnight. If false, resets at UTC midnight.
|
|
40
|
+
- **Only Allow Webhooks on Reserve:** When remaining OpenAPI budget reaches the reserve, only webhooks and user commands are allowed. Background polling/discovery pauses.
|
|
41
|
+
- **OpenAPI Batch Concurrency:** Maximum number of parallel OpenAPI status calls during a batch. Default: 5.
|
|
42
|
+
- **OpenAPI Batch Jitter (seconds):** Random startup delay before the first batch to reduce synchronized spikes. Default: 0.
|
|
43
|
+
|
|
44
|
+
Click **Save Advanced Settings** to apply changes. These settings match the options available in `config.schema.json` and can be overridden per device.
|
|
45
|
+
|
|
46
|
+
<!-- Optionally add a screenshot here -->
|
|
47
|
+
|
|
48
|
+
|
|
26
49
|
- ### If using OpenAPI Connection
|
|
27
50
|
1. Download SwitchBot App on App Store or Google Play Store
|
|
28
51
|
2. Register a SwitchBot account and log in into your account
|
|
@@ -168,6 +191,9 @@
|
|
|
168
191
|
- [SwitchBot Hub 2](https://us.switch-bot.com/products/switchbot-hub-2)
|
|
169
192
|
- Supports OpenAPI & Bluetooth Low Energy (BLE) Connections
|
|
170
193
|
- Enables Humidity, Temperature, and Light Sensor
|
|
194
|
+
- [SwitchBot Hub Mini 2](https://us.switch-bot.com/products/switchbot-hub-mini-2)
|
|
195
|
+
- Supports OpenAPI & Bluetooth Low Energy (BLE) Connections
|
|
196
|
+
- Enables Humidity, Temperature, and Light Sensor
|
|
171
197
|
- [SwitchBot Hub 3](https://us.switch-bot.com/products/switchbot-hub-3)
|
|
172
198
|
- Supports OpenAPI & Bluetooth Low Energy (BLE) Connections
|
|
173
199
|
- Enables Humidity, Temperature, and Light Sensor
|
|
@@ -176,9 +202,52 @@
|
|
|
176
202
|
- [SwitchBot Water Leak Detector](https://us.switch-bot.com/products/switchbot-water-leak-detector)
|
|
177
203
|
- Supports OpenAPI & Bluetooth Low Energy (BLE) Connections
|
|
178
204
|
|
|
205
|
+
|
|
206
|
+
## BLE Encryption Support
|
|
207
|
+
|
|
208
|
+
### BLE Encryption Key and Key ID
|
|
209
|
+
|
|
210
|
+
Some SwitchBot devices (notably newer locks, curtains, and select sensors) require a BLE encryption key and keyId for secure Bluetooth communication. This plugin supports configuring these fields for each device.
|
|
211
|
+
|
|
212
|
+
#### How to Obtain BLE Encryption Key and Key ID
|
|
213
|
+
|
|
214
|
+
1. **Open the SwitchBot App** and select your device.
|
|
215
|
+
2. Go to **Device Settings** (gear icon).
|
|
216
|
+
3. Tap **Device Info**.
|
|
217
|
+
4. If your device supports BLE encryption, you will see fields for **Encryption Key** and **Key ID**. (If not visible, your device may not require encryption or may need a firmware update.)
|
|
218
|
+
5. Copy the **Encryption Key** and **Key ID** values.
|
|
219
|
+
|
|
220
|
+
#### How to Configure in Homebridge
|
|
221
|
+
|
|
222
|
+
In the Homebridge UI, when adding or editing a SwitchBot device, enter the **Encryption Key** and **Key ID** in the provided fields. These values will be securely used for BLE communication with your device.
|
|
223
|
+
|
|
224
|
+
**Example device config excerpt:**
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"deviceId": "E7F8A1B2C3D4",
|
|
229
|
+
"deviceName": "SwitchBot Lock",
|
|
230
|
+
"enableBLE": true,
|
|
231
|
+
"encryptionKey": "0123456789abcdef0123456789abcdef",
|
|
232
|
+
"keyId": "01"
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
#### Which Devices Require BLE Encryption?
|
|
237
|
+
|
|
238
|
+
- SwitchBot Lock (and Lock Pro)
|
|
239
|
+
- SwitchBot Curtain 3 (and some Curtain 2 with updated firmware)
|
|
240
|
+
- Some sensors and new device models (see device info in app)
|
|
241
|
+
|
|
242
|
+
If you are unsure, check your device's info in the SwitchBot app. If the fields are present, copy them into the plugin config.
|
|
243
|
+
|
|
244
|
+
**Note:** If you enter an incorrect key or keyId, BLE communication will fail for that device. Double-check values if you encounter connection issues.
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
179
248
|
## Supported IR Devices
|
|
180
249
|
|
|
181
|
-
### _(All IR Devices require [SwitchBot Hub 2](https://us.switch-bot.com/products/switchbot-hub-2), [SwitchBot Hub 3](https://us.switch-bot.com/products/switchbot-hub-3), or [Hub Mini](https://www.switch-bot.com/products/switchbot-hub-mini))_
|
|
250
|
+
### _(All IR Devices require [SwitchBot Hub 2](https://us.switch-bot.com/products/switchbot-hub-2), [SwitchBot Hub Mini 2](https://us.switch-bot.com/products/switchbot-hub-mini-2), [SwitchBot Hub 3](https://us.switch-bot.com/products/switchbot-hub-3), or [Hub Mini](https://www.switch-bot.com/products/switchbot-hub-mini))_
|
|
182
251
|
|
|
183
252
|
- TV
|
|
184
253
|
- Allows for On/Off and Volume Controls
|
|
@@ -238,12 +307,14 @@ Reliability and rate-limiting:
|
|
|
238
307
|
|
|
239
308
|
These controls keep API usage smooth and predictable while preserving per-device control when needed.
|
|
240
309
|
|
|
241
|
-
## What's new
|
|
310
|
+
## What's new with node-switchbot v4.0.0
|
|
242
311
|
|
|
243
312
|
- Matter-first: when Homebridge Matter is available the plugin now prefers registering Matter accessories (with HAP fallback).
|
|
244
|
-
- Hybrid client: the plugin
|
|
313
|
+
- Hybrid client: the plugin uses `node-switchbot@^4.0.0` with BLE + OpenAPI discovery and OpenAPI fallback.
|
|
314
|
+
- OpenAPI credentials: cloud discovery and cloud fallback paths require both `openApiToken` and `openApiSecret`.
|
|
245
315
|
- UI always served: the plugin UI is packaged into `dist/homebridge-ui` and is always served when Homebridge UI support is present; there is no platform-level opt-out.
|
|
246
316
|
- OpenAPI hardening: OpenAPI calls have AbortController timeouts, jittered exponential backoff, per-device retry limits and cooldowns, and safe response parsing for resilient behavior.
|
|
317
|
+
- v4 resilience enabled in discovery: plugin discovery enables retry, circuit-breaker, and connection-intelligence flags from `node-switchbot` v4.
|
|
247
318
|
|
|
248
319
|
- Write coalescing (debounce): command writes to the same device are coalesced by default to avoid command floods. Configure with `writeDebounceMs` (milliseconds, default 100). Set to `0` to disable coalescing.
|
|
249
320
|
|
|
@@ -277,6 +348,16 @@ Example (excerpt):
|
|
|
277
348
|
- [OpenWonderLabs/SwitchBotAPI](https://github.com/OpenWonderLabs/SwitchBotAPI)
|
|
278
349
|
- [OpenWonderLabs/SwitchBotAPI-BLE](https://github.com/OpenWonderLabs/SwitchBotAPI-BLE)
|
|
279
350
|
|
|
351
|
+
## Development / Tests
|
|
352
|
+
|
|
353
|
+
- Run unit tests:
|
|
354
|
+
```bash
|
|
355
|
+
npm run test
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
- Notes:
|
|
359
|
+
- Added Lock Ultra (Cloud + BLE) support with `node-switchbot` v4.
|
|
360
|
+
|
|
280
361
|
## Community
|
|
281
362
|
|
|
282
363
|
- [SwitchBot (Official website)](https://www.switch-bot.com/)
|
package/TODO.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# SwitchBot Plugin TODO List
|
|
2
|
+
|
|
3
|
+
## Code Refactoring & Architecture
|
|
4
|
+
|
|
5
|
+
### Server-Side Refactoring (Priority: High)
|
|
6
|
+
|
|
7
|
+
- [x] **Split `server.ts` into modular structure** ✅ COMPLETED
|
|
8
|
+
- [x] Created `src/homebridge-ui/endpoints/discovery.ts` - Discovery endpoint
|
|
9
|
+
- [x] Created `src/homebridge-ui/endpoints/config.ts` - Config management endpoint
|
|
10
|
+
- [x] Created `src/homebridge-ui/endpoints/devices.ts` - Device CRUD operations
|
|
11
|
+
- [x] Created `src/homebridge-ui/endpoints/credentials.ts` - Credentials endpoint
|
|
12
|
+
- [x] Created `src/homebridge-ui/utils/config-parser.ts` - Config parsing helpers
|
|
13
|
+
- [x] Created `src/homebridge-ui/utils/logger.ts` - Logging utility
|
|
14
|
+
- [x] Updated `src/homebridge-ui/server.ts` - Main entry point (imports and registers endpoints)
|
|
15
|
+
|
|
16
|
+
**Status:** Server endpoints are fully modularized and organized by concern.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Bug Fixes (Priority: Critical)
|
|
21
|
+
|
|
22
|
+
### Matter Window Covering Conformance Issue
|
|
23
|
+
|
|
24
|
+
- [ ] **Fix Matter window covering Drapery enum validation error**
|
|
25
|
+
- [ ] **Issue:** Matter accessory registration fails for Curtain devices
|
|
26
|
+
- [ ] **Error:** `Conformance "LF & !TL": Matter does not allow enum value Drapery (ID 4) here`
|
|
27
|
+
- [ ] **Root Cause:** windowCovering.state.type is set to "Drapery" but Matter spec requires "LF & !TL" conformance (Lift Fail without Tilt)
|
|
28
|
+
- [ ] **Solution:** Need to validate/correct window covering type mappings for Matter compatibility
|
|
29
|
+
- [ ] **Affected Devices:** Curtain-type devices (e.g., "Master Bathroom Left Curtain")
|
|
30
|
+
- [ ] **Steps to Fix:**
|
|
31
|
+
- [ ] Check Matter window covering specification for valid type combinations
|
|
32
|
+
- [ ] Update device type mapping to use compliant enum values
|
|
33
|
+
- [ ] Validate conformance rules for Lift/Tilt combinations
|
|
34
|
+
- [ ] Test with Curtain, Curtain3, and Roller Shade devices
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### Invalid Device Type Validation ✅ COMPLETED
|
|
39
|
+
|
|
40
|
+
- [x] **Fix invalid device type in config schema validation**
|
|
41
|
+
- [x] **Issue:** Config validation rejects devices with invalid `configDeviceType` values (e.g., "Lock Vision Pro" is not in valid enum)
|
|
42
|
+
- [x] **Error:** "Value is not accepted. Valid values: ..." error shown in Homebridge UI
|
|
43
|
+
- [x] **Root Cause:** Device types in existing configs may not match current DEVICE_TYPES enum (legacy names, typos, or renamed devices)
|
|
44
|
+
- [x] **Affected Devices:** Any device with `configDeviceType` not matching DEVICE_TYPES enum
|
|
45
|
+
- [x] **Solution:** Implemented device type validation migration and auto-correction
|
|
46
|
+
|
|
47
|
+
**Implementation:**
|
|
48
|
+
- Added `normalizeDeviceType()` — Validates and maps invalid types to valid equivalents
|
|
49
|
+
- Added `isValidDeviceType()` — Checks if device type is in DEVICE_TYPES enum
|
|
50
|
+
- Added `getValidDeviceTypes()` — Returns set of all valid device types
|
|
51
|
+
- Created `src/homebridge-ui/utils/device-migration.ts` — Migration utilities for batch validation
|
|
52
|
+
- Updated `src/homebridge-ui/endpoints/config.ts` — Device loading now validates types and warns about invalid ones
|
|
53
|
+
- Added migration mapping: `"Lock Vision Pro"` → `"Keypad Vision Pro"` (and others)
|
|
54
|
+
- Config endpoint returns `validationWarnings` with invalid device types and suggestions
|
|
55
|
+
|
|
56
|
+
**Status:** Device type validation is now automatic. Invalid types are detected and suggestions provided to users. Auto-correction mappings handle legacy/typo device names.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### Client-Side Refactoring (Priority: Medium)
|
|
61
|
+
|
|
62
|
+
#### Phase 1: Quick Wins
|
|
63
|
+
|
|
64
|
+
- [x] **Extract DEVICE_TYPES constant** (~100 lines) ✅ COMPLETED
|
|
65
|
+
- [x] Created `src/device-types.ts` as single source of truth
|
|
66
|
+
- [x] Updated `src/homebridge-ui/public/js/constants.ts` to import from shared source
|
|
67
|
+
- [x] Added `DEVICE_TYPE_NORMALIZATION_MAP` for plugin type lookups
|
|
68
|
+
- [x] Updated `src/deviceFactory.ts` to use normalized type mappings
|
|
69
|
+
- [x] Created `scripts/sync-device-types.mjs` to auto-sync config.schema.json
|
|
70
|
+
- [x] Integrated sync into build process (runs before tsc)
|
|
71
|
+
|
|
72
|
+
**Status:** Device types now single-sourced with auto-sync. Config schema, UI dropdown, and plugin type handling all stay aligned automatically.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# SwitchBot Plugin TODO List (2026)
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## PRIORITY: HIGH (Start Here)
|
|
81
|
+
|
|
82
|
+
- [ ] **One-Click Device Import**
|
|
83
|
+
Add "Add to Config" button next to each discovered device. Dramatically speeds up onboarding, reduces manual steps for users.
|
|
84
|
+
- [ ] **Auto-populate Device Config Modal**
|
|
85
|
+
When importing, auto-fill the config modal with discovered values. Reduces user error, makes adding devices nearly frictionless.
|
|
86
|
+
- [ ] **Pre-fill MAC Address for BLE Devices**
|
|
87
|
+
Ensure BLE devices are always added with correct MAC, avoids connection issues.
|
|
88
|
+
- [ ] **Duplicate Detection**
|
|
89
|
+
Check if discovered device ID already exists in config. Prevents duplicate entries, avoids user confusion.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## PRIORITY: MEDIUM
|
|
94
|
+
|
|
95
|
+
- [ ] **Confirmation Toast on Import**
|
|
96
|
+
Show a toast message on successful import for user feedback.
|
|
97
|
+
- [ ] **Loading States for Discovery**
|
|
98
|
+
Show progress indicator, spinner, and allow cancel during discovery. Improves perceived performance and transparency.
|
|
99
|
+
- [ ] **Device Grouping**
|
|
100
|
+
Group devices by hub or connection type. Useful for users with many devices/hubs.
|
|
101
|
+
- [ ] **Connection Recommendations**
|
|
102
|
+
Show badges for recommended connection (BLE/API) based on signal/device type.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## PRIORITY: LOW
|
|
107
|
+
|
|
108
|
+
- [ ] **UI Polish: Badges, View in Config, Group Headers**
|
|
109
|
+
Add badges for "Already Added"/"New Device", view-in-config links, expandable group headers, device count per group, and remember expanded/collapsed state.
|
|
110
|
+
- [ ] **Configurable BLE Scan**
|
|
111
|
+
Add scan duration, BLE timeout, and Bluetooth availability status in settings. Remember user preferences in localStorage.
|
|
112
|
+
- [ ] **Discovery History/Cache**
|
|
113
|
+
Cache last discovery results, show last scanned timestamp, refresh button, and auto-refresh option.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
**Recommendation:**
|
|
118
|
+
|
|
119
|
+
Start with the HIGH priority section—these features have the biggest impact on user experience and onboarding. MEDIUM priority items improve polish and usability for power users. LOW priority items are mostly UI/UX enhancements and advanced options.
|
|
120
|
+
|
|
121
|
+
- [ ] **Build & Test**
|
|
122
|
+
- [ ] Run `npm run build`
|
|
123
|
+
- [ ] Test add device modal
|
|
124
|
+
- [ ] Test edit device modal
|
|
125
|
+
- [ ] Test delete confirmation modal
|
|
126
|
+
- [ ] Verify form validation works
|
|
127
|
+
|
|
128
|
+
### Step 6: Extract Form Handling
|
|
129
|
+
|
|
130
|
+
**Goal:** Move form validation and submission logic
|
|
131
|
+
|
|
132
|
+
- [ ] **Create forms module**
|
|
133
|
+
- [ ] Create `src/homebridge-ui/public/js/forms.js`
|
|
134
|
+
- [ ] Extract and export these functions:
|
|
135
|
+
- [ ] `validateDeviceForm(formData)` - Validate form inputs
|
|
136
|
+
- [ ] `handleDeviceSubmit(formData)` - Process form submission
|
|
137
|
+
- [ ] `resetForm()` - Clear form fields
|
|
138
|
+
- [ ] `formatFormData(rawData)` - Format form data for API
|
|
139
|
+
- [ ] `showFormError(field, message)` - Display validation error
|
|
140
|
+
- [ ] `clearFormErrors()` - Clear all validation errors
|
|
141
|
+
|
|
142
|
+
- [ ] **Update HTML**
|
|
143
|
+
- [ ] Remove form handling functions from `<script>` block
|
|
144
|
+
- [ ] Add import: `import * as forms from './js/forms.js'`
|
|
145
|
+
- [ ] Update event handlers to use imported functions
|
|
146
|
+
- [ ] Test form validation and submission
|
|
147
|
+
|
|
148
|
+
- [ ] **Build & Test**
|
|
149
|
+
- [ ] Run `npm run build`
|
|
150
|
+
- [ ] Test form validation (empty fields, invalid data)
|
|
151
|
+
- [ ] Test form submission (add/edit device)
|
|
152
|
+
- [ ] Verify error messages display correctly
|
|
153
|
+
|
|
154
|
+
### Step 7: Create Main App Module
|
|
155
|
+
|
|
156
|
+
**Goal:** Create central app initialization and coordination
|
|
157
|
+
|
|
158
|
+
- [ ] **Create app module**
|
|
159
|
+
- [ ] Create `src/homebridge-ui/public/js/app.ts`
|
|
160
|
+
- [ ] Export `init()` function that:
|
|
161
|
+
- [ ] Loads initial config on page load
|
|
162
|
+
- [ ] Sets up all event listeners
|
|
163
|
+
- [ ] Initializes UI components
|
|
164
|
+
- [ ] Handles global state
|
|
165
|
+
- [ ] Move event listeners from HTML to app.js
|
|
166
|
+
- [ ] Coordinate between all other modules
|
|
167
|
+
|
|
168
|
+
- [ ] **Update HTML**
|
|
169
|
+
- [ ] Remove all remaining JavaScript from `<script>` block
|
|
170
|
+
- [ ] Keep only imports and single line: `import { init } from './js/app.js'; init();`
|
|
171
|
+
- [ ] Or use DOMContentLoaded: `document.addEventListener('DOMContentLoaded', () => init())`
|
|
172
|
+
- [ ] Remove now-empty `<script>` block if all code moved
|
|
173
|
+
|
|
174
|
+
- [ ] **Build & Test**
|
|
175
|
+
- [ ] Run `npm run build`
|
|
176
|
+
- [ ] Test complete page load and initialization
|
|
177
|
+
- [ ] Test all features end-to-end
|
|
178
|
+
- [ ] Verify no console errors
|
|
179
|
+
|
|
180
|
+
### Step 8: Final Cleanup and Verification
|
|
181
|
+
|
|
182
|
+
**Goal:** Ensure everything works and clean up
|
|
183
|
+
|
|
184
|
+
- [ ] **Verify build output**
|
|
185
|
+
- [ ] Check all files copied to `dist/homebridge-ui/public/`
|
|
186
|
+
- [ ] Verify file structure matches source
|
|
187
|
+
- [ ] Check file sizes (modules should be reasonable)
|
|
188
|
+
|
|
189
|
+
- [ ] **Test all functionality**
|
|
190
|
+
- [ ] Load config on page open
|
|
191
|
+
- [ ] Add new device
|
|
192
|
+
- [ ] Edit existing device
|
|
193
|
+
- [ ] Delete device
|
|
194
|
+
- [ ] Run discovery
|
|
195
|
+
- [ ] Test all filters/sorting (if implemented)
|
|
196
|
+
- [ ] Test on different browsers (Chrome, Safari, Firefox)
|
|
197
|
+
|
|
198
|
+
- [ ] **Code cleanup**
|
|
199
|
+
- [ ] Remove any unused functions
|
|
200
|
+
- [ ] Add JSDoc comments to all exports
|
|
201
|
+
- [ ] Ensure consistent code style
|
|
202
|
+
- [ ] Remove console.log statements (or convert to proper logging)
|
|
203
|
+
|
|
204
|
+
- [ ] **Documentation**
|
|
205
|
+
- [ ] Update comments in code
|
|
206
|
+
- [ ] Document module dependencies
|
|
207
|
+
- [ ] Add README in `src/homebridge-ui/public/js/` if needed
|
|
208
|
+
- [ ] Update main README if UI architecture changed significantly
|
|
209
|
+
|
|
210
|
+
### Step 9: Optional Enhancements
|
|
211
|
+
|
|
212
|
+
**Goal:** Further improvements after basic split
|
|
213
|
+
|
|
214
|
+
- [ ] **Add TypeScript for UI code**
|
|
215
|
+
- [ ] Rename `.js` files to `.ts`
|
|
216
|
+
- [ ] Add type definitions
|
|
217
|
+
- [ ] Update build to compile UI TypeScript
|
|
218
|
+
- [ ] Add type checking to lint scripts
|
|
219
|
+
|
|
220
|
+
- [ ] **Add minification**
|
|
221
|
+
- [ ] Consider adding Terser for JS minification
|
|
222
|
+
- [ ] Consider adding cssnano for CSS minification
|
|
223
|
+
- [ ] Update build script for production builds
|
|
224
|
+
|
|
225
|
+
- [ ] **Add source maps**
|
|
226
|
+
- [ ] Generate source maps for easier debugging
|
|
227
|
+
- [ ] Configure build to include maps
|
|
228
|
+
- [ ] Test debugging in browser DevTools
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Implementation Notes
|
|
233
|
+
|
|
234
|
+
### Why Native ES6 Modules?
|
|
235
|
+
|
|
236
|
+
- ✅ No bundler needed (simpler build process)
|
|
237
|
+
- ✅ Native browser support (Safari 11+, Chrome 61+, Firefox 60+)
|
|
238
|
+
- ✅ Easier debugging (direct source code visibility)
|
|
239
|
+
- ✅ Suitable for local Homebridge UI (no network latency concerns)
|
|
240
|
+
- ✅ Hot reload friendly (just refresh browser)
|
|
241
|
+
|
|
242
|
+
### Browser Compatibility
|
|
243
|
+
|
|
244
|
+
- ES6 modules work in all modern browsers (2017+)
|
|
245
|
+
- Homebridge UI runs locally, so old browser support not critical
|
|
246
|
+
- Most Homebridge users have up-to-date browsers
|
|
247
|
+
|
|
248
|
+
### Build Process
|
|
249
|
+
|
|
250
|
+
- Current: `npm run plugin-ui` copies `src/homebridge-ui/public` → `dist/homebridge-ui/public`
|
|
251
|
+
- After split: Same command, just copies more files (no changes needed)
|
|
252
|
+
- Glob pattern `**/*` already handles subdirectories
|
|
253
|
+
|
|
254
|
+
### Testing Checklist
|
|
255
|
+
|
|
256
|
+
Each step should be tested before moving to next:
|
|
257
|
+
|
|
258
|
+
1. Build succeeds without errors
|
|
259
|
+
2. Files copied to dist/ correctly
|
|
260
|
+
3. UI loads in browser without errors
|
|
261
|
+
4. All functionality works as before
|
|
262
|
+
5. No console errors or warnings
|
|
263
|
+
6. Performance is same or better
|