UNPKG

node-lgtv-api

Version:

A NODE API for the LG SmartTV (2012+) which makes it easy for you to remote control your TV with code

205 lines (183 loc) 6.44 kB
const request = require("request") const xml2js = require("xml2js") const xmlBuilder = new xml2js.Builder() const xmlParser = new xml2js.Parser() const getErrorMessage = (error, response) => error || new Error("Response code:" + response.statusCode) const getOptions = function (body) { let options = { headers: { "Content-Type": "application/atom+xml", "Connection": "Keep-Alive" } } if (body) { options.body = body } return options } class LgTvApi { constructor(_host, _port, _pairingKey) { this.host = _host this.port = _port this.pairingKey = _pairingKey this.session = null this.debugMode = false this.scheme = "http" } setDebugMode(_debugMode) { this.debugMode = _debugMode } displayPairingKey() { return new Promise((resolve, reject) => { this.sendXMLRequest("/roap/api/auth", {auth: {type: "AuthKeyReq"}}).then(resolve, reject) }) } authenticate() { return new Promise((resolve, reject) => { (this.pairingKey === null) ? reject(new Error("No pairing key. You should call displayPairingKey at first.")) : 0 this.sendXMLRequest("/roap/api/auth", {auth: {type: "AuthReq", value: this.pairingKey}}).then( data => { xmlParser.parseString(data, (err, doc) => { err ? reject(err) : this.session = doc.envelope.session[0] & resolve(doc.envelope.session[0]) }) }, reject) }) } processCommand(commandName, parameters) { return new Promise((resolve, reject) => { (this.session === null) ? reject(new Error("No session id. You should call authenticate method at first.")) : 0 if (!isNaN(parseInt(commandName)) && parameters.length === 0) { parameters.value = commandName commandName = "HandleKeyInput" } else if (isNaN(parseInt(parameters)) && !(((typeof parameters === "object") && (parameters !== null)))) { parameters.value = parameters } parameters.name = commandName this.sendXMLRequest("roap/api/command", {command: parameters}).then( data => { xmlParser.parseString(data, (err, doc) => err ? reject(err) : resolve(doc)) }, reject) }) } queryData(targetId) { return new Promise((resolve, reject) => { (this.session === null) ? reject(new Error("No session id. You should call authenticate method at first.")) : 0 this.sendRequest(`roap/api/data?target=${targetId}`).then( data => { xmlParser.parseString(data, (err, doc) => err ? reject(err) : resolve(doc.envelope.data)) }, reject) }) } takeScreenShot() { return new Promise((resolve, reject) => { let uri = `${this.scheme}://${this.host}:${this.port}/roap/api/data?target=${LgTvApi.TV_INFO_SCREEN}` let options = getOptions() this.debugMode ? console.info("REQ:" + JSON.stringify(options)) : 0 request.get(uri, options, (err, response, data) => { this.debugMode ? console.info("RESP:" + data) : 0; (err || response.statusCode !== 200) ? reject(getErrorMessage(err, response)) : resolve(data) }) }) } sendXMLRequest(path, params) { return new Promise((resolve, reject) => { let uri = `${this.scheme}://${this.host}:${this.port}/${path}` let options = getOptions(xmlBuilder.buildObject(params)) this.debugMode ? console.info("REQ:" + options.body) : 0 request.post(uri, options, (err, response, data) => { this.debugMode ? console.info("RESP:" + data) : 0; (err || response.statusCode !== 200) ? reject(getErrorMessage(err, response)) : resolve(data) }) }) } sendRequest(path) { return new Promise((resolve, reject) => { let uri = `${this.scheme}://${this.host}:${this.port}/${path}` let options = getOptions() this.debugMode ? console.info("REQ:" + JSON.stringify(options)) : 0 request.get(uri, getOptions(), (err, response, data) => { this.debugMode ? console.info("RESP:" + data) : 0; (err || response.statusCode !== 200) ? reject(getErrorMessage(err, response)) : resolve(data) }) }) } } LgTvApi.TV_CMD_POWER = 1 LgTvApi.TV_CMD_NUMBER_0 = 2 LgTvApi.TV_CMD_NUMBER_1 = 3 LgTvApi.TV_CMD_NUMBER_2 = 4 LgTvApi.TV_CMD_NUMBER_3 = 5 LgTvApi.TV_CMD_NUMBER_4 = 6 LgTvApi.TV_CMD_NUMBER_5 = 7 LgTvApi.TV_CMD_NUMBER_6 = 8 LgTvApi.TV_CMD_NUMBER_7 = 9 LgTvApi.TV_CMD_NUMBER_8 = 10 LgTvApi.TV_CMD_NUMBER_9 = 11 LgTvApi.TV_CMD_UP = 12 LgTvApi.TV_CMD_DOWN = 13 LgTvApi.TV_CMD_LEFT = 14 LgTvApi.TV_CMD_RIGHT = 15 LgTvApi.TV_CMD_OK = 20 LgTvApi.TV_CMD_HOME_MENU = 21 LgTvApi.TV_CMD_BACK = 23 LgTvApi.TV_CMD_VOLUME_UP = 24 LgTvApi.TV_CMD_VOLUME_DOWN = 25 LgTvApi.TV_CMD_MUTE_TOGGLE = 26 LgTvApi.TV_CMD_CHANNEL_UP = 27 LgTvApi.TV_CMD_CHANNEL_DOWN = 28 LgTvApi.TV_CMD_BLUE = 29 LgTvApi.TV_CMD_GREEN = 30 LgTvApi.TV_CMD_RED = 31 LgTvApi.TV_CMD_YELLOW = 32 LgTvApi.TV_CMD_PLAY = 33 LgTvApi.TV_CMD_PAUSE = 34 LgTvApi.TV_CMD_STOP = 35 LgTvApi.TV_CMD_FAST_FORWARD = 36 LgTvApi.TV_CMD_REWIND = 37 LgTvApi.TV_CMD_SKIP_FORWARD = 38 LgTvApi.TV_CMD_SKIP_BACKWARD = 39 LgTvApi.TV_CMD_RECORD = 40 LgTvApi.TV_CMD_RECORDING_LIST = 41 LgTvApi.TV_CMD_REPEAT = 42 LgTvApi.TV_CMD_LIVE_TV = 43 LgTvApi.TV_CMD_EPG = 44 LgTvApi.TV_CMD_PROGRAM_INFORMATION = 45 LgTvApi.TV_CMD_ASPECT_RATIO = 46 LgTvApi.TV_CMD_EXTERNAL_INPUT = 47 LgTvApi.TV_CMD_PIP_SECONDARY_VIDEO = 48 LgTvApi.TV_CMD_SHOW_SUBTITLE = 49 LgTvApi.TV_CMD_PROGRAM_LIST = 50 LgTvApi.TV_CMD_TELE_TEXT = 51 LgTvApi.TV_CMD_MARK = 52 LgTvApi.TV_CMD_3D_VIDEO = 400 LgTvApi.TV_CMD_3D_LR = 401 LgTvApi.TV_CMD_DASH = 402 LgTvApi.TV_CMD_PREVIOUS_CHANNEL = 403 LgTvApi.TV_CMD_FAVORITE_CHANNEL = 404 LgTvApi.TV_CMD_QUICK_MENU = 405 LgTvApi.TV_CMD_TEXT_OPTION = 406 LgTvApi.TV_CMD_AUDIO_DESCRIPTION = 407 LgTvApi.TV_CMD_ENERGY_SAVING = 409 LgTvApi.TV_CMD_AV_MODE = 410 LgTvApi.TV_CMD_SIMPLINK = 411 LgTvApi.TV_CMD_EXIT = 412 LgTvApi.TV_CMD_RESERVATION_PROGRAM_LIST = 413 LgTvApi.TV_CMD_PIP_CHANNEL_UP = 414 LgTvApi.TV_CMD_PIP_CHANNEL_DOWN = 415 LgTvApi.TV_CMD_SWITCH_VIDEO = 416 LgTvApi.TV_CMD_APPS = 417 LgTvApi.TV_CMD_MOUSE_MOVE = "HandleTouchMove" LgTvApi.TV_CMD_MOUSE_CLICK = "HandleTouchClick" LgTvApi.TV_CMD_TOUCH_WHEEL = "HandleTouchWheel" LgTvApi.TV_CMD_CHANGE_CHANNEL = "HandleChannelChange" LgTvApi.TV_CMD_SCROLL_UP = "up" LgTvApi.TV_CMD_SCROLL_DOWN = "down" LgTvApi.TV_INFO_CURRENT_CHANNEL = "cur_channel" LgTvApi.TV_INFO_CHANNEL_LIST = "channel_list" LgTvApi.TV_INFO_CONTEXT_UI = "context_ui" LgTvApi.TV_INFO_VOLUME = "volume_info" LgTvApi.TV_INFO_SCREEN = "screen_image" LgTvApi.TV_INFO_3D = "is_3d" LgTvApi.TV_LAUNCH_APP = "AppExecute" LgTvApi.TV_TERMINATE_APP = "AppTerminate" module.exports = LgTvApi