UNPKG

homebridge-philips-hue-sync-box

Version:
282 lines 12.9 kB
import { SyncBoxDevice } from './base.js'; import { PASSTHROUGH, POWER_SAVE, MODE_VIDEO, MODE_MUSIC, MODE_GAME, MODE_LAST_SYNC, BRIGHTNESS_MAX_SYNCBOX, BRIGHTNESS_STEP_SYNCBOX, BRIGHTNESS_MIN, } from '../lib/constants.js'; import { convertSyncBoxToHomekit } from '../lib/brightness.js'; export class BaseTvDevice extends SyncBoxDevice { platform; accessory; state; primaryAccessory; lightbulbService; inputServices = []; mainAccessory; intensityToNumber = new Map([ ['subtle', 1], ['moderate', 2], ['high', 3], ['intense', 4], ]); numberToIntensity = new Map([ [1, 'subtle'], [2, 'moderate'], [3, 'high'], [4, 'intense'], ]); modeToNumber = new Map([ [MODE_VIDEO, 1], [MODE_MUSIC, 2], [MODE_GAME, 3], [PASSTHROUGH, 4], [POWER_SAVE, 5], ]); numberToMode = new Map([ [1, MODE_VIDEO], [2, MODE_MUSIC], [3, MODE_GAME], [4, PASSTHROUGH], [5, POWER_SAVE], ]); constructor(platform, accessory, state, primaryAccessory) { super(platform, accessory, state); this.platform = platform; this.accessory = accessory; this.state = state; this.primaryAccessory = primaryAccessory; this.mainAccessory = primaryAccessory; this.createInputServices(); this.createLightbulbService(); this.service.setCharacteristic(this.platform.api.hap.Characteristic.SleepDiscoveryMode, this.platform.api.hap.Characteristic.SleepDiscoveryMode .ALWAYS_DISCOVERABLE); this.service .getCharacteristic(this.platform.api.hap.Characteristic.RemoteKey) .onSet(this.handleRemoteButton.bind(this)); let name; if (this.platform.config[this.getConfiguredNamePropertyName()]) { name = this.platform.config[this.getConfiguredNamePropertyName()]; } else if (this.mainAccessory?.context[this.getConfiguredNamePropertyName()]) { name = this.mainAccessory?.context[this.getConfiguredNamePropertyName()]; } else { name = this.state.device.name; } this.service .getCharacteristic(this.platform.api.hap.Characteristic.ConfiguredName) .onSet(this.handleConfiguredNameChange.bind(this)); this.service.updateCharacteristic(this.platform.api.hap.Characteristic.ConfiguredName, name); } handleConfiguredNameChange(value) { if (this.platform.config[this.getConfiguredNamePropertyName()]) { this.platform.log.warn(this.getConfiguredNamePropertyName() + ' is set in the config, therefore it cannot be changed by HomeKit.' + ' Please change it in the Homebridge config. Alternatively remove the' + ' config and manually configure in HomeKit (not recommended).'); return; } this.platform.log.debug(this.getConfiguredNamePropertyName() + ' name changed to ' + value); if (this.mainAccessory) { this.mainAccessory.context[this.getConfiguredNamePropertyName()] = value; } } shouldBeOn() { if (this.platform.config.treatPassthroughAsOffForTv && this.state.execution.mode === PASSTHROUGH) { return false; } return this.state.execution.mode !== POWER_SAVE; } createLightbulbService() { if (!this.isLightbulbEnabled()) { return; } this.lightbulbService = this.accessory.getService(this.platform.api.hap.Service.Lightbulb) || this.accessory.addService(this.platform.api.hap.Service.Lightbulb); // Stores the light bulb service // Subscribes for changes of the on characteristic this.lightbulbService .getCharacteristic(this.platform.api.hap.Characteristic.On) .onSet(this.setOnLightbulb.bind(this)); // Subscribes for changes of the brightness characteristic this.lightbulbService .getCharacteristic(this.platform.api.hap.Characteristic.Brightness) .onSet(this.setBrightness.bind(this)); } setOnLightbulb(value) { if (!this.lightbulbService) { return; } this.platform.log.debug('Set On ->', value); const currentVal = this.lightbulbService.getCharacteristic(this.platform.api.hap.Characteristic.On).value; return this.updateMode(currentVal, value); } getServiceType() { return this.platform.api.hap.Service.Television; } handleRemoteButton(value) { this.platform.log.debug('Remote key pressed: ' + value); let mode; switch (value) { case this.platform.api.hap.Characteristic.RemoteKey.ARROW_UP: this.platform.log.debug('Increase brightness by 25%'); this.updateExecution({ brightness: Math.min(BRIGHTNESS_MAX_SYNCBOX, this.state.execution.brightness + BRIGHTNESS_STEP_SYNCBOX), }); break; case this.platform.api.hap.Characteristic.RemoteKey.ARROW_DOWN: this.platform.log.debug('Decrease brightness by 25%'); this.updateExecution({ brightness: Math.max(BRIGHTNESS_MIN, this.state.execution.brightness - BRIGHTNESS_STEP_SYNCBOX), }); break; case this.platform.api.hap.Characteristic.RemoteKey.ARROW_LEFT: { // Gets the current mode or the last sync mode to set the intensity mode = this.getMode(); this.platform.log.debug('Toggle intensity'); if (!this.state.execution[mode]) { this.platform.log.debug('Current mode ' + mode + ' does not have an intensity to update'); break; } const currentIntensity = this.state.execution[mode].intensity; const nextLowestIntensity = (this.intensityToNumber.get(currentIntensity) ?? 4) - 1; if (nextLowestIntensity < 1) { break; } const nextIntensity = this.numberToIntensity.get(nextLowestIntensity); const body = {}; body[mode] = { intensity: nextIntensity, }; this.updateExecution(body); break; } case this.platform.api.hap.Characteristic.RemoteKey.ARROW_RIGHT: { // Gets the current mode or the last sync mode to set the intensity mode = this.getMode(); this.platform.log.debug('Toggle intensity'); if (!this.state.execution[mode]) { this.platform.log.debug('Current mode ' + mode + ' does not have an intensity to update'); break; } const currentIntensity = this.state.execution[mode].intensity; const nextHighestIntensity = (this.intensityToNumber.get(currentIntensity) ?? 1) + 1; if (nextHighestIntensity > 4) { break; } const nextIntensity = this.numberToIntensity.get(nextHighestIntensity); const body = {}; body[mode] = { intensity: nextIntensity, }; this.updateExecution(body); break; } case this.platform.api.hap.Characteristic.RemoteKey.SELECT: { this.platform.log.debug('Toggle mode'); const currentMode = this.state.execution.mode; const nextMode = ((this.modeToNumber.get(currentMode) ?? 4) % 4) + 1; this.updateExecution({ mode: this.numberToMode.get(nextMode), }); break; } case this.platform.api.hap.Characteristic.RemoteKey.PLAY_PAUSE: this.platform.log.debug('Toggle switch state'); if (this.state.execution.mode !== POWER_SAVE && this.state.execution.mode !== PASSTHROUGH) { this.updateExecution({ mode: this.platform.config.defaultOffMode, }); } else { let onMode = this.platform.config.defaultOnMode; if (onMode === MODE_LAST_SYNC) { onMode = this?.state?.execution?.lastSyncMode ?? MODE_VIDEO; } this.updateExecution({ mode: onMode, }); } break; case this.platform.api.hap.Characteristic.RemoteKey.INFORMATION: { this.platform.log.debug('Toggle hdmi source'); const hdmiSource = this.state.execution.hdmiSource; const currentSourcePosition = parseInt(hdmiSource.replace('input', '')); const nextSourcePosition = (currentSourcePosition % 4) + 1; this.updateExecution({ hdmiSource: 'input' + nextSourcePosition, }); break; } } } updateSources(services) { // Handles showing/hiding of sources for (const service of services) { service .getCharacteristic(this.platform.api.hap.Characteristic.TargetVisibilityState) .onSet(this.setVisibility(service)); } } update(state) { super.update(state); if (!state) { this.setLightbulbUnresponsive(); return; } this.updateTv(); this.updateLightbulb(); } updateLightbulb() { if (!this.lightbulbService) { return; } this.platform.log.debug('Updated state to ' + this.state.execution.mode); this.lightbulbService.updateCharacteristic(this.platform.api.hap.Characteristic.On, this.state.execution.mode !== POWER_SAVE && this.state.execution.mode !== PASSTHROUGH); this.platform.log.debug('Updated brightness to ' + this.state.execution.brightness); this.lightbulbService.updateCharacteristic(this.platform.api.hap.Characteristic.Brightness, convertSyncBoxToHomekit(this.state.execution.brightness)); } setLightbulbUnresponsive() { if (!this.lightbulbService) { return; } this.platform.log.debug('Updated state to ' + this.state.execution.mode); this.lightbulbService.updateCharacteristic(this.platform.api.hap.Characteristic.On, new this.platform.api.hap.HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */)); } getInputService(name, position) { if (!name) { throw new Error('Name is required'); } const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1); this.platform.log.debug('Creating input service for ' + capitalizedName); const inputService = this.accessory.getServiceById(this.platform.api.hap.Service.InputSource, position) || this.accessory.addService(this.platform.api.hap.Service.InputSource, position.toLowerCase().replace(' ', ''), position); // Sets the TV name inputService .setCharacteristic(this.platform.api.hap.Characteristic.ConfiguredName, capitalizedName) .setCharacteristic(this.platform.api.hap.Characteristic.IsConfigured, this.platform.api.hap.Characteristic.IsConfigured.CONFIGURED) .setCharacteristic(this.platform.api.hap.Characteristic.CurrentVisibilityState, this.platform.api.hap.Characteristic.CurrentVisibilityState.SHOWN) .setCharacteristic(this.platform.api.hap.Characteristic.TargetVisibilityState, this.platform.api.hap.Characteristic.TargetVisibilityState.SHOWN); inputService .setCharacteristic(this.platform.api.hap.Characteristic.Identifier, position[position.length - 1]) .setCharacteristic(this.platform.api.hap.Characteristic.InputSourceType, this.platform.api.hap.Characteristic.InputSourceType.HDMI); return inputService; } setVisibility(service) { return (value) => { service.setCharacteristic(this.platform.api.hap.Characteristic.CurrentVisibilityState, value); }; } getMode() { let mode = MODE_VIDEO; if (this.state.execution.mode !== POWER_SAVE && this.state.execution.mode !== PASSTHROUGH) { mode = this.state.execution.mode; } else if (this.state.execution.lastSyncMode) { mode = this.state.execution.lastSyncMode; } return mode; } } //# sourceMappingURL=baseTv.js.map