UNPKG

homebridge-denon-speaker

Version:

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

171 lines 6.71 kB
"use strict"; const node_util_1 = require("node:util"); const denon_lib_1 = require("./lib/denon-lib"); let hap; class DenonSpeakerAccessory { log; name; pollingInterval; doPolling; speakerState = { active: false, volume: 0, mute: false, }; speakerService; informationService; denonLib; cacheTimeout = 5; // cache validity in seconds lastUpdate = 0; // timestamp in ms (Date.now()) constructor(log, config) { this.log = log; this.name = config.name; this.speakerState.volume = config.defaultVolume; this.pollingInterval = config.pollingInterval || 30; this.doPolling = config.doPolling ?? true; this.denonLib = new denon_lib_1.DenonLib(config.ip); this.informationService = new hap.Service.AccessoryInformation() .setCharacteristic(hap.Characteristic.Manufacturer, 'Denon') .setCharacteristic(hap.Characteristic.SerialNumber, '123-456-789') .setCharacteristic(hap.Characteristic.FirmwareRevision, '1.0.0'); this.informationService.getCharacteristic(hap.Characteristic.Model) .onGet(this.getModel.bind(this)); // Set Speaker Characteristic this.speakerService = new hap.Service.Speaker(this.name); // Configure required Speaker characteristics this.speakerService.getCharacteristic(hap.Characteristic.Mute) .onGet(this.getMuteState.bind(this)) .onSet(this.setMuteState.bind(this)); this.speakerService.getCharacteristic(hap.Characteristic.Active) .onGet(this.getActiveState.bind(this)) .onSet(this.setActiveState.bind(this)) .updateValue(false); // État initial this.speakerService.getCharacteristic(hap.Characteristic.Volume) .onGet(this.getVolumeState.bind(this)) .onSet(this.setVolumeState.bind(this)) .setProps({ minValue: 0, maxValue: 98, minStep: 2, }); if (this.doPolling) { this.log.debug(`Refresh every ${this.pollingInterval} sec`); setInterval(async () => { this.log.debug('Triggering updateSpeakerState'); const updated = await this.updateAllStates(); if (updated) { // Ne mettre à jour HomeKit que si les valeurs ont changé this.speakerService.updateCharacteristic(hap.Characteristic.Mute, this.speakerState.mute); this.speakerService.updateCharacteristic(hap.Characteristic.Active, this.speakerState.active); this.speakerService.updateCharacteristic(hap.Characteristic.Volume, this.speakerState.volume); this.log.debug('États mis à jour dans HomeKit'); } }, this.pollingInterval * 1000); // Mise à jour initiale des états this.updateAllStates().catch(error => { this.log.error('Erreur lors de la mise à jour initiale:', error); }); } log.info(`${this.name} finished initializing!`); } /* * This method is optional to implement. It is called when HomeKit ask to identify the accessory. * Typical this only ever happens at the pairing process. */ identify() { this.log('Identify!'); } /* * This method is called directly after creation of this instance. * It should return all services which should be added to the accessory. */ getServices() { return [ this.informationService, this.speakerService, ]; } async getModel() { const modelInfo = await this.denonLib.getModelInfo(); return modelInfo.model; } async getMuteState() { await this.updateAllStates(); const muteState = this.speakerState.mute; this.log.info('getMuteState: ' + (muteState ? 'ON' : 'OFF')); return muteState; } async setMuteState(wantedMuteState) { try { const muteState = await this.denonLib.setMuteState(wantedMuteState); this.log.debug('setMuteState: ' + (muteState ? 'ON' : 'OFF')); this.speakerState.mute = muteState; } catch (error) { this.log('setMuteState error: ' + error.message); throw error; } } async getActiveState() { await this.updateAllStates(); const activeState = this.speakerState.active; this.log.info('getActiveState: ' + (activeState ? 'ON' : 'OFF')); return activeState; } async setActiveState(wantedActiveState) { try { const activeState = await this.denonLib.setPowerState(wantedActiveState); this.log('setActiveState: ' + (activeState ? 'ON' : 'OFF')); this.speakerState.active = activeState; } catch (error) { this.log('setActiveState error: ' + error.message); throw error; } } async getVolumeState() { const now = Date.now(); if (now - this.lastUpdate >= this.cacheTimeout * 1000) { await this.updateAllStates(); } const volumeState = this.speakerState.volume; this.log.info('getVolumeState: ' + volumeState); return volumeState; } async setVolumeState(wantedVolumeState) { try { const volumeState = await this.denonLib.setVolume(wantedVolumeState); this.log('setVolumeState: ' + volumeState); this.speakerState.volume = volumeState; } catch (error) { this.log('setVolumeState error: ' + error.message); throw error; } } async updateAllStates() { const now = Date.now(); if (now - this.lastUpdate < this.cacheTimeout * 1000) { this.log.debug('Using cached data for updateAllStates'); return false; } try { const status = await this.denonLib.getStatus(); this.log.debug((0, node_util_1.inspect)(status)); this.speakerState.active = status.powerState; this.speakerState.volume = status.volumeState; this.speakerState.mute = status.muteState; this.lastUpdate = now; return true; } catch (error) { this.log('updateAllStates Error : ' + error.message); return false; } } } module.exports = (api) => { hap = api.hap; api.registerAccessory('homebridge-denon-speaker', 'DenonAVRSpeaker', DenonSpeakerAccessory); }; //# sourceMappingURL=homebridge-denon-speaker.js.map