UNPKG

homebridge-philips-tv6

Version:

Homebridge Plugin for Philips Android TV API v6+

237 lines (212 loc) 7.08 kB
"use strict"; const pkg = require("./package.json"); const PhilipsTV = require("./PhilipsTV.js"); const pluginName = pkg.name; const accessoryName = "PhilipsTV"; let Service, Characteristic; class PhilipsTvAccessory { state = { power: true, ambilight: true, source: 0, volume: 0, }; config = {}; services = []; tvService = null; constructor(log, config) { this.config = { ...this.config, ...config }; this.PhilipsTV = new PhilipsTV(config); this.registerAccessoryInformationService(); this.registerTelevisionService(); this.registerVolumeService(); if (config.has_ambilight) { this.registerAmbilightService(); } if (config.inputs) { this.registerInputService(); } } identify(callback) { callback(); // success } registerAccessoryInformationService = () => { const { name, model_year } = this.config; const { Name, Manufacturer, Model, FirmwareRevision } = Characteristic; const infoService = new Service.AccessoryInformation(); infoService .setCharacteristic(Name, name) .setCharacteristic(Manufacturer, "Philips") .setCharacteristic(Model, "Year " + model_year) .setCharacteristic(FirmwareRevision, pkg.version); this.services.push(infoService); }; registerTelevisionService = () => { const { name, poll_status_interval } = this.config; const { ConfiguredName, SleepDiscoveryMode, Active } = Characteristic; const tvService = new Service.Television(name, "Television"); const power = tvService.getCharacteristic(Active); tvService.setCharacteristic(ConfiguredName, name); tvService.setCharacteristic( SleepDiscoveryMode, SleepDiscoveryMode.ALWAYS_DISCOVERABLE ); power.on("get", this.PhilipsTV.getPowerState); power.on("set", (value, callback) => { this.state.power = value; this.PhilipsTV.setPowerState(value, callback); }); tvService .getCharacteristic(Characteristic.RemoteKey) .on("set", (value, callback) => { switch (value) { case Characteristic.RemoteKey.PLAY_PAUSE: this.PhilipsTV.sendKey("PlayPause"); break; case Characteristic.RemoteKey.BACK: this.PhilipsTV.sendKey("Back"); break; case Characteristic.RemoteKey.ARROW_UP: this.PhilipsTV.sendKey("CursorUp"); break; case Characteristic.RemoteKey.ARROW_DOWN: this.PhilipsTV.sendKey("CursorDown"); break; case Characteristic.RemoteKey.ARROW_LEFT: this.PhilipsTV.sendKey("CursorLeft"); break; case Characteristic.RemoteKey.ARROW_RIGHT: this.PhilipsTV.sendKey("CursorRight"); break; case Characteristic.RemoteKey.SELECT: this.PhilipsTV.sendKey("Confirm"); break; case Characteristic.RemoteKey.EXIT: this.PhilipsTV.sendKey("Exit"); break; case Characteristic.RemoteKey.INFORMATION: this.PhilipsTV.sendKey("Info"); break; } callback(null); }); if (poll_status_interval) { setInterval(() => { this.PhilipsTV.getPowerState((err, value) => { if (this.state.power !== value) { this.state.power = value; power.updateValue(value); } }); }, poll_status_interval * 1000); } this.tvService = tvService; this.services.push(tvService); }; registerInputService = () => { const { inputs } = this.config; const { ActiveIdentifier } = Characteristic; this.tvService.setCharacteristic(ActiveIdentifier, 1); this.tvService .getCharacteristic(ActiveIdentifier) .on("get", (callback) => { this.PhilipsTV.getCurrentSource(inputs).then((source) => { this.state.source = source; callback(null, this.state.source); }); }) .on("set", (value, callback) => { this.state.source = value; const input = inputs[value]; this.PhilipsTV.setSource(input, callback); }); inputs.forEach((item, index) => { const input = this.createInputSource(item.name, item.name, index); this.tvService.addLinkedService(input); this.services.push(input); }); }; registerAmbilightService = () => { const { name, poll_status_interval } = this.config; this.ambilightService = new Service.Lightbulb( name + " Ambilight", "tvAmbilight" ); const ambilightPower = this.ambilightService.getCharacteristic( Characteristic.On ); ambilightPower .on("get", this.PhilipsTV.getAmbilightState) .on("set", (value, callback) => { this.state.ambilight = value; this.PhilipsTV.setAmbilightState(value, callback); }); this.services.push(this.ambilightService); if (poll_status_interval) { setInterval(() => { this.PhilipsTV.getAmbilightState((err, value) => { if (this.state.ambilight !== value) { this.state.ambilight = value; ambilightPower.updateValue(value); } }); }, poll_status_interval * 1000); } }; registerVolumeService = () => { const { name, poll_status_interval } = this.config; this.volumeService = new Service.Fan(name + " Volume", "tvVolume"); this.volumeService .getCharacteristic(Characteristic.On) .on("get", (callback) => { callback(null, 1); }) .on("set", (value, callback) => { this.PhilipsTV.setMuteState(value, callback); }); const volumeLevel = this.volumeService.getCharacteristic( Characteristic.RotationSpeed ); volumeLevel .on("get", this.PhilipsTV.getVolumeState) .on("set", (value, callback) => { this.state.volume = value; this.PhilipsTV.setVolumeState(value, callback); }); if (poll_status_interval) { setInterval(() => { this.PhilipsTV.getVolumeState((err, value) => { if (this.state.volume !== value) { this.state.volume = value; volumeLevel.updateValue(value); } }); }, poll_status_interval * 1000); } this.services.push(this.volumeService); }; createInputSource( id, name, number, type = Characteristic.InputSourceType.TV ) { const { Identifier, ConfiguredName, IsConfigured, InputSourceType } = Characteristic; const input = new Service.InputSource(id, name); input .setCharacteristic(Identifier, number) .setCharacteristic(ConfiguredName, name) .setCharacteristic(IsConfigured, IsConfigured.CONFIGURED) .setCharacteristic(InputSourceType, type); return input; } getServices() { return this.services; } } module.exports = function (homebridge) { Service = homebridge.hap.Service; Characteristic = homebridge.hap.Characteristic; homebridge.registerAccessory(pluginName, accessoryName, PhilipsTvAccessory); };