import type { API, DynamicPlatformPlugin, Logging, PlatformAccessory, PlatformConfig, Service, Characteristic } from 'homebridge'; import miio from 'miio'; import { Accessory } from './accessory.js'; import { Device } from './device.js'; import { PLATFORM_NAME, PLUGIN_NAME } from './settings.js'; export class Platform implements DynamicPlatformPlugin { public readonly Service: typeof Service; public readonly Characteristic: typeof Characteristic; public readonly accessories: Map = new Map(); public readonly discoveredCacheUUIDs: string[] = []; constructor( public readonly log: Logging, public readonly config: PlatformConfig, public readonly api: API, ) { this.Service = api.hap.Service; this.Characteristic = api.hap.Characteristic; this.api.on('didFinishLaunching', () => { this.discoverDevices(); }); } configureAccessory(accessory: PlatformAccessory) { this.log.info('Loading accessory from cache:', accessory.displayName); this.accessories.set(accessory.UUID, accessory); } async discoverDevices() { for (const config of this.config.devices) { const connection = await miio.device({ address: config.address, token: config.token }); const device = new Device(connection); const uuid = this.api.hap.uuid.generate(device.deviceId().toString(16)); const existingAccessory = this.accessories.get(uuid); if (existingAccessory) { this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName); existingAccessory.context.config = config; this.api.updatePlatformAccessories([existingAccessory]); new Accessory(this, existingAccessory, device); } else { this.log.info('Adding new accessory:', config.name); const accessory = new this.api.platformAccessory(config.name, uuid); accessory.context.config = config; new Accessory(this, accessory, device); this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]); } this.discoveredCacheUUIDs.push(uuid); } for (const [uuid, accessory] of this.accessories) { if (! this.discoveredCacheUUIDs.includes(uuid)) { this.log.info('Removing existing accessory from cache:', accessory.displayName); this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, [accessory]); } } } }