@switchbot/homebridge-switchbot 5.1.0-beta.3 → 5.1.0-beta.5

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 (47) hide show
  1. package/.github/copilot-instructions.md +63 -0
  2. package/.github/workflows/release.yml +1 -1
  3. package/dist/{SwitchBotHAPPlatform.d.ts → Platform.HAP.d.ts} +2 -2
  4. package/dist/Platform.HAP.d.ts.map +1 -0
  5. package/dist/{SwitchBotHAPPlatform.js → Platform.HAP.js} +4 -2
  6. package/dist/Platform.HAP.js.map +1 -0
  7. package/dist/{SwitchBotMatterPlatform.d.ts → Platform.Matter.d.ts} +2 -2
  8. package/dist/Platform.Matter.d.ts.map +1 -0
  9. package/dist/{SwitchBotMatterPlatform.js → Platform.Matter.js} +1 -1
  10. package/dist/Platform.Matter.js.map +1 -0
  11. package/dist/homebridge-ui/public/index.html +19 -2
  12. package/dist/homebridge-ui/public/js/advanced-settings.d.ts.map +1 -1
  13. package/dist/homebridge-ui/public/js/advanced-settings.js +4 -3
  14. package/dist/homebridge-ui/public/js/advanced-settings.js.map +1 -1
  15. package/dist/homebridge-ui/public/js/advanced-settings.ts +4 -3
  16. package/dist/homebridge-ui/public/js/app.js +10 -5
  17. package/dist/homebridge-ui/public/js/app.js.map +2 -2
  18. package/dist/homebridge-ui/public/js/credentials.d.ts.map +1 -1
  19. package/dist/homebridge-ui/public/js/credentials.js +11 -5
  20. package/dist/homebridge-ui/public/js/credentials.js.map +1 -1
  21. package/dist/homebridge-ui/public/js/credentials.ts +11 -5
  22. package/dist/homebridge-ui/public/js/legacy-view.d.ts +3 -0
  23. package/dist/homebridge-ui/public/js/legacy-view.d.ts.map +1 -0
  24. package/dist/homebridge-ui/public/js/legacy-view.js +34 -0
  25. package/dist/homebridge-ui/public/js/legacy-view.js.map +1 -0
  26. package/dist/homebridge-ui/public/js/legacy-view.ts +94 -0
  27. package/dist/index.js +2 -2
  28. package/dist/index.js.map +1 -1
  29. package/docs/variables/default.html +1 -1
  30. package/package.json +9 -15
  31. package/src/{SwitchBotHAPPlatform.ts → Platform.HAP.ts} +5 -2
  32. package/src/{SwitchBotMatterPlatform.ts → Platform.Matter.ts} +2 -1
  33. package/src/homebridge-ui/public/index.html +17 -0
  34. package/src/homebridge-ui/public/js/advanced-settings.ts +4 -3
  35. package/src/homebridge-ui/public/js/credentials.ts +11 -5
  36. package/src/homebridge-ui/public/js/legacy-view.js +34 -0
  37. package/src/homebridge-ui/public/js/legacy-view.ts +94 -0
  38. package/src/index.ts +2 -2
  39. package/test/platform/accessory-restore.spec.ts +2 -2
  40. package/test/platform/matter-childbridge.spec.ts +1 -1
  41. package/test/platform/matter-integration.spec.ts +1 -1
  42. package/test/platform/platform-edge.spec.ts +2 -2
  43. package/test/platform/platform.integration.spec.ts +1 -1
  44. package/dist/SwitchBotHAPPlatform.d.ts.map +0 -1
  45. package/dist/SwitchBotHAPPlatform.js.map +0 -1
  46. package/dist/SwitchBotMatterPlatform.d.ts.map +0 -1
  47. package/dist/SwitchBotMatterPlatform.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../../src/homebridge-ui/public/js/credentials.ts"],"names":[],"mappings":"AAIA,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiC1D;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAiErD"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../../src/homebridge-ui/public/js/credentials.ts"],"names":[],"mappings":"AAIA,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiC1D;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAuErD"}
