Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import xbmc
- import xbmcaddon
- import xbmcgui
- import socket
- import httplib
- import time
- import re
- #SDK Docs
- #http://developer.lgappstv.com/TV_HELP/index.jsp?topic=%2Flge.tvsdk.references.book%2Fhtml%2FUDAP%2FUDAP%2FUDAP+Specifications+For+Second+Screen+TV+and+Companion+Apps.htm
- # Class to interface with LG TV
- class LGRemote:
- # ctor - load settings from kodi
- def __init__(self):
- self.settings = xbmcaddon.Addon(id="script.lg_remote")
- self.settings.getLocalizedString
- self.pairing = self.settings.getSetting("pairing_key")
- self.address = self.settings.getSetting("ip_address")
- self.port = self.settings.getSetting("ip_port")
- if ("" == self.address):
- self.findTV()
- # Search the local network for a tv
- # TODO: What if there are multiple TVs?
- def findTV(self):
- UDP_IP = "239.255.255.250"
- UDP_PORT = 1900
- cmd = ("M-SEARCH * HTTP/1.1\r\n"
- "HOST: 239.255.255.250:1900\r\n"
- "MAN: \"ssdp:discover\"\r\n"
- "MX: 3\r\n"
- "ST: udap:rootservice\r\n"
- "USER-AGENT: OpenELEC/1.0 UDAP/2.0 Kodi/15\r\n"
- "\r\n"
- )
- try:
- # Use UDP to find it
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- sock.settimeout(1)
- sock.sendto(cmd, (UDP_IP, UDP_PORT))
- data, addr = sock.recvfrom(1024)
- sock.close()
- data = data.split("\r\n")
- # TV Found!
- if "HTTP/1.1 200 OK" == data[0]:
- # Parse out IP address and port
- def loc(s): return s.startswith("LOCATION")
- data = filter(loc, data)
- if 1 == len(data):
- data = re.split("[\/:]", data[0]);
- self.address = data[4]
- self.port = data[5]
- self.saveSettings()
- # Pair-up with TV
- self.sendPairingCode()
- else:
- self.tvLost()
- except socket.timeout:
- self.tvLost()
- # Connection to TV failed
- def tvLost(self):
- # Reset so next call re-fetches data
- self.address = ""
- self.port = 0
- self.saveSettings()
- def saveSettings(self):
- self.settings.setSetting("ip_address", self.address)
- self.settings.setSetting("ip_port", str(self.port))
- # Send command to TV
- def sendMsg(self, path, msg):
- if ("" == self.address):
- self.findTV()
- if ("" == self.address):
- return;
- httpServ = httplib.HTTPConnection(self.address, self.port, timeout=1)
- headers = {
- "Content-Type": "text/xml; charset=utf-8",
- "Connection": "Close",
- "User-Agent": "OpenELEC/1.0 UDAP/2.0 Kodi/15"
- }
- httpServ.connect()
- httpServ.request("POST", "/udap/api/" + path, msg, headers)
- response = httpServ.getresponse()
- if response.status != httplib.OK:
- print("***************ERROR: ", response.read())
- self.tvLost()
- httpServ.close()
- # Fill in command and parameters of TV message
- def formatMsg(self, cmd, params):
- body = ("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
- "<envelope>"
- "<api type=\"{}\">"
- "{}"
- "</api>"
- "</envelope>")
- p = ""
- for key, value in params.items():
- p += "<{}>{}</{}>\n".format(key, value, key)
- return body.format(cmd, p)
- # Below are helper functions to send commands
- def showPairingCode(self):
- self.sendMsg("pairing", self.formatMsg("pairing", {"name": "showKey"}))
- def sendPairingCode(self):
- # Don't use return port, but I beleive it's required
- self.sendMsg("pairing", self.formatMsg("pairing", {"name": "hello", "value": self.pairing, "port": 6161}))
- def endPairing(self):
- self.sendMsg("pairing", self.formatMsg("pairing", {"name": "byebye", "port": 6161}))
- def sendKey(self, code):
- self.sendMsg("command", self.formatMsg("command", {"name": "HandleKeyInput", "value": code}))
- def volumeUp(self):
- self.sendKey(24)
- def volumeDown(self):
- self.sendKey(25)
- def mute(self):
- self.sendKey(26)
- def power(self):
- self.sendKey(1)
- # Create a connection
- remote = LGRemote()
- if (1 == len(sys.argv)):
- # This never gets called. Is there a "Kodi just started up" callback?
- print("****************init")
- elif (2 == len(sys.argv)):
- param = sys.argv[1]
- param.upper()
- if ("K" == param):
- # Display pairing code on the TV
- remote.showPairingCode()
- else:
- # Send commands mapped to key presses on remote
- remote.sendPairingCode()
- if ("VU" == param):
- remote.volumeUp()
- elif ("VD" == param):
- remote.volumeDown()
- elif ("M" == param):
- remote.mute()
- elif ("P" == param):
- remote.power()
- #remote.endPairing() <- apparently not required???
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement