UNPKG

@switchbot/homebridge-switchbot

Version:

The SwitchBot plugin allows you to access your SwitchBot device(s) from HomeKit.

126 lines (104 loc) 3.67 kB
/** * Ensure required fields are present on the SwitchBot platform config */ export function enforcePlatformConfigFields(platform: any): void { if (!platform) return if (!platform.platform) platform.platform = 'SwitchBot' if (!platform.name) platform.name = 'SwitchBot' if (!Array.isArray(platform.devices)) platform.devices = [] } import type { HomebridgePluginUiServer } from '@homebridge/plugin-ui-utils' import fs from 'node:fs/promises' import { uiLog } from './logger.js' // Module-scope regex pattern to avoid recompilation export const SWITCHBOT_PLATFORM_REGEX = /switchbot/i /** * Get reference to the devices array in platform config */ export function getDevicesRef(platform: any): any[] { if (!platform || typeof platform !== 'object') { return [] } if (Array.isArray(platform.devices)) { return platform.devices } platform.devices = [] return platform.devices } /** * Get all device arrays from platform config */ export function getDeviceArrays(platform: any): any[][] { const rootDevices = getDevicesRef(platform) return [rootDevices] } /** * Get all unique devices from platform config */ export function getAllDevices(platform: any): any[] { const all = getDevicesRef(platform) const seen = new Set<string>() return all.filter((d: any) => { const id = String(d?.deviceId ?? d?.id ?? '').trim().toLowerCase() if (!id || seen.has(id)) { return false } seen.add(id) return true }) } /** * Get credential from platform config */ export function getCredential(platform: any, key: 'openApiToken' | 'openApiSecret'): string | undefined { return platform?.[key] } /** * Set credential in platform config */ export function setCredential(platform: any, key: 'openApiToken' | 'openApiSecret', value: string): void { if (!platform || typeof platform !== 'object') { return } platform[key] = value } /** * Find and parse the SwitchBot platform config from Homebridge config file */ export async function getSwitchBotPlatformConfig(server: HomebridgePluginUiServer) { const cfgPath = server.homebridgeConfigPath if (!cfgPath) { throw new Error('HOMEBRIDGE_CONFIG_PATH not set') } const raw = await fs.readFile(cfgPath, 'utf-8') const cfg = JSON.parse(raw) const platforms = Array.isArray(cfg.platforms) ? cfg.platforms : [] const candidates = platforms.filter((p: any) => { const platformName = p.platform || p.name || '' return !!platformName && (SWITCHBOT_PLATFORM_REGEX.test(String(platformName)) || String(platformName).toLowerCase() === '@switchbot/homebridge-switchbot') }) uiLog.info(`Found ${candidates.length} SwitchBot candidate(s)`) const platform = candidates.find((p: any) => { const name = String(p.platform || '').toLowerCase() return name === 'switchbot' || name.includes('switchbot') }) if (!platform) { throw new Error('SwitchBot platform not found in config. Please add the plugin configuration first.') } uiLog.info(`Using SwitchBot platform: ${platform.name || platform.platform || 'SwitchBot'}`) return { platform, cfg, cfgPath } } /** * Save the Homebridge config file */ export async function saveConfig(cfgPath: string, cfg: any): Promise<void> { // Defensive: enforce required fields on all SwitchBot platform blocks before saving if (cfg && Array.isArray(cfg.platforms)) { for (const p of cfg.platforms) { if (p && (String(p.platform || '').toLowerCase() === 'switchbot' || String(p.name || '').toLowerCase() === 'switchbot')) { enforcePlatformConfigFields(p) } } } await fs.writeFile(cfgPath, JSON.stringify(cfg, null, 2), 'utf-8') }