UNPKG

homebridge-switchbot-smartlock

Version:

A Homebridge plugin for controlling SwitchBot Smart Lock via the SwitchBot Cloud API.

124 lines (98 loc) 5.34 kB
'use strict'; const { SwitchBotSmartLockAccessory } = require('./accessory'); class SwitchBotSmartLockPlatform { constructor(log, config, api) { this.log = log; this.config = config; this.api = api; this.accessories = []; this.lockAccessories = new Map(); // Store accessory instances separately // Wait for Homebridge to finish launching before adding accessories api.on('didFinishLaunching', () => { this.discoverDevices(); }); } // Required method - called when Homebridge restores cached accessories configureAccessory(accessory) { this.log.info('Loading accessory from cache:', accessory.displayName); // Update the accessory context with current config accessory.context.config = this.config; // Update accessory name if it has changed const newName = this.config.accessoryName || 'Smart Lock'; if (accessory.displayName !== newName) { this.log.info(`Updating accessory name from "${accessory.displayName}" to "${newName}"`); accessory.displayName = newName; accessory._associatedHAPAccessory.displayName = newName; // Update the platform accessories to reflect the name change this.api.updatePlatformAccessories([accessory]); } // Initialize the accessory and store reference separately (not in context) const lockAccessory = new SwitchBotSmartLockAccessory(this, accessory); this.lockAccessories.set(accessory.UUID, lockAccessory); this.accessories.push(accessory); } discoverDevices() { // Check if we already have this accessory const uuid = this.api.hap.uuid.generate('switchbot-smartlock-' + this.config.deviceId); const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid); if (existingAccessory) { // Update existing accessory const newName = this.config.accessoryName || 'Smart Lock'; this.log.info('Restoring existing accessory from cache:', existingAccessory.displayName); // Update name if changed if (existingAccessory.displayName !== newName) { this.log.info(`Updating accessory name from "${existingAccessory.displayName}" to "${newName}"`); existingAccessory.displayName = newName; existingAccessory._associatedHAPAccessory.displayName = newName; // Update the platform accessories to reflect the name change this.api.updatePlatformAccessories([existingAccessory]); } existingAccessory.context.config = this.config; // FIXED: Check if we already have a lock accessory instance for this UUID if (!this.lockAccessories.has(existingAccessory.UUID)) { this.log.info('Creating lock accessory instance for existing accessory'); const lockAccessory = new SwitchBotSmartLockAccessory(this, existingAccessory); this.lockAccessories.set(existingAccessory.UUID, lockAccessory); } else { this.log.info('Lock accessory instance already exists for this accessory'); } } else { // Create new accessory this.log.info('Adding new accessory:', this.config.accessoryName || 'Smart Lock'); this.addAccessory(); } } addAccessory() { const uuid = this.api.hap.uuid.generate('switchbot-smartlock-' + this.config.deviceId); const accessoryName = this.config.accessoryName || 'Smart Lock'; const accessory = new this.api.platformAccessory(accessoryName, uuid); // Set accessory information accessory.getService(this.api.hap.Service.AccessoryInformation) .setCharacteristic(this.api.hap.Characteristic.Manufacturer, 'SwitchBot') .setCharacteristic(this.api.hap.Characteristic.Model, 'Smart Lock') .setCharacteristic(this.api.hap.Characteristic.SerialNumber, this.config.deviceId); // Only store simple config data in context (no circular references) accessory.context.config = this.config; // Store accessory instance separately const lockAccessory = new SwitchBotSmartLockAccessory(this, accessory); this.lockAccessories.set(accessory.UUID, lockAccessory); this.api.registerPlatformAccessories('homebridge-switchbot-smartlock', 'SwitchBotSmartLock', [accessory]); this.accessories.push(accessory); } removeAccessory(accessory) { this.log.info('Removing accessory:', accessory.displayName); // Call destroy method if the accessory instance exists const lockAccessory = this.lockAccessories.get(accessory.UUID); if (lockAccessory && lockAccessory.destroy) { lockAccessory.destroy(); } // Remove from our tracking this.lockAccessories.delete(accessory.UUID); this.api.unregisterPlatformAccessories('homebridge-switchbot-smartlock', 'SwitchBotSmartLock', [accessory]); const index = this.accessories.indexOf(accessory); if (index > -1) { this.accessories.splice(index, 1); } } } module.exports = { SwitchBotSmartLockPlatform };