@switchbot/homebridge-switchbot 5.1.0-beta.8 → 5.1.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.
Files changed (130) hide show
  1. package/.github/copilot-instructions.md +0 -63
  2. package/.github/scripts/normalize-changelog-header.cjs +1 -1
  3. package/.github/scripts/npm-version-script-esm-auto.js +1 -1
  4. package/.github/scripts/resolve-version-bump-esm.js +1 -1
  5. package/CHANGELOG.md +10 -9
  6. package/MIGRATION.md +0 -5
  7. package/README.md +0 -25
  8. package/config.schema.json +0 -11
  9. package/dist/{Platform.HAP.d.ts → SwitchBotHAPPlatform.d.ts} +16 -2
  10. package/dist/SwitchBotHAPPlatform.d.ts.map +1 -0
  11. package/dist/{Platform.HAP.js → SwitchBotHAPPlatform.js} +111 -40
  12. package/dist/SwitchBotHAPPlatform.js.map +1 -0
  13. package/dist/{Platform.Matter.d.ts → SwitchBotMatterPlatform.d.ts} +2 -4
  14. package/dist/SwitchBotMatterPlatform.d.ts.map +1 -0
  15. package/dist/{Platform.Matter.js → SwitchBotMatterPlatform.js} +6 -62
  16. package/dist/SwitchBotMatterPlatform.js.map +1 -0
  17. package/dist/deviceFactory.d.ts.map +1 -1
  18. package/dist/deviceFactory.js +5 -15
  19. package/dist/deviceFactory.js.map +1 -1
  20. package/dist/devices/genericDevice.d.ts +63 -5
  21. package/dist/devices/genericDevice.d.ts.map +1 -1
  22. package/dist/devices/genericDevice.js +251 -11
  23. package/dist/devices/genericDevice.js.map +1 -1
  24. package/dist/homebridge-ui/endpoints/config.d.ts.map +1 -1
  25. package/dist/homebridge-ui/endpoints/config.js +2 -9
  26. package/dist/homebridge-ui/endpoints/config.js.map +1 -1
  27. package/dist/homebridge-ui/homebridge-ui/endpoints/config.js +2 -9
  28. package/dist/homebridge-ui/homebridge-ui/endpoints/config.js.map +1 -1
  29. package/dist/homebridge-ui/homebridge-ui/utils/config-parser.js +0 -8
  30. package/dist/homebridge-ui/homebridge-ui/utils/config-parser.js.map +1 -1
  31. package/dist/homebridge-ui/public/css/styles.css +1 -61
  32. package/dist/homebridge-ui/public/index.html +2 -61
  33. package/dist/homebridge-ui/public/js/advanced-settings.d.ts.map +1 -1
  34. package/dist/homebridge-ui/public/js/advanced-settings.js +3 -4
  35. package/dist/homebridge-ui/public/js/advanced-settings.js.map +1 -1
  36. package/dist/homebridge-ui/public/js/advanced-settings.ts +3 -4
  37. package/dist/homebridge-ui/public/js/api.d.ts +0 -16
  38. package/dist/homebridge-ui/public/js/api.d.ts.map +1 -1
  39. package/dist/homebridge-ui/public/js/api.js +0 -48
  40. package/dist/homebridge-ui/public/js/api.js.map +1 -1
  41. package/dist/homebridge-ui/public/js/api.ts +1 -61
  42. package/dist/homebridge-ui/public/js/app.js +115 -267
  43. package/dist/homebridge-ui/public/js/app.js.map +4 -4
  44. package/dist/homebridge-ui/public/js/app.ts +4 -47
  45. package/dist/homebridge-ui/public/js/credentials.d.ts.map +1 -1
  46. package/dist/homebridge-ui/public/js/credentials.js +5 -11
  47. package/dist/homebridge-ui/public/js/credentials.js.map +1 -1
  48. package/dist/homebridge-ui/public/js/credentials.ts +5 -11
  49. package/dist/homebridge-ui/public/js/devices.d.ts.map +1 -1
  50. package/dist/homebridge-ui/public/js/devices.js +0 -6
  51. package/dist/homebridge-ui/public/js/devices.js.map +1 -1
  52. package/dist/homebridge-ui/public/js/devices.ts +0 -6
  53. package/dist/homebridge-ui/public/js/modals.d.ts +0 -1
  54. package/dist/homebridge-ui/public/js/modals.d.ts.map +1 -1
  55. package/dist/homebridge-ui/public/js/modals.js +0 -53
  56. package/dist/homebridge-ui/public/js/modals.js.map +1 -1
  57. package/dist/homebridge-ui/public/js/modals.ts +0 -58
  58. package/dist/homebridge-ui/public/js/render.d.ts.map +1 -1
  59. package/dist/homebridge-ui/public/js/render.js +1 -2
  60. package/dist/homebridge-ui/public/js/render.js.map +1 -1
  61. package/dist/homebridge-ui/public/js/render.ts +1 -2
  62. package/dist/homebridge-ui/settings.js.map +1 -1
  63. package/dist/homebridge-ui/utils/config-parser.d.ts +0 -8
  64. package/dist/homebridge-ui/utils/config-parser.d.ts.map +1 -1
  65. package/dist/homebridge-ui/utils/config-parser.js +0 -8
  66. package/dist/homebridge-ui/utils/config-parser.js.map +1 -1
  67. package/dist/index.js +2 -2
  68. package/dist/index.js.map +1 -1
  69. package/dist/settings.d.ts +0 -11
  70. package/dist/settings.d.ts.map +1 -1
  71. package/dist/settings.js.map +1 -1
  72. package/dist/utils.d.ts +0 -5
  73. package/dist/utils.d.ts.map +1 -1
  74. package/dist/utils.js +0 -27
  75. package/dist/utils.js.map +1 -1
  76. package/docs/assets/highlight.css +15 -15
  77. package/docs/index.html +5 -22
  78. package/docs/variables/default.html +1 -1
  79. package/package.json +15 -9
  80. package/scripts/build-ui.js +0 -30
  81. package/src/{Platform.HAP.ts → SwitchBotHAPPlatform.ts} +112 -39
  82. package/src/{Platform.Matter.ts → SwitchBotMatterPlatform.ts} +8 -63
  83. package/src/deviceFactory.ts +5 -14
  84. package/src/devices/genericDevice.ts +271 -12
  85. package/src/homebridge-ui/endpoints/config.ts +2 -10
  86. package/src/homebridge-ui/public/css/styles.css +1 -61
  87. package/src/homebridge-ui/public/index.html +0 -59
  88. package/src/homebridge-ui/public/js/advanced-settings.ts +3 -4
  89. package/src/homebridge-ui/public/js/api.ts +1 -61
  90. package/src/homebridge-ui/public/js/app.ts +4 -47
  91. package/src/homebridge-ui/public/js/credentials.ts +5 -11
  92. package/src/homebridge-ui/public/js/devices.ts +0 -6
  93. package/src/homebridge-ui/public/js/modals.ts +0 -58
  94. package/src/homebridge-ui/public/js/render.ts +1 -2
  95. package/src/homebridge-ui/utils/config-parser.ts +0 -9
  96. package/src/index.ts +2 -2
  97. package/src/settings.ts +0 -12
  98. package/src/utils.ts +0 -31
  99. package/test/device/deviceFactory.spec.ts +9 -0
  100. package/test/device/getstate-cache.spec.ts +62 -0
  101. package/test/device/getstate-returns-status.spec.ts +89 -0
  102. package/test/device/water-detector-battery.spec.ts +81 -0
  103. package/test/device/water-detector-leak.spec.ts +43 -0
  104. package/test/hap-push-updates.spec.ts +150 -0
  105. package/test/platform/accessory-restore.spec.ts +2 -2
  106. package/test/platform/matter-childbridge.spec.ts +1 -1
  107. package/test/platform/matter-integration.spec.ts +1 -51
  108. package/test/platform/platform-edge.spec.ts +2 -2
  109. package/test/platform/platform.integration.spec.ts +1 -1
  110. package/test/utils/utils.spec.ts +0 -15
  111. package/.github/npm-version-script-esm.js +0 -97
  112. package/dist/Platform.HAP.d.ts.map +0 -1
  113. package/dist/Platform.HAP.js.map +0 -1
  114. package/dist/Platform.Matter.d.ts.map +0 -1
  115. package/dist/Platform.Matter.js.map +0 -1
  116. package/dist/homebridge-ui/homebridge-ui/utils/v4-detection.js +0 -23
  117. package/dist/homebridge-ui/homebridge-ui/utils/v4-detection.js.map +0 -1
  118. package/dist/homebridge-ui/public/js/legacy-view.d.ts +0 -3
  119. package/dist/homebridge-ui/public/js/legacy-view.d.ts.map +0 -1
  120. package/dist/homebridge-ui/public/js/legacy-view.js +0 -43
  121. package/dist/homebridge-ui/public/js/legacy-view.js.map +0 -1
  122. package/dist/homebridge-ui/public/js/legacy-view.ts +0 -99
  123. package/dist/homebridge-ui/utils/v4-detection.d.ts +0 -12
  124. package/dist/homebridge-ui/utils/v4-detection.d.ts.map +0 -1
  125. package/dist/homebridge-ui/utils/v4-detection.js +0 -23
  126. package/dist/homebridge-ui/utils/v4-detection.js.map +0 -1
  127. package/src/homebridge-ui/public/js/legacy-view.js +0 -43
  128. package/src/homebridge-ui/public/js/legacy-view.ts +0 -99
  129. package/src/homebridge-ui/utils/v4-detection.ts +0 -23
  130. package/test/homebridge-ui/config-parser.spec.ts +0 -61
