@switchbot/homebridge-switchbot 5.1.0-beta.9 → 5.1.1
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/.github/copilot-instructions.md +0 -63
- package/.github/scripts/compute-version-override.cjs +51 -0
- package/.github/scripts/normalize-changelog-header.cjs +1 -1
- package/.github/scripts/npm-version-script-esm-auto.js +1 -1
- package/.github/scripts/resolve-version-bump-esm.js +1 -1
- package/CHANGELOG.md +32 -9
- package/MIGRATION.md +0 -5
- package/README.md +0 -25
- package/config.schema.json +0 -11
- package/dist/{Platform.HAP.d.ts → SwitchBotHAPPlatform.d.ts} +16 -2
- package/dist/SwitchBotHAPPlatform.d.ts.map +1 -0
- package/dist/{Platform.HAP.js → SwitchBotHAPPlatform.js} +111 -40
- package/dist/SwitchBotHAPPlatform.js.map +1 -0
- package/dist/{Platform.Matter.d.ts → SwitchBotMatterPlatform.d.ts} +2 -4
- package/dist/SwitchBotMatterPlatform.d.ts.map +1 -0
- package/dist/{Platform.Matter.js → SwitchBotMatterPlatform.js} +6 -62
- package/dist/SwitchBotMatterPlatform.js.map +1 -0
- package/dist/device-types.d.ts.map +1 -1
- package/dist/device-types.js +10 -0
- package/dist/device-types.js.map +1 -1
- package/dist/deviceFactory.d.ts.map +1 -1
- package/dist/deviceFactory.js +10 -16
- package/dist/deviceFactory.js.map +1 -1
- package/dist/devices/genericDevice.d.ts +63 -5
- package/dist/devices/genericDevice.d.ts.map +1 -1
- package/dist/devices/genericDevice.js +251 -11
- package/dist/devices/genericDevice.js.map +1 -1
- package/dist/homebridge-ui/device-types.js +10 -0
- package/dist/homebridge-ui/device-types.js.map +1 -1
- package/dist/homebridge-ui/endpoints/config.d.ts.map +1 -1
- package/dist/homebridge-ui/endpoints/config.js +2 -9
- package/dist/homebridge-ui/endpoints/config.js.map +1 -1
- package/dist/homebridge-ui/homebridge-ui/endpoints/config.js +2 -9
- package/dist/homebridge-ui/homebridge-ui/endpoints/config.js.map +1 -1
- package/dist/homebridge-ui/homebridge-ui/utils/config-parser.js +0 -8
- package/dist/homebridge-ui/homebridge-ui/utils/config-parser.js.map +1 -1
- package/dist/homebridge-ui/public/css/styles.css +1 -61
- package/dist/homebridge-ui/public/index.html +2 -61
- package/dist/homebridge-ui/public/js/advanced-settings.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/advanced-settings.js +3 -4
- package/dist/homebridge-ui/public/js/advanced-settings.js.map +1 -1
- package/dist/homebridge-ui/public/js/advanced-settings.ts +3 -4
- package/dist/homebridge-ui/public/js/api.d.ts +0 -16
- package/dist/homebridge-ui/public/js/api.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/api.js +0 -48
- package/dist/homebridge-ui/public/js/api.js.map +1 -1
- package/dist/homebridge-ui/public/js/api.ts +1 -61
- package/dist/homebridge-ui/public/js/app.js +135 -272
- package/dist/homebridge-ui/public/js/app.js.map +4 -4
- package/dist/homebridge-ui/public/js/app.ts +4 -47
- package/dist/homebridge-ui/public/js/credentials.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/credentials.js +5 -11
- package/dist/homebridge-ui/public/js/credentials.js.map +1 -1
- package/dist/homebridge-ui/public/js/credentials.ts +5 -11
- package/dist/homebridge-ui/public/js/devices.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/devices.js +0 -6
- package/dist/homebridge-ui/public/js/devices.js.map +1 -1
- package/dist/homebridge-ui/public/js/devices.ts +0 -6
- package/dist/homebridge-ui/public/js/modals.d.ts +0 -1
- package/dist/homebridge-ui/public/js/modals.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/modals.js +0 -53
- package/dist/homebridge-ui/public/js/modals.js.map +1 -1
- package/dist/homebridge-ui/public/js/modals.ts +0 -58
- package/dist/homebridge-ui/public/js/render.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/render.js +1 -2
- package/dist/homebridge-ui/public/js/render.js.map +1 -1
- package/dist/homebridge-ui/public/js/render.ts +1 -2
- package/dist/homebridge-ui/settings.js.map +1 -1
- package/dist/homebridge-ui/utils/config-parser.d.ts +0 -8
- package/dist/homebridge-ui/utils/config-parser.d.ts.map +1 -1
- package/dist/homebridge-ui/utils/config-parser.js +0 -8
- package/dist/homebridge-ui/utils/config-parser.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/settings.d.ts +0 -11
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js.map +1 -1
- package/dist/utils.d.ts +0 -5
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +0 -27
- package/dist/utils.js.map +1 -1
- package/docs/assets/highlight.css +16 -16
- package/docs/assets/main.js +1 -1
- package/docs/assets/style.css +18 -3
- package/docs/hierarchy.html +26 -1
- package/docs/index.html +70 -23
- package/docs/modules.html +33 -1
- package/docs/variables/default.html +46 -3
- package/package.json +22 -15
- package/scripts/build-ui.js +0 -30
- package/src/{Platform.HAP.ts → SwitchBotHAPPlatform.ts} +112 -39
- package/src/{Platform.Matter.ts → SwitchBotMatterPlatform.ts} +8 -63
- package/src/device-types.ts +11 -0
- package/src/deviceFactory.ts +10 -15
- package/src/devices/genericDevice.ts +271 -12
- package/src/homebridge-ui/endpoints/config.ts +2 -10
- package/src/homebridge-ui/public/css/styles.css +1 -61
- package/src/homebridge-ui/public/index.html +0 -59
- package/src/homebridge-ui/public/js/advanced-settings.ts +3 -4
- package/src/homebridge-ui/public/js/api.ts +1 -61
- package/src/homebridge-ui/public/js/app.ts +4 -47
- package/src/homebridge-ui/public/js/credentials.ts +5 -11
- package/src/homebridge-ui/public/js/devices.ts +0 -6
- package/src/homebridge-ui/public/js/modals.ts +0 -58
- package/src/homebridge-ui/public/js/render.ts +1 -2
- package/src/homebridge-ui/utils/config-parser.ts +0 -9
- package/src/index.ts +2 -2
- package/src/settings.ts +0 -12
- package/src/utils.ts +0 -31
- package/test/device/deviceFactory.spec.ts +9 -0
- package/test/device/getstate-cache.spec.ts +62 -0
- package/test/device/getstate-returns-status.spec.ts +89 -0
- package/test/device/model-identities.spec.ts +45 -0
- package/test/device/water-detector-battery.spec.ts +81 -0
- package/test/device/water-detector-leak.spec.ts +43 -0
- package/test/hap-push-updates.spec.ts +150 -0
- package/test/platform/accessory-restore.spec.ts +2 -2
- package/test/platform/matter-childbridge.spec.ts +1 -1
- package/test/platform/matter-integration.spec.ts +1 -51
- package/test/platform/platform-edge.spec.ts +2 -2
- package/test/platform/platform.integration.spec.ts +1 -1
- package/test/utils/utils.spec.ts +0 -15
- package/.github/npm-version-script-esm.js +0 -97
- package/dist/Platform.HAP.d.ts.map +0 -1
- package/dist/Platform.HAP.js.map +0 -1
- package/dist/Platform.Matter.d.ts.map +0 -1
- package/dist/Platform.Matter.js.map +0 -1
- package/dist/homebridge-ui/homebridge-ui/utils/v4-detection.js +0 -23
- package/dist/homebridge-ui/homebridge-ui/utils/v4-detection.js.map +0 -1
- package/dist/homebridge-ui/public/js/legacy-view.d.ts +0 -3
- package/dist/homebridge-ui/public/js/legacy-view.d.ts.map +0 -1
- package/dist/homebridge-ui/public/js/legacy-view.js +0 -45
- package/dist/homebridge-ui/public/js/legacy-view.js.map +0 -1
- package/dist/homebridge-ui/public/js/legacy-view.ts +0 -107
- package/dist/homebridge-ui/utils/v4-detection.d.ts +0 -12
- package/dist/homebridge-ui/utils/v4-detection.d.ts.map +0 -1
- package/dist/homebridge-ui/utils/v4-detection.js +0 -23
- package/dist/homebridge-ui/utils/v4-detection.js.map +0 -1
- package/src/device-types.js +0 -246
- package/src/homebridge-ui/public/js/legacy-view.js +0 -45
- package/src/homebridge-ui/public/js/legacy-view.ts +0 -107
- package/src/homebridge-ui/utils/v4-detection.ts +0 -23
- package/test/homebridge-ui/config-parser.spec.ts +0 -61
|
@@ -1,14 +1,123 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
-
var __esm = (fn, res) => function __init() {
|
|
4
|
-
|
|
3
|
+
var __esm = (fn, res, err) => function __init() {
|
|
4
|
+
if (err) throw err[0];
|
|
5
|
+
try {
|
|
6
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
|
+
} catch (e) {
|
|
8
|
+
throw err = [e], e;
|
|
9
|
+
}
|
|
5
10
|
};
|
|
6
11
|
var __export = (target, all) => {
|
|
7
12
|
for (var name in all)
|
|
8
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
14
|
};
|
|
10
15
|
|
|
11
|
-
// src/
|
|
16
|
+
// src/homebridge-ui/public/js/logger.ts
|
|
17
|
+
var PREFIX, uiLog;
|
|
18
|
+
var init_logger = __esm({
|
|
19
|
+
"src/homebridge-ui/public/js/logger.ts"() {
|
|
20
|
+
"use strict";
|
|
21
|
+
PREFIX = "[SwitchBot UI/html]";
|
|
22
|
+
uiLog = {
|
|
23
|
+
info: (message, ...parameters) => {
|
|
24
|
+
console.log(PREFIX, message, ...parameters);
|
|
25
|
+
},
|
|
26
|
+
warn: (message, ...parameters) => {
|
|
27
|
+
console.warn(PREFIX, message, ...parameters);
|
|
28
|
+
},
|
|
29
|
+
error: (message, ...parameters) => {
|
|
30
|
+
console.error(PREFIX, message, ...parameters);
|
|
31
|
+
},
|
|
32
|
+
debug: (message, ...parameters) => {
|
|
33
|
+
console.debug(PREFIX, message, ...parameters);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// src/homebridge-ui/public/js/types.ts
|
|
40
|
+
var init_types = __esm({
|
|
41
|
+
"src/homebridge-ui/public/js/types.ts"() {
|
|
42
|
+
"use strict";
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// src/homebridge-ui/public/js/modal.ts
|
|
47
|
+
function callUiMethod(name, ...args) {
|
|
48
|
+
try {
|
|
49
|
+
if (typeof homebridge?.[name] === "function") {
|
|
50
|
+
uiLog.info(`[callUiMethod] Invoking homebridge.${String(name)}()`);
|
|
51
|
+
const fn = homebridge?.[name];
|
|
52
|
+
if (typeof fn === "function") {
|
|
53
|
+
uiLog.info(`[callUiMethod] Invoking homebridge.${String(name)}()`);
|
|
54
|
+
fn.apply(homebridge, args);
|
|
55
|
+
} else {
|
|
56
|
+
uiLog.warn(`[callUiMethod] homebridge[${String(name)}] is not a function.`);
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
uiLog.warn(`[callUiMethod] homebridge[${String(name)}] is not a function.`);
|
|
60
|
+
}
|
|
61
|
+
} catch (e) {
|
|
62
|
+
uiLog.warn(`Homebridge UI method ${String(name)} failed:`, e);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function showBusyUi() {
|
|
66
|
+
callUiMethod("disableSaveButton");
|
|
67
|
+
callUiMethod("showSpinner");
|
|
68
|
+
}
|
|
69
|
+
function hideBusyUi() {
|
|
70
|
+
callUiMethod("hideSpinner");
|
|
71
|
+
callUiMethod("enableSaveButton");
|
|
72
|
+
}
|
|
73
|
+
var init_modal = __esm({
|
|
74
|
+
"src/homebridge-ui/public/js/modal.ts"() {
|
|
75
|
+
"use strict";
|
|
76
|
+
init_types();
|
|
77
|
+
init_logger();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// src/homebridge-ui/public/js/toast.ts
|
|
82
|
+
function showToast(method, message, title = "SwitchBot") {
|
|
83
|
+
try {
|
|
84
|
+
const hb = typeof window !== "undefined" ? window.homebridge : void 0;
|
|
85
|
+
const toast = hb && typeof hb.toast === "object" ? hb.toast : void 0;
|
|
86
|
+
if (toast && typeof toast[method] === "function") {
|
|
87
|
+
try {
|
|
88
|
+
toast[method](message, title);
|
|
89
|
+
return;
|
|
90
|
+
} catch (err) {
|
|
91
|
+
uiLog.warn(`Toast ${method} threw:`, err);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
uiLog.info(`[Toast:${method}] ${title} - ${message}`);
|
|
95
|
+
} catch (e) {
|
|
96
|
+
uiLog.warn(`Toast ${method} outer error:`, e);
|
|
97
|
+
uiLog.info(`[Toast:${method}] ${title} - ${message}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function toastSuccess(message, title) {
|
|
101
|
+
showToast("success", message, title);
|
|
102
|
+
}
|
|
103
|
+
function toastError(message, title) {
|
|
104
|
+
showToast("error", message, title);
|
|
105
|
+
}
|
|
106
|
+
function toastWarning(message, title) {
|
|
107
|
+
showToast("warning", message, title);
|
|
108
|
+
}
|
|
109
|
+
function toastInfo(message, title) {
|
|
110
|
+
showToast("info", message, title);
|
|
111
|
+
}
|
|
112
|
+
var init_toast = __esm({
|
|
113
|
+
"src/homebridge-ui/public/js/toast.ts"() {
|
|
114
|
+
"use strict";
|
|
115
|
+
init_types();
|
|
116
|
+
init_logger();
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// src/device-types.ts
|
|
12
121
|
function getValidDeviceTypes() {
|
|
13
122
|
const validTypes = /* @__PURE__ */ new Set();
|
|
14
123
|
for (const category of Object.values(DEVICE_TYPES)) {
|
|
@@ -43,7 +152,7 @@ function isValidDeviceType(deviceType) {
|
|
|
43
152
|
}
|
|
44
153
|
var DEVICE_TYPES, DEVICE_TYPE_NORMALIZATION_MAP;
|
|
45
154
|
var init_device_types = __esm({
|
|
46
|
-
"src/device-types.
|
|
155
|
+
"src/device-types.ts"() {
|
|
47
156
|
"use strict";
|
|
48
157
|
DEVICE_TYPES = {
|
|
49
158
|
"Window Coverings": ["Blind Tilt", "Curtain", "Curtain3", "Roller Shade"],
|
|
@@ -232,7 +341,17 @@ var init_device_types = __esm({
|
|
|
232
341
|
"lock touch": "Keypad Touch",
|
|
233
342
|
// Invalid type
|
|
234
343
|
// Additional normalization for new/unknown types from logs
|
|
235
|
-
"woplugus": "Plug Mini (US)"
|
|
344
|
+
"woplugus": "Plug Mini (US)",
|
|
345
|
+
// Product-specific identities reported by node-switchbot 5 (pySwitchbot 3.0.0 parity)
|
|
346
|
+
"woplugjp": "Plug Mini (JP)",
|
|
347
|
+
"wocurtain3": "Curtain3",
|
|
348
|
+
"wometerplus": "Meter Plus",
|
|
349
|
+
"wothpc": "Meter Pro (CO2)",
|
|
350
|
+
"woceilingpro": "Ceiling Light Pro",
|
|
351
|
+
"wolinkmini": "Hub Mini",
|
|
352
|
+
"woiosensorth": "WoIOSensor",
|
|
353
|
+
"outdoor meter": "WoIOSensor",
|
|
354
|
+
"indoor/outdoor thermo-hygrometer": "WoIOSensor"
|
|
236
355
|
// Removed duplicate keys below, only last occurrence kept
|
|
237
356
|
// 'plug mini us': 'plug mini (us)', // duplicate, removed
|
|
238
357
|
// 'plug us': 'plug mini (us)', // duplicate, removed
|
|
@@ -249,90 +368,6 @@ var init_device_types = __esm({
|
|
|
249
368
|
}
|
|
250
369
|
});
|
|
251
370
|
|
|
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
371
|
// src/homebridge-ui/public/js/api.ts
|
|
337
372
|
var api_exports = {};
|
|
338
373
|
__export(api_exports, {
|
|
@@ -340,13 +375,12 @@ __export(api_exports, {
|
|
|
340
375
|
addDevicesInBulk: () => addDevicesInBulk,
|
|
341
376
|
deleteAllDevices: () => deleteAllDevices,
|
|
342
377
|
deleteDevice: () => deleteDevice,
|
|
343
|
-
detectV4Config: () => detectV4Config,
|
|
344
378
|
discoverDevices: () => discoverDevices,
|
|
345
379
|
fetchBluetoothStatus: () => fetchBluetoothStatus,
|
|
346
380
|
fetchCredentialStatus: () => fetchCredentialStatus,
|
|
347
381
|
fetchDevices: () => fetchDevices,
|
|
348
382
|
normalizeBulkAddDevicesResponse: () => normalizeBulkAddDevicesResponse,
|
|
349
|
-
saveCredentials: () =>
|
|
383
|
+
saveCredentials: () => saveCredentials2,
|
|
350
384
|
syncParentPluginConfigFromDisk: () => syncParentPluginConfigFromDisk,
|
|
351
385
|
testDeviceConnection: () => testDeviceConnection,
|
|
352
386
|
updateDevice: () => updateDevice,
|
|
@@ -369,25 +403,6 @@ async function fetchDevices() {
|
|
|
369
403
|
return [];
|
|
370
404
|
}
|
|
371
405
|
}
|
|
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
406
|
function validateAndFixDeviceTypes(devices) {
|
|
392
407
|
const errors = [];
|
|
393
408
|
for (const d of devices) {
|
|
@@ -457,7 +472,7 @@ async function fetchCredentialStatus() {
|
|
|
457
472
|
return null;
|
|
458
473
|
}
|
|
459
474
|
}
|
|
460
|
-
async function
|
|
475
|
+
async function saveCredentials2(token, secret) {
|
|
461
476
|
uiLog.info("Saving credentials...");
|
|
462
477
|
const resp = await homebridge.request("/credentials", { token, secret });
|
|
463
478
|
uiLog.info("Save response:", resp);
|
|
@@ -532,24 +547,6 @@ async function addDevice(deviceId, name, type, options) {
|
|
|
532
547
|
if (options?.keyId) {
|
|
533
548
|
newDevice.keyId = options.keyId;
|
|
534
549
|
}
|
|
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
550
|
config.devices.push(newDevice);
|
|
554
551
|
await homebridge.updatePluginConfig(configArr);
|
|
555
552
|
if (typeof homebridge.savePluginConfig === "function") {
|
|
@@ -670,48 +667,12 @@ var init_api = __esm({
|
|
|
670
667
|
"src/homebridge-ui/public/js/api.ts"() {
|
|
671
668
|
"use strict";
|
|
672
669
|
init_device_types();
|
|
673
|
-
init_v4_detection();
|
|
674
670
|
init_types();
|
|
675
671
|
init_logger();
|
|
676
672
|
init_toast();
|
|
677
673
|
}
|
|
678
674
|
});
|
|
679
675
|
|
|
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
676
|
// src/homebridge-ui/public/js/discovery.ts
|
|
716
677
|
var discovery_exports = {};
|
|
717
678
|
__export(discovery_exports, {
|
|
@@ -1923,27 +1884,6 @@ async function importDiscoveredDevice(device) {
|
|
|
1923
1884
|
opt.selected = (device.connectionPreference || "auto") === val;
|
|
1924
1885
|
connectionPrefSelect.appendChild(opt);
|
|
1925
1886
|
});
|
|
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
1887
|
const roomLabel = document.createElement("label");
|
|
1948
1888
|
roomLabel.textContent = "Room";
|
|
1949
1889
|
roomLabel.style.display = "block";
|
|
@@ -2075,7 +2015,6 @@ async function importDiscoveredDevice(device) {
|
|
|
2075
2015
|
configDeviceType: typeSelect.value || device.type,
|
|
2076
2016
|
address: macInput.value || void 0,
|
|
2077
2017
|
connectionPreference: connectionPrefSelect.value || void 0,
|
|
2078
|
-
externalPublishProtocol: externalPublishSelect.value || "none",
|
|
2079
2018
|
room: roomInput.value || void 0,
|
|
2080
2019
|
encryptionKey: encryptionKeyInput.value || void 0,
|
|
2081
2020
|
keyId: keyIdInput.value || void 0,
|
|
@@ -2097,8 +2036,6 @@ async function importDiscoveredDevice(device) {
|
|
|
2097
2036
|
contentDiv.appendChild(typeSelect);
|
|
2098
2037
|
contentDiv.appendChild(connectionPrefLabel);
|
|
2099
2038
|
contentDiv.appendChild(connectionPrefSelect);
|
|
2100
|
-
contentDiv.appendChild(externalPublishLabel);
|
|
2101
|
-
contentDiv.appendChild(externalPublishSelect);
|
|
2102
2039
|
contentDiv.appendChild(roomLabel);
|
|
2103
2040
|
contentDiv.appendChild(roomInput);
|
|
2104
2041
|
contentDiv.appendChild(macLabel);
|
|
@@ -2304,27 +2241,6 @@ async function editDevice(device) {
|
|
|
2304
2241
|
opt.selected = (device.connectionPreference || "auto") === val;
|
|
2305
2242
|
connectionPrefSelect.appendChild(opt);
|
|
2306
2243
|
});
|
|
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
2244
|
const roomLabel = document.createElement("label");
|
|
2329
2245
|
roomLabel.textContent = "Room";
|
|
2330
2246
|
roomLabel.style.display = "block";
|
|
@@ -2413,7 +2329,6 @@ async function editDevice(device) {
|
|
|
2413
2329
|
configDeviceName: nameInput.value || void 0,
|
|
2414
2330
|
configDeviceType: typeSelect.value,
|
|
2415
2331
|
connectionPreference: connectionPrefSelect.value,
|
|
2416
|
-
externalPublishProtocol: externalPublishSelect.value,
|
|
2417
2332
|
room: roomInput.value || void 0,
|
|
2418
2333
|
encryptionKey: encryptionKeyInput.value || void 0,
|
|
2419
2334
|
keyId: keyIdInput.value || void 0,
|
|
@@ -2428,9 +2343,6 @@ async function editDevice(device) {
|
|
|
2428
2343
|
if (params.room !== void 0) {
|
|
2429
2344
|
options.room = params.room;
|
|
2430
2345
|
}
|
|
2431
|
-
if (params.externalPublishProtocol !== void 0) {
|
|
2432
|
-
options.externalPublishProtocol = params.externalPublishProtocol;
|
|
2433
|
-
}
|
|
2434
2346
|
if (params.encryptionKey !== void 0) {
|
|
2435
2347
|
options.encryptionKey = params.encryptionKey;
|
|
2436
2348
|
}
|
|
@@ -2475,8 +2387,6 @@ async function editDevice(device) {
|
|
|
2475
2387
|
contentDiv.appendChild(typeSelect);
|
|
2476
2388
|
contentDiv.appendChild(connectionPrefLabel);
|
|
2477
2389
|
contentDiv.appendChild(connectionPrefSelect);
|
|
2478
|
-
contentDiv.appendChild(externalPublishLabel);
|
|
2479
|
-
contentDiv.appendChild(externalPublishSelect);
|
|
2480
2390
|
contentDiv.appendChild(roomLabel);
|
|
2481
2391
|
contentDiv.appendChild(roomInput);
|
|
2482
2392
|
contentDiv.appendChild(encryptionKeyLabel);
|
|
@@ -3525,9 +3435,8 @@ function renderDeviceList(list) {
|
|
|
3525
3435
|
const id = `ID: ${deviceIdentifier}`;
|
|
3526
3436
|
const typeText = d.configDeviceType || d.type ? `Type: ${d.configDeviceType || d.type}` : "";
|
|
3527
3437
|
const connText = d.connectionPreference ? `Conn: ${d.connectionPreference}` : "";
|
|
3528
|
-
const extText = d.externalPublishProtocol && d.externalPublishProtocol !== "none" ? `external: ${d.externalPublishProtocol}` : "";
|
|
3529
3438
|
const roomText = d.room ? `Room: ${d.room}` : "";
|
|
3530
|
-
meta.textContent = [id, typeText, connText,
|
|
3439
|
+
meta.textContent = [id, typeText, connText, roomText].filter(Boolean).join(" | ");
|
|
3531
3440
|
info.appendChild(nameContainer);
|
|
3532
3441
|
info.appendChild(meta);
|
|
3533
3442
|
info.appendChild(expandedDetails);
|
|
@@ -3626,14 +3535,8 @@ async function addDeviceToConfig2(device, options = {}) {
|
|
|
3626
3535
|
address: importValues.address,
|
|
3627
3536
|
model: device.model,
|
|
3628
3537
|
rssi: device.rssi,
|
|
3629
|
-
connectionPreference: importValues.connectionPreference,
|
|
3630
|
-
externalPublishProtocol: importValues.externalPublishProtocol,
|
|
3631
|
-
room: importValues.room,
|
|
3632
3538
|
encryptionKey: importValues.encryptionKey,
|
|
3633
|
-
keyId: importValues.keyId
|
|
3634
|
-
refreshRate: importValues.refreshRate,
|
|
3635
|
-
blePollingEnabled: importValues.blePollingEnabled,
|
|
3636
|
-
blePollIntervalMs: importValues.blePollIntervalMs
|
|
3539
|
+
keyId: importValues.keyId
|
|
3637
3540
|
});
|
|
3638
3541
|
uiLog.info("Add device response:", resp);
|
|
3639
3542
|
const alreadyExists = !!resp?.alreadyExists;
|
|
@@ -3704,9 +3607,6 @@ var init_devices = __esm({
|
|
|
3704
3607
|
}
|
|
3705
3608
|
});
|
|
3706
3609
|
|
|
3707
|
-
// src/homebridge-ui/public/js/app.ts
|
|
3708
|
-
init_api();
|
|
3709
|
-
|
|
3710
3610
|
// src/homebridge-ui/public/js/credentials.ts
|
|
3711
3611
|
init_logger();
|
|
3712
3612
|
init_modal();
|
|
@@ -3744,7 +3644,7 @@ async function loadCredentialStatus() {
|
|
|
3744
3644
|
uiLog.error("Error loading credentials:", e);
|
|
3745
3645
|
}
|
|
3746
3646
|
}
|
|
3747
|
-
async function
|
|
3647
|
+
async function saveCredentials() {
|
|
3748
3648
|
const token = document.getElementById("token")?.value;
|
|
3749
3649
|
const secret = document.getElementById("secret")?.value;
|
|
3750
3650
|
const saveStatus = document.getElementById("saveStatus");
|
|
@@ -3766,19 +3666,14 @@ async function saveCredentials2() {
|
|
|
3766
3666
|
if (typeof homebridge.getPluginConfig !== "function" || typeof homebridge.updatePluginConfig !== "function") {
|
|
3767
3667
|
throw new TypeError("Homebridge UI API not available");
|
|
3768
3668
|
}
|
|
3769
|
-
|
|
3770
|
-
if (!Array.isArray(configArr)) {
|
|
3771
|
-
|
|
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;
|
|
3669
|
+
const configArr = await homebridge.getPluginConfig();
|
|
3670
|
+
if (!Array.isArray(configArr) || configArr.length === 0) {
|
|
3671
|
+
throw new Error("No plugin config found");
|
|
3777
3672
|
}
|
|
3778
|
-
const config = configArr[
|
|
3673
|
+
const config = configArr[0];
|
|
3779
3674
|
config.openApiToken = token;
|
|
3780
3675
|
config.openApiSecret = secret;
|
|
3781
|
-
await homebridge.updatePluginConfig(
|
|
3676
|
+
await homebridge.updatePluginConfig([config]);
|
|
3782
3677
|
if (typeof homebridge.savePluginConfig === "function") {
|
|
3783
3678
|
await homebridge.savePluginConfig();
|
|
3784
3679
|
}
|
|
@@ -3808,42 +3703,10 @@ async function saveCredentials2() {
|
|
|
3808
3703
|
// src/homebridge-ui/public/js/app.ts
|
|
3809
3704
|
init_devices();
|
|
3810
3705
|
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
3706
|
window.loadCredentialStatus = loadCredentialStatus;
|
|
3832
|
-
window.saveCredentials =
|
|
3707
|
+
window.saveCredentials = saveCredentials;
|
|
3833
3708
|
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
3709
|
async function init() {
|
|
3845
|
-
await ensureSwitchBotConfigBlock();
|
|
3846
|
-
await checkV4Config();
|
|
3847
3710
|
await loadCredentialStatus();
|
|
3848
3711
|
await initializeDiscoverySettings();
|
|
3849
3712
|
await loadConfiguredDevices();
|