@switchbot/homebridge-switchbot
Version:
The SwitchBot plugin allows you to access your SwitchBot device(s) from HomeKit.
90 lines • 4.63 kB
JavaScript
import { RequestError } from '@homebridge/plugin-ui-utils';
import fs from 'node:fs/promises';
import { isValidDeviceType } from '../../device-types.js';
import { getAllDevices, SWITCHBOT_PLATFORM_REGEX } from '../utils/config-parser.js';
import { validateAndMigrateDeviceType } from '../utils/device-migration.js';
import { uiLog } from '../utils/logger.js';
export function registerConfigEndpoints(server) {
/**
* GET /devices - List all configured devices from Homebridge config
*/
server.onRequest('/devices', async () => {
try {
const cfgPath = server.homebridgeConfigPath;
if (!cfgPath) {
throw new Error('HOMEBRIDGE_CONFIG_PATH not set');
}
const raw = await fs.readFile(cfgPath, 'utf8');
const cfg = JSON.parse(raw);
const found = [];
const invalidTypeDevices = [];
const platforms = Array.isArray(cfg.platforms) ? cfg.platforms : [];
for (const p of platforms) {
try {
const platformName = p.platform || p.name || '';
// Match known SwitchBot platform identifiers
if (!platformName || !SWITCHBOT_PLATFORM_REGEX.test(String(platformName))) {
continue;
}
const devices = getAllDevices(p);
for (const d of devices) {
const id = d.deviceId ?? d.id;
if (!id) {
continue;
}
const deviceType = d.configDeviceType ?? d.type ?? d.deviceType;
const deviceName = d.configDeviceName ?? d.name ?? d.deviceName;
// Validate device type
const deviceObj = { configDeviceType: deviceType, configDeviceName: deviceName, deviceId: id };
const validationResult = validateAndMigrateDeviceType(deviceObj, false);
const deviceEntry = {
id,
name: deviceName,
type: deviceType,
connectionPreference: d.connectionPreference ?? d.connection ?? 'auto',
room: d.room || d.location || undefined,
};
if (!isValidDeviceType(deviceType)) {
deviceEntry.typeValidationWarning = `Invalid type "${deviceType}"`;
if (validationResult.correctedType) {
deviceEntry.typeValidationWarning += ` - should be "${validationResult.correctedType}"`;
invalidTypeDevices.push({
name: deviceName,
type: deviceType,
suggestion: validationResult.correctedType,
});
}
else {
invalidTypeDevices.push({
name: deviceName,
type: deviceType,
});
}
}
found.push(deviceEntry);
}
}
catch (e) {
// ignore malformed platform entries
}
}
// Log validation issues
if (invalidTypeDevices.length > 0) {
uiLog.warn(`Found ${invalidTypeDevices.length} device(s) with invalid types:\n${invalidTypeDevices.map(d => ` - "${d.name}": "${d.type}"${d.suggestion ? ` → should be "${d.suggestion}"` : ''}`).join('\n')}`);
}
uiLog.info(`GET /devices - Found ${found.length} devices in ${cfgPath}${invalidTypeDevices.length > 0 ? ` (${invalidTypeDevices.length} with validation warnings)` : ''}`);
return {
success: true,
data: found,
...(invalidTypeDevices.length > 0 && { validationWarnings: invalidTypeDevices }),
};
}
catch (e) {
const msg = e instanceof Error ? e.message : String(e);
uiLog.error(`Error in /devices: ${msg}`);
// Pass the real error message to the frontend for better diagnostics
throw new RequestError(msg || 'Failed to read Homebridge config', e);
}
});
}
//# sourceMappingURL=config.js.map