{"version":3,"file":"index.cjs","names":["Perms","Categories","LogLevel","Temperature","ADDON_SENSOR_MIN_ID","Humidity","ShellyPlus1","ShellyPlus1Ul","ShellyPlus1V3","ShellyPlus1Mini","ShellyPlus1MiniV3","ShellyGen4One","ShellyGen4OneMini","ShellyGen4OneAnz","Shelly1LGen3","ShellyPlus1Pm","ShellyPlus1PmUl","ShellyPlus1PmV3","ShellyPlus1PmMini","ShellyPlus1PmMiniV3","ShellyGen4OnePm","ShellyGen4OnePmAnz","ShellyPlusPmMini","ShellyPlusPmMiniV3","ShellyPlus2Pm","ShellyPlus2PmRev1","ShellyGen32Pm","ShellyGen42Pm","ShellyGen42PmAnz","ShellyPlusI4","ShellyPlusI4V3","ShellyPlusI4Dc","ShellyPlusPlugUs","ShellyPlusPlugEu","ShellyPlusPlugIt","ShellyPlusPlugUk","ShellyPlugSG3Eu","ShellyPlugAzG3Eu","ShellyOutdoorPlugSG3Eu","ShellyPlugMG3Eu","ShellyPlugPmG3Eu","ShellyPlugUsG4","ShellyPro1","ShellyPro1Rev1","ShellyPro1Rev2","ShellyPro1Rev2Ul","ShellyPro1Pm","ShellyPro1PmRev1","ShellyPro1PmRev2","ShellyPro1PmRev2Ul","ShellyPro2","ShellyPro2Rev1","ShellyPro2Rev2","ShellyPro3","ShellyPro2Pm","ShellyPro2PmRev1","ShellyPro2PmRev2","ShellyPro4Pm","ShellyPro4PmV2","ShellyPro4PmV3","ShellyProDimmer1Pm","ShellyProDimmer1Pm2","ShellyDimmer","ShellyProDimmer2Pm","ShellyProDualCoverPm","ShellyPlusPMDimmer","ShellyPlusDimmer","ShellyGen4Mini","ShellyPowerStrip4G4","ShellyPowerStrip4G4Black","DeviceDiscoverer","Shellies","MdnsDeviceDiscoverer"],"sources":["../src/utils/characteristics.ts","../src/utils/services.ts","../src/utils/device-cache.ts","../src/abilities/base.ts","../src/abilities/accessory-information.ts","../src/abilities/cover.ts","../src/abilities/light.ts","../src/abilities/outlet.ts","../src/abilities/power-meter.ts","../src/abilities/readonly-switch.ts","../src/abilities/service-label.ts","../src/abilities/stateless-programmable-switch.ts","../src/abilities/switch.ts","../src/abilities/pm1.ts","../src/abilities/temperature-sensor.ts","../src/abilities/humidity-sensor.ts","../src/accessory.ts","../src/utils/device-logger.ts","../src/device-delegates/base.ts","../src/device-delegates/shelly-plus-1.ts","../src/device-delegates/shelly-plus-1-pm.ts","../src/device-delegates/shelly-plus-pm.ts","../src/device-delegates/shelly-plus-2-pm.ts","../src/device-delegates/shelly-plus-i4.ts","../src/device-delegates/shelly-plus-plug.ts","../src/device-delegates/shelly-pro-1.ts","../src/device-delegates/shelly-pro-1-pm.ts","../src/device-delegates/shelly-pro-2.ts","../src/device-delegates/shelly-pro-3.ts","../src/device-delegates/shelly-pro-2-pm.ts","../src/device-delegates/shelly-pro-4-pm.ts","../src/device-delegates/shelly-pro-dimmer-1-pm.ts","../src/device-delegates/shelly-pro-dimmer-2-pm.ts","../src/device-delegates/shelly-pro-dual-cover-pm.ts","../src/device-delegates/shelly-plus-dimmer-pm.ts","../src/device-delegates/shelly-plus-dimmer.ts","../src/device-delegates/shelly-gen4-mini.ts","../src/device-delegates/shelly-gen4-power-strip-4.ts","../src/config.ts","../src/platform.ts","../src/index.ts"],"sourcesContent":["import { API, Characteristic, WithUUID } from 'homebridge';\n\ntype C = WithUUID<new () => Characteristic> & WithUUID<typeof Characteristic>;\n\nexport interface CustomCharacteristics {\n    CurrentConsumption: C;\n    ElectricCurrent: C;\n    TotalConsumption: C;\n    Voltage: C;\n}\n\n/**\n * Returns a set of custom HomeKit characteristics.\n * @param api - A reference to the homebridge API.\n */\nexport const createCharacteristics = (api: API): CustomCharacteristics => {\n    /**\n     * Current energy consumption, in watts.\n     */\n    class CurrentConsumption extends api.hap.Characteristic {\n        static readonly UUID = 'E863F10D-079E-48FF-8F27-9C2605A29F52';\n\n        constructor() {\n            super('Current Consumption', CurrentConsumption.UUID, {\n                format: api.hap.Formats.FLOAT,\n                perms: [api.hap.Perms.NOTIFY, api.hap.Perms.PAIRED_READ],\n                unit: 'W',\n                minValue: 0,\n                maxValue: 12000,\n                minStep: 0.1,\n            });\n        }\n    }\n\n    /**\n     * Current measured electric current, in amperes.\n     */\n    class ElectricCurrent extends api.hap.Characteristic {\n        static readonly UUID = 'E863F126-079E-48FF-8F27-9C2605A29F52';\n\n        constructor() {\n            super('Electric Current', ElectricCurrent.UUID, {\n                format: api.hap.Formats.FLOAT,\n                perms: [api.hap.Perms.NOTIFY, api.hap.Perms.PAIRED_READ],\n                unit: 'A',\n                minValue: 0,\n                maxValue: 48,\n                minStep: 0.1,\n            });\n        }\n    }\n\n    /**\n     * Total energy consumption, in kilowatt hours.\n     */\n    class TotalConsumption extends api.hap.Characteristic {\n        static readonly UUID = 'E863F10C-079E-48FF-8F27-9C2605A29F52';\n\n        constructor() {\n            super('Total Consumption', TotalConsumption.UUID, {\n                format: api.hap.Formats.FLOAT,\n                perms: [api.hap.Perms.NOTIFY, api.hap.Perms.PAIRED_READ],\n                unit: 'kWh',\n                minValue: 0,\n                maxValue: 1000000,\n                minStep: 0.1,\n            });\n        }\n    }\n\n    /**\n     * Current measured voltage, in volts.\n     */\n    class Voltage extends api.hap.Characteristic {\n        static readonly UUID = 'E863F10A-079E-48FF-8F27-9C2605A29F52';\n\n        constructor() {\n            super('Voltage', Voltage.UUID, {\n                format: api.hap.Formats.FLOAT,\n                perms: [api.hap.Perms.NOTIFY, api.hap.Perms.PAIRED_READ],\n                unit: 'V',\n                minValue: -1000,\n                maxValue: 1000,\n                minStep: 0.1,\n            });\n        }\n    }\n\n    return {\n        CurrentConsumption,\n        ElectricCurrent,\n        TotalConsumption,\n        Voltage,\n    };\n};\n","import { API, Service, WithUUID } from 'homebridge';\n\nimport { CustomCharacteristics } from './characteristics.ts';\n\ntype S = WithUUID<typeof Service>;\n\nexport interface CustomServices {\n    PowerMeter: S;\n    Pm1: S;\n}\n\n/**\n * Returns a set of custom HomeKit services.\n * @param api - A reference to the homebridge API.\n * @param characteristics - Custom characteristics used with these services.\n */\nexport const createServices = (api: API, characteristics: CustomCharacteristics): CustomServices => {\n    /**\n     * Reports power meter readings.\n     */\n    class PowerMeter extends api.hap.Service {\n        static readonly UUID = 'DEDBEA44-11ED-429C-BD75-9A2286AA8707';\n\n        constructor(displayName?: string, subtype?: string) {\n            super(displayName, PowerMeter.UUID, subtype);\n\n            this.addCharacteristic(characteristics.CurrentConsumption);\n\n            this.addOptionalCharacteristic(characteristics.TotalConsumption);\n            this.addOptionalCharacteristic(characteristics.ElectricCurrent);\n            this.addOptionalCharacteristic(characteristics.Voltage);\n        }\n    }\n    /**\n     * Reports Pm1 readings.\n     */\n    class Pm1 extends api.hap.Service {\n        static readonly UUID = 'DEDBEA44-11ED-429C-BD75-9A2286AA8707';\n\n        constructor(displayName?: string, subtype?: string) {\n            super(displayName, Pm1.UUID, subtype);\n\n            this.addCharacteristic(characteristics.CurrentConsumption);\n            this.addOptionalCharacteristic(characteristics.TotalConsumption);\n            this.addOptionalCharacteristic(characteristics.ElectricCurrent);\n            this.addOptionalCharacteristic(characteristics.Voltage);\n        }\n    }\n\n    return {\n        PowerMeter,\n        Pm1,\n    };\n};\n","import { Logger } from 'homebridge';\nimport { promises as fs } from 'fs';\nimport { resolve } from 'path';\n\nimport { Device, DeviceId, WebSocketRpcHandler } from '@lucavb/shellies-ds9';\n\nconst FILENAME = '.shelly-ds9.json';\nconst LEGACY_FILENAME = '.shelly-ng.json';\n\nconst SAVE_DELAY = 1000;\n\nexport interface CachedDeviceInfo {\n    /**\n     * Device ID.\n     */\n    id: DeviceId;\n    /**\n     * Device model.\n     */\n    model: string;\n    /**\n     * RPC handler protocol.\n     */\n    protocol: string;\n    /**\n     * The device's IP address or hostname.\n     */\n    hostname?: string;\n}\n\nexport interface DeviceStorage {\n    devices: CachedDeviceInfo[];\n}\n\n/**\n * Handles saving and loading device information to a cache file.\n */\nexport class DeviceCache {\n    /**\n     * A path to the cache file.\n     */\n    readonly path: string;\n\n    /**\n     * A path to the legacy cache file from the upstream plugin.\n     */\n    readonly legacyPath: string;\n\n    /**\n     * Holds all devices loaded from the cache file.\n     */\n    protected devices = new Map<DeviceId, CachedDeviceInfo>();\n\n    private saveTimeout: ReturnType<typeof setTimeout> | null = null;\n\n    /**\n     * @param storagePath - A path to the directory that the devices will be stored in.\n     * @param log - A logging device.\n     */\n    constructor(\n        storagePath: string,\n        readonly log: Logger,\n    ) {\n        this.path = resolve(storagePath, FILENAME);\n        this.legacyPath = resolve(storagePath, LEGACY_FILENAME);\n    }\n\n    /**\n     * Loads cached devices.\n     */\n    async load() {\n        this.devices.clear();\n\n        let data: string | undefined;\n        let loadedFromLegacy = false;\n\n        for (const filePath of [this.path, this.legacyPath]) {\n            try {\n                await fs.access(filePath);\n                data = await fs.readFile(filePath, { encoding: 'utf8' });\n                loadedFromLegacy = filePath === this.legacyPath;\n                break;\n            } catch {\n                // try next path\n            }\n        }\n\n        if (data === undefined) {\n            this.log.debug('Device cache file ' + this.path + ' not found');\n            return;\n        }\n\n        const s = JSON.parse(data) as DeviceStorage;\n\n        this.log.debug(`Loaded ${s.devices.length} device(s) from cache`);\n\n        for (const d of s.devices) {\n            this.devices.set(d.id, d);\n        }\n\n        if (loadedFromLegacy) {\n            this.saveDelayed();\n        }\n    }\n\n    /**\n     * Saves the devices to cache.\n     */\n    async save() {\n        // serialize the devices\n        const s = { devices: Array.from(this.devices.values()) };\n        const data = JSON.stringify(s);\n\n        this.log.debug(`Saving ${s.devices.length} device(s) to cache`);\n\n        // write them to disk\n        return fs.writeFile(this.path, data);\n    }\n\n    /**\n     * Saves the devices to cache after a short delay.\n     * Multiple calls to this method within the delay will be debounced.\n     */\n    saveDelayed() {\n        // clear any previously set timeout\n        if (this.saveTimeout !== null) {\n            clearTimeout(this.saveTimeout);\n        }\n\n        this.saveTimeout = setTimeout(async () => {\n            this.saveTimeout = null;\n\n            try {\n                await this.save();\n            } catch (e) {\n                this.log.error('Failed to save devices to cache:', e instanceof Error ? e.message : e);\n            }\n        }, SAVE_DELAY);\n    }\n\n    /**\n     * Returns device info for the given device ID.\n     */\n    get(id: DeviceId): CachedDeviceInfo | undefined {\n        return this.devices.get(id);\n    }\n\n    /**\n     * Stores the given device info.\n     * @param d - The device info.\n     * @param autoSave - Whether `saveDelayed()` should be automatically invoked.\n     */\n    set(d: CachedDeviceInfo, autoSave = true) {\n        this.devices.set(d.id, d);\n\n        if (autoSave === true) {\n            this.saveDelayed();\n        }\n    }\n\n    /**\n     * Stores info about the given device in cache.\n     * @param device - The device.\n     * @param autoSave - Whether `saveDelayed()` should be automatically invoked.\n     */\n    storeDevice(device: Device, autoSave = true) {\n        const protocol = device.rpcHandler.protocol;\n        let hostname;\n\n        if (protocol === 'websocket') {\n            hostname = (device.rpcHandler as WebSocketRpcHandler).hostname;\n        }\n\n        this.set({ hostname, id: device.id, model: device.model, protocol }, autoSave);\n    }\n\n    /**\n     * Deletes info about the device with the given ID from cache.\n     * @param id - The device ID.\n     * @param autoSave - Whether `saveDelayed()` should be automatically invoked.\n     */\n    delete(id: DeviceId, autoSave = true) {\n        this.devices.delete(id);\n\n        if (autoSave === true) {\n            this.saveDelayed();\n        }\n    }\n\n    /**\n     * Returns a new Iterator object that contains each device.\n     */\n    [Symbol.iterator](): IterableIterator<CachedDeviceInfo> {\n        return this.devices.values();\n    }\n}\n","import { API, Characteristic, PlatformAccessory, Service, WithUUID } from 'homebridge';\n\nimport { CustomCharacteristics } from '../utils/characteristics.ts';\nimport { CustomServices } from '../utils/services.ts';\nimport { DeviceLogger } from '../utils/device-logger.ts';\nimport { ShellyPlatform } from '../platform.ts';\n\nexport type ServiceClass = WithUUID<typeof Service>;\n\n/**\n * Base class for all abilities.\n * An ability is roughly equivalent to a HomeKit service.\n */\nexport abstract class Ability {\n    private _platformAccessory: PlatformAccessory | null = null;\n\n    /**\n     * The associated platform accessory.\n     */\n    get platformAccessory(): PlatformAccessory {\n        if (this._platformAccessory === null) {\n            throw new Error('Ability has not yet been setup');\n        }\n        return this._platformAccessory;\n    }\n\n    private _platform: ShellyPlatform | null = null;\n\n    /**\n     * A reference to the platform.\n     */\n    protected get platform(): ShellyPlatform {\n        if (this._platform === null) {\n            throw new Error('Ability has not yet been setup');\n        }\n        return this._platform;\n    }\n\n    /**\n     * A reference to the homebridge API.\n     */\n    protected get api(): API {\n        return this.platform.api;\n    }\n\n    /**\n     * Shorthand property.\n     */\n    protected get Characteristic(): typeof Characteristic {\n        return this.platform.api.hap.Characteristic;\n    }\n\n    /**\n     * Shorthand property.\n     */\n    protected get Service(): typeof Service {\n        return this.platform.api.hap.Service;\n    }\n\n    /**\n     * Shorthand property.\n     */\n    protected get customCharacteristics(): CustomCharacteristics {\n        return this.platform.customCharacteristics;\n    }\n\n    /**\n     * Shorthand property.\n     */\n    protected get customServices(): CustomServices {\n        return this.platform.customServices;\n    }\n\n    private _log: DeviceLogger | null = null;\n\n    /**\n     * The logging device to use.\n     */\n    protected get log(): DeviceLogger {\n        if (this._log === null) {\n            throw new Error('Ability has not yet been setup');\n        }\n        return this._log;\n    }\n\n    private _service: Service | null = null;\n\n    /**\n     * The HomeKit service that this ability uses.\n     */\n    protected get service(): Service {\n        if (this._service === null) {\n            throw new Error('Ability has not yet been setup');\n        }\n        return this._service;\n    }\n\n    private _active = true;\n\n    /**\n     * Whether this ability is active.\n     * Setting an ability to inactive will remove its HomeKit service.\n     */\n    get active(): boolean {\n        return this._active;\n    }\n\n    set active(value) {\n        if (value === this._active) {\n            return;\n        }\n\n        this._active = value;\n        this.update();\n    }\n\n    /**\n     * @param serviceName - A name of the service.\n     * @param serviceSubtype - A unique identifier for the service.\n     */\n    constructor(\n        protected readonly serviceName?: string,\n        protected readonly serviceSubtype?: string,\n    ) {}\n\n    /**\n     * Sets up this ability.\n     * This method is called by the parent accessory every time it becomes active.\n     * @param platformAccessory - The homebridge platform accessory to use.\n     * @param platform - A reference to the platform.\n     * @param log - The logger to use.\n     */\n    setup(platformAccessory: PlatformAccessory, platform: ShellyPlatform, log: DeviceLogger) {\n        this._platformAccessory = platformAccessory;\n        this._platform = platform;\n        this._log = log;\n\n        this.update();\n    }\n\n    /**\n     * Sets `active` to the given value.\n     * This method can be used when chaining calls, as it returns a reference to `this`.\n     * @param value - Whether the ability should be active.\n     */\n    setActive(value: boolean): this {\n        this.active = value;\n        return this;\n    }\n\n    /**\n     * Determines whether this ability is active.\n     * The default implementation simply returns the value of the `active` property.\n     * Subclasses can override this method to add more conditions.\n     */\n    protected isActive(): boolean {\n        return this.active;\n    }\n\n    /**\n     * Updates this ability based on whether it is active.\n     * If active, its service will be added and initialized.\n     * If inactive, its service will be removed.\n     */\n    protected update() {\n        if (this._platformAccessory === null) {\n            // abort if setup() hasn't been called yet\n            return;\n        }\n\n        if (this.isActive()) {\n            // we're active, add and initialize our service\n            if (this._service === null) {\n                this._service = this.addService();\n                this.initialize();\n            }\n        } else {\n            // we're inactive, detach from and remove our service\n            if (this._service !== null) {\n                this.detach();\n            }\n\n            this.removeService();\n            this._service = null;\n        }\n    }\n\n    /**\n     * Returns a service for this ability.\n     * If the platform accessory has a matching service, it will be returned. Otherwise, the service will be added.\n     */\n    protected addService(): Service | null {\n        let service: Service | undefined;\n        if (this.serviceName && this.serviceSubtype) {\n            service =\n                this.platformAccessory.getService(this.serviceName) ||\n                this.platformAccessory.addService(this.serviceClass, this.serviceName, this.serviceSubtype);\n        } else {\n            service = this.platformAccessory.getService(this.serviceClass);\n        }\n        return service ?? null;\n    }\n\n    /**\n     * Removes this ability's service from the platform accessory.\n     */\n    protected removeService() {\n        let service: Service | undefined;\n\n        // since the platform accessory may have been loaded from cache with a service created previously,\n        // we can't just rely on the _service property here\n        if (this._service !== null) {\n            service = this._service;\n        } else if (this.serviceName && this.serviceSubtype) {\n            service = this.platformAccessory.getService(this.serviceName);\n        } else {\n            service = this.platformAccessory.getService(this.serviceClass);\n        }\n\n        if (service) {\n            this.platformAccessory.removeService(service);\n        }\n    }\n\n    /**\n     * Helper method that removes a characteristic based on its class (Service.removeCharacteristic()\n     * only accepts an instance).\n     * @param characteristic - The characteristic to remove.\n     */\n    protected removeCharacteristic(\n        characteristic: WithUUID<new () => Characteristic> & WithUUID<typeof Characteristic>,\n    ) {\n        const s = this.service;\n\n        // getCharacteristic() will add the characteristic if it doesn't exist, so we need to use testCharacteristic() to avoid\n        // adding and then immediately removing it\n        if (s.testCharacteristic(characteristic)) {\n            s.removeCharacteristic(s.getCharacteristic(characteristic));\n        }\n    }\n\n    /**\n     * Subclasses should implement this method to return the HomeKit service type to use.\n     */\n    protected abstract get serviceClass(): ServiceClass;\n\n    /**\n     * Subclasses should use this method to initialize the service and attach their event listeners.\n     */\n    protected abstract initialize();\n\n    /**\n     * Subclasses should use this method to remove their event listeners.\n     */\n    abstract detach();\n\n    /**\n     * Removes all event listeners and all references to the platform accessory.\n     * This method is called by the parent accessory every time it becomes inactive.\n     * Note that this method doesn't remove the service from the platform accessory as it is assumed that\n     * the entire platform accessory is about to be unregistered and discarded.\n     */\n    destroy() {\n        this.detach();\n\n        this._platformAccessory = null;\n        this._platform = null;\n        this._log = null;\n        this._service = null;\n    }\n}\n","import { Device } from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\n/**\n * Handles the AccessoryInformation service.\n */\nexport class AccessoryInformationAbility extends Ability {\n    /**\n     * @param device - The associated device.\n     */\n    constructor(readonly device: Device) {\n        super();\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.Service.AccessoryInformation;\n    }\n\n    protected initialize() {\n        this.service\n            .setCharacteristic(this.Characteristic.Name, this.platformAccessory.displayName)\n            .setCharacteristic(this.Characteristic.Manufacturer, 'Allterco')\n            .setCharacteristic(this.Characteristic.Model, this.device.modelName)\n            .setCharacteristic(this.Characteristic.SerialNumber, this.device.macAddress)\n            .setCharacteristic(this.Characteristic.FirmwareRevision, this.device.firmware.version || '1.0.0');\n    }\n\n    detach() {\n        // no event handlers\n    }\n}\n","import { CharacteristicValue } from 'homebridge';\nimport { Cover } from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\nconst names = {\n    door: 'Door',\n    window: 'Window',\n    windowCovering: 'Window Covering',\n};\n\nexport class CoverAbility extends Ability {\n    /**\n     * @param component - The cover component to control.\n     * @param type - The type of cover.\n     */\n    constructor(\n        readonly component: Cover,\n        readonly type: 'door' | 'window' | 'windowCovering' = 'window',\n    ) {\n        super(`${names[type]} ${component.id + 1}`, `${type}-${component.id}`);\n    }\n\n    protected get serviceClass(): ServiceClass {\n        if (this.type === 'door') {\n            return this.Service.Door;\n        } else if (this.type === 'windowCovering') {\n            return this.Service.WindowCovering;\n        }\n        return this.Service.Window;\n    }\n\n    /**\n     * The current state of the cover.\n     */\n    protected get positionState(): CharacteristicValue {\n        const state = this.component.state;\n\n        if (state === 'opening') {\n            return this.Characteristic.PositionState.INCREASING;\n        } else if (state === 'closing') {\n            return this.Characteristic.PositionState.DECREASING;\n        }\n\n        return this.Characteristic.PositionState.STOPPED;\n    }\n\n    /**\n     * The current position of the cover.\n     */\n    protected get currentPosition(): number {\n        return this.component.current_pos ?? 0;\n    }\n\n    /**\n     * The target position that the cover is moving towards.\n     */\n    protected get targetPosition(): number {\n        return this.component.target_pos ?? this.currentPosition;\n    }\n\n    protected initialize() {\n        // abort if this cover hasn't been calibrated\n        if (!this.component.pos_control) {\n            this.log.warn('Only calibrated covers are supported.');\n            return;\n        }\n\n        // set the initial values\n        this.service\n            .setCharacteristic(this.Characteristic.PositionState, this.positionState)\n            .setCharacteristic(this.Characteristic.CurrentPosition, this.currentPosition)\n            .setCharacteristic(this.Characteristic.TargetPosition, this.targetPosition);\n\n        // listen for commands from HomeKit\n        this.service\n            .getCharacteristic(this.Characteristic.TargetPosition)\n            .onSet(this.targetPositionSetHandler.bind(this));\n\n        // listen for updates from the device\n        this.component\n            .on('change:state', this.stateChangeHandler, this)\n            .on('change:current_pos', this.currentPosChangeHandler, this)\n            .on('change:target_pos', this.targetPosChangeHandler, this);\n    }\n\n    detach() {\n        this.component\n            .off('change:state', this.stateChangeHandler, this)\n            .off('change:current_pos', this.currentPosChangeHandler, this)\n            .off('change:target_pos', this.targetPosChangeHandler, this);\n    }\n\n    /**\n     * Handles changes to the TargetPosition characteristic.\n     */\n    protected async targetPositionSetHandler(value: CharacteristicValue) {\n        if (value === this.component.target_pos) {\n            return;\n        }\n\n        try {\n            await this.component.goToPosition(value as number);\n        } catch (e) {\n            this.log.error('Failed to set target position:', e instanceof Error ? e.message : e);\n            throw new this.api.hap.HapStatusError(this.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);\n        }\n    }\n\n    /**\n     * Handles changes to the `state` property.\n     */\n    protected stateChangeHandler() {\n        this.log.debug(`${this.component.id} state changed to ${this.positionState}`, {\n            target: this.targetPosition,\n            current: this.currentPosition,\n        });\n        this.updateStates();\n    }\n\n    /**\n     * Updates all states.\n     *\n     * Shelly does not send all attributes in a single notification.\n     * We apparently need to update all states when any of them change, otherwise HomeKit\n     * gets confused and thinks the cover is in a different state than it actually is.\n     */\n    protected updateStates() {\n        this.service.getCharacteristic(this.Characteristic.PositionState).updateValue(this.positionState);\n        this.service.getCharacteristic(this.Characteristic.TargetPosition).updateValue(this.targetPosition);\n        this.service.getCharacteristic(this.Characteristic.CurrentPosition).updateValue(this.currentPosition);\n    }\n\n    /**\n     * Handles changes to the `current_pos` property.\n     */\n    protected currentPosChangeHandler() {\n        this.log.debug(`${this.component.id} position changed to ${this.currentPosition}`, {\n            target: this.targetPosition,\n            state: this.positionState,\n        });\n        this.updateStates();\n\n        // Shelly does not update the target position when it is triggered with a physical switch.\n        // If we don't change the target position, HomeKit waits for the original position forever.\n        this.service.getCharacteristic(this.Characteristic.TargetPosition).updateValue(this.currentPosition);\n    }\n\n    /**\n     * Handles changes to the `target_pos` property.\n     */\n    protected targetPosChangeHandler() {\n        this.log.debug(`${this.component.id} target position changed to ${this.targetPosition}`, {\n            state: this.positionState,\n            current: this.currentPosition,\n        });\n        this.updateStates();\n    }\n}\n","import { CharacteristicValue } from 'homebridge';\nimport { CharacteristicValue as ShelliesCharacteristicValue, Light } from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\nexport class LightAbility extends Ability {\n    /**\n     * @param component - The light component to control.\n     */\n    constructor(readonly component: Light) {\n        super(`Light ${component.id + 1}`, `light-${component.id}`);\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.Service.Lightbulb;\n    }\n\n    protected initialize() {\n        // set the initial value\n        this.service.setCharacteristic(this.Characteristic.On, this.component.output);\n\n        // listen for commands from HomeKit\n        this.service.getCharacteristic(this.Characteristic.On).onSet(this.onSetHandler.bind(this));\n        this.service.getCharacteristic(this.Characteristic.Brightness).onSet(this.brightnessSetHandler.bind(this));\n\n        // listen for updates from the device\n        this.component.on('change:output', this.outputChangeHandler, this);\n        this.component.on('change:brightness', this.brightnessChangeHandler, this);\n    }\n\n    detach() {\n        this.component.off('change:output', this.outputChangeHandler, this);\n        this.component.off('change:brightness', this.brightnessChangeHandler, this);\n    }\n\n    /**\n     * Handles changes to the Light.On characteristic.\n     */\n    protected async onSetHandler(value: CharacteristicValue) {\n        if (value === this.component.output) {\n            return;\n        }\n\n        try {\n            await this.component.set(value as boolean);\n        } catch (e) {\n            this.log.error('Failed to set light:', e instanceof Error ? e.message : e);\n            throw new this.api.hap.HapStatusError(this.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);\n        }\n    }\n\n    /**\n     * Handles changes to the `output` property.\n     */\n    protected outputChangeHandler(value: ShelliesCharacteristicValue) {\n        if (value) {\n            this.log.info('Light Status(' + this.component.id + '): on');\n        } else {\n            this.log.info('Light Status(' + this.component.id + '): off');\n        }\n        this.service.getCharacteristic(this.Characteristic.On).updateValue(value as boolean);\n    }\n\n    /**\n     * Handles changes to the Light.Brightness characteristic.\n     */\n    protected async brightnessSetHandler(value: CharacteristicValue) {\n        if (value === this.component.brightness) {\n            return;\n        }\n\n        try {\n            await this.component.set(undefined, value as number);\n        } catch (e) {\n            this.log.error('Failed to set light:', e instanceof Error ? e.message : e);\n            throw new this.api.hap.HapStatusError(this.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);\n        }\n    }\n\n    /**\n     * Handles changes to the `brightness` property.\n     */\n    protected brightnessChangeHandler(value: ShelliesCharacteristicValue) {\n        this.log.info('Light Status(' + this.component.id + '): ' + value);\n        this.service.getCharacteristic(this.Characteristic.Brightness).updateValue(value as number);\n    }\n}\n","import { CharacteristicValue } from 'homebridge';\nimport { CharacteristicValue as ShelliesCharacteristicValue, Switch } from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\nexport class OutletAbility extends Ability {\n    /**\n     * @param component - The switch component to control.\n     */\n    constructor(readonly component: Switch) {\n        super(`Outlet ${component.id + 1}`, `outlet-${component.id}`);\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.Service.Outlet;\n    }\n\n    protected initialize() {\n        // set the initial values\n        this.service\n            .setCharacteristic(this.Characteristic.On, this.component.output)\n            .setCharacteristic(\n                this.Characteristic.OutletInUse,\n                this.component.apower !== undefined && this.component.apower !== 0,\n            );\n\n        // listen for commands from HomeKit\n        this.service.getCharacteristic(this.Characteristic.On).onSet(this.onSetHandler.bind(this));\n\n        // listen for updates from the device\n        this.component\n            .on('change:output', this.outputChangeHandler, this)\n            .on('change:apower', this.apowerChangeHandler, this);\n    }\n\n    detach() {\n        this.component\n            .off('change:output', this.outputChangeHandler, this)\n            .off('change:apower', this.apowerChangeHandler, this);\n    }\n\n    /**\n     * Handles changes to the Outlet.On characteristic.\n     */\n    protected async onSetHandler(value: CharacteristicValue) {\n        if (value === this.component.output) {\n            return;\n        }\n\n        try {\n            await this.component.set(value as boolean);\n        } catch (e) {\n            this.log.error('Failed to set switch:', e instanceof Error ? e.message : e);\n            throw new this.api.hap.HapStatusError(this.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);\n        }\n    }\n\n    /**\n     * Handles changes to the `output` property.\n     */\n    protected outputChangeHandler(value: ShelliesCharacteristicValue) {\n        if (value) {\n            this.log.info('Switch Status(' + this.component.id + '): on');\n        } else {\n            this.log.info('Switch Status(' + this.component.id + '): off');\n        }\n\n        this.service.getCharacteristic(this.Characteristic.On).updateValue(value as boolean);\n    }\n\n    /**\n     * Handles changes to the `apower` property.\n     */\n    protected apowerChangeHandler(value: ShelliesCharacteristicValue) {\n        this.service.getCharacteristic(this.Characteristic.OutletInUse).updateValue(value as number);\n    }\n}\n","import {\n    CharacteristicValue as ShelliesCharacteristicValue,\n    Cover,\n    Switch,\n    SwitchEnergyCounterAttributes,\n} from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\n/**\n * This ability sets up a custom service that reports power meter readings.\n */\nexport class PowerMeterAbility extends Ability {\n    /**\n     * @param component - The switch or cover component to get readings from.\n     */\n    constructor(readonly component: Switch | Cover) {\n        super(`Power Meter ${component.id + 1}`, `power-meter-${component.id}`);\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.customServices.PowerMeter;\n    }\n\n    protected initialize() {\n        const s = this.service;\n        const c = this.component;\n        const cc = this.customCharacteristics;\n\n        // setup Current Consumption\n        s.setCharacteristic(cc.CurrentConsumption, c.apower ?? 0);\n\n        c.on('change:apower', this.apowerChangeHandler, this);\n\n        // setup Voltage\n        if (c.voltage !== undefined) {\n            s.setCharacteristic(cc.Voltage, c.voltage);\n\n            c.on('change:voltage', this.voltageChangeHandler, this);\n        } else {\n            this.removeCharacteristic(cc.Voltage);\n        }\n\n        // setup Electric Current\n        if (c.current !== undefined) {\n            s.setCharacteristic(cc.ElectricCurrent, c.current);\n\n            c.on('change:current', this.currentChangeHandler, this);\n        } else {\n            this.removeCharacteristic(cc.ElectricCurrent);\n        }\n\n        // setup Total Consumption\n        if (c.aenergy !== undefined) {\n            s.setCharacteristic(cc.TotalConsumption, c.aenergy.total / 1000);\n\n            c.on('change:aenergy', this.aenergyChangeHandler, this);\n        } else {\n            this.removeCharacteristic(cc.TotalConsumption);\n        }\n    }\n\n    detach() {\n        this.component\n            .off('change:apower', this.apowerChangeHandler, this)\n            .off('change:voltage', this.voltageChangeHandler, this)\n            .off('change:current', this.currentChangeHandler, this)\n            .off('change:aenergy', this.aenergyChangeHandler, this);\n    }\n\n    /**\n     * Handles changes to the `apower` property.\n     */\n    protected apowerChangeHandler(value: ShelliesCharacteristicValue) {\n        /**\n         * Handles changes to the 'apower' property. HomeKit does not support negative values for the 'Current Consumption' characteristic.\n         * For the use case of this plugin, knowing the negative voltage is not necessary, so we ensure that the value is never negative.\n         */\n        const positiveValue = Math.max(0, value as number);\n        this.service.updateCharacteristic(this.customCharacteristics.CurrentConsumption, positiveValue);\n    }\n\n    /**\n     * Handles changes to the `voltage` property.\n     */\n    protected voltageChangeHandler(value: ShelliesCharacteristicValue) {\n        this.service.updateCharacteristic(this.customCharacteristics.Voltage, value as number);\n    }\n\n    /**\n     * Handles changes to the `current` property.\n     */\n    protected currentChangeHandler(value: ShelliesCharacteristicValue) {\n        this.service.updateCharacteristic(this.customCharacteristics.ElectricCurrent, value as number);\n    }\n\n    /**\n     * Handles changes to the `aenergy` property.\n     */\n    protected aenergyChangeHandler(value: ShelliesCharacteristicValue) {\n        const attr = value as unknown as SwitchEnergyCounterAttributes;\n\n        this.service.updateCharacteristic(this.customCharacteristics.TotalConsumption, attr.total / 1000);\n    }\n}\n","import { Perms } from 'homebridge';\nimport { CharacteristicValue as ShelliesCharacteristicValue, Input } from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\n/**\n * This ability creates a switch that can't be controlled from HomeKit, it only reflects\n * the device's input state.\n */\nexport class ReadonlySwitchAbility extends Ability {\n    /**\n     * @param component - The input component to represent.\n     */\n    constructor(readonly component: Input) {\n        super(`Switch ${component.id + 1}`, `readonly-switch-${component.id}`);\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.Service.Switch;\n    }\n\n    protected initialize() {\n        this.service\n            .getCharacteristic(this.Characteristic.On)\n            // remove the write permissions\n            .setProps({\n                perms: [Perms.NOTIFY, Perms.PAIRED_READ],\n            })\n            // set the initial value\n            .setValue(this.component.state ?? false);\n\n        // listen for updates from the device\n        this.component.on('change:state', this.stateChangeHandler, this);\n    }\n\n    detach() {\n        this.component.off('change:state', this.stateChangeHandler, this);\n    }\n\n    /**\n     * Handles changes to the `state` property.\n     */\n    protected stateChangeHandler(value: ShelliesCharacteristicValue) {\n        const v: boolean = value === null ? false : (value as boolean);\n        if (value) {\n            this.log.info('Switch Status(' + this.component.id + '): on');\n        } else {\n            this.log.info('Switch Status(' + this.component.id + '): off');\n        }\n        this.service.getCharacteristic(this.Characteristic.On).updateValue(v);\n    }\n}\n","import { Ability, ServiceClass } from './base.ts';\n\nexport class ServiceLabelAbility extends Ability {\n    /**\n     * @param namespace - The naming schema for the accessory.\n     */\n    constructor(readonly namespace: 'dots' | 'arabicNumerals' = 'arabicNumerals') {\n        super();\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.Service.ServiceLabel;\n    }\n\n    protected initialize() {\n        const SLN = this.Characteristic.ServiceLabelNamespace;\n\n        // set the namespace\n        this.service.setCharacteristic(SLN, this.namespace === 'dots' ? SLN.DOTS : SLN.ARABIC_NUMERALS);\n    }\n\n    detach() {\n        // nothing to detach\n    }\n}\n","import { Input } from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\nenum ButtonPress {\n    Single = 'single',\n    Double = 'double',\n    Long = 'long',\n}\n\nexport class StatelessProgrammableSwitchAbility extends Ability {\n    /**\n     * @param component - The input component to control.\n     */\n    constructor(readonly component: Input) {\n        super(`Button ${component.id + 1}`, `stateless-programmable-switch-${component.id}`);\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.Service.StatelessProgrammableSwitch;\n    }\n\n    protected initialize() {\n        // set the index number for this switch\n        this.service.setCharacteristic(this.Characteristic.ServiceLabelIndex, this.component.id + 1);\n\n        // listen for button press events\n        this.component\n            .on('singlePush', this.singlePushHandler, this)\n            .on('doublePush', this.doublePushHandler, this)\n            .on('longPush', this.longPushHandler, this);\n    }\n\n    detach() {\n        this.component\n            .off('singlePush', this.singlePushHandler, this)\n            .off('doublePush', this.doublePushHandler, this)\n            .off('longPush', this.longPushHandler, this);\n    }\n\n    /**\n     * Triggers a button press event.\n     * @param type - The type of button press to trigger.\n     */\n    protected triggerPress(type: ButtonPress) {\n        this.log.debug(`Input ${this.component.id}: ${type} press`);\n\n        const PSE = this.Characteristic.ProgrammableSwitchEvent;\n        let value: number;\n\n        // get the corresponding characteristic value\n        switch (type) {\n            case ButtonPress.Single:\n                value = PSE.SINGLE_PRESS;\n                break;\n\n            case ButtonPress.Double:\n                value = PSE.DOUBLE_PRESS;\n                break;\n\n            case ButtonPress.Long:\n                value = PSE.LONG_PRESS;\n                break;\n        }\n\n        // update the characteristic\n        this.service.getCharacteristic(this.Characteristic.ProgrammableSwitchEvent).updateValue(value);\n    }\n\n    /**\n     * Handles 'singlePush' events from our input component.\n     */\n    protected singlePushHandler() {\n        this.triggerPress(ButtonPress.Single);\n    }\n\n    /**\n     * Handles 'doublePush' events from our input component.\n     */\n    protected doublePushHandler() {\n        this.triggerPress(ButtonPress.Double);\n    }\n\n    /**\n     * Handles 'longPush' events from our input component.\n     */\n    protected longPushHandler() {\n        this.triggerPress(ButtonPress.Long);\n    }\n}\n","import { CharacteristicValue } from 'homebridge';\nimport { CharacteristicValue as ShelliesCharacteristicValue, Switch } from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\nexport class SwitchAbility extends Ability {\n    /**\n     * @param component - The switch component to control.\n     */\n    constructor(readonly component: Switch) {\n        super(`Switch ${component.id + 1}`, `switch-${component.id}`);\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.Service.Switch;\n    }\n\n    protected initialize() {\n        // set the initial value\n        this.service.setCharacteristic(this.Characteristic.On, this.component.output);\n\n        // listen for commands from HomeKit\n        this.service.getCharacteristic(this.Characteristic.On).onSet(this.onSetHandler.bind(this));\n\n        // listen for updates from the device\n        this.component.on('change:output', this.outputChangeHandler, this);\n    }\n\n    detach() {\n        this.component.off('change:output', this.outputChangeHandler, this);\n    }\n\n    /**\n     * Handles changes to the Switch.On characteristic.\n     */\n    protected async onSetHandler(value: CharacteristicValue) {\n        if (value === this.component.output) {\n            return;\n        }\n\n        try {\n            await this.component.set(value as boolean);\n        } catch (e) {\n            this.log.error('Failed to set switch:', e instanceof Error ? e.message : e);\n            throw new this.api.hap.HapStatusError(this.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE);\n        }\n    }\n\n    /**\n     * Handles changes to the `output` property.\n     */\n    protected outputChangeHandler(value: ShelliesCharacteristicValue) {\n        if (value) {\n            this.log.info('Switch Status(' + this.component.id + '): on');\n        } else {\n            this.log.info('Switch Status(' + this.component.id + '): off');\n        }\n        this.service.getCharacteristic(this.Characteristic.On).updateValue(value as boolean);\n    }\n}\n","//import { Perms } from \"homebridge\";\nimport { CharacteristicValue as ShelliesCharacteristicValue, Pm1, Pm1AenergyStatus } from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\n/**\n * This ability sets up a custom service that reports power meter readings.\n */\nexport class Pm1Ability extends Ability {\n    /**\n     * @param componentPm1 - The switch or cover component to get readings from.\n     */\n    constructor(readonly componentPm1: Pm1) {\n        super(`Pm1 ${componentPm1.id + 1}`, `Pm1-${componentPm1.id}`);\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.customServices.Pm1;\n    }\n\n    protected initialize() {\n        const s = this.service;\n        const cPm1 = this.componentPm1;\n        const cc = this.customCharacteristics;\n\n        // setup Current Consumption\n        s.setCharacteristic(cc.CurrentConsumption, cPm1.apower ?? 0);\n        // set the initial value\n        s.setCharacteristic(this.Characteristic.On, false);\n\n        cPm1.on('change:apower', this.apowerChangeHandler, this);\n\n        // setup Voltage\n        if (cPm1.voltage !== undefined) {\n            s.setCharacteristic(cc.Voltage, cPm1.voltage);\n\n            cPm1.on('change:voltage', this.voltageChangeHandler, this);\n        } else {\n            this.removeCharacteristic(cc.Voltage);\n        }\n\n        // setup Electric Current\n        if (cPm1.current !== undefined) {\n            s.setCharacteristic(cc.ElectricCurrent, cPm1.current);\n\n            cPm1.on('change:current', this.currentChangeHandler, this);\n        } else {\n            this.removeCharacteristic(cc.ElectricCurrent);\n        }\n\n        // setup Total Consumption\n        if (cPm1.aenergy !== undefined) {\n            s.setCharacteristic(cc.TotalConsumption, cPm1.aenergy.total / 1000);\n\n            cPm1.on('change:aenergy', this.aenergyChangeHandler, this);\n        } else {\n            this.removeCharacteristic(cc.TotalConsumption);\n        }\n    }\n\n    detach() {\n        this.componentPm1\n            .off('change:apower', this.apowerChangeHandler, this)\n            .off('change:voltage', this.voltageChangeHandler, this)\n            .off('change:current', this.currentChangeHandler, this)\n            .off('change:aenergy', this.aenergyChangeHandler, this);\n    }\n\n    /**\n     * Handles changes to the `apower` property.\n     */\n    protected apowerChangeHandler(value: ShelliesCharacteristicValue) {\n        this.service.updateCharacteristic(this.customCharacteristics.CurrentConsumption, value as number);\n        // set status\n        if (typeof value === 'number') {\n            //value is definitely a number and not null\n            if (value >= 1) {\n                //this.log.info('Switch Status('+this.component.id+'): on');\n                this.service.updateCharacteristic(this.Characteristic.On, true);\n            } else {\n                // this.log.info('Switch Status('+this.component.id+'): off');\n                this.service.updateCharacteristic(this.Characteristic.On, false);\n            }\n        }\n    }\n\n    /**\n     * Handles changes to the `voltage` property.\n     */\n    protected voltageChangeHandler(value: ShelliesCharacteristicValue) {\n        this.service.updateCharacteristic(this.customCharacteristics.Voltage, value as number);\n    }\n\n    /**\n     * Handles changes to the `current` property.\n     */\n    protected currentChangeHandler(value: ShelliesCharacteristicValue) {\n        this.service.updateCharacteristic(this.customCharacteristics.ElectricCurrent, value as number);\n    }\n\n    /**\n     * Handles changes to the `aenergy` property.\n     */\n    protected aenergyChangeHandler(value: ShelliesCharacteristicValue) {\n        const attr = value as unknown as Pm1AenergyStatus;\n\n        this.service.updateCharacteristic(this.customCharacteristics.TotalConsumption, attr.total / 1000);\n    }\n}\n","import { CharacteristicValue as ShelliesCharacteristicValue, Temperature } from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\n/** DS18B20 operating range upper bound (°C); HAP CurrentTemperature defaults to 100. */\nconst DS18B20_MAX_CELSIUS = 125;\n\n/**\n * Exposes a Shelly temperature component as a HomeKit temperature sensor.\n */\nexport class TemperatureSensorAbility extends Ability {\n    constructor(readonly component: Temperature) {\n        super(`Temperature ${component.id}`, `temperature-sensor-${component.id}`);\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.Service.TemperatureSensor;\n    }\n\n    protected initialize() {\n        const characteristic = this.service.getCharacteristic(this.Characteristic.CurrentTemperature);\n        characteristic.setProps({ maxValue: DS18B20_MAX_CELSIUS });\n        this.updateTemperature(this.component.tC);\n\n        this.component.on('change:tC', this.temperatureChangeHandler, this);\n    }\n\n    detach() {\n        this.component.off('change:tC', this.temperatureChangeHandler, this);\n    }\n\n    protected temperatureChangeHandler(value: ShelliesCharacteristicValue) {\n        this.updateTemperature(value);\n    }\n\n    private updateTemperature(value: ShelliesCharacteristicValue) {\n        const characteristic = this.service.getCharacteristic(this.Characteristic.CurrentTemperature);\n\n        if (value === null || typeof value !== 'number' || Number.isNaN(value)) {\n            characteristic.updateValue(new this.api.hap.HapStatusError(this.api.hap.HAPStatus.RESOURCE_BUSY));\n            return;\n        }\n\n        characteristic.updateValue(Math.min(value, DS18B20_MAX_CELSIUS));\n    }\n}\n","import { CharacteristicValue as ShelliesCharacteristicValue, Humidity } from '@lucavb/shellies-ds9';\n\nimport { Ability, ServiceClass } from './base.ts';\n\n/**\n * Exposes a Shelly humidity component as a HomeKit humidity sensor.\n */\nexport class HumiditySensorAbility extends Ability {\n    constructor(readonly component: Humidity) {\n        super(`Humidity ${component.id}`, `humidity-sensor-${component.id}`);\n    }\n\n    protected get serviceClass(): ServiceClass {\n        return this.Service.HumiditySensor;\n    }\n\n    protected initialize() {\n        this.updateHumidity(this.component.rh);\n\n        this.component.on('change:rh', this.humidityChangeHandler, this);\n    }\n\n    detach() {\n        this.component.off('change:rh', this.humidityChangeHandler, this);\n    }\n\n    protected humidityChangeHandler(value: ShelliesCharacteristicValue) {\n        this.updateHumidity(value);\n    }\n\n    private updateHumidity(value: ShelliesCharacteristicValue) {\n        const characteristic = this.service.getCharacteristic(this.Characteristic.CurrentRelativeHumidity);\n\n        if (value === null || typeof value !== 'number' || Number.isNaN(value)) {\n            characteristic.updateValue(new this.api.hap.HapStatusError(this.api.hap.HAPStatus.RESOURCE_BUSY));\n            return;\n        }\n\n        characteristic.updateValue(value);\n    }\n}\n","import { DeviceId } from '@lucavb/shellies-ds9';\nimport { Categories, PlatformAccessory } from 'homebridge';\n\nimport {\n    Ability,\n    CoverAbility,\n    HumiditySensorAbility,\n    LightAbility,\n    OutletAbility,\n    ReadonlySwitchAbility,\n    StatelessProgrammableSwitchAbility,\n    SwitchAbility,\n    TemperatureSensorAbility,\n} from './abilities/index.ts';\nimport { DeviceLogger } from './utils/device-logger.ts';\nimport { ShellyPlatform } from './platform.ts';\n\nexport type AccessoryId = string;\nexport type AccessoryUuid = string;\n\nexport function resolveAccessoryCategory(abilities: Ability[]): Categories {\n    const active = abilities.filter((a) => a.active);\n\n    for (const a of active) {\n        if (a instanceof OutletAbility) {\n            return Categories.OUTLET;\n        }\n    }\n    for (const a of active) {\n        if (a instanceof SwitchAbility || a instanceof ReadonlySwitchAbility) {\n            return Categories.SWITCH;\n        }\n    }\n    for (const a of active) {\n        if (a instanceof LightAbility) {\n            return Categories.LIGHTBULB;\n        }\n    }\n    for (const a of active) {\n        if (a instanceof CoverAbility) {\n            if (a.type === 'door') {\n                return Categories.DOOR;\n            }\n            if (a.type === 'window') {\n                return Categories.WINDOW;\n            }\n            return Categories.WINDOW_COVERING;\n        }\n    }\n    for (const a of active) {\n        if (a instanceof StatelessProgrammableSwitchAbility) {\n            return Categories.PROGRAMMABLE_SWITCH;\n        }\n    }\n    for (const a of active) {\n        if (a instanceof TemperatureSensorAbility || a instanceof HumiditySensorAbility) {\n            return Categories.SENSOR;\n        }\n    }\n\n    return Categories.OTHER;\n}\n\n/**\n * Represents a HomeKit accessory.\n */\nexport class Accessory {\n    /**\n     * The UUID used to identify this accessory with HomeKit.\n     */\n    readonly uuid: AccessoryUuid;\n\n    protected _platformAccessory: PlatformAccessory | null;\n\n    /**\n     * The underlying homebridge platform accessory.\n     * This property will be `null` when the accessory is inactive.\n     */\n    get platformAccessory(): PlatformAccessory | null {\n        return this._platformAccessory;\n    }\n\n    /**\n     * Holds this accessory's abilities.\n     */\n    readonly abilities: Ability[];\n\n    private _active = true;\n\n    /**\n     * Whether this accessory is active.\n     * Setting an accessory to inactive will remove it from HoneKit.\n     */\n    get active(): boolean {\n        return this._active;\n    }\n\n    set active(value) {\n        if (value === this._active) {\n            return;\n        }\n\n        this._active = value;\n        this.update();\n    }\n\n    /**\n     * Timeout used to delay calls to `update()`.\n     */\n    protected updateTimeout: ReturnType<typeof setTimeout> | null = null;\n\n    /**\n     * @param id - The accessory ID.\n     * @param deviceId - The associated device ID.\n     * @param name - A user-friendly name of the accessory.\n     * @param platform - A reference to the homebridge platform.\n     * @param log - The logger to use.\n     * @param abilities - The abilities that this accessory has.\n     */\n    constructor(\n        readonly id: AccessoryId,\n        readonly deviceId: DeviceId,\n        readonly name: string,\n        readonly platform: ShellyPlatform,\n        readonly log: DeviceLogger,\n        ...abilities: Ability[]\n    ) {\n        this.uuid = platform.api.hap.uuid.generate(`${deviceId}-${id}`);\n        this.abilities = abilities;\n\n        // try to load the platform accessory from cache\n        this._platformAccessory = platform.getAccessory(this.uuid) || null;\n        if (this._platformAccessory !== null) {\n            log.debug(`Accessory loaded from cache (ID: ${id})`);\n        }\n\n        this.update();\n    }\n\n    /**\n     * Sets `active` to the given value.\n     * This method can be used when chaining calls, as it returns a reference to `this`.\n     * @param value - Whether the accessory should be active.\n     */\n    setActive(value: boolean): this {\n        this.active = value;\n        return this;\n    }\n\n    /**\n     * Updates this accessory based on whether it is active.\n     */\n    protected update() {\n        // clear any running timeout\n        if (this.updateTimeout !== null) {\n            clearTimeout(this.updateTimeout);\n        }\n\n        // call either activate() or deactivate() depending on whether the accessory is active\n        // these calls are made after a short timeout to avoid unnecessary activations when an\n        // accessory is deactivated immediately after construction\n        this.updateTimeout = setTimeout(() => {\n            this.updateTimeout = null;\n\n            if (this.active) {\n                this.activate();\n            } else {\n                this.deactivate();\n            }\n        }, 0);\n    }\n\n    /**\n     * Activates this accessory, by creating a platform accessory and setting up all abilities.\n     */\n    protected activate() {\n        if (this._platformAccessory === null) {\n            // create a new platform accessory\n            this._platformAccessory = this.createPlatformAccessory();\n\n            this.log.debug(`Accessory activated (ID: ${this.id})`);\n        }\n\n        // setup all abilities\n        for (const a of this.abilities) {\n            try {\n                a.setup(this._platformAccessory, this.platform, this.log);\n            } catch (e) {\n                this.log.error('Failed to setup ability:', e instanceof Error ? e.message : e);\n                this.log.debug('Accessory ID:', this.id);\n                if (e instanceof Error && e.stack) {\n                    this.log.debug(e.stack);\n                }\n            }\n        }\n\n        // register the platform accessory\n        this.platform.addAccessory(this._platformAccessory);\n    }\n\n    /**\n     * Deactivates this accessory, by destroying all abilities and the platform accessory.\n     */\n    protected deactivate() {\n        // destroy all abilities\n        for (const a of this.abilities) {\n            try {\n                a.destroy();\n            } catch (e) {\n                this.log.error('Failed to destroy ability:', e instanceof Error ? e.message : e);\n                this.log.debug('Accessory ID:', this.id);\n                if (e instanceof Error && e.stack) {\n                    this.log.debug(e.stack);\n                }\n            }\n        }\n\n        if (this._platformAccessory !== null) {\n            // unregister the platform accessory\n            this.platform.removeAccessory(this._platformAccessory);\n            this._platformAccessory = null;\n\n            this.log.debug(`Accessory deactivated (ID: ${this.id})`);\n        }\n    }\n\n    /**\n     * Creates a new platform accessory for this accessory.\n     */\n    protected createPlatformAccessory(): PlatformAccessory {\n        const category = resolveAccessoryCategory(this.abilities);\n        const pa = new this.platform.api.platformAccessory(this.name, this.uuid, category);\n\n        // store info in the context\n        pa.context.device = {\n            id: this.deviceId,\n        };\n\n        return pa;\n    }\n\n    /**\n     * Removes all event listeners from this accessory.\n     */\n    detach() {\n        // abort any pending update\n        if (this.updateTimeout !== null) {\n            clearTimeout(this.updateTimeout);\n            this.updateTimeout = null;\n        }\n\n        // invoke detach() on all abilities\n        for (const a of this.abilities) {\n            try {\n                a.detach();\n            } catch (e) {\n                this.log.error('Failed to detach ability:', e instanceof Error ? e.message : e);\n                this.log.debug('Accessory ID:', this.id);\n                if (e instanceof Error && e.stack) {\n                    this.log.debug(e.stack);\n                }\n            }\n        }\n    }\n}\n","import { Device } from '@lucavb/shellies-ds9';\nimport { Logger, LogLevel } from 'homebridge';\n\n/**\n * Utility used to prefix log messages with device IDs.\n */\nexport class DeviceLogger {\n    protected readonly prefix: string;\n\n    /**\n     * @param device - The device to use.\n     * @param deviceName - A user-friendly name of the device.\n     * @param logger - The logging device to write to.\n     */\n    constructor(\n        readonly device: Device,\n        deviceName: string | undefined,\n        protected readonly logger: Logger,\n    ) {\n        this.prefix = `[${deviceName || device.id}] `;\n    }\n\n    info(message: string, ...parameters: unknown[]) {\n        this.log(LogLevel.INFO, message, ...parameters);\n    }\n\n    warn(message: string, ...parameters: unknown[]) {\n        this.log(LogLevel.WARN, message, ...parameters);\n    }\n\n    error(message: string, ...parameters: unknown[]) {\n        this.log(LogLevel.ERROR, message, ...parameters);\n    }\n\n    debug(message: string, ...parameters: unknown[]) {\n        this.log(LogLevel.DEBUG, message, ...parameters);\n    }\n\n    log(level: LogLevel, message: string, ...parameters: unknown[]) {\n        this.logger.log(level, this.prefix + message, ...parameters);\n    }\n}\n","import {\n    ADDON_SENSOR_MIN_ID,\n    ComponentLike,\n    Cover,\n    Device,\n    Humidity,\n    Light,\n    Switch,\n    Temperature,\n} from '@lucavb/shellies-ds9';\nimport { PlatformAccessory } from 'homebridge';\n\nimport {\n    Ability,\n    AccessoryInformationAbility,\n    CoverAbility,\n    HumiditySensorAbility,\n    OutletAbility,\n    PowerMeterAbility,\n    SwitchAbility,\n    LightAbility,\n    TemperatureSensorAbility,\n} from '../abilities/index.ts';\nimport { Accessory, AccessoryId } from '../accessory.ts';\nimport { DeviceLogger } from '../utils/device-logger.ts';\nimport { AddonSensorOptions, CoverOptions, DeviceOptions, SwitchOptions, LightOptions } from '../config.ts';\nimport { ShellyPlatform } from '../platform.ts';\n\n/**\n * Describes a device delegate class.\n */\nexport interface DeviceDelegateClass {\n    new (device: Device, options: DeviceOptions, platform: ShellyPlatform): DeviceDelegate;\n}\n\n/**\n * Describes a device class.\n */\nexport interface DeviceClass {\n    model: string;\n}\n\nexport interface AddSwitchOptions {\n    /**\n     * Whether the accessory should be active.\n     */\n    active: boolean;\n    /**\n     * Whether the device has a single switch.\n     */\n    single: boolean;\n}\n\nexport interface AddCoverOptions {\n    /**\n     * Whether the accessory should be active.\n     */\n    active: boolean;\n    /**\n     * Whether the device has a single cover.\n     */\n    single: boolean;\n}\n\nexport interface AddLightOptions {\n    /**\n     * Whether the accessory should be active.\n     */\n    active: boolean;\n    /**\n     * Whether the device has a single light.\n     */\n    single: boolean;\n}\n\n/**\n * A DeviceDelegate manages accessories for a device.\n */\nexport abstract class DeviceDelegate {\n    /**\n     * Holds all registered delegates.\n     */\n    private static readonly delegates: Map<string, DeviceDelegateClass> = new Map();\n\n    /**\n     * Registers a device delegate, so that it can later be found based on a device class or model\n     * using the `DeviceDelegate.getDelegate()` method.\n     * @param delegate - A subclass of `DeviceDelegate`.\n     * @param deviceClasses - One or more subclasses of `Device`.\n     */\n    static registerDelegate(delegate: DeviceDelegateClass, ...deviceClasses: DeviceClass[]) {\n        for (const deviceCls of deviceClasses) {\n            const mdl = deviceCls.model.toUpperCase();\n\n            // make sure it's not already registered\n            if (DeviceDelegate.delegates.has(mdl)) {\n                throw new Error(`A device delegate for ${deviceCls.model} has already been registered`);\n            }\n\n            // add it to the list\n            DeviceDelegate.delegates.set(mdl, delegate);\n        }\n    }\n\n    /**\n     * Returns the device delegate for the given device class or model, if one has been registered.\n     * @param deviceClsOrModel - The device class or model ID to lookup.\n     */\n    static getDelegate(deviceClsOrModel: DeviceClass | string): DeviceDelegateClass | undefined {\n        const mdl = typeof deviceClsOrModel === 'string' ? deviceClsOrModel : deviceClsOrModel.model;\n        return DeviceDelegate.delegates.get(mdl.toUpperCase());\n    }\n\n    /**\n     * Holds all accessories for this device.\n     */\n    protected readonly accessories: Map<AccessoryId, Accessory> = new Map();\n\n    /**\n     * Logger specific for this device.\n     */\n    readonly log: DeviceLogger;\n\n    /**\n     * Used to keep track of whether a connection had been established when the 'disconnect' event is emitted by our RPC handler.\n     */\n    protected connected: boolean;\n\n    /**\n     * @param device - The device to handle.\n     * @param options - Configuration options for the device.\n     * @param platform - A reference to the homebridge platform.\n     */\n    constructor(\n        readonly device: Device,\n        readonly options: DeviceOptions,\n        readonly platform: ShellyPlatform,\n    ) {\n        this.log = new DeviceLogger(device, options.name, platform.log);\n        this.log.info('Device added');\n\n        this.log.debug(device.rpcHandler.connected ? 'Device is connected' : 'Device is disconnected');\n\n        this.connected = device.rpcHandler.connected;\n\n        device.rpcHandler\n            .on('connect', this.handleConnect, this)\n            .on('disconnect', this.handleDisconnect, this)\n            .on('request', this.handleRequest, this);\n\n        this.setup();\n        this.setupAddonSensors();\n    }\n\n    /**\n     * Subclasses should override this method to setup the device delegate and create their\n     * accessories.\n     */\n    protected abstract setup();\n\n    /**\n     * Creates HomeKit accessories for Shelly Sensor Add-on temperature and humidity components.\n     */\n    protected setupAddonSensors() {\n        const temperatures = new Map<number, Temperature>();\n        const humidities = new Map<number, Humidity>();\n\n        for (const [, component] of this.device) {\n            if (component instanceof Temperature && component.id >= ADDON_SENSOR_MIN_ID) {\n                temperatures.set(component.id, component);\n            } else if (component instanceof Humidity && component.id >= ADDON_SENSOR_MIN_ID) {\n                humidities.set(component.id, component);\n            }\n        }\n\n        const pairedHumidityIds = new Set<number>();\n\n        for (const [id, temperature] of temperatures) {\n            const temperatureOptions = this.getComponentOptions<AddonSensorOptions>(temperature) ?? {};\n            const humidity = humidities.get(id);\n\n            if (temperatureOptions.exclude === true) {\n                if (humidity) {\n                    pairedHumidityIds.add(id);\n                }\n                continue;\n            }\n            const abilities: Ability[] = [new TemperatureSensorAbility(temperature)];\n            let accessoryId = `addon-temperature-${id}`;\n            let nameSuffix = this.formatAddonSensorName(temperature, 'Temperature', id);\n\n            if (humidity) {\n                const humidityOptions = this.getComponentOptions<AddonSensorOptions>(humidity) ?? {};\n                if (humidityOptions.exclude !== true) {\n                    abilities.push(new HumiditySensorAbility(humidity));\n                    accessoryId = `addon-climate-${id}`;\n                    nameSuffix = this.formatAddonClimateName(temperature, humidity, id);\n                    pairedHumidityIds.add(id);\n                }\n            }\n\n            this.createAccessory(accessoryId, nameSuffix, ...abilities);\n        }\n\n        for (const [id, humidity] of humidities) {\n            if (pairedHumidityIds.has(id)) {\n                continue;\n            }\n\n            const humidityOptions = this.getComponentOptions<AddonSensorOptions>(humidity) ?? {};\n            if (humidityOptions.exclude === true) {\n                continue;\n            }\n\n            this.createAccessory(\n                `addon-humidity-${id}`,\n                this.formatAddonSensorName(humidity, 'Humidity', id),\n                new HumiditySensorAbility(humidity),\n            );\n        }\n    }\n\n    private formatAddonSensorName(component: Temperature | Humidity, fallbackLabel: string, id: number): string {\n        const name = component.config?.name;\n        if (typeof name === 'string' && name.length > 0) {\n            return name;\n        }\n\n        return `${fallbackLabel} ${id}`;\n    }\n\n    private formatAddonClimateName(temperature: Temperature, humidity: Humidity, id: number): string {\n        const temperatureName = temperature.config?.name;\n        const humidityName = humidity.config?.name;\n\n        if (typeof temperatureName === 'string' && temperatureName.length > 0) {\n            return temperatureName;\n        }\n\n        if (typeof humidityName === 'string' && humidityName.length > 0) {\n            return humidityName;\n        }\n\n        return `Climate ${id}`;\n    }\n\n    /**\n     * Retrieves configuration options for the given component from the device options.\n     * @param component - The component.\n     * @returns A set of options, if found.\n     */\n    protected getComponentOptions<T>(component: ComponentLike): T | undefined {\n        return this.options?.[component.key] as T;\n    }\n\n    /**\n     * Creates an accessory with the given ID.\n     * If a matching platform accessory is not found in cache, a new one will be created.\n     * @param id - A unique identifier for this accessory.\n     * @param nameSuffix - A string to append to the name of this accessory.\n     * @param abilities - The abilities to add to this accessory.\n     */\n    protected createAccessory(id: AccessoryId, nameSuffix: string | null, ...abilities: Ability[]): Accessory {\n        // make sure the given ID is unique\n        if (this.accessories.has(id)) {\n            throw new Error(`An accessory with ID '${id}' already exists`);\n        }\n\n        let name = this.options.name || this.device.modelName;\n        if (nameSuffix) {\n            name += ' ' + nameSuffix;\n        }\n\n        // create an accessory\n        const accessory = new Accessory(\n            id,\n            this.device.id,\n            name,\n            this.platform,\n            this.log,\n            new AccessoryInformationAbility(this.device),\n            ...abilities,\n        );\n\n        // store the accessory\n        this.accessories.set(id, accessory);\n\n        return accessory;\n    }\n\n    /**\n     * Creates an accessory for a switch component.\n     * @param swtch - The switch component to use.\n     * @param opts - Options for the switch.\n     */\n    protected addSwitch(swtch: Switch, opts?: Partial<AddSwitchOptions>): Accessory {\n        const o = opts ?? {};\n\n        // get the config options for this switch\n        const switchOpts = this.getComponentOptions<SwitchOptions>(swtch) ?? {};\n\n        // determine the switch tyoe\n        const type = typeof switchOpts.type === 'string' ? switchOpts.type.toLowerCase() : 'switch';\n        const isOutlet = type === 'outlet';\n\n        const id = o.single === true ? 'switch' : `switch-${swtch.id}`;\n        const nameSuffix = o.single === true ? null : `Switch ${swtch.id + 1}`;\n\n        return this.createAccessory(\n            id,\n            nameSuffix,\n            new OutletAbility(swtch).setActive(isOutlet),\n            new SwitchAbility(swtch).setActive(!isOutlet),\n            // use the apower property to determine whether power metering is available\n            new PowerMeterAbility(swtch).setActive(swtch.apower !== undefined),\n        ).setActive(switchOpts.exclude !== true && o.active !== false);\n    }\n\n    /**\n     * Creates an accessory for a cover component.\n     * @param cover - The cover component to use.\n     * @param opts - Options for the cover.\n     */\n    protected addCover(cover: Cover, opts?: Partial<AddCoverOptions>): Accessory {\n        const o = opts ?? {};\n\n        // get the config options for this cover\n        const coverOpts = this.getComponentOptions<CoverOptions>(cover) ?? {};\n\n        // determine the cover tyoe\n        const type = typeof coverOpts.type === 'string' ? coverOpts.type.toLowerCase() : 'window';\n        const isDoor = type === 'door';\n        const isWindowCovering = type === 'windowcovering';\n\n        const id = o.single === true ? 'cover' : `cover-${cover.id}`;\n\n        return this.createAccessory(\n            id,\n            'Cover',\n            new CoverAbility(cover, 'door').setActive(isDoor),\n            new CoverAbility(cover, 'windowCovering').setActive(isWindowCovering),\n            new CoverAbility(cover, 'window').setActive(!isDoor && !isWindowCovering),\n            new PowerMeterAbility(cover),\n        ).setActive(coverOpts.exclude !== true && o.active !== false);\n    }\n\n    /**\n     * Creates an accessory for a light component.\n     * @param light - The light component to use.\n     * @param opts - Options for the light.\n     */\n    protected addLight(light: Light, opts?: Partial<AddLightOptions>): Accessory {\n        const o = opts ?? {};\n\n        // get the config options for this light\n        const lightOpts = this.getComponentOptions<LightOptions>(light) ?? {};\n\n        const id = o.single === true ? 'light' : `light-${light.id}`;\n        const nameSuffix = o.single === true ? null : `Light ${light.id + 1}`;\n\n        return this.createAccessory(id, nameSuffix, new LightAbility(light)).setActive(\n            lightOpts.exclude !== true && o.active !== false,\n        );\n    }\n\n    /**\n     * Handles 'connect' events from the RPC handler.\n     */\n    protected handleConnect() {\n        this.log.info('Device connected');\n        this.connected = true;\n    }\n\n    /**\n     * Handles 'disconnect' events from the RPC handler.\n     */\n    protected handleDisconnect(code: number, reason: string, reconnectIn: number | null) {\n        const details = reason.length > 0 ? 'reason: ' + reason : 'code: ' + code;\n        this.log.warn((this.connected ? 'Device disconnected' : 'Connection failed') + ' (' + details + ')');\n\n        if (reconnectIn !== null) {\n            let msg = 'Reconnecting in ';\n\n            if (reconnectIn < 60 * 1000) {\n                msg += Math.floor(reconnectIn / 1000) + ' second(s)';\n            } else if (reconnectIn < 60 * 60 * 1000) {\n                msg += Math.floor(reconnectIn / (60 * 1000)) + ' minute(s)';\n            } else {\n                msg += Math.floor(reconnectIn / (60 * 60 * 1000)) + ' hour(s)';\n            }\n\n            this.log.info(msg);\n        }\n\n        this.connected = false;\n    }\n\n    /**\n     * Handles 'request' events from the RPC handler.\n     */\n    protected handleRequest(method: string) {\n        this.log.debug('WebSocket:', method);\n    }\n\n    /**\n     * Removes all event listeners from this device.\n     */\n    detach() {\n        this.device.rpcHandler\n            .off('connect', this.handleConnect, this)\n            .off('disconnect', this.handleDisconnect, this)\n            .off('request', this.handleRequest, this);\n\n        // invoke detach() on all accessories\n        for (const a of this.accessories.values()) {\n            a.detach();\n        }\n    }\n\n    /**\n     * Destroys this device delegate, removing all event listeners and unregistering all accessories.\n     */\n    destroy() {\n        this.detach();\n\n        // find all platform accessories\n        const pas = Array.from(this.accessories.values())\n            .map((a) => a.platformAccessory)\n            .filter((a) => a !== null) as PlatformAccessory[];\n\n        if (pas.length > 0) {\n            // remove the accessories from the platform\n            this.platform.removeAccessory(...pas);\n        }\n\n        this.log.info('Device removed');\n    }\n}\n","import {\n    Shelly1LGen3,\n    ShellyGen4One,\n    ShellyGen4OneAnz,\n    ShellyGen4OneMini,\n    ShellyPlus1,\n    ShellyPlus1Ul,\n    ShellyPlus1V3,\n    ShellyPlus1Mini,\n    ShellyPlus1MiniV3,\n} from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Plus 1 devices.\n */\nexport class ShellyPlus1Delegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPlus1;\n\n        this.addSwitch(d.switch0, { single: true });\n    }\n}\n\nDeviceDelegate.registerDelegate(\n    ShellyPlus1Delegate,\n    ShellyPlus1,\n    ShellyPlus1Ul,\n    ShellyPlus1V3,\n    ShellyPlus1Mini,\n    ShellyPlus1MiniV3,\n    ShellyGen4One,\n    ShellyGen4OneMini,\n    ShellyGen4OneAnz,\n    Shelly1LGen3,\n);\n","import {\n    ShellyGen4OnePm,\n    ShellyGen4OnePmAnz,\n    ShellyPlus1Pm,\n    ShellyPlus1PmUl,\n    ShellyPlus1PmV3,\n    ShellyPlus1PmMini,\n    ShellyPlus1PmMiniV3,\n} from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Plus 1PM devices.\n */\nexport class ShellyPlus1PmDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPlus1Pm;\n\n        this.addSwitch(d.switch0, { single: true });\n    }\n}\n\nDeviceDelegate.registerDelegate(\n    ShellyPlus1PmDelegate,\n    ShellyPlus1Pm,\n    ShellyPlus1PmUl,\n    ShellyPlus1PmV3,\n    ShellyPlus1PmMini,\n    ShellyPlus1PmMiniV3,\n    ShellyGen4OnePm,\n    ShellyGen4OnePmAnz,\n);\n","import { ShellyPlusPmMini, ShellyPlusPmMiniV3 } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\nimport { Pm1Ability } from '../abilities/index.ts';\n\n/**\n * Handles Shelly Plus 1PM devices.\n */\nexport class ShellyPlusPmDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPlusPmMini;\n\n        this.createAccessory('switch', this.device.id, new Pm1Ability(d.pm1));\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyPlusPmDelegate, ShellyPlusPmMini, ShellyPlusPmMiniV3);\n","import { ShellyGen32Pm, ShellyGen42Pm, ShellyGen42PmAnz, ShellyPlus2Pm, ShellyPlus2PmRev1 } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Plus 2 PM devices.\n */\nexport class ShellyPlus2PmDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPlus2Pm;\n        const isCover = d.profile === 'cover';\n\n        this.addCover(d.cover0, { active: isCover });\n\n        this.addSwitch(d.switch0, { active: !isCover });\n        this.addSwitch(d.switch1, { active: !isCover });\n    }\n}\n\nDeviceDelegate.registerDelegate(\n    ShellyPlus2PmDelegate,\n    ShellyPlus2Pm,\n    ShellyPlus2PmRev1,\n    ShellyGen32Pm,\n    ShellyGen42Pm,\n    ShellyGen42PmAnz,\n);\n","import { ShellyPlusI4, ShellyPlusI4Dc, ShellyPlusI4V3 } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\nimport { ReadonlySwitchAbility, ServiceLabelAbility, StatelessProgrammableSwitchAbility } from '../abilities/index.ts';\n\n/**\n * Handles Shelly Plus I4 devices.\n */\nexport class ShellyPlusI4Delegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPlusI4;\n\n        // determine each input type\n        const input0IsButton = d.input0.config?.type === 'button';\n        const input1IsButton = d.input1.config?.type === 'button';\n        const input2IsButton = d.input2.config?.type === 'button';\n        const input3IsButton = d.input3.config?.type === 'button';\n\n        // create an accessory for all button inputs\n        this.createAccessory(\n            'buttons',\n            null,\n            new StatelessProgrammableSwitchAbility(d.input0).setActive(input0IsButton),\n            new StatelessProgrammableSwitchAbility(d.input1).setActive(input1IsButton),\n            new StatelessProgrammableSwitchAbility(d.input2).setActive(input2IsButton),\n            new StatelessProgrammableSwitchAbility(d.input3).setActive(input3IsButton),\n            new ServiceLabelAbility(),\n        ).setActive(input0IsButton || input1IsButton || input2IsButton || input3IsButton);\n\n        // create accessories for all switch inputs\n        this.createAccessory('switch0', null, new ReadonlySwitchAbility(d.input0)).setActive(!input0IsButton);\n        this.createAccessory('switch1', null, new ReadonlySwitchAbility(d.input1)).setActive(!input1IsButton);\n        this.createAccessory('switch2', null, new ReadonlySwitchAbility(d.input2)).setActive(!input2IsButton);\n        this.createAccessory('switch3', null, new ReadonlySwitchAbility(d.input3)).setActive(!input3IsButton);\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyPlusI4Delegate, ShellyPlusI4, ShellyPlusI4V3, ShellyPlusI4Dc);\n","import {\n    ShellyOutdoorPlugSG3Eu,\n    ShellyPlugAzG3Eu,\n    ShellyPlugMG3Eu,\n    ShellyPlugPmG3Eu,\n    ShellyPlugSG3Eu,\n    ShellyPlugUsG4,\n    ShellyPlusPlugUs,\n    ShellyPlusPlugEu,\n    ShellyPlusPlugIt,\n    ShellyPlusPlugUk,\n} from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Plus Plug US devices.\n */\nexport class ShellyPlusPlugUsDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPlusPlugUs;\n\n        this.addSwitch(d.switch0, { single: true });\n    }\n}\n\nDeviceDelegate.registerDelegate(\n    ShellyPlusPlugUsDelegate,\n    ShellyPlusPlugUs,\n    ShellyPlusPlugEu,\n    ShellyPlusPlugIt,\n    ShellyPlusPlugUk,\n    ShellyPlugSG3Eu,\n    ShellyPlugAzG3Eu,\n    ShellyOutdoorPlugSG3Eu,\n    ShellyPlugMG3Eu,\n    ShellyPlugPmG3Eu,\n    ShellyPlugUsG4,\n);\n","import { ShellyPro1, ShellyPro1Rev1, ShellyPro1Rev2, ShellyPro1Rev2Ul } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro 1 devices.\n */\nexport class ShellyPro1Delegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPro1;\n\n        this.addSwitch(d.switch0, { single: true });\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyPro1Delegate, ShellyPro1, ShellyPro1Rev1, ShellyPro1Rev2, ShellyPro1Rev2Ul);\n","import { ShellyPro1Pm, ShellyPro1PmRev1, ShellyPro1PmRev2, ShellyPro1PmRev2Ul } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro 1 PM devices.\n */\nexport class ShellyPro1PmDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPro1Pm;\n\n        this.addSwitch(d.switch0, { single: true });\n    }\n}\n\nDeviceDelegate.registerDelegate(\n    ShellyPro1PmDelegate,\n    ShellyPro1Pm,\n    ShellyPro1PmRev1,\n    ShellyPro1PmRev2,\n    ShellyPro1PmRev2Ul,\n);\n","import { ShellyPro2, ShellyPro2Rev1, ShellyPro2Rev2 } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro 2 devices.\n */\nexport class ShellyPro2Delegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPro2;\n\n        this.addSwitch(d.switch0);\n        this.addSwitch(d.switch1);\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyPro2Delegate, ShellyPro2, ShellyPro2Rev1, ShellyPro2Rev2);\n","import { ShellyPro3 } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro 3 devices.\n */\nexport class ShellyPro3Delegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPro3;\n\n        this.addSwitch(d.switch0);\n        this.addSwitch(d.switch1);\n        this.addSwitch(d.switch2);\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyPro3Delegate, ShellyPro3);\n","import { ShellyPro2Pm, ShellyPro2PmRev1, ShellyPro2PmRev2 } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro 2 PM devices.\n */\nexport class ShellyPro2PmDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPro2Pm;\n        const isCover = d.profile === 'cover';\n\n        this.addCover(d.cover0, { active: isCover });\n\n        this.addSwitch(d.switch0, { active: !isCover });\n        this.addSwitch(d.switch1, { active: !isCover });\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyPro2PmDelegate, ShellyPro2Pm, ShellyPro2PmRev1, ShellyPro2PmRev2);\n","import { ShellyPro4Pm, ShellyPro4PmV2, ShellyPro4PmV3 } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro 4PM devices.\n */\nexport class ShellyPro4PmDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPro4Pm;\n\n        this.addSwitch(d.switch0);\n        this.addSwitch(d.switch1);\n        this.addSwitch(d.switch2);\n        this.addSwitch(d.switch3);\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyPro4PmDelegate, ShellyPro4Pm, ShellyPro4PmV2, ShellyPro4PmV3);\n","import { ShellyDimmer, ShellyProDimmer1Pm, ShellyProDimmer1Pm2 } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro Dimmer 1PM devices.\n */\nexport class ShellyProDimmer1PmDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyProDimmer1Pm;\n\n        this.addLight(d.light0, { single: true });\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyProDimmer1PmDelegate, ShellyProDimmer1Pm, ShellyProDimmer1Pm2, ShellyDimmer);\n","import { ShellyProDimmer2Pm } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro Dimmer 2PM devices.\n */\nexport class ShellyProDimmer2PmDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyProDimmer2Pm;\n\n        this.addLight(d.light0);\n        this.addLight(d.light1);\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyProDimmer2PmDelegate, ShellyProDimmer2Pm);\n","import { ShellyProDualCoverPm } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro Dual Cover PM devices.\n */\nexport class ShellyProDualCoverPmDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyProDualCoverPm;\n        this.addCover(d.cover0, { active: true });\n        this.addCover(d.cover1, { active: true });\n        //TODO fix it ...\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyProDualCoverPmDelegate, ShellyProDualCoverPm);\n","import { ShellyPlusPMDimmer } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro Dimmer 1PM devices.\n */\nexport class ShellyPlusDimmer010PmDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPlusPMDimmer;\n\n        this.addLight(d.light0, { single: true });\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyPlusDimmer010PmDelegate, ShellyPlusPMDimmer);\n","import { ShellyPlusDimmer } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Pro Dimmer 1PM devices.\n */\nexport class ShellyPlusDimmer010Delegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPlusDimmer;\n\n        this.addLight(d.light0, { single: true });\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyPlusDimmer010Delegate, ShellyPlusDimmer);\n","import { ShellyGen4Mini } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly 1PM Gen4 Mini devices.\n */\nexport class ShellyGen4MiniDelegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyGen4Mini;\n\n        this.addSwitch(d.switch, { single: true });\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyGen4MiniDelegate, ShellyGen4Mini);\n","import { ShellyPowerStrip4G4, ShellyPowerStrip4G4Black } from '@lucavb/shellies-ds9';\n\nimport { DeviceDelegate } from './base.ts';\n\n/**\n * Handles Shelly Power Strip 4 Gen4 devices.\n */\nexport class ShellyPowerStrip4G4Delegate extends DeviceDelegate {\n    protected setup() {\n        const d = this.device as ShellyPowerStrip4G4;\n\n        this.addSwitch(d.switch0);\n        this.addSwitch(d.switch1);\n        this.addSwitch(d.switch2);\n        this.addSwitch(d.switch3);\n    }\n}\n\nDeviceDelegate.registerDelegate(ShellyPowerStrip4G4Delegate, ShellyPowerStrip4G4, ShellyPowerStrip4G4Black);\n","import { PlatformConfig } from 'homebridge';\n\nimport { DeviceId } from '@lucavb/shellies-ds9';\n\nexport interface MdnsOptions {\n    /**\n     * Whether device discovery using mDNS should be enabled.\n     */\n    enable: boolean;\n    /**\n     * The network interface to use. If none is specified, all available\n     * interfaces will be used.\n     */\n    interface?: string;\n}\n\nconst DEFAULT_MDNS_OPTIONS: Readonly<MdnsOptions> = {\n    enable: true,\n};\n\nexport interface WebSocketOptions {\n    /**\n     * The time, in seconds, to wait for a response before a request is aborted.\n     */\n    requestTimeout: number;\n    /**\n     * The interval, in seconds, at which ping requests should be made to verify that the connection is open.\n     * Set to `0` to disable.\n     */\n    pingInterval: number;\n    /**\n     * The interval, in seconds, at which a connection attempt should be made after a socket has been closed.\n     * If an array is specified, the first value of the array will be used for the first connection attempt, the second\n     * value for the second attempt and so on. When the last item in the array has been reached, it will be used for\n     * all subsequent connection attempts; unless the value is `0`, in which case no more attempts will be made.\n     * Set to `0` or an empty array to disable.\n     */\n    reconnectInterval: number | number[];\n}\n\nconst DEFAULT_WEB_SOCKET_OPTIONS: Readonly<WebSocketOptions> = {\n    requestTimeout: 10,\n    pingInterval: 60,\n    reconnectInterval: [\n        5,\n        10,\n        30,\n        60,\n        5 * 60, // 5 minutes\n        10 * 60, // 10 minutes\n    ],\n};\n\nexport interface SwitchOptions {\n    /**\n     * Whether this switch should be excluded.\n     */\n    exclude?: boolean;\n    /**\n     * The type of accessory used to represent the switch.\n     */\n    type?: 'outlet' | 'switch';\n}\n\nexport interface CoverOptions {\n    /**\n     * Whether this cover should be excluded.\n     */\n    exclude?: boolean;\n    /**\n     * The type of accessory used to represent the cover.\n     */\n    type?: 'door' | 'window' | 'windowCovering';\n}\n\nexport interface LightOptions {\n    /**\n     * Whether this light should be excluded.\n     */\n    exclude?: boolean;\n}\n\nexport interface AddonSensorOptions {\n    /**\n     * Whether this add-on sensor should be excluded.\n     */\n    exclude?: boolean;\n}\n\nexport interface DeviceOptions {\n    /**\n     * The name of the device.\n     */\n    name?: string;\n    /**\n     * Whether the device should be excluded.\n     */\n    exclude: boolean;\n    /**\n     * The protocol to use when communicating with the device.\n     */\n    protocol: 'websocket';\n    /**\n     * The IP address or hostname of the device.\n     */\n    hostname?: string;\n    /**\n     * The password to use if the Shelly device requires authentication.\n     */\n    password?: string;\n    /**\n     * Options for devices that have one or more switch.\n     */\n    ['switch:0']?: SwitchOptions;\n    /**\n     * Options for devices that have multiple switches.\n     */\n    ['switch:1']?: SwitchOptions;\n    /**\n     * Options for devices that have multiple switches.\n     */\n    ['switch:2']?: SwitchOptions;\n    /**\n     * Options for devices that have multiple switches.\n     */\n    ['switch:3']?: SwitchOptions;\n    /**\n     * Options for devices that have a cover.\n     */\n    ['cover:0']?: CoverOptions;\n    /**\n     * Options for Shelly Sensor Add-on temperature components.\n     */\n    [key: `temperature:${number}`]: AddonSensorOptions | undefined;\n    /**\n     * Options for Shelly Sensor Add-on humidity components.\n     */\n    [key: `humidity:${number}`]: AddonSensorOptions | undefined;\n}\n\nconst DEFAULT_DEVICE_OPTIONS: Readonly<DeviceOptions> = {\n    exclude: false,\n    protocol: 'websocket',\n};\n\n/**\n * Handles configuration options for the platform.\n */\nexport class PlatformOptions {\n    /**\n     * Options for the mDNS device discoverer.\n     */\n    readonly mdns: MdnsOptions;\n    /**\n     * Options for WebSocket connections.\n     */\n    readonly websocket: WebSocketOptions;\n    /**\n     * Device specific configuration options.\n     */\n    readonly deviceOptions: Map<DeviceId, DeviceOptions> = new Map();\n\n    /**\n     * @param config - The platform configuration.\n     */\n    constructor(config: PlatformConfig) {\n        // store the mDNS options (with default values)\n        this.mdns = { ...DEFAULT_MDNS_OPTIONS, ...config.mdns };\n\n        // allow websocket.reconnectInterval to be a string of comma-separated numbers\n        if (typeof config.websocket?.reconnectInterval === 'string') {\n            const intervals: number[] = [];\n\n            for (const i of config.websocket.reconnectInterval.split(',')) {\n                intervals.push(parseInt(i, 10));\n            }\n\n            config.websocket.reconnectInterval = intervals;\n        }\n\n        // store the WebSocket options (with default values)\n        this.websocket = { ...DEFAULT_WEB_SOCKET_OPTIONS, ...config.websocket };\n\n        // store the device options\n        if (Array.isArray(config.devices)) {\n            // loop through each item and add default values\n            for (const d of config.devices) {\n                if (d && typeof d.id === 'string') {\n                    this.deviceOptions.set(d.id.toLowerCase(), { ...DEFAULT_DEVICE_OPTIONS, ...d });\n                }\n            }\n        }\n    }\n\n    /**\n     * Return the configuration options for the device with the given ID.\n     * If no options have been specified, default values will be returned.\n     * @param deviceId - The device ID.\n     */\n    getDeviceOptions(deviceId: DeviceId): DeviceOptions {\n        return this.deviceOptions.get(deviceId) || DEFAULT_DEVICE_OPTIONS;\n    }\n}\n","import { API, DynamicPlatformPlugin, Logger, PlatformAccessory, PlatformConfig } from 'homebridge';\n\nimport {\n    Device,\n    DeviceDiscoverer,\n    DeviceId,\n    DeviceIdentifiers,\n    MdnsDeviceDiscoverer,\n    Shellies,\n} from '@lucavb/shellies-ds9';\n\nimport { CustomCharacteristics, createCharacteristics } from './utils/characteristics.ts';\nimport { CustomServices, createServices } from './utils/services.ts';\nimport { DeviceCache } from './utils/device-cache.ts';\nimport { DeviceDelegate } from './device-delegates/index.ts';\nimport { PlatformOptions } from './config.ts';\n\ntype AccessoryUuid = string;\n\n/**\n * The name of this plugin.\n */\nexport const PLUGIN_NAME = '@lucavb/homebridge-shelly-ds9';\n\n/**\n * The name of this homebridge platform.\n */\nexport const PLATFORM_NAME = 'ShellyDS9';\n\n/**\n * Utility class that \"discovers\" devices from the configuration options.\n */\nexport class ConfigDeviceDiscoverer extends DeviceDiscoverer {\n    /**\n     * @param options - The platform configuration options.\n     * @param emitInterval - The interval, in milliseconds, to wait between each emitted device.\n     */\n    constructor(\n        readonly options: PlatformOptions,\n        readonly emitInterval = 20,\n    ) {\n        super();\n    }\n\n    /**\n     * Runs this discoverer.\n     */\n    async run() {\n        // emit all devices that have a configured hostname\n        for (const [id, opts] of this.options.deviceOptions) {\n            if (opts.hostname) {\n                await this.emitDevice({\n                    deviceId: id,\n                    hostname: opts.hostname,\n                });\n            }\n        }\n    }\n\n    /**\n     * Emits a device after the configured time interval has passed.\n     */\n    protected emitDevice(identifiers: DeviceIdentifiers): Promise<void> {\n        return new Promise((resolve) => {\n            setTimeout(() => {\n                super.handleDiscoveredDevice(identifiers);\n                resolve();\n            }, this.emitInterval);\n        });\n    }\n}\n\n/**\n * Utility class that \"discovers\" devices from a cache.\n */\nexport class CacheDeviceDiscoverer extends DeviceDiscoverer {\n    /**\n     * @param deviceCache - The cached devices.\n     * @param emitInterval - The interval, in milliseconds, to wait between each emitted device.\n     */\n    constructor(\n        readonly deviceCache: DeviceCache,\n        readonly emitInterval = 20,\n    ) {\n        super();\n    }\n\n    /**\n     * Runs this discoverer.\n     */\n    async run() {\n        // emit all cached devices\n        for (const d of this.deviceCache) {\n            await this.emitDevice({\n                deviceId: d.id,\n                hostname: d.hostname,\n            });\n        }\n    }\n\n    /**\n     * Emits a device after the configured time interval has passed.\n     */\n    protected emitDevice(identifiers: DeviceIdentifiers): Promise<void> {\n        return new Promise((resolve) => {\n            setTimeout(() => {\n                super.handleDiscoveredDevice(identifiers);\n                resolve();\n            }, this.emitInterval);\n        });\n    }\n}\n\n/**\n * Implements a homebridge dynamic platform plugin.\n */\nexport class ShellyPlatform implements DynamicPlatformPlugin {\n    /**\n     * The configuration options for this platform.\n     */\n    readonly options: PlatformOptions;\n\n    /**\n     * A set of custom HomeKit characteristics.\n     */\n    readonly customCharacteristics: CustomCharacteristics;\n\n    /**\n     * A set of custom HomeKit services.\n     */\n    readonly customServices: CustomServices;\n\n    /**\n     * A reference to the shellies-ds9 library.\n     */\n    protected readonly shellies: Shellies;\n\n    /**\n     * Holds all platform accessories that were loaded from cache during launch,\n     * as well as accessories that have been created since launch.\n     */\n    protected readonly accessories: Map<AccessoryUuid, PlatformAccessory> = new Map();\n\n    /**\n     * A reference to our cached devices.\n     */\n    readonly deviceCache: DeviceCache;\n\n    /**\n     * Holds all device delegates.\n     */\n    readonly deviceDelegates: Map<DeviceId, DeviceDelegate> = new Map();\n\n    /**\n     * This constructor is invoked by homebridge.\n     * @param log - A logging device for this platform.\n     * @param config - Configuration options for this platform.\n     * @param api - A reference to the homebridge API.\n     */\n    constructor(\n        readonly log: Logger,\n        config: PlatformConfig,\n        readonly api: API,\n    ) {\n        // get the platform options\n        this.options = new PlatformOptions(config);\n\n        this.customCharacteristics = Object.freeze(createCharacteristics(api));\n        this.customServices = Object.freeze(createServices(api, this.customCharacteristics));\n\n        // setup shellies-ds9\n        this.shellies = new Shellies({\n            websocket: {\n                ...this.options.websocket,\n                clientId: 'homebridge-shelly-ds9-' + Math.round(Math.random() * 1000000),\n            },\n            autoLoadStatus: true,\n            autoLoadConfig: true,\n            deviceOptions: this.options.deviceOptions,\n        });\n        this.shellies\n            .on('add', this.handleAddedDevice, this)\n            .on('remove', this.handleRemovedDevice, this)\n            .on('exclude', this.handleExcludedDevice, this)\n            .on('unknown', this.handleUnknownDevice, this)\n            .on('error', this.handleError, this);\n\n        const localStorage = api.hap.HAPStorage.storage();\n        const storagePath =\n            typeof localStorage.options?.dir === 'string' ? localStorage.options.dir : api.user.storagePath() || '.';\n        this.deviceCache = new DeviceCache(storagePath, log);\n\n        // wait for homebridge to finish launching\n        api.on('didFinishLaunching', this.initialize.bind(this));\n    }\n\n    /**\n     * Configures cached accessories.\n     * This method is invoked once for each cached accessory that is loaded during launch.\n     */\n    configureAccessory(accessory: PlatformAccessory) {\n        // store it for later\n        this.accessories.set(accessory.UUID, accessory);\n    }\n\n    /**\n     * Returns the platform accessory with the given UUID.\n     * @param uuid - The UUID.\n     */\n    getAccessory(uuid: AccessoryUuid): PlatformAccessory | undefined {\n        return this.accessories.get(uuid);\n    }\n\n    /**\n     * Adds one or more platform accessories to this platform.\n     * This method will also register the accessories with homebridge.\n     * @param accessories - The platform accessories to add.\n     */\n    addAccessory(...accessories: PlatformAccessory[]) {\n        if (accessories.length === 0) {\n            return;\n        }\n\n        const accs: PlatformAccessory[] = [];\n\n        // add the accessories to our list\n        for (const pa of accessories) {\n            // skip if this accessory has already been added\n            if (this.accessories.has(pa.UUID)) {\n                continue;\n            }\n\n            this.accessories.set(pa.UUID, pa);\n            accs.push(pa);\n        }\n\n        // register the accessories with homebridge\n        this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, accs);\n    }\n\n    /**\n     * Removes one or more platform accessories from this platform.\n     * This method will also unregister the accessories from homebridge.\n     * @param accessories - The platform accessories to remove.\n     */\n    removeAccessory(...accessories: PlatformAccessory[]) {\n        if (accessories.length === 0) {\n            return;\n        }\n\n        // remove the accessories from our list\n        for (const pa of accessories) {\n            this.accessories.delete(pa.UUID);\n        }\n\n        // unregister the accessories from homebridge\n        this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, accessories);\n    }\n\n    /**\n     * Initializes this platform.\n     */\n    protected async initialize() {\n        this.log.debug(\n            this.accessories.size === 1\n                ? 'Loaded 1 accessory from cache'\n                : `Loaded ${this.accessories.size} accessories from cache`,\n        );\n\n        await this.runConfigDeviceDiscoverer();\n\n        // load cached devices\n        try {\n            await this.deviceCache.load();\n        } catch (e) {\n            this.log.error('Failed to load cached devices:', e instanceof Error ? e.message : e);\n        }\n\n        await this.runCacheDeviceDiscoverer();\n\n        if (this.options.mdns.enable === true) {\n            this.startMdnsDeviceDiscovery();\n        } else {\n            this.log.debug('mDNS device discovery disabled');\n        }\n    }\n\n    /**\n     * Discovers all devices found in the configuration.\n     */\n    protected runConfigDeviceDiscoverer(): Promise<void> {\n        // create a device discoverer\n        const discoverer = new ConfigDeviceDiscoverer(this.options);\n        // register it\n        this.shellies.registerDiscoverer(discoverer);\n        // run it\n        return discoverer.run();\n    }\n\n    /**\n     * Discovers all devices found in cache.\n     */\n    protected runCacheDeviceDiscoverer(): Promise<void> {\n        // create a device discoverer\n        const discoverer = new CacheDeviceDiscoverer(this.deviceCache);\n        // register it\n        this.shellies.registerDiscoverer(discoverer);\n        // run it\n        return discoverer.run();\n    }\n\n    /**\n     * Starts device discovery over mDNS.\n     */\n    protected async startMdnsDeviceDiscovery() {\n        // create a device discoverer\n        const discoverer = new MdnsDeviceDiscoverer(this.options.mdns);\n        // register it\n        this.shellies.registerDiscoverer(discoverer);\n\n        // log errors\n        discoverer.on('error', (error: Error) => {\n            this.log.error('An error occurred in the mDNS device discovery service:', error.message);\n            this.log.debug(error.stack || '');\n        });\n\n        try {\n            // start the service\n            await discoverer.start();\n\n            this.log.info('mDNS device discovery started');\n        } catch (e) {\n            this.log.error('Failed to start the mDNS device discovery service:', e instanceof Error ? e.message : e);\n            if (e instanceof Error && e.stack) {\n                this.log.debug(e.stack);\n            }\n        }\n    }\n\n    /**\n     * Handles 'add' events from the shellies-ds9 library.\n     */\n    protected async handleAddedDevice(device: Device) {\n        // make sure this device hasn't already been added\n        if (this.deviceDelegates.has(device.id)) {\n            this.log.error(`Device with ID ${device.id} has already been added`);\n            return;\n        }\n\n        // get the device delegate class for this device\n        const cls = DeviceDelegate.getDelegate(device.model);\n        if (cls === undefined) {\n            // this is an unknown device\n            this.handleUnknownDevice(device.id, device.model);\n            return;\n        }\n\n        // get the configuration options for this device (and copy them)\n        const opts = { ...this.options.getDeviceOptions(device.id) };\n\n        // if no name has been specified...\n        if (!opts.name) {\n            // use the name from the API\n            opts.name = device.system.config?.device?.name;\n        }\n\n        // create a delegate for this device\n        const delegate = new cls(device, opts, this);\n\n        // store the delegate\n        this.deviceDelegates.set(device.id, delegate);\n\n        // store info about this device in cache\n        this.deviceCache.storeDevice(device);\n    }\n\n    /**\n     * Handles 'remove' events from the shellies-ds9 library.\n     */\n    protected handleRemovedDevice(device: Device) {\n        // destroy and remove the device delegate\n        this.deviceDelegates.get(device.id)?.destroy();\n        this.deviceDelegates.delete(device.id);\n\n        // delete this device from cache\n        this.deviceCache.delete(device.id);\n    }\n\n    /**\n     * Handles 'exclude' events from the shellies-ds9 library.\n     */\n    protected handleExcludedDevice(deviceId: DeviceId) {\n        this.log.info(`[${deviceId}] Device excluded`);\n\n        // delete this device from cache\n        this.deviceCache.delete(deviceId);\n\n        if (this.deviceDelegates.has(deviceId)) {\n            // destroy and remove the device delegate\n            this.deviceDelegates.get(deviceId)!.destroy();\n            this.deviceDelegates.delete(deviceId);\n        } else {\n            // find all of its platform accessories\n            const pas: PlatformAccessory[] = [];\n\n            for (const pa of this.accessories.values()) {\n                if (pa.context.device?.id === deviceId) {\n                    pas.push(pa);\n                }\n            }\n\n            // unregister them\n            if (pas.length > 0) {\n                this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_NAME, pas);\n            }\n\n            this.log.debug(\n                pas.length === 1\n                    ? '1 platform accessory unregistered'\n                    : `${pas.length} platform accessories unregistered`,\n            );\n        }\n    }\n\n    /**\n     * Handles 'unknown' events from the shellies-ds9 library.\n     */\n    protected handleUnknownDevice(deviceId: DeviceId, model: string) {\n        this.log.warn(`[${deviceId}] Unknown device of model \"${model}\" discovered.`);\n    }\n\n    /**\n     * Handles 'error' events from the shellies-ds9 library.\n     */\n    protected handleError(deviceId: DeviceId, error: Error) {\n        // print the error to the log\n        this.log.error(error.message);\n        this.log.debug(error.stack || '');\n    }\n}\n","import type { API } from 'homebridge';\n\nimport { PLATFORM_NAME, ShellyPlatform } from './platform.ts';\n\nexport default (api: API) => {\n    api.registerPlatform(PLATFORM_NAME, ShellyPlatform);\n};\n"],"mappings":"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"}