@@ -8,6 +8,110 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
+ // src/homebridge-ui/public/js/logger.ts
12
+ var PREFIX, uiLog;
13
+ var init_logger = __esm({
14
+ "src/homebridge-ui/public/js/logger.ts"() {
15
+ "use strict";
16
+ PREFIX = "[SwitchBot UI/html]";
17
+ uiLog = {
18
+ info: (message, ...parameters) => {
19
+ console.log(PREFIX, message, ...parameters);
20
+ },
21
+ warn: (message, ...parameters) => {
22
+ console.warn(PREFIX, message, ...parameters);
23
+ },
24
+ error: (message, ...parameters) => {
25
+ console.error(PREFIX, message, ...parameters);
26
+ },
27
+ debug: (message, ...parameters) => {
28
+ console.debug(PREFIX, message, ...parameters);
29
+ }
30
+ };
31
+ }
32
+ });
33
+
34
+ // src/homebridge-ui/public/js/types.ts
35
+ var init_types = __esm({
36
+ "src/homebridge-ui/public/js/types.ts"() {
37
+ "use strict";
38
+ }
39
+ });
40
+
41
+ // src/homebridge-ui/public/js/modal.ts
42
+ function callUiMethod(name, ...args) {
43
+ try {
44
+ if (typeof homebridge?.[name] === "function") {
45
+ uiLog.info(`[callUiMethod] Invoking homebridge.${String(name)}()`);
46
+ const fn = homebridge?.[name];
47
+ if (typeof fn === "function") {
48
+ uiLog.info(`[callUiMethod] Invoking homebridge.${String(name)}()`);
49
+ fn.apply(homebridge, args);
50
+ } else {
51
+ uiLog.warn(`[callUiMethod] homebridge[${String(name)}] is not a function.`);
52
+ }
53
+ } else {
54
+ uiLog.warn(`[callUiMethod] homebridge[${String(name)}] is not a function.`);
55
+ }
56
+ } catch (e) {
57
+ uiLog.warn(`Homebridge UI method ${String(name)} failed:`, e);
58
+ }
59
+ }
60
+ function showBusyUi() {
61
+ callUiMethod("disableSaveButton");
62
+ callUiMethod("showSpinner");
63
+ }
64
+ function hideBusyUi() {
65
+ callUiMethod("hideSpinner");
66
+ callUiMethod("enableSaveButton");
67
+ }
68
+ var init_modal = __esm({
69
+ "src/homebridge-ui/public/js/modal.ts"() {
70
+ "use strict";
71
+ init_types();
72
+ init_logger();
73
+ }
74
+ });
75
+
76
+ // src/homebridge-ui/public/js/toast.ts
77
+ function showToast(method, message, title = "SwitchBot") {
78
+ try {
79
+ const hb = typeof window !== "undefined" ? window.homebridge : void 0;
80
+ const toast = hb && typeof hb.toast === "object" ? hb.toast : void 0;
81
+ if (toast && typeof toast[method] === "function") {
82
+ try {
83
+ toast[method](message, title);
84
+ return;
85
+ } catch (err) {
86
+ uiLog.warn(`Toast ${method} threw:`, err);
87
+ }
88
+ }
89
+ uiLog.info(`[Toast:${method}] ${title} - ${message}`);
90
+ } catch (e) {
91
+ uiLog.warn(`Toast ${method} outer error:`, e);
92
+ uiLog.info(`[Toast:${method}] ${title} - ${message}`);
93
+ }
94
+ }
95
+ function toastSuccess(message, title) {
96
+ showToast("success", message, title);
97
+ }
98
+ function toastError(message, title) {
99
+ showToast("error", message, title);
100
+ }
101
+ function toastWarning(message, title) {
102
+ showToast("warning", message, title);
103
+ }
104
+ function toastInfo(message, title) {
105
+ showToast("info", message, title);
106
+ }
107
+ var init_toast = __esm({
108
+ "src/homebridge-ui/public/js/toast.ts"() {
109
+ "use strict";
110
+ init_types();
111
+ init_logger();
112
+ }
113
+ });
114
+
11
115
  // src/device-types.js
