UNPKG

homebridge-pioneer-avr-2025

Version:

A Pioneer AVR plugin for homebridge. This plugin is designed for Pioneer models that use Telnet Commands (e.g., VSX-922). It may not be compatible with newer models (e.g., VSX-LX304).

971 lines 59.4 kB
"use strict";
// src/pioneer-avr-accessory.ts
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const pioneerAvr_1 = __importDefault(require("./pioneer-avr/pioneerAvr"));
const fs_1 = __importDefault(require("fs")); // For file system operations
const path_1 = __importDefault(require("path")); // For handling file paths
const package_json_1 = __importDefault(require("../package.json"));
const exitHandler_1 = require("./exitHandler");
class PioneerAvrAccessory {
    // private timeoutFunctionSetSwitchListeningMode: NodeJS.Timeout | null = null;
    constructor(device, platform, accessory) {
        this.device = device;
        this.enabledServices = [];
        this.inputCacheFile = '';
        this.inputCache = {};
        this.writeVisbilityTimeout = null;
        this.telnetConnectedServiceSwitchDisconnectTimeout = null;
        this.lastListeningSwitchPressTime = 0;
        this.LOCK_INTERVAL_LISTENING_SWITCH = 2000;
        /**
        * Prepares the Switch service for check/control if telnet connected.
        */
        this.timeoutFunctionSetSwitchTelnetConnected = null;
        // Timestamp for the last input switch press
        // Lock interval in milliseconds for input switch commands
        this.lastInputSwitchPressTime = 0;
        this.timeoutupdateInputSwitchStates = null;
        this.LOCK_INTERVAL_INPUT_SWITCH = 3000;
        this.device = device;
        this.platform = platform;
        this.accessory = accessory;
        this.log = this.platform.log;
        this.name = device.name || 'Pioneer AVR';
        this.manufacturer = this.platform.config.manufacturer || 'Pioneer';
        this.model =
            this.platform.config.model || device.name || 'Unknown Model';
        this.host = device.host || this.platform.config.host || '';
        this.maxVolume = this.platform.config.maxVolume || 100;
        this.prefsDir =
            this.platform.config.prefsDir ||
                this.platform.api.user.storagePath() + '/pioneerAvr/';
        this.inputCacheFile = path_1.default.join(this.prefsDir, `inputCache_${this.host}.json`);
        this.version = package_json_1.default.version;
        this.name = this.name.replace(/[^a-zA-Z0-9 ']/g, '');
        this.name = this.name
            .replace(/^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$/g, '')
            .trim();
        this.log.info(`Creating accessory ${this.name} for: ${this.device.origName} at ${this.device.host}:${this.device.port}`);
        try {
            this.avr = new pioneerAvr_1.default(platform, this, () => __awaiter(this, void 0, void 0, function* () {
                var _a, _b;
                try {
                    while (!this.avr) {
                        yield new Promise((resolve) => setTimeout(resolve, 180));
                    }
                    this.enabledServices = [];
                    yield this.prepareInformationService();
                    yield this.prepareTvService();
                    yield this.prepareTvSpeakerService();
                    if ((_a = this.platform.config.toggleListeningMode) !== null && _a !== void 0 ? _a : true) {
                        yield this.prepareListeningService();
                    }
                    if (this.maxVolume !== 0) {
                        yield this.prepareVolumeService();
                    }
                    if ((_b = this.platform.config.telnetSwitch) !== null && _b !== void 0 ? _b : true) {
                        yield this.prepareTelnetConnectedService();
                    }
                    this.log.info(`> Finished initializing. Device ${this.name} ready!`);
                }
                catch (err) {
                    this.log.debug('Error during AVR setup callback:', err);
                }
            }));
            this.avr.addInputSourceService =
                this.addInputSourceService.bind(this);
        }
        catch (err) {
            this.log.debug('Error initializing AVR:', err);
        }
        // addExitHandler(() => {
        //     if (this.writeVisbilityTimeout) {
        //         clearTimeout(this.writeVisbilityTimeout);
        //     }
        // }, this);
    }
    handleInputSwitches() {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.device.inputSwitches && Array.isArray(this.device.inputSwitches) && this.device.inputSwitches.length > 0) {
                yield this.addInputSwitch(this.device.host, this.device.inputSwitches);
            }
        });
    }
    /**
     * Prepares the accessory's information service.
     */
    prepareInformationService() {
        return __awaiter(this, void 0, void 0, function* () {
            this.informationService =
                this.accessory.getService(this.platform.service.AccessoryInformation) ||
                    this.accessory.addService(this.platform.service.AccessoryInformation);
            this.informationService
                .setCharacteristic(this.platform.characteristic.Name, this.device.name.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9 '])/g, ''))
                .setCharacteristic(this.platform.characteristic.Manufacturer, this.manufacturer)
                .setCharacteristic(this.platform.characteristic.Model, this.model)
                .setCharacteristic(this.platform.characteristic.SerialNumber, this.device.origName.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9\-\. '])/g, ''))
                .setCharacteristic(this.platform.characteristic.FirmwareRevision, this.version);
            this.enabledServices.push(this.informationService);
        });
    }
    /**
     * Sets up the Television service to control the AVR's power and input selection.
     */
    prepareTvService() {
        return __awaiter(this, void 0, void 0, function* () {
            this.tvService =
                this.accessory.getService(this.platform.service.Television) ||
                    this.accessory.addService(this.platform.service.Television, this.name, 'tvService');
            this.tvService
                .setCharacteristic(this.platform.characteristic.ConfiguredName, this.name)
                .setCharacteristic(this.platform.characteristic.SleepDiscoveryMode, this.platform.characteristic.SleepDiscoveryMode
                .ALWAYS_DISCOVERABLE);
            (0, exitHandler_1.addExitHandler)(() => {
                this.tvService.updateCharacteristic(this.platform.characteristic.SleepDiscoveryMode, this.platform.characteristic.SleepDiscoveryMode
                    .NOT_DISCOVERABLE);
            }, this);
            this.tvService
                .getCharacteristic(this.platform.characteristic.Active)
                .onGet(this.getPowerOn.bind(this))
                .onSet(this.setPowerOn.bind(this));
            this.tvService
                .getCharacteristic(this.platform.characteristic.ActiveIdentifier)
                .onGet(this.getActiveIdentifier.bind(this))
                .onSet(this.setActiveIdentifier.bind(this));
            this.tvService
                .getCharacteristic(this.platform.characteristic.RemoteKey)
                .onSet(this.remoteKeyPress.bind(this));
            this.enabledServices.push(this.tvService);
            this.avr.functionSetPowerState = (set) => {
                try {
                    const boolToNum = set ? 1 : 0;
                    if (this.tvService.getCharacteristic(this.platform.characteristic.Active).value !== boolToNum) {
                        // console.log('functionSetPowerState SET', boolToNum)
                        this.tvService.updateCharacteristic(this.platform.characteristic.SleepDiscoveryMode, !boolToNum);
                        this.tvService.updateCharacteristic(this.platform.characteristic.Active, boolToNum);
                    }
                }
                catch (e) {
                    this.log.debug('Error functionSetPowerState:', e);
                }
            };
            this.avr.functionSetPowerState(this.avr.state.on);
            this.avr.functionSetActiveIdentifier = (set) => {
                if (this.tvService.getCharacteristic(this.platform.characteristic.ActiveIdentifier).value !== set) {
                    this.tvService.updateCharacteristic(this.platform.characteristic.ActiveIdentifier, set);
                }
            };
        });
    }
    /**
     * Prepares the Television Speaker service for volume control.
     */
    prepareTvSpeakerService() {
        return __awaiter(this, void 0, void 0, function* () {
            while (!this.tvService ||
                !this.enabledServices.includes(this.tvService)) {
                yield new Promise((resolve) => setTimeout(resolve, 180));
            }
            this.tvSpeakerService =
                this.accessory.getService(this.platform.service.TelevisionSpeaker) ||
                    this.accessory.addService(this.platform.service.TelevisionSpeaker, this.name + ' Speaker', 'tvSpeakerService');
            this.tvSpeakerService
                .getCharacteristic(this.platform.characteristic.Active)
                .onGet(this.getMutedInverted.bind(this))
                .onSet(this.setMutedInverted.bind(this));
            this.tvSpeakerService
                // .setCharacteristic(this.platform.characteristic.Active, this.platform.characteristic.Active.ACTIVE)
                .setCharacteristic(this.platform.characteristic.VolumeControlType, this.platform.characteristic.VolumeControlType.RELATIVE);
            // .setCharacteristic(this.platform.characteristic.VolumeControlType, this.platform.characteristic.VolumeControlType.ABSOLUTE);
            this.tvSpeakerService
                .getCharacteristic(this.platform.characteristic.VolumeSelector)
                .onSet(this.setVolumeSwitch.bind(this));
            this.tvSpeakerService
                .getCharacteristic(this.platform.characteristic.Mute)
                .onGet(this.getMuted.bind(this))
                .onSet(this.setMuted.bind(this));
            this.tvSpeakerService
                .getCharacteristic(this.platform.characteristic.Volume)
                .onGet(this.getVolume.bind(this));
            // this.tvSpeakerService.getCharacteristic(this.platform.characteristic.Volume)
            //     .onGet(this.getVolume.bind(this))
            //     .onSet(this.setVolume.bind(this));
            this.tvService.addLinkedService(this.tvSpeakerService);
            this.enabledServices.push(this.tvSpeakerService);
            // this.log.debug('prepareTvSpeakerService enabled')
        });
    }
    /**
     * Prepares the Lightbulb service for volume control.
     */
    prepareVolumeService() {
        return __awaiter(this, void 0, void 0, function* () {
            while (!this.tvService ||
                !this.enabledServices.includes(this.tvService) ||
                !this.tvSpeakerService ||
                !this.enabledServices.includes(this.tvSpeakerService)) {
                yield new Promise((resolve) => setTimeout(resolve, 180));
            }
            this.volumeServiceLightbulb =
                this.accessory.getService(this.platform.service.Lightbulb) ||
                    this.accessory.addService(this.platform.service.Lightbulb, this.name + ' Volume', 'volumeInput');
            this.volumeServiceLightbulb.addOptionalCharacteristic(this.platform.characteristic.ConfiguredName);
            this.volumeServiceLightbulb.setCharacteristic(this.platform.characteristic.Name, 'Volume');
            this.volumeServiceLightbulb.setCharacteristic(this.platform.characteristic.ConfiguredName, 'Volume');
            this.volumeServiceLightbulb
                .getCharacteristic(this.platform.characteristic.On)
                .onGet(this.getMutedInverted.bind(this))
                .onSet(this.setMutedInverted.bind(this));
            this.volumeServiceLightbulb
                .getCharacteristic(this.platform.characteristic.Brightness)
                .onGet(this.getVolume.bind(this))
                .onSet(this.setVolume.bind(this));
            this.tvService.addLinkedService(this.volumeServiceLightbulb);
            this.enabledServices.push(this.volumeServiceLightbulb);
            this.avr.functionSetLightbulbVolume = (set) => {
                try {
                    const currentBrightness = this.volumeServiceLightbulb.getCharacteristic(this.platform.characteristic.Brightness).value;
                    const currentOnState = this.volumeServiceLightbulb.getCharacteristic(this.platform.characteristic.On).value;
                    // Update Brightness only if it is different from the new volume
                    if (currentBrightness !== set) {
                        this.volumeServiceLightbulb.updateCharacteristic(this.platform.characteristic.Brightness, this.avr.state.muted || !this.avr.state.on ? 0 : set);
                    }
                    // Update On state based on mute and power status
                    if (currentOnState !==
                        !(this.avr.state.muted || !this.avr.state.on)) {
                        this.volumeServiceLightbulb.updateCharacteristic(this.platform.characteristic.On, !(this.avr.state.muted || !this.avr.state.on));
                    }
                }
                catch (e) {
                    this.log.debug('Error updating Lightbulb volume:', e);
                }
            };
            // Initial volume setup only if volume state is valid
            if (typeof this.avr.state.volume === 'number') {
                this.avr.functionSetLightbulbVolume(this.avr.state.volume);
            }
            this.avr.functionSetLightbulbMuted = () => {
                try {
                    const currentOnState = this.volumeServiceLightbulb.getCharacteristic(this.platform.characteristic.On).value;
                    if (currentOnState !==
                        !(this.avr.state.muted || !this.avr.state.on)) {
                        this.volumeServiceLightbulb.updateCharacteristic(this.platform.characteristic.On, !(this.avr.state.muted || !this.avr.state.on));
                    }
                }
                catch (e) {
                    this.log.debug('Error updating Lightbulb mute state:', e);
                }
            };
            this.avr.functionSetLightbulbMuted(this.avr.state.muted);
        });
    }
    prepareTelnetConnectedService() {
        return __awaiter(this, void 0, void 0, function* () {
            while (!this.tvService ||
                !this.enabledServices.includes(this.tvService)) {
                yield new Promise((resolve) => setTimeout(resolve, 180));
            }
            try {
                let switchName = `${this.name} telnet`;
                switchName = switchName.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9 '])/g, '')
                    .trim();
                this.log.debug(`Creating switch accessory: ${switchName} for: ${this.name}`);
                const uuid = this.platform.api.hap.uuid.generate(`${this.host}-telnetState`);
                // Check if accessory already exists
                let accessory = this.platform.accessories.find((existing) => existing.UUID === uuid);
                if (!accessory) {
                    accessory = new this.platform.api.platformAccessory(switchName, uuid);
                    this.platform.accessories.push(accessory);
                    this.platform.api.registerPlatformAccessories(this.platform.pluginName, this.platform.platformName, [accessory]);
                }
                // Add or update Switch service
                this.telnetConnectedServiceSwitch =
                    accessory.getServiceById(this.platform.service.Switch, this.name + 'telnetState') ||
                        accessory.addService(this.platform.service.Switch, switchName, this.name + 'telnetState');
                const informationService = accessory.getService(this.platform.service.AccessoryInformation) ||
                    accessory.addService(this.platform.service.AccessoryInformation);
                informationService
                    .setCharacteristic(this.platform.characteristic.Name, switchName.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9 '])/g, ''))
                    .setCharacteristic(this.platform.characteristic.Manufacturer, this.manufacturer)
                    .setCharacteristic(this.platform.characteristic.Model, this.model)
                    .setCharacteristic(this.platform.characteristic.SerialNumber, `${this.name}-telnetState`.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9\-\. '])/g, ''))
                    .setCharacteristic(this.platform.characteristic.FirmwareRevision, this.version);
                this.telnetConnectedServiceSwitch
                    .getCharacteristic(this.platform.characteristic.On)
                    .onGet(() => __awaiter(this, void 0, void 0, function* () {
                    var _a, _b, _c, _d, _e, _f, _g, _h;
                    return !!(((_d = (_c = (_b = (_a = this.avr) === null || _a === void 0 ? void 0 : _a.telnetAvr) === null || _b === void 0 ? void 0 : _b.connection) === null || _c === void 0 ? void 0 : _c.socket) === null || _d === void 0 ? void 0 : _d.connecting) || ((_h = (_g = (_f = (_e = this.avr) === null || _e === void 0 ? void 0 : _e.telnetAvr) === null || _f === void 0 ? void 0 : _f.connection) === null || _g === void 0 ? void 0 : _g.socket) === null || _h === void 0 ? void 0 : _h.readyState) === 'open');
                }))
                    .onSet((value) => __awaiter(this, void 0, void 0, function* () {
                    var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
                    // this.log.debug('telnetConnectedServiceSwitch pressed:', value);
                    if (this.timeoutFunctionSetSwitchTelnetConnected) {
                        clearTimeout(this.timeoutFunctionSetSwitchTelnetConnected);
                    }
                    const currentState = !!(((_d = (_c = (_b = (_a = this.avr) === null || _a === void 0 ? void 0 : _a.telnetAvr) === null || _b === void 0 ? void 0 : _b.connection) === null || _c === void 0 ? void 0 : _c.socket) === null || _d === void 0 ? void 0 : _d.connecting) || ((_h = (_g = (_f = (_e = this.avr) === null || _e === void 0 ? void 0 : _e.telnetAvr) === null || _f === void 0 ? void 0 : _f.connection) === null || _g === void 0 ? void 0 : _g.socket) === null || _h === void 0 ? void 0 : _h.readyState) === 'open');
                    if (!!value !== !!currentState) {
                        if (!!value) {
                            //connect?
                            if (this.telnetConnectedServiceSwitchDisconnectTimeout) {
                                clearTimeout(this.telnetConnectedServiceSwitchDisconnectTimeout);
                            }
                            if (((_k = (_j = this.avr) === null || _j === void 0 ? void 0 : _j.telnetAvr) === null || _k === void 0 ? void 0 : _k.connection) && 'forcedDisconnect' in this.avr.telnetAvr.connection) {
                                this.avr.telnetAvr.connection.forcedDisconnect = false;
                            }
                            if ((_l = this.avr) === null || _l === void 0 ? void 0 : _l.lastUserInteraction) {
                                this.avr.lastUserInteraction = Date.now();
                            }
                            if ((_p = (_o = (_m = this.avr) === null || _m === void 0 ? void 0 : _m.telnetAvr) === null || _o === void 0 ? void 0 : _o.connection) === null || _p === void 0 ? void 0 : _p.connect) {
                                this.avr.telnetAvr.connection.connect();
                            }
                        }
                        else {
                            //disconnect?
                            let timeoutToDisconnect = 4900;
                            if ((_r = (_q = this.avr) === null || _q === void 0 ? void 0 : _q.state) === null || _r === void 0 ? void 0 : _r.on) {
                                timeoutToDisconnect = ((5 * 60 * 1000) + 4900);
                            }
                            else if ((_s = this.avr) === null || _s === void 0 ? void 0 : _s.lastUserInteraction) {
                                if ((((5 * 60 * 1000) + 4900) - (Date.now() - this.avr.lastUserInteraction)) > 5000) {
                                    timeoutToDisconnect = (((5 * 60 * 1000) + 4900) - (Date.now() - this.avr.lastUserInteraction));
                                }
                                else {
                                    timeoutToDisconnect = 4900;
                                }
                                // this.log.debug('lastUserInteraction', Date.now(), this.avr.lastUserInteraction, (Date.now() - this.avr.lastUserInteraction) / 1000, ((Date.now() - this.avr.lastUserInteraction) < (62 * 1000)));
                                if ((Date.now() - this.avr.lastUserInteraction) < (62 * 1000)) {
                                    timeoutToDisconnect = 62 * 1000;
                                }
                            }
                            if (timeoutToDisconnect < 4900) {
                                timeoutToDisconnect = 4900;
                            }
                            if (this.telnetConnectedServiceSwitchDisconnectTimeout) {
                                clearTimeout(this.telnetConnectedServiceSwitchDisconnectTimeout);
                            }
                            if (timeoutToDisconnect < (60 * 1000) && ((_u = (_t = this.avr) === null || _t === void 0 ? void 0 : _t.telnetAvr) === null || _u === void 0 ? void 0 : _u.connection) && 'forcedDisconnect' in this.avr.telnetAvr.connection) {
                                this.avr.telnetAvr.connection.forcedDisconnect = true;
                            }
                            this.telnetConnectedServiceSwitchDisconnectTimeout = setTimeout(() => {
                                var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
                                if (!((_b = (_a = this.avr) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.on) && (((_f = (_e = (_d = (_c = this.avr) === null || _c === void 0 ? void 0 : _c.telnetAvr) === null || _d === void 0 ? void 0 : _d.connection) === null || _e === void 0 ? void 0 : _e.socket) === null || _f === void 0 ? void 0 : _f.readyState) === 'open' || ((_k = (_j = (_h = (_g = this.avr) === null || _g === void 0 ? void 0 : _g.telnetAvr) === null || _h === void 0 ? void 0 : _h.connection) === null || _j === void 0 ? void 0 : _j.socket) === null || _k === void 0 ? void 0 : _k.connecting)) && (!((_l = this.avr) === null || _l === void 0 ? void 0 : _l.lastUserInteraction) ||
                                    ((Date.now() - this.avr.lastUserInteraction) > (61 * 1000)))) {
                                    let runDisconnect = false;
                                    if (((_m = this.avr) === null || _m === void 0 ? void 0 : _m.telnetAvr) && 'connectionReady' in this.avr.telnetAvr) {
                                        if ((_p = (_o = this.avr) === null || _o === void 0 ? void 0 : _o.telnetAvr) === null || _p === void 0 ? void 0 : _p.connectionReady) {
                                            runDisconnect = true;
                                        }
                                        this.avr.telnetAvr.connectionReady = false;
                                    }
                                    else {
                                        runDisconnect = true;
                                    }
                                    if (runDisconnect) {
                                        if (((_r = (_q = this.avr) === null || _q === void 0 ? void 0 : _q.telnetAvr) === null || _r === void 0 ? void 0 : _r.connection) && 'forcedDisconnect' in this.avr.telnetAvr.connection) {
                                            this.avr.telnetAvr.connection.forcedDisconnect = true;
                                        }
                                        if ((_v = (_u = (_t = (_s = this.avr) === null || _s === void 0 ? void 0 : _s.telnetAvr) === null || _t === void 0 ? void 0 : _t.connection) === null || _u === void 0 ? void 0 : _u.messageQueue) === null || _v === void 0 ? void 0 : _v.clearQueue) {
                                            this.avr.telnetAvr.connection.messageQueue.clearQueue();
                                        }
                                        if ((_y = (_x = (_w = this.avr) === null || _w === void 0 ? void 0 : _w.telnetAvr) === null || _x === void 0 ? void 0 : _x.connection) === null || _y === void 0 ? void 0 : _y.disconnect) {
                                            setTimeout(() => {
                                                this.avr.telnetAvr.connection.disconnect();
                                            }, 100);
                                        }
                                    }
                                }
                                else if ((_0 = (_z = this.avr) === null || _z === void 0 ? void 0 : _z.state) === null || _0 === void 0 ? void 0 : _0.on) {
                                    this.log.debug('the receiver is still on, no disconnect.');
                                }
                                if (this.timeoutFunctionSetSwitchTelnetConnected) {
                                    clearTimeout(this.timeoutFunctionSetSwitchTelnetConnected);
                                }
                                this.avr.functionSetSwitchTelnetConnected();
                            }, timeoutToDisconnect);
                            this.log.debug('time to disconnect ms:', timeoutToDisconnect);
                        }
                        if (this.timeoutFunctionSetSwitchTelnetConnected) {
                            clearTimeout(this.timeoutFunctionSetSwitchTelnetConnected);
                        }
                        this.timeoutFunctionSetSwitchTelnetConnected = setTimeout(() => {
                            this.avr.functionSetSwitchTelnetConnected();
                        }, 5000);
                    }
                }));
                (0, exitHandler_1.addExitHandler)(() => {
                    this.telnetConnectedServiceSwitch.updateCharacteristic(this.platform.characteristic.On, false);
                }, this);
                this.enabledServices.push(this.telnetConnectedServiceSwitch);
                this.avr.functionSetSwitchTelnetConnected = () => {
                    var _a, _b, _c, _d, _e, _f, _g, _h;
                    try {
                        const currentOnState = this.telnetConnectedServiceSwitch.getCharacteristic(this.platform.characteristic.On).value;
                        // Update On state based on whether a listening mode is active
                        if ((((_d = (_c = (_b = (_a = this.avr) === null || _a === void 0 ? void 0 : _a.telnetAvr) === null || _b === void 0 ? void 0 : _b.connection) === null || _c === void 0 ? void 0 : _c.socket) === null || _d === void 0 ? void 0 : _d.readyState) === 'open') !== currentOnState) {
                            this.telnetConnectedServiceSwitch.updateCharacteristic(this.platform.characteristic.On, !!(((_h = (_g = (_f = (_e = this.avr) === null || _e === void 0 ? void 0 : _e.telnetAvr) === null || _f === void 0 ? void 0 : _f.connection) === null || _g === void 0 ? void 0 : _g.socket) === null || _h === void 0 ? void 0 : _h.readyState) === 'open'));
                        }
                    }
                    catch (e) {
                        this.log.debug('Error updating Switch listening mode:', e);
                    }
                };
                // Initial listening mode setup
                this.avr.functionSetSwitchTelnetConnected();
                this.avr.telnetAvr.addOnDisconnectCallback(() => {
                    this.avr.functionSetSwitchTelnetConnected();
                });
                this.avr.telnetAvr.addOnConnectCallback(() => __awaiter(this, void 0, void 0, function* () {
                    this.avr.functionSetSwitchTelnetConnected();
                }));
            }
            catch (error) {
                this.log.error('telnetConnectedServiceSwitchError:', error);
            }
        });
    }
    /**
    * Prepares the Switch service for listening mode control.
    */
    prepareListeningService() {
        return __awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            while (!this.tvService ||
                !this.enabledServices.includes(this.tvService)) {
                yield new Promise((resolve) => setTimeout(resolve, 180));
            }
            const isValidListeningMode = (value, defaultValue) => {
                return /^[0-9]{4}$/.test(value || '') ? value : defaultValue;
            };
            const listeningModeOne = isValidListeningMode(this.device.listeningMode || this.platform.config.listeningMode, '0013'); // PRO LOGIC2 MOVIE
            const listeningModeFallback = isValidListeningMode(this.device.listeningModeFallback || this.platform.config.listeningModeFallback, '0101'); // ACTION
            // const listeningModeOther = isValidListeningMode(this.device.listeningModeOther || this.platform.config.listeningModeOther, '0112'); // EXTENDED STEREO
            let switchName = `${this.name} Audio`;
            switchName = switchName.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9 '])/g, '')
                .trim();
            // Add or update Switch service
            if ((_a = this.platform.config.toggleListeningModeLink) !== null && _a !== void 0 ? _a : true) {
                this.listeningServiceSwitch =
                    this.accessory.getServiceById(this.platform.service.Switch, this.name + 'listeningMode') ||
                        this.accessory.addService(this.platform.service.Switch, switchName, this.name + 'listeningMode');
                this.listeningServiceSwitch.addOptionalCharacteristic(this.platform.characteristic.ConfiguredName);
                this.listeningServiceSwitch.setCharacteristic(this.platform.characteristic.Name, 'listeningMode');
                this.listeningServiceSwitch.setCharacteristic(this.platform.characteristic.ConfiguredName, 'listeningMode');
            }
            else {
                const uuid = this.platform.api.hap.uuid.generate(`${this.host}-listeningMode`);
                // Check if accessory already exists
                let accessory = this.platform.accessories.find((existing) => existing.UUID === uuid);
                if (!accessory) {
                    accessory = new this.platform.api.platformAccessory(switchName, uuid);
                    this.platform.accessories.push(accessory);
                    this.platform.api.registerPlatformAccessories(this.platform.pluginName, this.platform.platformName, [accessory]);
                }
                this.listeningServiceSwitch =
                    accessory.getServiceById(this.platform.service.Switch, this.name + 'listeningMode') ||
                        accessory.addService(this.platform.service.Switch, switchName, this.name + 'listeningMode');
                const informationService = accessory.getService(this.platform.service.AccessoryInformation) ||
                    accessory.addService(this.platform.service.AccessoryInformation);
                informationService
                    .setCharacteristic(this.platform.characteristic.Name, switchName.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9 '])/g, ''))
                    .setCharacteristic(this.platform.characteristic.Manufacturer, this.manufacturer)
                    .setCharacteristic(this.platform.characteristic.Model, this.model)
                    .setCharacteristic(this.platform.characteristic.SerialNumber, `${this.name}-listeningMode`.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9\-\. '])/g, ''))
                    .setCharacteristic(this.platform.characteristic.FirmwareRevision, this.version);
            }
            this.listeningServiceSwitch
                .getCharacteristic(this.platform.characteristic.On)
                .onGet(() => __awaiter(this, void 0, void 0, function* () {
                var _a, _b, _c, _d, _e, _f;
                let isOn = ((_b = (_a = this === null || this === void 0 ? void 0 : this.avr) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.on) && [listeningModeOne, listeningModeFallback].includes(this.avr.state.listeningMode || '');
                if (((_d = (_c = this === null || this === void 0 ? void 0 : this.avr) === null || _c === void 0 ? void 0 : _c.state) === null || _d === void 0 ? void 0 : _d.on) && !((_f = (_e = this === null || this === void 0 ? void 0 : this.avr) === null || _e === void 0 ? void 0 : _e.state) === null || _f === void 0 ? void 0 : _f.listeningMode)) {
                    isOn = true;
                }
                return isOn;
            }))
                .onSet(() => __awaiter(this, void 0, void 0, function* () {
                var _a, _b, _c, _d;
                const now = Date.now();
                const timeSinceLastPress = now - this.lastListeningSwitchPressTime;
                if (((_b = (_a = this === null || this === void 0 ? void 0 : this.avr) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.on) && !((_d = (_c = this === null || this === void 0 ? void 0 : this.avr) === null || _c === void 0 ? void 0 : _c.state) === null || _d === void 0 ? void 0 : _d.listeningMode)) {
                    return;
                }
                if (timeSinceLastPress < this.LOCK_INTERVAL_LISTENING_SWITCH) {
                    const remaining = this.LOCK_INTERVAL_LISTENING_SWITCH - timeSinceLastPress;
                    this.log.debug(`Listening switch pressed too soon, ignoring press. ${remaining} ms remaining.`);
                    // Reset the switch state to the actual current state
                    const currentState = this.avr.state.on &&
                        [listeningModeOne, listeningModeFallback].includes(this.avr.state.listeningMode || '');
                    this.listeningServiceSwitch
                        .getCharacteristic(this.platform.characteristic.On)
                        .updateValue(currentState);
                    return;
                }
                this.lastListeningSwitchPressTime = now;
                this.avr.toggleListeningMode();
            }));
            (0, exitHandler_1.addExitHandler)(() => {
                this.listeningServiceSwitch.updateCharacteristic(this.platform.characteristic.On, false);
            }, this);
            if ((_b = this.platform.config.toggleListeningModeLink) !== null && _b !== void 0 ? _b : true) {
                this.tvService.addLinkedService(this.listeningServiceSwitch);
            }
            this.enabledServices.push(this.listeningServiceSwitch);
            this.avr.functionSetSwitchListeningMode = () => __awaiter(this, void 0, void 0, function* () {
                var _a, _b, _c, _d, _e, _f, _g;
                if (!((_b = (_a = this === null || this === void 0 ? void 0 : this.avr) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.on) && (!this.tvService ||
                    !this.enabledServices.includes(this.tvService) ||
                    !((_c = this === null || this === void 0 ? void 0 : this.avr) === null || _c === void 0 ? void 0 : _c.isReady) || !((_e = (_d = this === null || this === void 0 ? void 0 : this.avr) === null || _d === void 0 ? void 0 : _d.state) === null || _e === void 0 ? void 0 : _e.listeningMode))) {
                    this.listeningServiceSwitch.updateCharacteristic(this.platform.characteristic.On, false);
                    return;
                }
                if (this.avr.state.on && !this.avr.state.listeningMode) {
                    yield ((_g = (_f = this === null || this === void 0 ? void 0 : this.avr) === null || _f === void 0 ? void 0 : _f.__updateListeningMode) === null || _g === void 0 ? void 0 : _g.call(_f, () => { }));
                }
                try {
                    const currentOnState = this.listeningServiceSwitch.getCharacteristic(this.platform.characteristic.On).value;
                    const isValidListeningMode = (value, defaultValue) => {
                        return /^[0-9]{4}$/.test(value || '') ? value : defaultValue;
                    };
                    const listeningModeOne = isValidListeningMode(this.device.listeningMode || this.platform.config.listeningMode, '0013'); // PRO LOGIC2 MOVIE
                    const listeningModeFallback = isValidListeningMode(this.device.listeningModeFallback || this.platform.config.listeningModeFallback, '0101'); // ACTION
                    // const listeningModeOther = isValidListeningMode(this.device.listeningModeOther || this.platform.config.listeningModeOther, '0112'); // EXTENDED STEREO
                    const listeningModeActive = isValidListeningMode(this.avr.state.listeningMode || '', ''); // EXTENDED STEREO
                    const currentState = this.avr.state.on && [listeningModeOne, listeningModeFallback].includes(listeningModeActive);
                    // Update On state based on whether a listening mode is active
                    if (!!currentOnState !== !!currentState) {
                        this.listeningServiceSwitch.updateCharacteristic(this.platform.characteristic.On, !!currentState);
                    }
                }
                catch (e) {
                    this.log.debug('Error updating Switch listening mode:', e);
                }
            });
        });
    }
    /**
     * Prepares the input source service to allow selection of various AVR inputs.
     */
    addInputSourceService(error, key) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a, _b;
            if (error) {
                return;
            }
            while (!this.tvService ||
                !this.enabledServices.includes(this.tvService)) {
                yield new Promise((resolve) => setTimeout(resolve, 180));
            }
            if (!(key in this.avr.inputs)) {
                this.log.error('addInputSourceService() input key not found.', key, this.avr.inputs);
                return;
            }
            try {
                const input = this.avr.inputs[key];
                const tmpInput = this.accessory.getServiceById(this.platform.service.InputSource, key.toString()) ||
                    this.accessory.addService(this.platform.service.InputSource, input.name.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9 '])/g, ''), key.toString());
                tmpInput
                    .setCharacteristic(this.platform.characteristic.Identifier, key)
                    .setCharacteristic(this.platform.characteristic.ConfiguredName, input.name.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9 '])/g, ''))
                    .setCharacteristic(this.platform.characteristic.IsConfigured, this.platform.characteristic.IsConfigured.CONFIGURED)
                    .setCharacteristic(this.platform.characteristic.InputSourceType, (_a = input.type) !== null && _a !== void 0 ? _a : 0)
                    .setCharacteristic(this.platform.characteristic.CurrentVisibilityState, this.avr.booleanToVisibilityState((_b = input.visible) !== null && _b !== void 0 ? _b : true));
                tmpInput
                    .getCharacteristic(this.platform.characteristic.TargetVisibilityState)
                    .onSet((state) => {
                    // const state = this.avr.booleanToVisibilityState(true); // 0
                    // const isVisible = this.avr.visibilityStateToBoolean(1); // false
                    this.avr.inputs[key].visible = this.avr.visibilityStateToBoolean(parseInt(String(state), 10));
                    setTimeout(() => {
                        tmpInput.updateCharacteristic(this.platform.characteristic
                            .CurrentVisibilityState, state);
                    }, key * 233);
                    if (this.writeVisbilityTimeout) {
                        clearTimeout(this.writeVisbilityTimeout);
                    }
                    this.writeVisbilityTimeout = setTimeout(() => {
                        try {
                            if (fs_1.default.existsSync(this.inputCacheFile)) {
                                this.inputCache = JSON.parse(fs_1.default.readFileSync(this.inputCacheFile, 'utf-8'));
                            }
                            if (!this.inputCache) {
                                this.inputCache = {};
                            }
                            this.inputCache.inputs = this.avr.inputs;
                            fs_1.default.writeFile(this.inputCacheFile, JSON.stringify(this.inputCache), () => {
                                this.log.debug('saved visibility:');
                            });
                        }
                        catch (error) {
                            this.log.error('set visibility Error', error);
                        }
                    }, 15000);
                });
                tmpInput
                    .getCharacteristic(this.platform.characteristic.ConfiguredName)
                    .onSet((name) => {
                    this.avr.renameInput(input.id, String(name));
                });
                // console.log('add input to homebridge', key)
                this.tvService.addLinkedService(tmpInput);
                this.enabledServices.push(tmpInput);
            }
            catch (e) {
                console.error('Error addInputSourceService:', e);
            }
        });
    }
    /**
     * Returns the enabled HomeKit services.
     */
    getServices() {
        return this.enabledServices;
    }
    // Method to get the power status as a CharacteristicValue
    getPowerOn() {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.avr.telnetAvr.connectionReady) {
                return false;
            }
            return new Promise((resolve) => {
                this.avr.powerStatus((error, status) => {
                    if (error) {
                        this.log.error('Error getting power status:', error);
                        resolve(false);
                    }
                    else {
                        resolve(status);
                    }
                });
            });
        });
    }
    // Method to set the power status
    setPowerOn(on) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c, _d;
            // if (!this.avr.telnetAvr.connectionReady) {
            //     return;
            // }
            if (on) {
                if (!((_b = (_a = this.avr) === null || _a === void 0 ? void 0 : _a.state) === null || _b === void 0 ? void 0 : _b.on)) {
                    this.avr.powerOn();
                }
            }
            else {
                if ((_d = (_c = this.avr) === null || _c === void 0 ? void 0 : _c.state) === null || _d === void 0 ? void 0 : _d.on) {
                    this.avr.powerOff();
                }
            }
        });
    }
    getActiveIdentifier() {
        return __awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve) => {
                this.avr.inputStatus((_error, status) => {
                    resolve(status || 0);
                });
            });
        });
    }
    setActiveIdentifier(newValue) {
        return __awaiter(this, void 0, void 0, function* () {
            // console.log('setActiveIdentifier called', newValue, typeof(newValue))
            if (typeof newValue === 'number' &&
                this.avr.telnetAvr.connectionReady) {
                this.log.debug('set active identifier:', this.avr.inputs[newValue].name, this.avr.inputs[newValue].id);
                this.avr.setInput(this.avr.inputs[newValue].id);
            }
        });
    }
    setVolumeSwitch(state) {
        return __awaiter(this, void 0, void 0, function* () {
            this.log.debug('setVolumeSwitch called:', state);
            if (state !== 1) {
                this.avr.volumeUp();
            }
            else {
                this.avr.volumeDown();
            }
        });
    }
    // private async setVolumeSwitch(direction: CharacteristicValue): Promise<void> {
    //     // Check if direction is actually a number
    //     if (typeof direction === 'number') {
    //         // direction = 1 (volume down), direction = 0 (volume up)
    //         const adjustment = direction === 0 ? 1 : -3;
    //         const currentVolume = await this.getVolume();
    //
    //         this.log.debug('setVolumeSwitch()currentVolume:', currentVolume)
    //
    //         // Ensure currentVolume is a number
    //         const newVolume = typeof currentVolume === 'number'
    //             ? Math.min(Math.max(currentVolume + adjustment, 0), 100)
    //             : 0;  // Set to 0 if currentVolume is not a valid value
    //
    //         await this.setVolume(newVolume);
    //         this.log.debug('setVolumeSwitch called, adjusting volume from %s%% to: %s%%', currentVolume, newVolume);
    //     } else {
    //         this.log.debug('setVolumeSwitch called with invalid direction:', direction);
    //     }
    // }
    getVolume() {
        return __awaiter(this, void 0, void 0, function* () {
            // Extract the return value from volume as a number or default to 0 if undefined
            return new Promise((resolve) => {
                this.avr.volumeStatus((_error, volume) => {
                    resolve(typeof volume === 'number' ? volume : 0);
                });
            });
        });
    }
    setVolume(volume) {
        return __awaiter(this, void 0, void 0, function* () {
            // Check if volume is a number before sending it to the device
            if (typeof volume === 'number') {
                this.avr.setVolume(volume);
            }
            else {
                this.log.debug('setVolume called with invalid volume:', volume);
            }
        });
    }
    getMuted() {
        return __awaiter(this, void 0, void 0, function* () {
            if (!this.avr || this.avr.state.muted || !this.avr.state.on) {
                return true;
            }
            return new Promise((resolve) => {
                this.avr.muteStatus((_error, isMuted) => {
                    resolve(isMuted || false);
                });
            });
        });
    }
    setMuted(mute) {
        return __awaiter(this, void 0, void 0, function* () {
            if (mute) {
                this.avr.muteOn();
            }
            else {
                this.avr.muteOff();
            }
        });
    }
    getMutedInverted() {
        return __awaiter(this, void 0, void 0, function* () {
            return !(!this.avr || this.avr.state.muted || !this.avr.state.on);
        });
    }
    setMutedInverted(mute) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!mute) {
                this.avr.muteOn();
            }
            else {
                this.avr.muteOff();
            }
        });
    }
    remoteKeyPress(remoteKey) {
        return __awaiter(this, void 0, void 0, function* () {
            switch (remoteKey) {
                case this.platform.characteristic.RemoteKey.ARROW_UP:
                    this.avr.remoteKey('UP');
                    break;
                case this.platform.characteristic.RemoteKey.ARROW_DOWN:
                    this.avr.remoteKey('DOWN');
                    break;
                case this.platform.characteristic.RemoteKey.ARROW_LEFT:
                    this.avr.remoteKey('LEFT');
                    break;
                case this.platform.characteristic.RemoteKey.ARROW_RIGHT:
                    this.avr.remoteKey('RIGHT');
                    break;
                case this.platform.characteristic.RemoteKey.SELECT:
                    this.avr.remoteKey('ENTER');
                    break;
                case this.platform.characteristic.RemoteKey.BACK:
                    this.avr.remoteKey('RETURN');
                    break;
                case this.platform.characteristic.RemoteKey.PLAY_PAUSE:
                    this.avr.remoteKey('TOGGLE_PLAY_PAUSE');
                    break;
                case this.platform.characteristic.RemoteKey.INFORMATION:
                    this.avr.remoteKey('HOME_MENU');
                    break;
                default:
                    break;
            }
        });
    }
    updateInputSwitchStates(activeInputId) {
        // Iterate through all accessories
        this.platform.accessories.forEach((accessory) => {
            var _a, _b, _c;
            const service = accessory.getService(this.platform.service.Switch);
            // not listeningMode
            if (service && ((_a = accessory === null || accessory === void 0 ? void 0 : accessory.context) === null || _a === void 0 ? void 0 : _a.inputId)) {
                // Check if the current accessory corresponds to the active input
                // only input switches have inputId
                const isActive = !!(((_c = (_b = this.avr) === null || _b === void 0 ? void 0 : _b.state) === null || _c === void 0 ? void 0 : _c.on) && (accessory.context.inputId === activeInputId));
                // Update the switch state
                service.getCharacteristic(this.platform.characteristic.On).updateValue(isActive);
            }
        });
        // this.log.debug(`Switch states updated. Active input ID: ${activeInputId}`);
    }
    addInputSwitch(host, inputToSwitches) {
        var _a;
        const cachedInputs = ((_a = this.platform.cachedReceivers.get(host)) === null || _a === void 0 ? void 0 : _a.inputs) || [];
        if (cachedInputs.length === 0) {
            this.log.warn(`No cached inputs found for host: ${host}`);
            return;
        }
        const validAccessories = []; // Track valid accessory UUIDs
        inputToSwitches.slice(0, 5).sort((a, b) => parseInt(a, 10) - parseInt(b, 10)).forEach((inputId) => {
            const input = cachedInputs.find((input) => input.id === inputId);
            if (!input) {
                this.log.warn(`Input ID ${inputId} not found for host: ${host}`);
                return;
            }
            let switchName = `${input.name} ${this.name}`;
            switchName = switchName.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9 '])/g, '')
                .trim();
            this.log.debug(`Creating switch accessory: ${switchName} for host: ${host}`);
            const uuid = this.platform.api.hap.uuid.generate(`${host}-${inputId}`);
            validAccessories.push(uuid); // Mark this accessory as valid
            // Check if accessory already exists
            let accessory = this.platform.accessories.find((existing) => existing.UUID === uuid);
            if (!accessory) {
                accessory = new this.platform.api.platformAccessory(switchName, uuid);
                accessory.context = {
                    host,
                    inputId: input.id,
                    inputName: input.name,
                };
                this.platform.accessories.push(accessory);
                this.platform.api.registerPlatformAccessories(this.platform.pluginName, this.platform.platformName, [accessory]);
            }
            // Add or update Switch service
            const switchService = accessory.getServiceById(this.platform.service.Switch, this.name + input.id) ||
                accessory.addService(this.platform.service.Switch, switchName, this.name + input.id);
            const inputIndex = this.avr.inputs.findIndex((findInput) => findInput.id === input.id);
            // switchService.setCharacteristic(
            //     this.platform.characteristic.SerialNumber,
            //     `${host}-${input.id}-${input.name}`.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9\-\. '])/g, ''),
            // )
            const informationService = accessory.getService(this.platform.service.AccessoryInformation) ||
                accessory.addService(this.platform.service.AccessoryInformation);
            informationService
                .setCharacteristic(this.platform.characteristic.Name, switchName.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9 '])/g, ''))
                .setCharacteristic(this.platform.characteristic.Manufacturer, this.manufacturer)
                .setCharacteristic(this.platform.characteristic.Model, this.model)
                .setCharacteristic(this.platform.characteristic.SerialNumber, `${host}-${input.id}-${input.name}`.replace(/(^[^a-zA-Z0-9]+)|([^a-zA-Z0-9]+$)|([^a-zA-Z0-9\-\. '])/g, ''))
                .setCharacteristic(this.platform.characteristic.FirmwareRevision, this.version);
            // Configure 'On' characteristic
            switchService
                .getCharacteristic(this.platform.characteristic.On)
                .onGet(() => __awaiter(this, void 0, void 0, function* () {
                // Return true if the receiver is on and the input matches the switch index
                const isOn = this.avr.state.on && inputIndex === this.avr.state.input;
                return isOn;
            }))
                .onSet((value) => __awaiter(this, void 0, void 0, function* () {
                var _a;
                const now = Date.now();
                const timeSinceLastPress = now - this.lastInputSwitchPressTime;
                // If the last command was executed less than the lock interval ago, discard the press
                if (timeSinceLastPress < this.LOCK_INTERVAL_INPUT_SWITCH) {
                    const remaining = this.LOCK_INTERVAL_INPUT_SWITCH - timeSinceLastPress;
                    this.log.debug(`Pressed too soon, ignoring press. ${remaining} ms remaining.`);
                    // Reset the switch state to the current state so the UI reflects the actual state
                    const currentState = this.avr.state.on && inputIndex === this.avr.state.input;
                    switchService.getCharacteristic(this.platform.characteristic.On).updateValue(currentState);
                    return;
                }
                // Update the timestamp after waiting the necessary time
                this.lastInputSwitchPressTime = Date.now();
                if (this.timeoutupdateInputSwitchStates) {
                    clearTimeout(this.timeoutupdateInputSwitchStates);
                }
                if ((_a = this.platform.config.toggleOffIfActive) !== null && _a !== void 0 ? _a : true) {
                    if (this.avr.state.on) {
                        if (this.avr.state.input === inputIndex) {
                            yield this.avr.powerOff();
                            return;
                        }
                    }
                    else {
                        yield this.avr.powerOn();
                        let c = 1000;
                        while (!this.avr.state.on && c-- > 0) {
                            yield new Promise((resolve) => setTimeout(resolve, 1555)); // Wait
                        }
                        yield new Promise((resolve) => setTimeout(resolve, 5000));
                    }
                    // Set the desired input
                    yield this.avr.setInput(input.id);
                    this.log.debug(`Input set to ${input.name} (${input.id})`);
                    this.timeoutupdateInputSwitchStates = setTimeout(() => {
                        // Update all switch states
                        this.updateInputSwitchStates(input.id);
                    }, 2000);
                }
                else if (value) {
                    // Turn on the receiver if it is off
                    if (!this.avr.state.on) {
                        yield this.avr.powerOn();
                        let c = 1000;
                        while (!this.avr.state.on && c-- > 0) {
                            yield new Promise((resolve) => setTimeout(resolve, 1555)); // Wait
                        }
                        yield new Promise((resolve) => setTimeout(resolve, 5000));
                    }
                    // Set the desired input
                    yield this.avr.setInput(input.id);
                    this.log.debug(`Input set to ${input.name} (${input.id})`);
                    this.timeoutupdateInputSwitchStates = setTimeout(() => {
                        // Update all switch states
                        this.updateInputSwitchStates(input.id);
                    }, 2000);
                }
                else {
                    this.log.debug(`Switch for ${switchName} turned off.`);
                    // Check if the receiver is still on and the input matches
                    if (this.avr.state.on && this.avr.state.input === inputIndex) {
                        yield this.avr.powerOff();
                    }
                }
            }));
            (0, exitHandler_1.addExitHandler)(() => {
                this.updateInputSwitchStates('-9999');
            }, this);
            this.log.info(`${this.name}> Switch accessory created for input: ${input.name} (${input.id}) on host: ${host}`);
        });
        // Cleanup invalid accessories
        const validAccessoryUUIDs = new Set(validAccessories);
        this.platform.accessories = this.platform.accessories.filter((accessory) => {
            var _a;
            const isValid = validAccessoryUUIDs.has(accessory.UUID);
            if (!isValid && ((_a = accessory === null || accessory === void 0 ? void 0 : accessory.context) === null || _a === void 0 ? void 0 : _a.host) && host && accessory.context.host.toLowerCase() === host.toLowerCase()) {
                this.log.info(`${this.name}> Removing accessory: ${accessory.displayName} (no longer valid)`);
                this.platform.api.unregisterPlatformAccessories(this.platform.pluginName, this.platform.platformName, [accessory]);
            }
            return isValid || accessory.context.host !== host;
        });
    }
}
exports.default = PioneerAvrAccessory;
//# sourceMappingURL=pioneer-avr-accessory.js.map