@switchbot/homebridge-switchbot 5.0.0-beta.147 → 5.0.0-beta.149
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/workflows/ci.yml +1 -1
- package/.github/workflows/manual-e2e.yml +3 -3
- package/config.schema.json +6 -0
- package/dist/SwitchBotHAPPlatform.d.ts +133 -0
- package/dist/SwitchBotHAPPlatform.d.ts.map +1 -0
- package/dist/SwitchBotHAPPlatform.js +555 -0
- package/dist/SwitchBotHAPPlatform.js.map +1 -0
- package/dist/SwitchBotMatterPlatform.d.ts +141 -0
- package/dist/SwitchBotMatterPlatform.d.ts.map +1 -0
- package/dist/SwitchBotMatterPlatform.js +536 -0
- package/dist/SwitchBotMatterPlatform.js.map +1 -0
- package/dist/deviceFactory.d.ts +2 -3
- package/dist/deviceFactory.d.ts.map +1 -1
- package/dist/deviceFactory.js +12 -3
- 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 +1 -18
- package/dist/homebridge-ui/endpoints/config.js.map +1 -1
- package/dist/homebridge-ui/endpoints/devices.d.ts.map +1 -1
- package/dist/homebridge-ui/endpoints/devices.js +1 -350
- package/dist/homebridge-ui/endpoints/devices.js.map +1 -1
- package/dist/homebridge-ui/public/index.html +6 -0
- package/dist/homebridge-ui/public/js/advanced-settings.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/advanced-settings.js +22 -12
- package/dist/homebridge-ui/public/js/advanced-settings.js.map +1 -1
- package/dist/homebridge-ui/public/js/advanced-settings.ts +36 -25
- package/dist/homebridge-ui/public/js/api.d.ts +1 -1
- package/dist/homebridge-ui/public/js/api.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/api.js +111 -52
- package/dist/homebridge-ui/public/js/api.js.map +1 -1
- package/dist/homebridge-ui/public/js/api.ts +112 -53
- package/dist/homebridge-ui/public/js/app.js +234 -177
- package/dist/homebridge-ui/public/js/app.js.map +4 -4
- package/dist/homebridge-ui/public/js/credentials.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/credentials.js +26 -23
- package/dist/homebridge-ui/public/js/credentials.js.map +1 -1
- package/dist/homebridge-ui/public/js/credentials.ts +26 -25
- package/dist/homebridge-ui/public/js/devices-delete.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/devices-delete.js +3 -10
- package/dist/homebridge-ui/public/js/devices-delete.js.map +1 -1
- package/dist/homebridge-ui/public/js/devices-delete.ts +3 -12
- package/dist/homebridge-ui/public/js/devices.d.ts.map +1 -1
- package/dist/homebridge-ui/public/js/devices.js +0 -3
- package/dist/homebridge-ui/public/js/devices.js.map +1 -1
- package/dist/homebridge-ui/public/js/devices.ts +5 -9
- package/dist/homebridge-ui/server.js +0 -2
- package/dist/homebridge-ui/server.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/settings.d.ts +1 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +1 -0
- package/dist/settings.js.map +1 -1
- package/dist/switchbotClient.js +1 -1
- package/dist/switchbotClient.js.map +1 -1
- package/dist/utils.d.ts +76 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1117 -2
- package/dist/utils.js.map +1 -1
- package/docs/variables/default.html +3 -1
- package/package.json +1 -1
- package/src/SwitchBotHAPPlatform.ts +558 -0
- package/src/SwitchBotMatterPlatform.ts +538 -0
- package/src/deviceFactory.ts +14 -6
- package/src/homebridge-ui/endpoints/config.ts +2 -18
- package/src/homebridge-ui/endpoints/devices.ts +1 -392
- package/src/homebridge-ui/public/index.html +6 -0
- package/src/homebridge-ui/public/js/advanced-settings.ts +36 -25
- package/src/homebridge-ui/public/js/api.ts +112 -53
- package/src/homebridge-ui/public/js/credentials.ts +26 -25
- package/src/homebridge-ui/public/js/devices-delete.ts +3 -12
- package/src/homebridge-ui/public/js/devices.ts +5 -9
- package/src/homebridge-ui/server.ts +0 -2
- package/src/index.ts +12 -2
- package/src/settings.ts +2 -0
- package/src/switchbotClient.ts +1 -1
- package/src/utils.ts +1128 -3
- package/test/platform/accessory-restore.spec.ts +2 -1
- package/test/platform/matter-childbridge.spec.ts +1 -1
- package/test/platform/matter-integration.spec.ts +1 -1
- package/test/platform/platform-edge.spec.ts +2 -1
- package/test/platform/platform.integration.spec.ts +1 -1
- package/dist/homebridge-ui/endpoints/credentials.d.ts +0 -6
- package/dist/homebridge-ui/endpoints/credentials.d.ts.map +0 -1
- package/dist/homebridge-ui/endpoints/credentials.js +0 -65
- package/dist/homebridge-ui/endpoints/credentials.js.map +0 -1
- package/dist/platform.d.ts +0 -48
- package/dist/platform.d.ts.map +0 -1
- package/dist/platform.js +0 -1733
- package/dist/platform.js.map +0 -1
- package/src/homebridge-ui/endpoints/credentials.ts +0 -74
- package/src/platform.ts +0 -1750
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
// Fetch the list of configured devices from the Homebridge UI API
|
|
1
2
|
import { isValidDeviceType, normalizeDeviceType } from '../../../device-types.js'
|
|
2
3
|
import './types.js'
|
|
3
4
|
import { uiLog } from './logger.js'
|
|
4
5
|
|
|
6
|
+
export async function fetchDevices(): Promise<any[]> {
|
|
7
|
+
try {
|
|
8
|
+
if (typeof homebridge.getPluginConfig !== 'function') {
|
|
9
|
+
throw new TypeError('Homebridge UI API not available')
|
|
10
|
+
}
|
|
11
|
+
const configArr = await homebridge.getPluginConfig()
|
|
12
|
+
const config = Array.isArray(configArr) && configArr.length > 0 ? configArr.find(isSwitchBotPlatformConfig) : null
|
|
13
|
+
if (!config || !Array.isArray(config.devices)) {
|
|
14
|
+
return []
|
|
15
|
+
}
|
|
16
|
+
return config.devices
|
|
17
|
+
} catch (e) {
|
|
18
|
+
const msg = e instanceof Error ? e.message : String(e)
|
|
19
|
+
uiLog.error('Error fetching devices:', msg)
|
|
20
|
+
return []
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
5
24
|
/**
|
|
6
25
|
* Validate and auto-correct device types in the config array before saving.
|
|
7
26
|
* Returns an array of errors for devices that cannot be fixed.
|
|
@@ -114,24 +133,6 @@ export async function saveCredentials(token: string, secret: string): Promise<an
|
|
|
114
133
|
return resp.data || resp
|
|
115
134
|
}
|
|
116
135
|
|
|
117
|
-
export async function fetchDevices(): Promise<any[]> {
|
|
118
|
-
try {
|
|
119
|
-
const resp = await homebridge.request('/devices', {})
|
|
120
|
-
if (!resp || resp.success === false) {
|
|
121
|
-
// Prefer backend error message if available
|
|
122
|
-
const backendMsg = resp?.data?.message || resp?.message
|
|
123
|
-
throw new Error(backendMsg || 'request failed')
|
|
124
|
-
}
|
|
125
|
-
return resp.data || []
|
|
126
|
-
} catch (e) {
|
|
127
|
-
// Show the real error to the user
|
|
128
|
-
const msg = e instanceof Error ? e.message : String(e)
|
|
129
|
-
uiLog.error('Error fetching devices:', msg)
|
|
130
|
-
// Optionally, show a toast or UI error here if needed
|
|
131
|
-
return []
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
136
|
export interface DiscoverRequestOptions {
|
|
136
137
|
bleEnabled?: boolean
|
|
137
138
|
bleScanDurationSeconds?: number
|
|
@@ -194,29 +195,45 @@ export async function addDevice(
|
|
|
194
195
|
type: string,
|
|
195
196
|
options?: { address?: string, model?: string, rssi?: number, encryptionKey?: string, keyId?: string },
|
|
196
197
|
): Promise<any> {
|
|
197
|
-
|
|
198
|
+
if (typeof homebridge.getPluginConfig !== 'function' || typeof homebridge.updatePluginConfig !== 'function') {
|
|
199
|
+
throw new TypeError('Homebridge UI API not available')
|
|
200
|
+
}
|
|
201
|
+
const configArr = await homebridge.getPluginConfig()
|
|
202
|
+
const idx = Array.isArray(configArr) ? configArr.findIndex(isSwitchBotPlatformConfig) : -1
|
|
203
|
+
if (idx === -1) {
|
|
204
|
+
throw new Error('SwitchBot config not found')
|
|
205
|
+
}
|
|
206
|
+
const config = configArr[idx]
|
|
207
|
+
if (!Array.isArray(config.devices)) {
|
|
208
|
+
config.devices = []
|
|
209
|
+
}
|
|
210
|
+
const normalizedDeviceId = String(deviceId).trim().toLowerCase()
|
|
211
|
+
const exists = config.devices.some((d: any) => String(d.deviceId ?? d.id ?? '').trim().toLowerCase() === normalizedDeviceId)
|
|
212
|
+
if (exists) {
|
|
213
|
+
return { alreadyExists: true, message: 'Device already in config' }
|
|
214
|
+
}
|
|
215
|
+
const newDevice: any = { deviceId, configDeviceName: name, configDeviceType: type }
|
|
198
216
|
if (options?.address) {
|
|
199
|
-
|
|
217
|
+
newDevice.address = options.address
|
|
200
218
|
}
|
|
201
219
|
if (options?.model) {
|
|
202
|
-
|
|
220
|
+
newDevice.model = options.model
|
|
203
221
|
}
|
|
204
222
|
if (options?.rssi !== undefined && options?.rssi !== null && options?.rssi !== 0) {
|
|
205
|
-
|
|
223
|
+
newDevice.rssi = options.rssi
|
|
206
224
|
}
|
|
207
225
|
if (options?.encryptionKey) {
|
|
208
|
-
|
|
226
|
+
newDevice.encryptionKey = options.encryptionKey
|
|
209
227
|
}
|
|
210
228
|
if (options?.keyId) {
|
|
211
|
-
|
|
229
|
+
newDevice.keyId = options.keyId
|
|
212
230
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
throw new Error(resp?.data?.message || 'Failed to add device')
|
|
231
|
+
config.devices.push(newDevice)
|
|
232
|
+
await homebridge.updatePluginConfig(configArr)
|
|
233
|
+
if (typeof homebridge.savePluginConfig === 'function') {
|
|
234
|
+
await homebridge.savePluginConfig()
|
|
218
235
|
}
|
|
219
|
-
return
|
|
236
|
+
return { added: true, message: `Device "${name}" added successfully` }
|
|
220
237
|
}
|
|
221
238
|
|
|
222
239
|
export async function addDevicesInBulk(
|
|
@@ -241,43 +258,85 @@ export async function updateDevice(
|
|
|
241
258
|
keyId?: string
|
|
242
259
|
room?: string
|
|
243
260
|
[key: string]: any
|
|
244
|
-
}
|
|
261
|
+
},
|
|
245
262
|
): Promise<any> {
|
|
246
|
-
|
|
263
|
+
if (typeof homebridge.getPluginConfig !== 'function' || typeof homebridge.updatePluginConfig !== 'function') {
|
|
264
|
+
throw new TypeError('Homebridge UI API not available')
|
|
265
|
+
}
|
|
266
|
+
const configArr = await homebridge.getPluginConfig()
|
|
267
|
+
const idx = Array.isArray(configArr) ? configArr.findIndex(isSwitchBotPlatformConfig) : -1
|
|
268
|
+
if (idx === -1) {
|
|
269
|
+
throw new Error('SwitchBot config not found')
|
|
270
|
+
}
|
|
271
|
+
const config = configArr[idx]
|
|
272
|
+
if (!Array.isArray(config.devices)) {
|
|
273
|
+
throw new TypeError('No devices array in config')
|
|
274
|
+
}
|
|
275
|
+
const normalizedDeviceId = String(deviceId).trim().toLowerCase()
|
|
276
|
+
const device = config.devices.find((d: any) => String(d.deviceId ?? d.id ?? '').trim().toLowerCase() === normalizedDeviceId)
|
|
277
|
+
if (!device) {
|
|
278
|
+
throw new Error('Device not found in config')
|
|
279
|
+
}
|
|
247
280
|
if (configDeviceName) {
|
|
248
|
-
|
|
281
|
+
device.configDeviceName = configDeviceName
|
|
249
282
|
}
|
|
250
283
|
if (configDeviceType) {
|
|
251
|
-
|
|
284
|
+
device.configDeviceType = configDeviceType
|
|
252
285
|
}
|
|
253
286
|
if (options) {
|
|
254
|
-
Object.assign(
|
|
287
|
+
Object.assign(device, options)
|
|
255
288
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
if (!resp || resp.success === false) {
|
|
260
|
-
throw new Error(resp?.data?.message || 'Failed to update device')
|
|
289
|
+
await homebridge.updatePluginConfig(configArr)
|
|
290
|
+
if (typeof homebridge.savePluginConfig === 'function') {
|
|
291
|
+
await homebridge.savePluginConfig()
|
|
261
292
|
}
|
|
262
|
-
return
|
|
293
|
+
return { updated: true, message: `Device updated successfully` }
|
|
263
294
|
}
|
|
264
295
|
|
|
265
296
|
export async function deleteDevice(deviceId: string): Promise<any> {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
uiLog.info('Delete response:', resp)
|
|
269
|
-
if (!resp || resp.success === false) {
|
|
270
|
-
throw new Error(resp?.data?.message || 'Failed to delete device')
|
|
297
|
+
if (typeof homebridge.getPluginConfig !== 'function' || typeof homebridge.updatePluginConfig !== 'function') {
|
|
298
|
+
throw new TypeError('Homebridge UI API not available')
|
|
271
299
|
}
|
|
272
|
-
|
|
300
|
+
const configArr = await homebridge.getPluginConfig()
|
|
301
|
+
const idx = Array.isArray(configArr) ? configArr.findIndex(isSwitchBotPlatformConfig) : -1
|
|
302
|
+
if (idx === -1) {
|
|
303
|
+
throw new Error('SwitchBot config not found')
|
|
304
|
+
}
|
|
305
|
+
const config = configArr[idx]
|
|
306
|
+
if (!Array.isArray(config.devices)) {
|
|
307
|
+
throw new TypeError('No devices array in config')
|
|
308
|
+
}
|
|
309
|
+
const normalizedDeviceId = String(deviceId).trim().toLowerCase()
|
|
310
|
+
const before = config.devices.length
|
|
311
|
+
config.devices = config.devices.filter((d: any) => String(d.deviceId ?? d.id ?? '').trim().toLowerCase() !== normalizedDeviceId)
|
|
312
|
+
if (config.devices.length === before) {
|
|
313
|
+
throw new Error('Device not found in config')
|
|
314
|
+
}
|
|
315
|
+
await homebridge.updatePluginConfig(configArr)
|
|
316
|
+
if (typeof homebridge.savePluginConfig === 'function') {
|
|
317
|
+
await homebridge.savePluginConfig()
|
|
318
|
+
}
|
|
319
|
+
return { deleted: true, message: `Device removed from config` }
|
|
273
320
|
}
|
|
274
321
|
|
|
275
322
|
export async function deleteAllDevices(): Promise<any> {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
uiLog.info('Delete all response:', resp)
|
|
279
|
-
if (!resp || resp.success === false) {
|
|
280
|
-
throw new Error(resp?.data?.message || 'Failed to delete all devices')
|
|
323
|
+
if (typeof homebridge.getPluginConfig !== 'function' || typeof homebridge.updatePluginConfig !== 'function') {
|
|
324
|
+
throw new TypeError('Homebridge UI API not available')
|
|
281
325
|
}
|
|
282
|
-
|
|
326
|
+
const configArr = await homebridge.getPluginConfig()
|
|
327
|
+
const idx = Array.isArray(configArr) ? configArr.findIndex(isSwitchBotPlatformConfig) : -1
|
|
328
|
+
if (idx === -1) {
|
|
329
|
+
throw new Error('SwitchBot config not found')
|
|
330
|
+
}
|
|
331
|
+
const config = configArr[idx]
|
|
332
|
+
if (!Array.isArray(config.devices)) {
|
|
333
|
+
throw new TypeError('No devices array in config')
|
|
334
|
+
}
|
|
335
|
+
const deletedCount = config.devices.length
|
|
336
|
+
config.devices = []
|
|
337
|
+
await homebridge.updatePluginConfig(configArr)
|
|
338
|
+
if (typeof homebridge.savePluginConfig === 'function') {
|
|
339
|
+
await homebridge.savePluginConfig()
|
|
340
|
+
}
|
|
341
|
+
return { deleted: true, deletedCount, message: `Removed ${deletedCount} device(s) from config` }
|
|
283
342
|
}
|