@@ -59,14 +59,20 @@ export async function saveCredentials() {
59
59
  if (typeof homebridge.getPluginConfig !== 'function' || typeof homebridge.updatePluginConfig !== 'function') {
60
60
  throw new TypeError('Homebridge UI API not available');
61
61
  }
62
- const configArr = await homebridge.getPluginConfig();
63
- if (!Array.isArray(configArr) || configArr.length === 0) {
64
- throw new Error('No plugin config found');
62
+ let configArr = await homebridge.getPluginConfig();
63
+ if (!Array.isArray(configArr)) {
64
+ configArr = [];
65
+ }
66
+ let idx = configArr.findIndex(c => (c.platform || c.name || '').toLowerCase() === 'switchbot');
67
+ if (idx === -1) {
68
+ // Add new SwitchBot platform config
69
+ configArr.push({ platform: 'SwitchBot' });
70
+ idx = configArr.length - 1;
65
71
  }
66
- const config = configArr[0];
72
+ const config = configArr[idx];
67
73
  config.openApiToken = token;
68
74
  config.openApiSecret = secret;
69
- await homebridge.updatePluginConfig([config]);
75
+ await homebridge.updatePluginConfig(configArr);
70
76
  if (typeof homebridge.savePluginConfig === 'function') {
71
77
  await homebridge.savePluginConfig();
72
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../../src/homebridge-ui/public/js/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEnE,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC;QACH,IAAI,OAAO,UAAU,CAAC,eAAe,KAAK,UAAU,EAAE,CAAC;YACrD,KAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAA;YAC9C,OAAM;QACR,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,eAAe,EAAE,CAAA;QACpD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACnF,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,IAAI,EAAE,CAAA;QACvC,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,IAAI,EAAE,CAAA;QAEzC,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,aAAa,CAAC,CAAA;QAC1D,MAAM,YAAY,GAAG,QAAQ,CAAC,cAAc,CAAC,cAAc,CAAC,CAAA;QAC5D,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY,EAAE,CAAC;YAClC,OAAM;QACR,CAAC;QACD,IAAI,KAAK,EAAE,CAAC;YACV,WAAW,CAAC,WAAW,GAAG,iBAAiB,KAAK,CAAC,MAAM,cAAc,CAAA;YACrE,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjC,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,WAAW,GAAG,gBAAgB,CAAA;YAC1C,WAAW,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACpC,CAAC;QACD,IAAI,MAAM,EAAE,CAAC;YACX,YAAY,CAAC,WAAW,GAAG,iBAAiB,MAAM,CAAC,MAAM,cAAc,CAAA;YACvE,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAClC,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,WAAW,GAAG,gBAAgB,CAAA;YAC3C,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,KAAK,CAAC,KAAK,CAAC,4BAA4B,EAAE,CAAC,CAAC,CAAA;IAC9C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,GAAI,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAsB,EAAE,KAAK,CAAA;IAC3E,MAAM,MAAM,GAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAsB,EAAE,KAAK,CAAA;IAC7E,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,YAAY,CAAC,CAAA;IACxD,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAsB,CAAA;IAEvE,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,OAAM;IACR,CAAC;IAED,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACtB,UAAU,CAAC,WAAW,GAAG,oCAAoC,CAAA;QAC7D,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjC,YAAY,CAAC,oCAAoC,CAAC,CAAA;QAClD,OAAM;IACR,CAAC;IAED,IAAI,CAAC;QACH,UAAU,EAAE,CAAA;QACZ,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAA;QACvB,OAAO,CAAC,WAAW,GAAG,WAAW,CAAA;QACjC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;QAEnC,IAAI,OAAO,UAAU,CAAC,eAAe,KAAK,UAAU,IAAI,OAAO,UAAU,CAAC,kBAAkB,KAAK,UAAU,EAAE,CAAC;YAC5G,MAAM,IAAI,SAAS,CAAC,iCAAiC,CAAC,CAAA;QACxD,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,eAAe,EAAE,CAAA;QACpD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;QAC3C,CAAC;QACD,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;QAC3B,MAAM,CAAC,YAAY,GAAG,KAAK,CAAA;QAC3B,MAAM,CAAC,aAAa,GAAG,MAAM,CAAA;QAC7B,MAAM,UAAU,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;QAC7C,IAAI,OAAO,UAAU,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;YACtD,MAAM,UAAU,CAAC,gBAAgB,EAAE,CAAA;QACrC,CAAC;QAED,UAAU,CAAC,WAAW,GAAG,kCAAkC,CAAA;QAC3D,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QACpC,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;QACvC,YAAY,CAAC,gCAAgC,CAAC,CAG7C;QAAC,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAsB,CAAC,KAAK,GAAG,EAAE,CACjE;QAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAsB,CAAC,KAAK,GAAG,EAAE,CAAA;QAEnE,+BAA+B;QAC/B,UAAU,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAA;QAErC,uBAAuB;QACvB,UAAU,CAAC,GAAG,EAAE;YACd,UAAU,CAAC,WAAW,GAAG,EAAE,CAAA;YAC3B,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,CAAC,CAAA;QAC5C,CAAC,EAAE,IAAI,CAAC,CAAA;IACV,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAA;QAC7B,UAAU,CAAC,WAAW,GAAG,UAAU,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAA;QACtF,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjC,UAAU,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAA;IAC3E,CAAC;YAAS,CAAC;QACT,UAAU,EAAE,CAAA;QACZ,OAAO,CAAC,QAAQ,GAAG,KAAK,CAAA;QACxB,OAAO,CAAC,WAAW,GAAG,kBAAkB,CAAA;IAC1C,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../../src/homebridge-ui/public/js/credentials.ts"],"names":[],"mappings":"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"}
@@ -63,14 +63,20 @@ export async function saveCredentials(): Promise<void> {
63
63
  if (typeof homebridge.getPluginConfig !== 'function' || typeof homebridge.updatePluginConfig !== 'function') {
64
64
  throw new TypeError('Homebridge UI API not available')
65
65
  }
66
- const configArr = await homebridge.getPluginConfig()
67
- if (!Array.isArray(configArr) || configArr.length === 0) {
68
- throw new Error('No plugin config found')
66
+ let configArr = await homebridge.getPluginConfig()
67
+ if (!Array.isArray(configArr)) {
68
+ configArr = []
69
+ }
70
+ let idx = configArr.findIndex(c => (c.platform || c.name || '').toLowerCase() === 'switchbot')
71
+ if (idx === -1) {
72
+ // Add new SwitchBot platform config
73
+ configArr.push({ platform: 'SwitchBot' })
74
+ idx = configArr.length - 1
69
75
  }
70
- const config = configArr[0]
76
+ const config = configArr[idx]
71
77
  config.openApiToken = token
72
78
  config.openApiSecret = secret
73
- await homebridge.updatePluginConfig([config])
79
+ await homebridge.updatePluginConfig(configArr)
74
80
  if (typeof homebridge.savePluginConfig === 'function') {
75
81
  await homebridge.savePluginConfig()
76
82
  }
@@ -0,0 +1,3 @@
1
+ export declare function enableLegacyView(): void;
2
+ export declare function disableLegacyView(): void;
3
+ //# sourceMappingURL=legacy-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-view.d.ts","sourceRoot":"","sources":["../../../../src/homebridge-ui/public/js/legacy-view.ts"],"names":[],"mappings":"AAkFA,wBAAgB,gBAAgB,SAI/B;AAED,wBAAgB,iBAAiB,SAGhC"}
@@ -0,0 +1,34 @@
1
+ import { disableLegacyView, enableLegacyView } from './legacy-view.js'
2
+
3
+ // Toggle button visibility and view containers
4
+ function updateViewButtons() {
5
+ const legacyBtn = document.getElementById('legacyViewBtn')
6
+ const dynamicBtn = document.getElementById('dynamicViewBtn')
7
+ const legacyContainer = document.getElementById('legacyViewContainer')
8
+ if (legacyContainer && legacyContainer.style.display === 'block') {
9
+ if (legacyBtn) {
10
+ legacyBtn.style.display = 'none'
11
+ }
12
+ if (dynamicBtn) {
13
+ dynamicBtn.style.display = 'inline-block'
14
+ }
15
+ } else {
16
+ if (legacyBtn) {
17
+ legacyBtn.style.display = 'inline-block'
18
+ }
19
+ if (dynamicBtn) {
20
+ dynamicBtn.style.display = 'none'
21
+ }
22
+ }
23
+ }
24
+
25
+ window.enableLegacyView = function () {
26
+ enableLegacyView()
27
+ updateViewButtons()
28
+ }
29
+ window.disableLegacyView = function () {
30
+ disableLegacyView()
31
+ updateViewButtons()
32
+ }
33
+
34
+ document.addEventListener('DOMContentLoaded', updateViewButtons)
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legacy-view.js","sourceRoot":"","sources":["../../../../src/homebridge-ui/public/js/legacy-view.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,0FAA0F;AAE1F,OAAO,MAAM,MAAM,gCAAgC,CAAA;AAEnD,SAAS,gBAAgB;IACvB,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAA;IAC7D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAM;IACR,CAAC;IACD,SAAS,CAAC,SAAS,GAAG,EAAE,CAAA;IACxB,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAAC,MAAM,CAAA;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAA;IAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAA;IAC3C,KAAK,MAAM,OAAO,IAAI,MAAM,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,UAAU,CAAC,CAAA;QACnD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;YAC/C,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAA;YAClC,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;QAC9B,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;YAC5B,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,SAAQ;YACV,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;gBACjE,qCAAqC;gBACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;gBAC7C,KAAK,CAAC,KAAK,CAAC,YAAY,GAAG,MAAM,CAAA;gBACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;gBAC7C,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;gBAC9C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;oBACxD,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;oBACvC,EAAE,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,MAAM,CAAA;oBAC9D,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;gBAC3B,CAAC;gBACD,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;gBAC5B,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;gBACxB,uCAAuC;gBACvC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;gBAC3B,SAAQ;YACV,CAAC;YACD,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;YAC7C,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,CAAA;YACrC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAA;YAC7B,IAAI,KAAkB,CAAA;YACtB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;gBAC/C,MAAM,CAAC,IAAI,GAAG,GAAG,CAAA;gBACjB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;oBAC5B,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;oBAC/C,MAAM,CAAC,KAAK,GAAG,GAAG,CAAA;oBAClB,MAAM,CAAC,WAAW,GAAG,GAAG,CAAA;oBACxB,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;gBAC5B,CAAC;gBACD,KAAK,GAAG,MAAM,CAAA;YAChB,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACnC,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;gBAChD,QAAQ,CAAC,IAAI,GAAG,UAAU,CAAA;gBAC1B,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAA;gBACnB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBACjB,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAA;gBACzB,CAAC;gBACD,KAAK,GAAG,QAAQ,CAAA;YAClB,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;gBAC5C,IAAI,CAAC,IAAI,GAAG,GAAG,CAAA;gBACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAA;gBAC5D,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBACjB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAA;gBAC3B,CAAC;gBACD,KAAK,GAAG,IAAI,CAAA;YACd,CAAC;YACD,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;YACxB,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;QAC7B,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAA;IAC5B,CAAC;IACD,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;AAC7B,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,QAAQ,CAAC,cAAc,CAAC,oBAAoB,CAAE,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAA;IACrE,QAAQ,CAAC,cAAc,CAAC,qBAAqB,CAAE,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAA;IACvE,gBAAgB,EAAE,CAAA;AACpB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,QAAQ,CAAC,cAAc,CAAC,oBAAoB,CAAE,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAA;IACtE,QAAQ,CAAC,cAAc,CAAC,qBAAqB,CAAE,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAA;AACxE,CAAC;AAED,0DAA0D"}
@@ -0,0 +1,94 @@
1
+ // legacy-view.ts
2
+ // Renders the config UI from config.schema.json and toggles between legacy and dynamic UI
3
+
4
+ import schema from '../../../../config.schema.json'
5
+
6
+ function renderLegacyView() {
7
+ const container = document.getElementById('legacyConfigForm')
8
+ if (!container) {
9
+ return
10
+ }
11
+ container.innerHTML = ''
12
+ const { properties } = schema.schema
13
+ const layout = schema.layout || []
14
+ const form = document.createElement('form')
15
+ for (const section of layout) {
16
+ const fieldset = document.createElement('fieldset')
17
+ if (section.title) {
18
+ const legend = document.createElement('legend')
19
+ legend.textContent = section.title
20
+ fieldset.appendChild(legend)
21
+ }
22
+ for (const key of section.items) {
23
+ const prop = properties[key]
24
+ if (!prop) {
25
+ continue
26
+ }
27
+ if (prop.type === 'array' && prop.items && prop.items.properties) {
28
+ // Render array of devices as a table
29
+ const table = document.createElement('table')
30
+ table.style.marginBottom = '12px'
31
+ const thead = document.createElement('thead')
32
+ const headerRow = document.createElement('tr')
33
+ for (const colKey of Object.keys(prop.items.properties)) {
34
+ const th = document.createElement('th')
35
+ th.textContent = prop.items.properties[colKey].title || colKey
36
+ headerRow.appendChild(th)
37
+ }
38
+ thead.appendChild(headerRow)
39
+ table.appendChild(thead)
40
+ // No data rows (read-only legacy view)
41
+ fieldset.appendChild(table)
42
+ continue
43
+ }
44
+ const label = document.createElement('label')
45
+ label.textContent = prop.title || key
46
+ label.style.display = 'block'
47
+ let input: HTMLElement
48
+ if (prop.enum) {
49
+ const select = document.createElement('select')
50
+ select.name = key
51
+ for (const opt of prop.enum) {
52
+ const option = document.createElement('option')
53
+ option.value = opt
54
+ option.textContent = opt
55
+ select.appendChild(option)
56
+ }
57
+ input = select
58
+ } else if (prop.type === 'boolean') {
59
+ const checkbox = document.createElement('input')
60
+ checkbox.type = 'checkbox'
61
+ checkbox.name = key
62
+ if (prop.default) {
63
+ checkbox.checked = true
64
+ }
65
+ input = checkbox
66
+ } else {
67
+ const text = document.createElement('input')
68
+ text.name = key
69
+ text.type = prop.format === 'password' ? 'password' : 'text'
70
+ if (prop.default) {
71
+ text.value = prop.default
72
+ }
73
+ input = text
74
+ }
75
+ label.appendChild(input)
76
+ fieldset.appendChild(label)
77
+ }
78
+ form.appendChild(fieldset)
79
+ }
80
+ container.appendChild(form)
81
+ }
82
+
83
+ export function enableLegacyView() {
84
+ document.getElementById('dynamicUiContainer')!.style.display = 'none'
85
+ document.getElementById('legacyViewContainer')!.style.display = 'block'
86
+ renderLegacyView()
87
+ }
88
+
89
+ export function disableLegacyView() {
90
+ document.getElementById('dynamicUiContainer')!.style.display = 'block'
91
+ document.getElementById('legacyViewContainer')!.style.display = 'none'
92
+ }
93
+
94
+ // (window assignment removed; handled in .js entry point)
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
+ import { SwitchBotHAPPlatform } from './Platform.HAP.js';
2
+ import { SwitchBotMatterPlatform } from './Platform.Matter.js';
1
3
  import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js';
2
- import { SwitchBotHAPPlatform } from './SwitchBotHAPPlatform.js';
3
- import { SwitchBotMatterPlatform } from './SwitchBotMatterPlatform.js';
4
4
  import { createPlatformProxy } from './utils.js';
5
5
  /**
6
6
  * Registers the SwitchBot platform with Homebridge.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAA;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAEhD;;;;;;;;;GASG;AACH,eAAe,CAAC,GAAQ,EAAQ,EAAE;IAChC,MAAM,SAAS,GAAG,mBAAmB,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,CAAA;IACpF,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,aAAa,EAAE,SAAgB,CAAC,CAAA;AACpE,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAEhD;;;;;;;;;GASG;AACH,eAAe,CAAC,GAAQ,EAAQ,EAAE;IAChC,MAAM,SAAS,GAAG,mBAAmB,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,CAAA;IACpF,GAAG,CAAC,gBAAgB,CAAC,WAAW,EAAE,aAAa,EAAE,SAAgB,CAAC,CAAA;AACpE,CAAC,CAAA"}
@@ -1,3 +1,3 @@
1
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">=&gt;</span> <span class="tsd-signature-type">void</span></div><div class="tsd-comment tsd-typography"><p>Registers the SwitchBot platform with Homebridge.</p>
2
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/6b0ee010f7c7ffffd101cfe2d9ea4408816f7cac/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>
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/8dc92c138cae368869d9128ad331bcc05c230da1/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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@switchbot/homebridge-switchbot",
3
3
  "displayName": "SwitchBot",
4
4
  "type": "module",
5
- "version": "5.1.0-beta.3",
5
+ "version": "5.1.0-beta.5",
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": [
@@ -32,6 +32,7 @@
32
32
  },
33
33
  "keywords": [
34
34
  "homebridge-plugin",
35
+ "homebridge-matter",
35
36
  "switchbot",
36
37
  "lights",
37
38
  "fan",
@@ -92,28 +93,21 @@
92
93
  },
93
94
  "dependencies": {
94
95
  "@homebridge/plugin-ui-utils": "^2.2.3",
95
- "class-validator": "^0.15.1",
96
- "node-switchbot": "^4.0.1"
96
+ "node-switchbot": "^4.0.2"
97
97
  },
98
98
  "devDependencies": {
99
99
  "@antfu/eslint-config": "^8.2.0",
100
- "@types/debug": "^4.1.13",
101
- "@types/fs-extra": "^11.0.4",
102
100
  "@types/node": "^25.6.0",
103
- "@types/semver": "^7.7.1",
104
- "@types/source-map-support": "^0.5.10",
105
- "@vitest/coverage-v8": "^4.1.4",
101
+ "@vitest/coverage-v8": "^4.1.5",
106
102
  "esbuild": "^0.28.0",
107
- "eslint": "^10.2.0",
103
+ "eslint": "^10.3.0",
108
104
  "eslint-plugin-format": "^2.0.1",
109
- "eslint-plugin-html": "^8.1.4",
110
- "eslint-plugin-perfectionist": "^5.8.0",
111
- "homebridge": "^2.0.0-beta.89",
112
- "homebridge-config-ui-x": "^5.21.0",
105
+ "eslint-plugin-perfectionist": "^5.9.0",
106
+ "homebridge": "^2.0.1",
113
107
  "nodemon": "^3.1.14",
114
108
  "shx": "^0.4.0",
115
109
  "typedoc": "^0.28.19",
116
- "typescript": "^6.0.2",
117
- "vitest": "^4.1.4"
110
+ "typescript": "^6.0.3",
111
+ "vitest": "^4.1.5"
118
112
  }
119
113
  }
@@ -1,6 +1,7 @@
1
- import type { SwitchBotPluginConfig } from './settings.js'
2
1
  import type { API, Logger, PlatformConfig } from 'homebridge'
3
2
 
3
+ import type { SwitchBotPluginConfig } from './settings.js'
4
+
4
5
  import { createDevice } from './deviceFactory.js'
5
6
  import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js'
6
7
  import { SwitchBotClient } from './switchbotClient.js'
@@ -214,7 +215,9 @@ export class SwitchBotHAPPlatform {
214
215
  }
215
216
  }
216
217
  if (!accessory) {
217
- accessory = new (this.api as any).platformAccessory(d.name || type, uuid)
218
+ // Use the PlatformAccessory constructor from the HAP API
219
+ const PlatformAccessory = (this.api as any).hap?.PlatformAccessory || (this.api as any).platformAccessory
220
+ accessory = new PlatformAccessory(d.name || type, uuid)
218
221
  try {
219
222
  accessory.context = accessory.context || {}
220
223
  accessory.context.deviceId = d.id
@@ -1,6 +1,7 @@
1
- import type { SwitchBotPluginConfig } from './settings.js'
2
1
  import type { API, Logger, PlatformConfig } from 'homebridge'
3
2
 
3
+ import type { SwitchBotPluginConfig } from './settings.js'
4
+
4
5
  import { createDevice } from './deviceFactory.js'
5
6
  import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js'
6
7
  import { SwitchBotClient } from './switchbotClient.js'
@@ -9,7 +9,14 @@
9
9
  </head>
10
10
 
11
11
  <body>
12
+
12
13
  <h1>🤖 SwitchBot Configuration</h1>
14
+ <div style="margin-bottom: 12px;">
15
+ <button id="legacyViewBtn" onclick="enableLegacyView()" style="font-size: 12px; padding: 4px 10px;">Legacy View</button>
16
+ <button id="dynamicViewBtn" onclick="disableLegacyView()" style="font-size: 12px; padding: 4px 10px; display: none;">Dynamic View</button>
17
+ </div>
18
+
19
+ <div id="dynamicUiContainer">
13
20
 
14
21
  <!-- v4 config incompatibility warning – shown dynamically by app.js -->
15
22
  <div id="v4ConfigWarning" class="v4-config-warning" style="display: none">
@@ -227,8 +234,18 @@
227
234
  </form>
228
235
  </div>
229
236
 
237
+ </div> <!-- end dynamicUiContainer -->
238
+
239
+ <div id="legacyViewContainer" style="display: none;">
240
+ <div class="card compact">
241
+ <h2>Legacy Config View</h2>
242
+ <div id="legacyConfigForm"></div>
243
+ </div>
244
+ </div>
245
+
230
246
  <script type="module" src="js/app.js"></script>
231
247
  <script type="module" src="js/advanced-settings.js"></script>
248
+ <script type="module" src="js/legacy-view.js"></script>
232
249
  </body>
233
250
 
234
251
  </html>
@@ -46,10 +46,11 @@ async function saveAdvancedSettings(): Promise<void> {
46
46
  if (!Array.isArray(pluginConfigBlocks) || !pluginConfigBlocks.length) {
47
47
  throw new Error('No plugin config blocks returned from Homebridge')
48
48
  }
49
- // Find the SwitchBot config block
50
- const idx = pluginConfigBlocks.findIndex(c => (c.platform || c.name || '').toLowerCase().includes('switchbot'))
49
+ // Find or add the SwitchBot config block
50
+ let idx = pluginConfigBlocks.findIndex(c => (c.platform || c.name || '').toLowerCase().includes('switchbot'))
51
51
  if (idx === -1) {
52
- throw new Error('SwitchBot config not found')
52
+ pluginConfigBlocks.push({ platform: 'SwitchBot' })
53
+ idx = pluginConfigBlocks.length - 1
53
54
  }
54
55
  const config = pluginConfigBlocks[idx]
55
56
  // Update config values from UI
@@ -63,14 +63,20 @@ export async function saveCredentials(): Promise<void> {
63
63
  if (typeof homebridge.getPluginConfig !== 'function' || typeof homebridge.updatePluginConfig !== 'function') {
64
64
  throw new TypeError('Homebridge UI API not available')
65
65
  }
66
- const configArr = await homebridge.getPluginConfig()
67
- if (!Array.isArray(configArr) || configArr.length === 0) {
68
- throw new Error('No plugin config found')
66
+ let configArr = await homebridge.getPluginConfig()
67
+ if (!Array.isArray(configArr)) {
68
+ configArr = []
69
+ }
70
+ let idx = configArr.findIndex(c => (c.platform || c.name || '').toLowerCase() === 'switchbot')
71
+ if (idx === -1) {
72
+ // Add new SwitchBot platform config
73
+ configArr.push({ platform: 'SwitchBot' })
74
+ idx = configArr.length - 1
69
75
  }
70
- const config = configArr[0]
76
+ const config = configArr[idx]
71
77
  config.openApiToken = token
72
78
  config.openApiSecret = secret
73
- await homebridge.updatePluginConfig([config])
79
+ await homebridge.updatePluginConfig(configArr)
74
80
  if (typeof homebridge.savePluginConfig === 'function') {
75
81
  await homebridge.savePluginConfig()
76
82
  }
@@ -0,0 +1,34 @@
1
+ import { disableLegacyView, enableLegacyView } from './legacy-view.js'
2
+
3
+ // Toggle button visibility and view containers
4
+ function updateViewButtons() {
5
+ const legacyBtn = document.getElementById('legacyViewBtn')
6
+ const dynamicBtn = document.getElementById('dynamicViewBtn')
7
+ const legacyContainer = document.getElementById('legacyViewContainer')
8
+ if (legacyContainer && legacyContainer.style.display === 'block') {
9
+ if (legacyBtn) {
10
+ legacyBtn.style.display = 'none'
11
+ }
12
+ if (dynamicBtn) {
13
+ dynamicBtn.style.display = 'inline-block'
14
+ }
15
+ } else {
16
+ if (legacyBtn) {
17
+ legacyBtn.style.display = 'inline-block'
18
+ }
19
+ if (dynamicBtn) {
20
+ dynamicBtn.style.display = 'none'
21
+ }
22
+ }
23
+ }
24
+
25
+ window.enableLegacyView = function () {
26
+ enableLegacyView()
27
+ updateViewButtons()
28
+ }
29
+ window.disableLegacyView = function () {
30
+ disableLegacyView()
31
+ updateViewButtons()
32
+ }
33
+
34
+ document.addEventListener('DOMContentLoaded', updateViewButtons)
@@ -0,0 +1,94 @@
1
+ // legacy-view.ts
2
+ // Renders the config UI from config.schema.json and toggles between legacy and dynamic UI
3
+
4
+ import schema from '../../../../config.schema.json'
5
+
6
+ function renderLegacyView() {
7
+ const container = document.getElementById('legacyConfigForm')
8
+ if (!container) {
9
+ return
10
+ }
11
+ container.innerHTML = ''
12
+ const { properties } = schema.schema
13
+ const layout = schema.layout || []
14
+ const form = document.createElement('form')
15
+ for (const section of layout) {
16
+ const fieldset = document.createElement('fieldset')
17
+ if (section.title) {
18
+ const legend = document.createElement('legend')
19
+ legend.textContent = section.title
20
+ fieldset.appendChild(legend)
21
+ }
22
+ for (const key of section.items) {
23
+ const prop = properties[key]
24
+ if (!prop) {
25
+ continue
26
+ }
27
+ if (prop.type === 'array' && prop.items && prop.items.properties) {
28
+ // Render array of devices as a table
29
+ const table = document.createElement('table')
30
+ table.style.marginBottom = '12px'
31
+ const thead = document.createElement('thead')
32
+ const headerRow = document.createElement('tr')
33
+ for (const colKey of Object.keys(prop.items.properties)) {
34
+ const th = document.createElement('th')
35
+ th.textContent = prop.items.properties[colKey].title || colKey
36
+ headerRow.appendChild(th)
37
+ }
38
+ thead.appendChild(headerRow)
39
+ table.appendChild(thead)
40
+ // No data rows (read-only legacy view)
41
+ fieldset.appendChild(table)
42
+ continue
43
+ }
44
+ const label = document.createElement('label')
45
+ label.textContent = prop.title || key
46
+ label.style.display = 'block'
47
+ let input: HTMLElement
48
+ if (prop.enum) {
49
+ const select = document.createElement('select')
50
+ select.name = key
51
+ for (const opt of prop.enum) {
52
+ const option = document.createElement('option')
53
+ option.value = opt
54
+ option.textContent = opt
55
+ select.appendChild(option)
56
+ }
57
+ input = select
58
+ } else if (prop.type === 'boolean') {
59
+ const checkbox = document.createElement('input')
60
+ checkbox.type = 'checkbox'
61
+ checkbox.name = key
62
+ if (prop.default) {
63
+ checkbox.checked = true
64
+ }
65
+ input = checkbox
66
+ } else {
67
+ const text = document.createElement('input')
68
+ text.name = key
69
+ text.type = prop.format === 'password' ? 'password' : 'text'
70
+ if (prop.default) {
71
+ text.value = prop.default
72
+ }
73
+ input = text
74
+ }
75
+ label.appendChild(input)
76
+ fieldset.appendChild(label)
77
+ }
78
+ form.appendChild(fieldset)
79
+ }
80
+ container.appendChild(form)
81
+ }
82
+
83
+ export function enableLegacyView() {
84
+ document.getElementById('dynamicUiContainer')!.style.display = 'none'
85
+ document.getElementById('legacyViewContainer')!.style.display = 'block'
86
+ renderLegacyView()
87
+ }
88
+
89
+ export function disableLegacyView() {
90
+ document.getElementById('dynamicUiContainer')!.style.display = 'block'
91
+ document.getElementById('legacyViewContainer')!.style.display = 'none'
92
+ }
93
+
94
+ // (window assignment removed; handled in .js entry point)
package/src/index.ts CHANGED
@@ -4,9 +4,9 @@
4
4
  */
5
5
  import type { API } from 'homebridge'
6
6
 
7
+ import { SwitchBotHAPPlatform } from './Platform.HAP.js'
8
+ import { SwitchBotMatterPlatform } from './Platform.Matter.js'
7
9
  import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js'
8
- import { SwitchBotHAPPlatform } from './SwitchBotHAPPlatform.js'
9
- import { SwitchBotMatterPlatform } from './SwitchBotMatterPlatform.js'
10
10
  import { createPlatformProxy } from './utils.js'
11
11
 
12
12
  /**
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest'
2
2
 
3
- import { SwitchBotHAPPlatform } from '../../src/SwitchBotHAPPlatform.js'
4
- import { SwitchBotMatterPlatform } from '../../src/SwitchBotMatterPlatform.js'
3
+ import { SwitchBotHAPPlatform } from '../../src/Platform.HAP.js'
4
+ import { SwitchBotMatterPlatform } from '../../src/Platform.Matter.js'
5
5
 
6
6
  describe('accessory restoration', () => {
7
7
  class TestHAPPlatform extends SwitchBotHAPPlatform {
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from 'vitest'
2
2
 
3
- import { SwitchBotMatterPlatform } from '../../src/SwitchBotMatterPlatform.js'
3
+ import { SwitchBotMatterPlatform } from '../../src/Platform.Matter.js'
4
4
 
5
5
  describe('matter child bridge accessory restoration', () => {
6
6
  class TestMatterPlatform extends SwitchBotMatterPlatform {
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it, vi } from 'vitest'
2
2
 
3
- import { SwitchBotMatterPlatform } from '../../src/SwitchBotMatterPlatform.js'
3
+ import { SwitchBotMatterPlatform } from '../../src/Platform.Matter.js'
4
4
 
5
5
  describe('matter integration platform', () => {
6
6
  class TestMatterPlatform extends SwitchBotMatterPlatform {
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest'
2
2
 
3
- import SwitchBotHAPPlatform from '../../src/SwitchBotHAPPlatform.js'
4
- import { SwitchBotMatterPlatform } from '../../src/SwitchBotMatterPlatform.js'
3
+ import SwitchBotHAPPlatform from '../../src/Platform.HAP.js'
4
+ import { SwitchBotMatterPlatform } from '../../src/Platform.Matter.js'
5
5
 
6
6
  const mockLogger = {
7
7
  info: () => {},
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it, vi } from 'vitest'
2
2
 
3
- import { SwitchBotHAPPlatform } from '../../src/SwitchBotHAPPlatform.js'
3
+ import { SwitchBotHAPPlatform } from '../../src/Platform.HAP.js'
4
4
 
5
5
  describe('hAP platform integration', () => {
6
6
  class TestHAPPlatform extends SwitchBotHAPPlatform {
@@ -1 +0,0 @@
1
- {"version":3,"file":"SwitchBotHAPPlatform.d.ts","sourceRoot":"","sources":["../src/SwitchBotHAPPlatform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAC1D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAO7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,oBAAoB;IAC/B,8BAA8B;IAC9B,GAAG,EAAE,GAAG,GAAG,SAAS,CAAA;IACpB,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,2BAA2B;IAC3B,MAAM,EAAE,qBAAqB,CAAA;IAC7B,mCAAmC;IACnC,OAAO,EAAE,GAAG,EAAE,CAAK;IACnB,gDAAgD;IAChD,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC7B,sDAAsD;IACtD,OAAO,CAAC,cAAc,CAAa;IACnC,0CAA0C;IAC1C,OAAO,CAAC,oBAAoB,CAA8B;IAC1D,4CAA4C;IAC5C,OAAO,CAAC,iBAAiB,CAAyC;IAClE,wCAAwC;IACxC,OAAO,CAAC,iBAAiB,CAA8B;IACvD,2CAA2C;IAC3C,OAAO,CAAC,oBAAoB,CAAI;IAChC,yDAAyD;IACzD,OAAO,CAAC,gBAAgB,CAAI;IAE5B;;;;;OAKG;gBACS,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,GAAG;IA2C1D;;;;;;OAMG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IA8DlC;;;;;;;;;;;;;;;;;;;;OAoBG;YACW,sBAAsB;IAuIpC;;;OAGG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;;OAGG;IACH,mBAAmB,IAAI,IAAI;IAS3B;;;OAGG;IACH,OAAO,CAAC,aAAa;IAWrB;;;;;;OAMG;YACW,qBAAqB;IAiCnC;;;;OAIG;IACH,QAAQ,IAAI,IAAI;IAQhB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAkI5B;;;;OAIG;IACG,kBAAkB,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAUvD;;;;OAIG;IACH,wBAAwB,CAAC,CAAC,SAAS,EAAE,GAAG,GAAG,IAAI;CAShD;AAED,eAAe,oBAAoB,CAAA"}