UNPKG

homebridge-denon-v3

Version:

Denon and Marantz AVR support for Homebridge: https://github.com/nfarina/homebridge

194 lines 9.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DenonMarantzAVRAccessory = void 0; const types_js_1 = require("./types.js"); const sleep = (ms) => new Promise(r => setTimeout(r, ms)); class DenonMarantzAVRAccessory { constructor(log, platform, accessory, zone, controller) { this.platform = platform; this.accessory = accessory; this.controller = controller; this.inputServices = []; this.state = { isPlaying: true, inputs: [], connectionError: false, }; this.log = log; // set the AVR accessory information this.accessory .getService(this.platform.Service.AccessoryInformation) .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Denon/Marantz'); this.log.info("adding television service"); this.service = this.accessory.getService(this.platform.Service.Television) || this.accessory.addService(this.platform.Service.Television); this.zone = zone; this.init(); // regularly ping the AVR to keep power/input state syncronised setInterval(this.updateAVRState.bind(this), 60000); } async init() { try { await this.updateInputSources(); await this.createTVService(); await this.createTVSpeakerService(); await this.createInputSourceServices(); } catch (err) { this.platform.log.error(err); } } async updateInputSources() { let inputs = this.accessory.context.device.availableInputs || types_js_1.INPUTS; inputs.forEach((input) => { this.state.inputs.push(input); }); } async createTVService() { // Set Television Service Name & Discovery Mode this.log.info("display name is ", this.accessory.context.device.display); this.service .setCharacteristic(this.platform.Characteristic.Name, this.accessory.context.device.displayName) // .setCharacteristic(this.platform.Characteristic.ConfiguredName, this.accessory.context.device.displayName) .setCharacteristic(this.platform.Characteristic.SleepDiscoveryMode, this.platform.Characteristic.SleepDiscoveryMode.ALWAYS_DISCOVERABLE); // Power State Get/Set this.service .getCharacteristic(this.platform.Characteristic.Active) .onSet(this.setPowerState.bind(this)) .onGet(this.getPowerState.bind(this)); // Input Source Get/Set this.service .getCharacteristic(this.platform.Characteristic.ActiveIdentifier) .onSet(this.setInputState.bind(this)) .onGet(this.getInputState.bind(this)); // Remote Key Set this.service.getCharacteristic(this.platform.Characteristic.RemoteKey).onSet(this.setRemoteKey.bind(this)); return; } async createTVSpeakerService() { this.log.info("adding television speaker service"); const speakerService = this.accessory.getService(this.platform.Service.TelevisionSpeaker) || this.accessory.addService(this.platform.Service.TelevisionSpeaker); speakerService .setCharacteristic(this.platform.Characteristic.Name, `${this.accessory.context.device.displayName} Speaker`) .setCharacteristic(this.platform.Characteristic.Active, this.platform.Characteristic.Active.ACTIVE) .setCharacteristic(this.platform.Characteristic.VolumeControlType, this.platform.Characteristic.VolumeControlType.ABSOLUTE); speakerService.getCharacteristic(this.platform.Characteristic.Mute).onGet(this.getMute.bind(this)).onSet(this.setMute.bind(this)); // handle volume control speakerService.getCharacteristic(this.platform.Characteristic.Volume).onGet(this.getVolume.bind(this)).onSet(this.setVolume.bind(this)); speakerService.getCharacteristic(this.platform.Characteristic.VolumeSelector).onSet(this.setVolumeSelector.bind(this)); return; } async createInputSourceServices() { this.state.inputs.forEach(async (input, i) => { try { this.log.info(`adding television input service with name ${input} `); const inputService = this.accessory.getServiceById(this.platform.Service.InputSource, input) || this.accessory.addService(this.platform.Service.InputSource, input, input); inputService .setCharacteristic(this.platform.Characteristic.Identifier, i) .setCharacteristic(this.platform.Characteristic.ConfiguredName, input) .setCharacteristic(this.platform.Characteristic.Name, `${this.accessory.context.device.displayName} input ${input}`) .setCharacteristic(this.platform.Characteristic.IsConfigured, this.platform.Characteristic.IsConfigured.CONFIGURED) .setCharacteristic(this.platform.Characteristic.CurrentVisibilityState, this.platform.Characteristic.CurrentVisibilityState.SHOWN) .setCharacteristic(this.platform.Characteristic.InputSourceType, this.platform.Characteristic.InputSourceType.APPLICATION) .setCharacteristic(this.platform.Characteristic.InputDeviceType, this.platform.Characteristic.InputDeviceType.TV); this.service.addLinkedService(inputService); this.inputServices.push(inputService); } catch (err) { this.platform.log.error(` Failed to add input service ${input}: ${err} `); } }); } async setRemoteKey(remoteKey) { try { this.log.info("trying to set key", remoteKey); } catch (error) { this.platform.log.error(error.message); } } async updateAVRState() { try { await this.controller.refresh(); let power = this.controller.GetPowerState(this.zone); let source = this.controller.GetInputSource(this.zone); this.platform.log.debug(`AVR PING`, { power: power, input: source }); this.service.updateCharacteristic(this.platform.Characteristic.Active, power); this.service.updateCharacteristic(this.platform.Characteristic.ActiveIdentifier, this.state.inputs.findIndex((input) => input === source)); if (this.state.connectionError) { this.state.connectionError = false; this.platform.log.info(`Communication with Yamaha AVR at ${this.platform.config.ip} restored`); } } catch (error) { if (this.state.connectionError) { return; } this.state.connectionError = true; this.platform.log.error(` Cannot communicate with Yamaha AVR at ${this.platform.config.ip}. Connection will be restored automatically when the AVR begins responding. `); } } async getPowerState() { this.log.info(`Get power state ${this.controller.ipaddress} zone ${this.zone} power ${this.controller.GetPowerState(this.zone)} `); return this.controller.GetPowerState(this.zone); } async setPowerState(state) { await this.controller.SetPowerState(this.zone, state); if (state && this.zone === 'main') { this.log.info(`setting default values input:${this.accessory.context.device.defaultInput} volume:${this.accessory.context.device.defaultVolume}`); await sleep(5000); // sleep needed between powwer on otherwise volume set to 0 this.setInputState(this.accessory.context.device.defaultInput); await sleep(1000); this.setVolume(this.accessory.context.device.defaultVolume); } } async getMute() { this.log.info(`Get mute state ${this.controller.GetMuteState(this.zone)} `); return this.controller.GetMuteState(this.zone); } async setMute(state) { await this.controller.SetMuteSate(this.zone, state); } async setVolumeSelector(direction) { try { const currentVolume = this.controller.GetVolume(this.zone); const volumeStep = 5; if (direction === this.platform.Characteristic.VolumeSelector.INCREMENT) { this.platform.log.info('Volume Up', currentVolume + volumeStep); await this.controller.SetVolume(this.zone, currentVolume + volumeStep); } else { this.platform.log.info('Volume Down', currentVolume - volumeStep); await this.controller.SetVolume(this.zone, currentVolume - volumeStep); } } catch (error) { this.platform.log.error(error.message); } } async setVolume(value) { await this.controller.SetVolume(this.zone, value); } async getVolume() { return this.controller.GetVolume(this.zone); } async getInputState() { this.log.info(`Get input state ${this.controller.GetInputSource(this.zone)} `); let source = this.controller.GetInputSource(this.zone); return this.state.inputs.findIndex((input) => input === source); } async setInputState(inputIndex) { try { const setInputResponse = await this.controller.SetInputSource(this.zone, this.state.inputs[inputIndex]); this.platform.log.info(`Set input: ${this.state.inputs[inputIndex]}`); } catch (error) { this.platform.log.error(error.message); } } } exports.DenonMarantzAVRAccessory = DenonMarantzAVRAccessory; //# sourceMappingURL=accessory.js.map