12
116
  function getValidDeviceTypes() {
13
117
  const validTypes = /* @__PURE__ */ new Set();
@@ -249,90 +353,6 @@ var init_device_types = __esm({
249
353
  }
250
354
  });
251
355
 
252
- // src/homebridge-ui/utils/v4-detection.ts
253
- function isV4Config(platform) {
254
- if (!platform || typeof platform !== "object") {
255
- return false;
256
- }
257
- const hasCredentials = platform.credentials !== void 0 && typeof platform.credentials === "object";
258
- const hasOptionsDevices = platform.options !== void 0 && typeof platform.options === "object" && Array.isArray(platform.options.devices);
259
- return hasCredentials || hasOptionsDevices;
260
- }
261
- var init_v4_detection = __esm({
262
- "src/homebridge-ui/utils/v4-detection.ts"() {
263
- "use strict";
264
- }
265
- });
266
-
267
- // src/homebridge-ui/public/js/types.ts
268
- var init_types = __esm({
269
- "src/homebridge-ui/public/js/types.ts"() {
270
- "use strict";
271
- }
272
- });
273
-
274
- // src/homebridge-ui/public/js/logger.ts
275
- var PREFIX, uiLog;
276
- var init_logger = __esm({
277
- "src/homebridge-ui/public/js/logger.ts"() {
278
- "use strict";
279
- PREFIX = "[SwitchBot UI/html]";
280
- uiLog = {
281
- info: (message, ...parameters) => {
282
- console.log(PREFIX, message, ...parameters);
283
- },
284
- warn: (message, ...parameters) => {
285
- console.warn(PREFIX, message, ...parameters);
286
- },
287
- error: (message, ...parameters) => {
288
- console.error(PREFIX, message, ...parameters);
289
- },
290
- debug: (message, ...parameters) => {
291
- console.debug(PREFIX, message, ...parameters);
292
- }
293
- };
294
- }
295
- });
296
-
297
- // src/homebridge-ui/public/js/toast.ts
298
- function showToast(method, message, title = "SwitchBot") {
299
- try {
300
- const hb = typeof window !== "undefined" ? window.homebridge : void 0;
301
- const toast = hb && typeof hb.toast === "object" ? hb.toast : void 0;
302
- if (toast && typeof toast[method] === "function") {
303
- try {
304
- toast[method](message, title);
305
- return;
306
- } catch (err) {
307
- uiLog.warn(`Toast ${method} threw:`, err);
308
- }
309
- }
310
- uiLog.info(`[Toast:${method}] ${title} - ${message}`);
311
- } catch (e) {
312
- uiLog.warn(`Toast ${method} outer error:`, e);
313
- uiLog.info(`[Toast:${method}] ${title} - ${message}`);
314
- }
315
- }
316
- function toastSuccess(message, title) {
317
- showToast("success", message, title);
318
- }
319
- function toastError(message, title) {
320
- showToast("error", message, title);
321
- }
322
- function toastWarning(message, title) {
323
- showToast("warning", message, title);
324
- }
325
- function toastInfo(message, title) {
326
- showToast("info", message, title);
327
- }
328
- var init_toast = __esm({
329
- "src/homebridge-ui/public/js/toast.ts"() {
330
- "use strict";
331
- init_types();
332
- init_logger();
333
- }
334
- });
335
-
336
356
  // src/homebridge-ui/public/js/api.ts
