Skip to content

Instantly share code, notes, and snippets.

@cyanidium
Created October 19, 2014 18:05
Show Gist options
  • Save cyanidium/fef39c27e456c13d85cf to your computer and use it in GitHub Desktop.
Save cyanidium/fef39c27e456c13d85cf to your computer and use it in GitHub Desktop.
Script to control LG TVs via their serial interface. Not all LG TVs have this port, but if it does then you can control it directly from the computer without a remote. This script can also be used directly from a XBMC/Kodi keymap file with some indicated modifications.
#!/usr/bin/python
# Put this file in /usr/local/bin/ then chmod +x
import sys
# You need to tell python where to look for serial module if running from a keymap.
#sys.path.append("/usr/lib/python2.7/")
#set by computer, change to your needs
SERIAL_DEV = "/dev/ttyUSB0"
LOCKFILE = "/var/lock/LG_on_"+SERIAL_DEV.split("/")[-1]
#set by TV, read the manual for your TV's codes
LG_SET_NUM = "01"
INPUT = "xb"
HTPC = "a0"
WII = "40"
OSD = "kl"
REMOTE_BLOCK = "km"
POWER = "ka"
OFF = "00"
ON = "01"
QUERY = "FF"
import fcntl
import serial
import time
from optparse import OptionParser
parser = OptionParser(description="Sends commands to LG TV via serial connection")
parser.add_option("--power",
help="turn power off or on (opposite of current setting)",
action="store_true",
default=False)
parser.add_option("--power-on",
help="turn power on",
action="store_true",
default=False)
parser.add_option("--power-off",
help="turn power off",
action="store_true",
default=False)
parser.add_option("--htpc",
help="change to HTPC display",
action="store_const",
const=HTPC,
dest="input")
parser.add_option("--wii",
help="change to Wii Display",
action="store_const",
const=WII,
dest="input")
options, args = parser.parse_args()
#make sure only one instance runs at a time to save confusing everyone
lf = open(LOCKFILE, "w")
try:
fcntl.lockf(lf, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
sys.exit(0)
#run a command
def LG(command, data):
ser.write("%s %s %s\r" % (command, LG_SET_NUM, data))
#run a command and return its condition, always
def LG_return(command, data):
status = ""
while status == "":
LG(command, data)
timeout = 5
while timeout > 0:
timeout -= 1
if ser.inWaiting() > 0:
#if there are more than one return, they are separated by an x
LG_returns = ser.read(ser.inWaiting()).split("x")
for r in LG_returns:
if r == "":
continue
#need to match to the command we sent
elif r.split()[0] == command[1]:
#check if the command was processed correctly
if r.split()[2][:2] == "OK":
status = r.split()[2][2:]
#break out to either re-run command or return
timeout = 0
break
time.sleep(0.2)
return status
#the magic of python
ser = serial.Serial(SERIAL_DEV, timeout=0)
if options.power:
state = LG_return(POWER, QUERY)
if state == ON:
LG_return(POWER, OFF)
elif state == OFF:
LG_return(POWER, ON)
elif options.power_on:
LG_return(POWER, ON)
elif options.power_off:
LG_return(POWER, OFF)
elif options.input:
LG(INPUT, options.input)
else:
parser.print_help()
#clean up
ser.read(ser.inWaiting())
ser.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment