@switchbot/homebridge-switchbot 5.0.0-beta.115 → 5.0.0-beta.117
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/dist/deviceFactory.d.ts.map +1 -1
- package/dist/deviceFactory.js +4 -2
- package/dist/deviceFactory.js.map +1 -1
- package/dist/homebridge-ui/endpoints/config.d.ts.map +1 -1
- package/dist/homebridge-ui/endpoints/config.js +9 -6
- package/dist/homebridge-ui/endpoints/config.js.map +1 -1
- package/dist/homebridge-ui/public/js/api.d.ts +15 -2
- package/dist/homebridge-ui/public/js/api.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/api.js +99 -99
- package/dist/homebridge-ui/public/js/api.js.map +1 -1
- package/dist/homebridge-ui/public/js/api.ts +105 -97
- package/dist/homebridge-ui/public/js/app.js +342 -200
- package/dist/homebridge-ui/public/js/app.js.map +3 -3
- package/dist/homebridge-ui/public/js/devices.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/devices.js +4 -3
- package/dist/homebridge-ui/public/js/devices.js.map +1 -1
- package/dist/homebridge-ui/public/js/devices.ts +4 -3
- package/dist/platform.d.ts +4 -1
- package/dist/platform.d.ts.map +1 -1
- package/dist/platform.js +55 -36
- package/dist/platform.js.map +1 -1
- package/docs/variables/default.html +1 -1
- package/package.json +1 -1
- package/src/deviceFactory.ts +6 -3
- package/src/homebridge-ui/endpoints/config.ts +9 -6
- package/src/homebridge-ui/public/js/api.ts +105 -97
- package/src/homebridge-ui/public/js/devices.ts +4 -3
- package/src/platform.ts +57 -35
- package/test/matter-integration.spec.ts +1 -1
|
@@ -8,6 +8,251 @@ var __export = (target, all) => {
|
|
|
8
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
// src/device-types.ts
|
|
12
|
+
function getValidDeviceTypes() {
|
|
13
|
+
const validTypes = /* @__PURE__ */ new Set();
|
|
14
|
+
for (const category of Object.values(DEVICE_TYPES)) {
|
|
15
|
+
for (const type of category) {
|
|
16
|
+
validTypes.add(type);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return validTypes;
|
|
20
|
+
}
|
|
21
|
+
function normalizeDeviceType(deviceType) {
|
|
22
|
+
if (!deviceType || typeof deviceType !== "string") {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const trimmed = deviceType.trim();
|
|
26
|
+
const lowercase = trimmed.toLowerCase();
|
|
27
|
+
const validTypes = getValidDeviceTypes();
|
|
28
|
+
if (validTypes.has(trimmed)) {
|
|
29
|
+
return trimmed;
|
|
30
|
+
}
|
|
31
|
+
const normalized = DEVICE_TYPE_NORMALIZATION_MAP[lowercase];
|
|
32
|
+
if (normalized && validTypes.has(normalized)) {
|
|
33
|
+
return normalized;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
function isValidDeviceType(deviceType) {
|
|
38
|
+
if (!deviceType || typeof deviceType !== "string") {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
const validTypes = getValidDeviceTypes();
|
|
42
|
+
return validTypes.has(deviceType.trim());
|
|
43
|
+
}
|
|
44
|
+
var DEVICE_TYPES, DEVICE_TYPE_NORMALIZATION_MAP;
|
|
45
|
+
var init_device_types = __esm({
|
|
46
|
+
"src/device-types.ts"() {
|
|
47
|
+
"use strict";
|
|
48
|
+
DEVICE_TYPES = {
|
|
49
|
+
"Window Coverings": ["Blind Tilt", "Curtain", "Curtain3", "Roller Shade"],
|
|
50
|
+
"Locks & Access": [
|
|
51
|
+
"Keypad",
|
|
52
|
+
"Keypad Touch",
|
|
53
|
+
"Keypad Vision",
|
|
54
|
+
"Keypad Vision Pro",
|
|
55
|
+
"Lock Vision Pro",
|
|
56
|
+
"Lock Lite",
|
|
57
|
+
"Smart Lock",
|
|
58
|
+
"Smart Lock Pro",
|
|
59
|
+
"Smart Lock Ultra",
|
|
60
|
+
"Video Doorbell"
|
|
61
|
+
],
|
|
62
|
+
"Sensors": ["Contact Sensor", "Motion Sensor", "Presence Sensor", "Water Detector"],
|
|
63
|
+
"Lighting": [
|
|
64
|
+
"Candle Warmer Lamp",
|
|
65
|
+
"Ceiling Light",
|
|
66
|
+
"Ceiling Light Pro",
|
|
67
|
+
"Color Bulb",
|
|
68
|
+
"Floor Lamp",
|
|
69
|
+
"RGBIC Neon Rope Light",
|
|
70
|
+
"RGBIC Neon Wire Rope Light",
|
|
71
|
+
"RGBICWW Floor Lamp",
|
|
72
|
+
"RGBICWW Strip Light",
|
|
73
|
+
"Strip Light",
|
|
74
|
+
"Strip Light 3"
|
|
75
|
+
],
|
|
76
|
+
"Climate Control": [
|
|
77
|
+
"Air Purifier PM2.5",
|
|
78
|
+
"Air Purifier Table PM2.5",
|
|
79
|
+
"Air Purifier VOC",
|
|
80
|
+
"Air Purifier Table VOC",
|
|
81
|
+
"Battery Circulator Fan",
|
|
82
|
+
"Circulator Fan",
|
|
83
|
+
"Humidifier",
|
|
84
|
+
"Humidifier2",
|
|
85
|
+
"Meter",
|
|
86
|
+
"MeterPlus",
|
|
87
|
+
"Meter Plus",
|
|
88
|
+
"MeterPro",
|
|
89
|
+
"Meter Pro",
|
|
90
|
+
"MeterPro(CO2)",
|
|
91
|
+
"Meter Pro (CO2)",
|
|
92
|
+
"Smart Radiator Thermostat",
|
|
93
|
+
"Standing Circulator Fan",
|
|
94
|
+
"WoIOSensor"
|
|
95
|
+
],
|
|
96
|
+
"Plugs & Switches": [
|
|
97
|
+
"Garage Door Opener",
|
|
98
|
+
"Plug",
|
|
99
|
+
"Plug Mini (EU)",
|
|
100
|
+
"Plug Mini (JP)",
|
|
101
|
+
"Plug Mini (US)",
|
|
102
|
+
"Relay Switch 1",
|
|
103
|
+
"Relay Switch 1PM",
|
|
104
|
+
"Relay Switch 2PM"
|
|
105
|
+
],
|
|
106
|
+
"Robot Vacuums": [
|
|
107
|
+
"K10+",
|
|
108
|
+
"K10+ Pro",
|
|
109
|
+
"Robot Vacuum Cleaner K10+ Pro Combo",
|
|
110
|
+
"Robot Vacuum Cleaner K11+",
|
|
111
|
+
"Robot Vacuum Cleaner K20 Plus Pro",
|
|
112
|
+
"Robot Vacuum Cleaner S1",
|
|
113
|
+
"Robot Vacuum Cleaner S1 Plus",
|
|
114
|
+
"Robot Vacuum Cleaner S10",
|
|
115
|
+
"Robot Vacuum Cleaner S20"
|
|
116
|
+
],
|
|
117
|
+
"Hubs": ["AI Hub", "Hub", "Hub 2", "Hub 3", "Hub Mini", "Hub Plus"],
|
|
118
|
+
"Cameras": [
|
|
119
|
+
"Indoor Cam",
|
|
120
|
+
"Pan/Tilt Cam",
|
|
121
|
+
"Pan/Tilt Cam 2K",
|
|
122
|
+
"Pan/Tilt Cam Plus 2K",
|
|
123
|
+
"Pan/Tilt Cam Plus 3K"
|
|
124
|
+
],
|
|
125
|
+
"IR Devices": [
|
|
126
|
+
"Air Conditioner",
|
|
127
|
+
"Air Purifier",
|
|
128
|
+
"Camera",
|
|
129
|
+
"DVD",
|
|
130
|
+
"Fan",
|
|
131
|
+
"Light",
|
|
132
|
+
"Others",
|
|
133
|
+
"Projector",
|
|
134
|
+
"Set Top Box",
|
|
135
|
+
"Speaker",
|
|
136
|
+
"Streamer",
|
|
137
|
+
"TV",
|
|
138
|
+
"Vacuum Cleaner",
|
|
139
|
+
"Water Heater"
|
|
140
|
+
],
|
|
141
|
+
"Other Devices": ["AI Art Frame", "Bot", "Home Climate Panel", "Remote", "remote with screen"]
|
|
142
|
+
};
|
|
143
|
+
DEVICE_TYPE_NORMALIZATION_MAP = {
|
|
144
|
+
// --- node-switchbot beta new types normalization additions ---
|
|
145
|
+
"hub mini": "Hub Mini",
|
|
146
|
+
"hub 3": "Hub 3",
|
|
147
|
+
"keypad": "Keypad",
|
|
148
|
+
// node-switchbot beta
|
|
149
|
+
"plug mini": "Plug Mini (US)",
|
|
150
|
+
// fallback to US if region not specified
|
|
151
|
+
"art frame": "AI Art Frame",
|
|
152
|
+
"rgbicww": "RGBICWW Strip Light",
|
|
153
|
+
"lock vision": "Lock Vision Pro",
|
|
154
|
+
// alias for new lock vision
|
|
155
|
+
"lock pro": "Smart Lock Pro",
|
|
156
|
+
"lock lite": "Lock Lite",
|
|
157
|
+
// node-switchbot beta
|
|
158
|
+
"circulator fan": "Circulator Fan",
|
|
159
|
+
// node-switchbot beta
|
|
160
|
+
"smart thermostat radiator": "Smart Radiator Thermostat",
|
|
161
|
+
"climate panel": "Home Climate Panel",
|
|
162
|
+
"evaporative humidifier": "Humidifier",
|
|
163
|
+
// --- end node-switchbot beta additions ---
|
|
164
|
+
// Only keep the last occurrence for each key, all values canonical
|
|
165
|
+
"air purifier pm2.5": "Air Purifier PM2.5",
|
|
166
|
+
"pan/tilt cam plus 3k": "Pan/Tilt Cam Plus 3K",
|
|
167
|
+
"remote with screen": "Remote with Screen",
|
|
168
|
+
"ai hub": "AI Hub",
|
|
169
|
+
"water detector": "Water Detector",
|
|
170
|
+
"video doorbell": "Video Doorbell",
|
|
171
|
+
"smart radiator thermostat": "Smart Radiator Thermostat",
|
|
172
|
+
"woiosensor": "WoIOSensor",
|
|
173
|
+
"garage door opener": "Garage Door Opener",
|
|
174
|
+
"air purifier table pm2.5": "Air Purifier Table PM2.5",
|
|
175
|
+
"air purifier voc": "Air Purifier VOC",
|
|
176
|
+
"air purifier table voc": "Air Purifier Table VOC",
|
|
177
|
+
"plug mini (eu)": "Plug Mini (EU)",
|
|
178
|
+
// Only last occurrence for each key is kept above. Removed duplicates here.
|
|
179
|
+
// Climate control conversions
|
|
180
|
+
"humidifier2": "Humidifier2",
|
|
181
|
+
"battery circulator fan": "Battery Circulator Fan",
|
|
182
|
+
"standing circulator fan": "Standing Circulator Fan",
|
|
183
|
+
// Lock/keypad conversions
|
|
184
|
+
"smart lock": "Smart Lock",
|
|
185
|
+
"smart lock pro": "Smart Lock Pro",
|
|
186
|
+
"smart lock ultra": "Smart Lock Ultra",
|
|
187
|
+
"keypad touch": "Keypad Touch",
|
|
188
|
+
"keypad vision": "Keypad Vision",
|
|
189
|
+
"keypad vision pro": "Keypad Vision Pro",
|
|
190
|
+
// Light conversions
|
|
191
|
+
"color bulb": "Color Bulb",
|
|
192
|
+
"ceiling light": "Ceiling Light",
|
|
193
|
+
"ceiling light pro": "Ceiling Light Pro",
|
|
194
|
+
"candle warmer lamp": "Candle Warmer Lamp",
|
|
195
|
+
"floor lamp": "Floor Lamp",
|
|
196
|
+
"rgbic neon rope light": "RGBIC Neon Rope Light",
|
|
197
|
+
"rgbic neon wire rope light": "RGBIC Neon Wire Rope Light",
|
|
198
|
+
"rgbicww floor lamp": "RGBICWW Floor Lamp",
|
|
199
|
+
"rgbicww strip light": "RGBICWW Strip Light",
|
|
200
|
+
"strip light": "Strip Light",
|
|
201
|
+
"strip light 3": "Strip Light 3",
|
|
202
|
+
// node-switchbot beta
|
|
203
|
+
// Vacuum conversions
|
|
204
|
+
"robot vacuum cleaner s1": "Robot Vacuum Cleaner S1",
|
|
205
|
+
"robot vacuum cleaner s1 plus": "Robot Vacuum Cleaner S1 Plus",
|
|
206
|
+
"robot vacuum cleaner s10": "Robot Vacuum Cleaner S10",
|
|
207
|
+
"robot vacuum cleaner s20": "Robot Vacuum Cleaner S20",
|
|
208
|
+
"robot vacuum cleaner k10+ pro combo": "Robot Vacuum Cleaner K10+ Pro Combo",
|
|
209
|
+
"robot vacuum cleaner k11+": "Robot Vacuum Cleaner K11+",
|
|
210
|
+
"robot vacuum cleaner k20 plus pro": "Robot Vacuum Cleaner K20 Plus Pro",
|
|
211
|
+
// Exact device type mappings (API format → canonical format)
|
|
212
|
+
"relay switch 1": "Relay Switch 1",
|
|
213
|
+
"blind tilt": "Blind Tilt",
|
|
214
|
+
"roller shade": "Roller Shade",
|
|
215
|
+
"curtain3": "Curtain3",
|
|
216
|
+
"hub 2": "Hub 2",
|
|
217
|
+
"meterplus": "MeterPlus",
|
|
218
|
+
"meterpro": "MeterPro",
|
|
219
|
+
"meterpro(co2)": "MeterPro(CO2)",
|
|
220
|
+
"walletfinder": "WalletFinder",
|
|
221
|
+
"k10+": "K10+",
|
|
222
|
+
"k10+ pro (wosweeperminipro)": "K10+ Pro (wosweeperminipro)",
|
|
223
|
+
// Handle spaced variants from config files (normalize back to canonical type)
|
|
224
|
+
"meter pro": "Meter Pro",
|
|
225
|
+
"meter pro (co2)": "Meter Pro (CO2)",
|
|
226
|
+
"meter plus": "Meter Plus",
|
|
227
|
+
"relay switch 1 pm": "Relay Switch 1PM",
|
|
228
|
+
"relay switch 2 pm": "Relay Switch 2PM",
|
|
229
|
+
"plug mini eu": "Plug Mini (EU)",
|
|
230
|
+
"plug mini jp": "Plug Mini (JP)",
|
|
231
|
+
"plug mini us": "Plug Mini (US)",
|
|
232
|
+
// Migration mappings for invalid/legacy device types
|
|
233
|
+
"lock vision pro": "Lock Vision Pro",
|
|
234
|
+
// Valid alias; map to canonical
|
|
235
|
+
// 'lock vision': 'Keypad Vision', // Invalid type (removed, now node-switchbot beta alias above)
|
|
236
|
+
"lock touch": "Keypad Touch",
|
|
237
|
+
// Invalid type
|
|
238
|
+
// Additional normalization for new/unknown types from logs
|
|
239
|
+
"woplugus": "Plug Mini (US)"
|
|
240
|
+
// Removed duplicate keys below, only last occurrence kept
|
|
241
|
+
// 'plug mini us': 'plug mini (us)', // duplicate, removed
|
|
242
|
+
// 'plug us': 'plug mini (us)', // duplicate, removed
|
|
243
|
+
// 'plug': 'plug', // duplicate, removed
|
|
244
|
+
// 'air purifier pm2.5': 'air purifier pm2.5', // duplicate, removed
|
|
245
|
+
// 'rgbic neon wire rope light': 'rgbic neon wire rope light', // duplicate, removed
|
|
246
|
+
// 'candle warmer lamp': 'candle warmer lamp', // duplicate, removed
|
|
247
|
+
// 'pan/tilt cam plus 3k': 'pan/tilt cam plus 3k', // duplicate, removed
|
|
248
|
+
// 'remote with screen': 'remote with screen', // duplicate, removed
|
|
249
|
+
// 'ai hub': 'ai hub', // duplicate, removed
|
|
250
|
+
// 'lock vision pro': 'lock vision pro', // duplicate, remove this line
|
|
251
|
+
// Add any other device types from logs as needed
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
|
|
11
256
|
// src/homebridge-ui/public/js/types.ts
|
|
12
257
|
var init_types = __esm({
|
|
13
258
|
"src/homebridge-ui/public/js/types.ts"() {
|
|
@@ -48,8 +293,27 @@ __export(api_exports, {
|
|
|
48
293
|
saveCredentials: () => saveCredentials,
|
|
49
294
|
syncParentPluginConfigFromDisk: () => syncParentPluginConfigFromDisk,
|
|
50
295
|
testDeviceConnection: () => testDeviceConnection,
|
|
51
|
-
updateDevice: () => updateDevice
|
|
296
|
+
updateDevice: () => updateDevice,
|
|
297
|
+
validateAndFixDeviceTypes: () => validateAndFixDeviceTypes
|
|
52
298
|
});
|
|
299
|
+
function validateAndFixDeviceTypes(devices) {
|
|
300
|
+
const errors = [];
|
|
301
|
+
for (const d of devices) {
|
|
302
|
+
if (!isValidDeviceType(d.configDeviceType)) {
|
|
303
|
+
const fixed = normalizeDeviceType(d.configDeviceType);
|
|
304
|
+
if (fixed) {
|
|
305
|
+
d.configDeviceType = fixed;
|
|
306
|
+
} else {
|
|
307
|
+
errors.push({
|
|
308
|
+
deviceId: d.deviceId,
|
|
309
|
+
name: d.configDeviceName,
|
|
310
|
+
type: d.configDeviceType
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return errors;
|
|
316
|
+
}
|
|
53
317
|
function isSwitchBotPlatformConfig(block) {
|
|
54
318
|
const platformName = String(block?.platform || block?.name || "").toLowerCase();
|
|
55
319
|
return platformName === "switchbot" || platformName === "@switchbot/homebridge-switchbot" || platformName.includes("switchbot");
|
|
@@ -75,6 +339,11 @@ async function syncParentPluginConfigFromDisk(autoSave = false) {
|
|
|
75
339
|
uiLog.warn("SwitchBot platform block not found in Homebridge plugin config");
|
|
76
340
|
return false;
|
|
77
341
|
}
|
|
342
|
+
const errors = validateAndFixDeviceTypes(diskResp.data.devices || []);
|
|
343
|
+
if (errors.length > 0) {
|
|
344
|
+
homebridge.toast?.error?.(`Invalid device types found: ${errors.map((e) => `${e.name} (${e.type})`).join(", ")}`);
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
78
347
|
pluginConfigBlocks[index] = diskResp.data;
|
|
79
348
|
await homebridge.updatePluginConfig(pluginConfigBlocks);
|
|
80
349
|
if (autoSave && typeof homebridge.savePluginConfig === "function") {
|
|
@@ -103,41 +372,35 @@ async function fetchCredentialStatus() {
|
|
|
103
372
|
}
|
|
104
373
|
}
|
|
105
374
|
async function saveCredentials(token, secret) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
throw new Error(resp?.message || "Save failed");
|
|
112
|
-
}
|
|
113
|
-
return resp.data || resp;
|
|
114
|
-
} catch (e) {
|
|
115
|
-
throw e;
|
|
375
|
+
uiLog.info("Saving credentials...");
|
|
376
|
+
const resp = await homebridge.request("/credentials", { token, secret });
|
|
377
|
+
uiLog.info("Save response:", resp);
|
|
378
|
+
if (!resp || resp.success === false) {
|
|
379
|
+
throw new Error(resp?.message || "Save failed");
|
|
116
380
|
}
|
|
381
|
+
return resp.data || resp;
|
|
117
382
|
}
|
|
118
383
|
async function fetchDevices() {
|
|
119
384
|
try {
|
|
120
385
|
const resp = await homebridge.request("/devices", {});
|
|
121
386
|
if (!resp || resp.success === false) {
|
|
122
|
-
|
|
387
|
+
const backendMsg = resp?.data?.message || resp?.message;
|
|
388
|
+
throw new Error(backendMsg || "request failed");
|
|
123
389
|
}
|
|
124
390
|
return resp.data || [];
|
|
125
391
|
} catch (e) {
|
|
126
|
-
|
|
392
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
393
|
+
uiLog.error("Error fetching devices:", msg);
|
|
127
394
|
return [];
|
|
128
395
|
}
|
|
129
396
|
}
|
|
130
397
|
async function discoverDevices(mode = "all", options) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
throw new Error(resp?.data?.message || "Discovery failed");
|
|
136
|
-
}
|
|
137
|
-
return resp.data || [];
|
|
138
|
-
} catch (e) {
|
|
139
|
-
throw e;
|
|
398
|
+
const resp = await homebridge.request("/discover", { mode, ...options });
|
|
399
|
+
uiLog.info("Discover response:", resp);
|
|
400
|
+
if (!resp || resp.success === false) {
|
|
401
|
+
throw new Error(resp?.data?.message || "Discovery failed");
|
|
140
402
|
}
|
|
403
|
+
return resp.data || [];
|
|
141
404
|
}
|
|
142
405
|
async function fetchBluetoothStatus() {
|
|
143
406
|
try {
|
|
@@ -164,95 +427,76 @@ async function testDeviceConnection(payload) {
|
|
|
164
427
|
};
|
|
165
428
|
}
|
|
166
429
|
async function addDevice(deviceId, name, type, options) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
throw new Error(resp?.data?.message || "Failed to add device");
|
|
189
|
-
}
|
|
190
|
-
return resp.data || resp;
|
|
191
|
-
} catch (e) {
|
|
192
|
-
throw e;
|
|
430
|
+
const payload = { deviceId, name, type };
|
|
431
|
+
if (options?.address) {
|
|
432
|
+
payload.address = options.address;
|
|
433
|
+
}
|
|
434
|
+
if (options?.model) {
|
|
435
|
+
payload.model = options.model;
|
|
436
|
+
}
|
|
437
|
+
if (options?.rssi !== void 0 && options?.rssi !== null && options?.rssi !== 0) {
|
|
438
|
+
payload.rssi = options.rssi;
|
|
439
|
+
}
|
|
440
|
+
if (options?.encryptionKey) {
|
|
441
|
+
payload.encryptionKey = options.encryptionKey;
|
|
442
|
+
}
|
|
443
|
+
if (options?.keyId) {
|
|
444
|
+
payload.keyId = options.keyId;
|
|
445
|
+
}
|
|
446
|
+
uiLog.info("Adding device to config:", payload);
|
|
447
|
+
const resp = await homebridge.request("/add-device", payload);
|
|
448
|
+
uiLog.info("Add device response:", resp);
|
|
449
|
+
if (!resp || resp.success === false) {
|
|
450
|
+
throw new Error(resp?.data?.message || "Failed to add device");
|
|
193
451
|
}
|
|
452
|
+
return resp.data || resp;
|
|
194
453
|
}
|
|
195
454
|
async function addDevicesInBulk(devices) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
throw new Error(resp?.data?.message || "Bulk add failed");
|
|
201
|
-
}
|
|
202
|
-
return resp.data || resp;
|
|
203
|
-
} catch (e) {
|
|
204
|
-
throw e;
|
|
455
|
+
const resp = await homebridge.request("/add-devices", { devices });
|
|
456
|
+
uiLog.info("Bulk add response:", resp);
|
|
457
|
+
if (!resp || resp.success === false) {
|
|
458
|
+
throw new Error(resp?.data?.message || "Bulk add failed");
|
|
205
459
|
}
|
|
460
|
+
return resp.data || resp;
|
|
206
461
|
}
|
|
207
462
|
async function updateDevice(deviceId, configDeviceName, configDeviceType) {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
throw new Error(resp?.data?.message || "Failed to update device");
|
|
221
|
-
}
|
|
222
|
-
return resp.data || resp;
|
|
223
|
-
} catch (e) {
|
|
224
|
-
throw e;
|
|
463
|
+
const params = { deviceId };
|
|
464
|
+
if (configDeviceName) {
|
|
465
|
+
params.configDeviceName = configDeviceName;
|
|
466
|
+
}
|
|
467
|
+
if (configDeviceType) {
|
|
468
|
+
params.configDeviceType = configDeviceType;
|
|
469
|
+
}
|
|
470
|
+
uiLog.info("[Update Device] Sending update request with params:", params);
|
|
471
|
+
const resp = await homebridge.request("/update-device", params);
|
|
472
|
+
uiLog.info("[Update Device] Update response:", resp);
|
|
473
|
+
if (!resp || resp.success === false) {
|
|
474
|
+
throw new Error(resp?.data?.message || "Failed to update device");
|
|
225
475
|
}
|
|
476
|
+
return resp.data || resp;
|
|
226
477
|
}
|
|
227
478
|
async function deleteDevice(deviceId) {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
throw new Error(resp?.data?.message || "Failed to delete device");
|
|
234
|
-
}
|
|
235
|
-
return resp.data || resp;
|
|
236
|
-
} catch (e) {
|
|
237
|
-
throw e;
|
|
479
|
+
uiLog.info("Sending delete request for deviceId:", deviceId);
|
|
480
|
+
const resp = await homebridge.request("/delete-device", { deviceId });
|
|
481
|
+
uiLog.info("Delete response:", resp);
|
|
482
|
+
if (!resp || resp.success === false) {
|
|
483
|
+
throw new Error(resp?.data?.message || "Failed to delete device");
|
|
238
484
|
}
|
|
485
|
+
return resp.data || resp;
|
|
239
486
|
}
|
|
240
487
|
async function deleteAllDevices() {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
throw new Error(resp?.data?.message || "Failed to delete all devices");
|
|
247
|
-
}
|
|
248
|
-
return resp.data || resp;
|
|
249
|
-
} catch (e) {
|
|
250
|
-
throw e;
|
|
488
|
+
uiLog.info("Sending delete all devices request");
|
|
489
|
+
const resp = await homebridge.request("/delete-all-devices", {});
|
|
490
|
+
uiLog.info("Delete all response:", resp);
|
|
491
|
+
if (!resp || resp.success === false) {
|
|
492
|
+
throw new Error(resp?.data?.message || "Failed to delete all devices");
|
|
251
493
|
}
|
|
494
|
+
return resp.data || resp;
|
|
252
495
|
}
|
|
253
496
|
var init_api = __esm({
|
|
254
497
|
"src/homebridge-ui/public/js/api.ts"() {
|
|
255
498
|
"use strict";
|
|
499
|
+
init_device_types();
|
|
256
500
|
init_types();
|
|
257
501
|
init_logger();
|
|
258
502
|
}
|
|
@@ -1581,109 +1825,6 @@ var init_discovery = __esm({
|
|
|
1581
1825
|
}
|
|
1582
1826
|
});
|
|
1583
1827
|
|
|
1584
|
-
// src/device-types.ts
|
|
1585
|
-
var DEVICE_TYPES;
|
|
1586
|
-
var init_device_types = __esm({
|
|
1587
|
-
"src/device-types.ts"() {
|
|
1588
|
-
"use strict";
|
|
1589
|
-
DEVICE_TYPES = {
|
|
1590
|
-
"Window Coverings": ["Blind Tilt", "Curtain", "Curtain3", "Roller Shade"],
|
|
1591
|
-
"Locks & Access": [
|
|
1592
|
-
"Keypad",
|
|
1593
|
-
"Keypad Touch",
|
|
1594
|
-
"Keypad Vision",
|
|
1595
|
-
"Keypad Vision Pro",
|
|
1596
|
-
"Lock Vision Pro",
|
|
1597
|
-
"Lock Lite",
|
|
1598
|
-
"Smart Lock",
|
|
1599
|
-
"Smart Lock Pro",
|
|
1600
|
-
"Smart Lock Ultra",
|
|
1601
|
-
"Video Doorbell"
|
|
1602
|
-
],
|
|
1603
|
-
"Sensors": ["Contact Sensor", "Motion Sensor", "Presence Sensor", "Water Detector"],
|
|
1604
|
-
"Lighting": [
|
|
1605
|
-
"Candle Warmer Lamp",
|
|
1606
|
-
"Ceiling Light",
|
|
1607
|
-
"Ceiling Light Pro",
|
|
1608
|
-
"Color Bulb",
|
|
1609
|
-
"Floor Lamp",
|
|
1610
|
-
"RGBIC Neon Rope Light",
|
|
1611
|
-
"RGBIC Neon Wire Rope Light",
|
|
1612
|
-
"RGBICWW Floor Lamp",
|
|
1613
|
-
"RGBICWW Strip Light",
|
|
1614
|
-
"Strip Light",
|
|
1615
|
-
"Strip Light 3"
|
|
1616
|
-
],
|
|
1617
|
-
"Climate Control": [
|
|
1618
|
-
"Air Purifier PM2.5",
|
|
1619
|
-
"Air Purifier Table PM2.5",
|
|
1620
|
-
"Air Purifier VOC",
|
|
1621
|
-
"Air Purifier Table VOC",
|
|
1622
|
-
"Battery Circulator Fan",
|
|
1623
|
-
"Circulator Fan",
|
|
1624
|
-
"Humidifier",
|
|
1625
|
-
"Humidifier2",
|
|
1626
|
-
"Meter",
|
|
1627
|
-
"MeterPlus",
|
|
1628
|
-
"Meter Plus",
|
|
1629
|
-
"MeterPro",
|
|
1630
|
-
"Meter Pro",
|
|
1631
|
-
"MeterPro(CO2)",
|
|
1632
|
-
"Meter Pro (CO2)",
|
|
1633
|
-
"Smart Radiator Thermostat",
|
|
1634
|
-
"Standing Circulator Fan",
|
|
1635
|
-
"WoIOSensor"
|
|
1636
|
-
],
|
|
1637
|
-
"Plugs & Switches": [
|
|
1638
|
-
"Garage Door Opener",
|
|
1639
|
-
"Plug",
|
|
1640
|
-
"Plug Mini (EU)",
|
|
1641
|
-
"Plug Mini (JP)",
|
|
1642
|
-
"Plug Mini (US)",
|
|
1643
|
-
"Relay Switch 1",
|
|
1644
|
-
"Relay Switch 1PM",
|
|
1645
|
-
"Relay Switch 2PM"
|
|
1646
|
-
],
|
|
1647
|
-
"Robot Vacuums": [
|
|
1648
|
-
"K10+",
|
|
1649
|
-
"K10+ Pro",
|
|
1650
|
-
"Robot Vacuum Cleaner K10+ Pro Combo",
|
|
1651
|
-
"Robot Vacuum Cleaner K11+",
|
|
1652
|
-
"Robot Vacuum Cleaner K20 Plus Pro",
|
|
1653
|
-
"Robot Vacuum Cleaner S1",
|
|
1654
|
-
"Robot Vacuum Cleaner S1 Plus",
|
|
1655
|
-
"Robot Vacuum Cleaner S10",
|
|
1656
|
-
"Robot Vacuum Cleaner S20"
|
|
1657
|
-
],
|
|
1658
|
-
"Hubs": ["AI Hub", "Hub", "Hub 2", "Hub 3", "Hub Mini", "Hub Plus"],
|
|
1659
|
-
"Cameras": [
|
|
1660
|
-
"Indoor Cam",
|
|
1661
|
-
"Pan/Tilt Cam",
|
|
1662
|
-
"Pan/Tilt Cam 2K",
|
|
1663
|
-
"Pan/Tilt Cam Plus 2K",
|
|
1664
|
-
"Pan/Tilt Cam Plus 3K"
|
|
1665
|
-
],
|
|
1666
|
-
"IR Devices": [
|
|
1667
|
-
"Air Conditioner",
|
|
1668
|
-
"Air Purifier",
|
|
1669
|
-
"Camera",
|
|
1670
|
-
"DVD",
|
|
1671
|
-
"Fan",
|
|
1672
|
-
"Light",
|
|
1673
|
-
"Others",
|
|
1674
|
-
"Projector",
|
|
1675
|
-
"Set Top Box",
|
|
1676
|
-
"Speaker",
|
|
1677
|
-
"Streamer",
|
|
1678
|
-
"TV",
|
|
1679
|
-
"Vacuum Cleaner",
|
|
1680
|
-
"Water Heater"
|
|
1681
|
-
],
|
|
1682
|
-
"Other Devices": ["AI Art Frame", "Bot", "Home Climate Panel", "Remote", "remote with screen"]
|
|
1683
|
-
};
|
|
1684
|
-
}
|
|
1685
|
-
});
|
|
1686
|
-
|
|
1687
1828
|
// src/homebridge-ui/public/js/constants.ts
|
|
1688
1829
|
var init_constants = __esm({
|
|
1689
1830
|
"src/homebridge-ui/public/js/constants.ts"() {
|
|
@@ -3188,13 +3329,14 @@ async function addDeviceToConfig2(device, options = {}) {
|
|
|
3188
3329
|
}
|
|
3189
3330
|
return { added: !alreadyExists };
|
|
3190
3331
|
} catch (e) {
|
|
3191
|
-
|
|
3332
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
3333
|
+
uiLog.error("Add device error:", msg);
|
|
3192
3334
|
const status = document.getElementById("discoverStatus");
|
|
3193
3335
|
if (status) {
|
|
3194
|
-
status.textContent = `\u2717 Error: ${
|
|
3336
|
+
status.textContent = `\u2717 Error: ${msg}`;
|
|
3195
3337
|
status.classList.add("error");
|
|
3196
3338
|
}
|
|
3197
|
-
toastError(
|
|
3339
|
+
toastError(msg);
|
|
3198
3340
|
return { added: false };
|
|
3199
3341
|
} finally {
|
|
3200
3342
|
hideBusyUi();
|