337
357
  var api_exports = {};
338
358
  __export(api_exports, {
@@ -340,13 +360,12 @@ __export(api_exports, {
340
360
  addDevicesInBulk: () => addDevicesInBulk,
341
361
  deleteAllDevices: () => deleteAllDevices,
342
362
  deleteDevice: () => deleteDevice,
343
- detectV4Config: () => detectV4Config,
344
363
  discoverDevices: () => discoverDevices,
345
364
  fetchBluetoothStatus: () => fetchBluetoothStatus,
346
365
  fetchCredentialStatus: () => fetchCredentialStatus,
347
366
  fetchDevices: () => fetchDevices,
348
367
  normalizeBulkAddDevicesResponse: () => normalizeBulkAddDevicesResponse,
349
- saveCredentials: () => saveCredentials,
368
+ saveCredentials: () => saveCredentials2,
350
369
  syncParentPluginConfigFromDisk: () => syncParentPluginConfigFromDisk,
351
370
  testDeviceConnection: () => testDeviceConnection,
352
371
  updateDevice: () => updateDevice,
@@ -369,25 +388,6 @@ async function fetchDevices() {
369
388
  return [];
370
389
  }
371
390
  }
372
- async function detectV4Config() {
373
- try {
374
- if (typeof homebridge.getPluginConfig !== "function") {
375
- return false;
376
- }
377
- const configArr = await homebridge.getPluginConfig();
378
- if (!Array.isArray(configArr)) {
379
- return false;
380
- }
381
- const config = configArr.find(isSwitchBotPlatformConfig);
382
- if (!config || typeof config !== "object") {
383
- return false;
384
- }
385
- return isV4Config(config);
386
- } catch (e) {
387
- uiLog.warn("Error detecting v4 config:", e);
388
- return false;
389
- }
390
- }
391
391
  function validateAndFixDeviceTypes(devices) {
392
392
  const errors = [];
393
393
  for (const d of devices) {
@@ -457,7 +457,7 @@ async function fetchCredentialStatus() {
457
457
  return null;
458
458
  }
459
459
  }
460
- async function saveCredentials(token, secret) {
460
+ async function saveCredentials2(token, secret) {
461
461
  uiLog.info("Saving credentials...");
462
462
  const resp = await homebridge.request("/credentials", { token, secret });
463
463
  uiLog.info("Save response:", resp);
@@ -532,24 +532,6 @@ async function addDevice(deviceId, name, type, options) {
532
532
  if (options?.keyId) {
533
533
  newDevice.keyId = options.keyId;
534
534
  }
535
- if (options?.connectionPreference) {
536
- newDevice.connectionPreference = options.connectionPreference;
537
- }
538
- if (options?.externalPublishProtocol) {
539
- newDevice.externalPublishProtocol = options.externalPublishProtocol;
540
- }
541
- if (options?.room) {
542
- newDevice.room = options.room;
543
- }
544
- if (typeof options?.refreshRate === "number" && Number.isFinite(options.refreshRate)) {
545
- newDevice.refreshRate = options.refreshRate;
546
- }
547
- if (typeof options?.blePollingEnabled === "boolean") {
548
- newDevice.blePollingEnabled = options.blePollingEnabled;
549
- }
550
- if (typeof options?.blePollIntervalMs === "number" && Number.isFinite(options.blePollIntervalMs)) {
551
- newDevice.blePollIntervalMs = options.blePollIntervalMs;
552
- }
553
535
  config.devices.push(newDevice);
554
536
  await homebridge.updatePluginConfig(configArr);
555
537
  if (typeof homebridge.savePluginConfig === "function") {
@@ -670,48 +652,12 @@ var init_api = __esm({
670
652
  "src/homebridge-ui/public/js/api.ts"() {
671
653
  "use strict";
672
654
  init_device_types();
673
- init_v4_detection();
674
655
  init_types();
675
656
  init_logger();
676
657
  init_toast();
677
658
  }
678
659
  });
679
660
 
680
- // src/homebridge-ui/public/js/modal.ts
681
- function callUiMethod(name, ...args) {
682
- try {
683
- if (typeof homebridge?.[name] === "function") {
684
- uiLog.info(`[callUiMethod] Invoking homebridge.${String(name)}()`);
685
- const fn = homebridge?.[name];
686
- if (typeof fn === "function") {
687
- uiLog.info(`[callUiMethod] Invoking homebridge.${String(name)}()`);
688
- fn.apply(homebridge, args);
689
- } else {
690
- uiLog.warn(`[callUiMethod] homebridge[${String(name)}] is not a function.`);
691
- }
692
- } else {
693
- uiLog.warn(`[callUiMethod] homebridge[${String(name)}] is not a function.`);
694
- }
695
- } catch (e) {
696
- uiLog.warn(`Homebridge UI method ${String(name)} failed:`, e);
697
- }
698
- }
699
- function showBusyUi() {
700
- callUiMethod("disableSaveButton");
701
- callUiMethod("showSpinner");
702
- }
703
- function hideBusyUi() {
704
- callUiMethod("hideSpinner");
705
- callUiMethod("enableSaveButton");
706
- }
707
- var init_modal = __esm({
708
- "src/homebridge-ui/public/js/modal.ts"() {
709
- "use strict";
710
- init_types();
711
- init_logger();
712
- }
713
- });
714
-
715
661
  // src/homebridge-ui/public/js/discovery.ts
716
662
  var discovery_exports = {};
717
663
  __export(discovery_exports, {
@@ -1923,27 +1869,6 @@ async function importDiscoveredDevice(device) {
1923
1869
  opt.selected = (device.connectionPreference || "auto") === val;
1924
1870
  connectionPrefSelect.appendChild(opt);
1925
1871
  });
1926
- const externalPublishLabel = document.createElement("label");
1927
- externalPublishLabel.textContent = "Publish as External Device";
1928
- externalPublishLabel.style.display = "block";
1929
- externalPublishLabel.style.marginBottom = "6px";
1930
- externalPublishLabel.style.fontWeight = "500";
1931
- externalPublishLabel.style.fontSize = "12px";
1932
- externalPublishLabel.style.color = "#6b7280";
1933
- const externalPublishSelect = document.createElement("select");
1934
- externalPublishSelect.style.width = "100%";
1935
- externalPublishSelect.style.marginBottom = "12px";
1936
- externalPublishSelect.style.padding = "8px 10px";
1937
- externalPublishSelect.style.borderRadius = "6px";
1938
- externalPublishSelect.style.fontSize = "14px";
1939
- externalPublishSelect.style.boxSizing = "border-box";
1940
- ["none", "hap", "matter"].forEach((val) => {
1941
- const opt = document.createElement("option");
1942
- opt.value = val;
1943
- opt.text = val === "none" ? "None" : val.toUpperCase();
1944
- opt.selected = (device.externalPublishProtocol || "none") === val;
1945
- externalPublishSelect.appendChild(opt);
1946
- });
1947
1872
  const roomLabel = document.createElement("label");
1948
1873
  roomLabel.textContent = "Room";
1949
1874
  roomLabel.style.display = "block";
@@ -2075,7 +2000,6 @@ async function importDiscoveredDevice(device) {
2075
2000
  configDeviceType: typeSelect.value || device.type,
2076
2001
  address: macInput.value || void 0,
2077
2002
  connectionPreference: connectionPrefSelect.value || void 0,
2078
- externalPublishProtocol: externalPublishSelect.value || "none",
2079
2003
  room: roomInput.value || void 0,
2080
2004
  encryptionKey: encryptionKeyInput.value || void 0,
2081
2005
  keyId: keyIdInput.value || void 0,
@@ -2097,8 +2021,6 @@ async function importDiscoveredDevice(device) {
2097
2021
  contentDiv.appendChild(typeSelect);
2098
2022
  contentDiv.appendChild(connectionPrefLabel);
2099
2023
  contentDiv.appendChild(connectionPrefSelect);
2100
- contentDiv.appendChild(externalPublishLabel);
2101
- contentDiv.appendChild(externalPublishSelect);
2102
2024
  contentDiv.appendChild(roomLabel);
2103
2025
  contentDiv.appendChild(roomInput);
2104
2026
  contentDiv.appendChild(macLabel);
@@ -2304,27 +2226,6 @@ async function editDevice(device) {
2304
2226
  opt.selected = (device.connectionPreference || "auto") === val;
2305
2227
  connectionPrefSelect.appendChild(opt);
2306
2228
  });
2307
- const externalPublishLabel = document.createElement("label");
2308
- externalPublishLabel.textContent = "Publish as External Device";
2309
- externalPublishLabel.style.display = "block";
2310
- externalPublishLabel.style.marginBottom = "6px";
2311
- externalPublishLabel.style.fontWeight = "500";
2312
- externalPublishLabel.style.fontSize = "12px";
2313
- externalPublishLabel.style.color = "#6b7280";
2314
- const externalPublishSelect = document.createElement("select");
2315
- externalPublishSelect.style.width = "100%";
2316
- externalPublishSelect.style.marginBottom = "12px";
2317
- externalPublishSelect.style.padding = "8px 10px";
2318
- externalPublishSelect.style.borderRadius = "6px";
2319
- externalPublishSelect.style.fontSize = "14px";
2320
- externalPublishSelect.style.boxSizing = "border-box";
2321
- ["none", "hap", "matter"].forEach((val) => {
2322
- const opt = document.createElement("option");
2323
- opt.value = val;
2324
- opt.text = val === "none" ? "None" : val.toUpperCase();
2325
- opt.selected = (device.externalPublishProtocol || "none") === val;
2326
- externalPublishSelect.appendChild(opt);
2327
- });
2328
2229
  const roomLabel = document.createElement("label");
2329
2230
  roomLabel.textContent = "Room";
2330
2231
  roomLabel.style.display = "block";
@@ -2413,7 +2314,6 @@ async function editDevice(device) {
2413
2314
  configDeviceName: nameInput.value || void 0,
2414
2315
  configDeviceType: typeSelect.value,
2415
2316
  connectionPreference: connectionPrefSelect.value,
2416
- externalPublishProtocol: externalPublishSelect.value,
2417
2317
  room: roomInput.value || void 0,
2418
2318
  encryptionKey: encryptionKeyInput.value || void 0,
2419
2319
  keyId: keyIdInput.value || void 0,
@@ -2428,9 +2328,6 @@ async function editDevice(device) {
2428
2328
  if (params.room !== void 0) {
2429
2329
  options.room = params.room;
2430
2330
  }
2431
- if (params.externalPublishProtocol !== void 0) {
2432
- options.externalPublishProtocol = params.externalPublishProtocol;
2433
- }
2434
2331
  if (params.encryptionKey !== void 0) {
2435
2332
  options.encryptionKey = params.encryptionKey;
2436
2333
  }
@@ -2475,8 +2372,6 @@ async function editDevice(device) {
2475
2372
  contentDiv.appendChild(typeSelect);
2476
2373
  contentDiv.appendChild(connectionPrefLabel);
2477
2374
  contentDiv.appendChild(connectionPrefSelect);
2478
- contentDiv.appendChild(externalPublishLabel);
2479
- contentDiv.appendChild(externalPublishSelect);
2480
2375
  contentDiv.appendChild(roomLabel);
2481
2376
  contentDiv.appendChild(roomInput);
2482
2377
  contentDiv.appendChild(encryptionKeyLabel);
@@ -3525,9 +3420,8 @@ function renderDeviceList(list) {
3525
3420
  const id = `ID: ${deviceIdentifier}`;
3526
3421
  const typeText = d.configDeviceType || d.type ? `Type: ${d.configDeviceType || d.type}` : "";
3527
3422
  const connText = d.connectionPreference ? `Conn: ${d.connectionPreference}` : "";
3528
- const extText = d.externalPublishProtocol && d.externalPublishProtocol !== "none" ? `external: ${d.externalPublishProtocol}` : "";
3529
3423
  const roomText = d.room ? `Room: ${d.room}` : "";
3530
- meta.textContent = [id, typeText, connText, extText, roomText].filter(Boolean).join(" | ");
3424
+ meta.textContent = [id, typeText, connText, roomText].filter(Boolean).join(" | ");
3531
3425
  info.appendChild(nameContainer);
3532
3426
  info.appendChild(meta);
3533
3427
  info.appendChild(expandedDetails);
@@ -3626,14 +3520,8 @@ async function addDeviceToConfig2(device, options = {}) {
3626
3520
  address: importValues.address,
3627
3521
  model: device.model,
3628
3522
  rssi: device.rssi,
3629
- connectionPreference: importValues.connectionPreference,
3630
- externalPublishProtocol: importValues.externalPublishProtocol,
3631
- room: importValues.room,
3632
3523
  encryptionKey: importValues.encryptionKey,
3633
- keyId: importValues.keyId,
3634
- refreshRate: importValues.refreshRate,
3635
- blePollingEnabled: importValues.blePollingEnabled,
3636
- blePollIntervalMs: importValues.blePollIntervalMs
3524
+ keyId: importValues.keyId
3637
3525
  });
3638
3526
  uiLog.info("Add device response:", resp);
3639
3527
  const alreadyExists = !!resp?.alreadyExists;
@@ -3704,9 +3592,6 @@ var init_devices = __esm({
3704
3592
  }
3705
3593
  });
3706
3594
 
3707
- // src/homebridge-ui/public/js/app.ts
3708
- init_api();
3709
-
3710
3595
  // src/homebridge-ui/public/js/credentials.ts
3711
3596
  init_logger();
3712
3597
  init_modal();
@@ -3744,7 +3629,7 @@ async function loadCredentialStatus() {
3744
3629
  uiLog.error("Error loading credentials:", e);
3745
3630
  }
3746
3631
  }
3747
- async function saveCredentials2() {
3632
+ async function saveCredentials() {
3748
3633
  const token = document.getElementById("token")?.value;
3749
3634
  const secret = document.getElementById("secret")?.value;
3750
3635
  const saveStatus = document.getElementById("saveStatus");
@@ -3766,19 +3651,14 @@ async function saveCredentials2() {
3766
3651
  if (typeof homebridge.getPluginConfig !== "function" || typeof homebridge.updatePluginConfig !== "function") {
3767
3652
  throw new TypeError("Homebridge UI API not available");
3768
3653
  }
3769
- let configArr = await homebridge.getPluginConfig();
3770
- if (!Array.isArray(configArr)) {
3771
- configArr = [];
3772
- }
3773
- let idx = configArr.findIndex((c) => (c.platform || c.name || "").toLowerCase() === "switchbot");
3774
- if (idx === -1) {
3775
- configArr.push({ platform: "SwitchBot" });
3776
- idx = configArr.length - 1;
3654
+ const configArr = await homebridge.getPluginConfig();
3655
+ if (!Array.isArray(configArr) || configArr.length === 0) {
3656
+ throw new Error("No plugin config found");
3777
3657
  }
3778
- const config = configArr[idx];
3658
+ const config = configArr[0];
3779
3659
  config.openApiToken = token;
3780
3660
  config.openApiSecret = secret;
3781
- await homebridge.updatePluginConfig(configArr);
3661
+ await homebridge.updatePluginConfig([config]);
3782
3662
  if (typeof homebridge.savePluginConfig === "function") {
3783
3663
  await homebridge.savePluginConfig();
3784
3664
  }
@@ -3808,42 +3688,10 @@ async function saveCredentials2() {
3808
3688
  // src/homebridge-ui/public/js/app.ts
3809
3689
  init_devices();
3810
3690
  init_discovery();
3811
- async function ensureSwitchBotConfigBlock() {
3812
- try {
3813
- if (typeof homebridge.getPluginConfig !== "function" || typeof homebridge.updatePluginConfig !== "function") {
3814
- return;
3815
- }
3816
- let configArr = await homebridge.getPluginConfig();
3817
- if (!Array.isArray(configArr)) {
3818
- configArr = [];
3819
- }
3820
- const idx = configArr.findIndex((c) => (c.platform || c.name || "").toLowerCase().includes("switchbot"));
3821
- if (idx === -1) {
3822
- configArr.push({ platform: "SwitchBot" });
3823
- await homebridge.updatePluginConfig(configArr);
3824
- if (typeof homebridge.savePluginConfig === "function") {
3825
- await homebridge.savePluginConfig();
3826
- }
3827
- }
3828
- } catch (_e) {
3829
- }
3830
- }
3831
3691
  window.loadCredentialStatus = loadCredentialStatus;
3832
- window.saveCredentials = saveCredentials2;
3692
+ window.saveCredentials = saveCredentials;
3833
3693
  window.discoverDevices = discoverDevices2;
3834
- async function checkV4Config() {
3835
- const banner = document.getElementById("v4ConfigWarning");
3836
- if (!banner) {
3837
- return;
3838
- }
3839
- const isV4 = await detectV4Config();
3840
- if (isV4) {
3841
- banner.style.display = "block";
3842
- }
3843
- }
3844
3694
  async function init() {
3845
- await ensureSwitchBotConfigBlock();
3846
- await checkV4Config();
3847
3695
  await loadCredentialStatus();
3848
3696
  await initializeDiscoverySettings();
3849
3697
  await loadConfiguredDevices();