Solved
[attachment=0]2851_422_220.png[/attachment]
Solved
[attachment=0]2851_422_220.png[/attachment]
May I ask how you solved this one? Will it work with older non webos-based smart-TVs from LG?
Sure. This is what I did. And it works for pre-WebOS models.
Particular script I use is for models released in 2011. Also have script for 2012 models.
In configuration.yaml add
[color=#0080FF][b]
script.powerofftv:
hidden: true
script.powerontv:
hidden: true
#################################################################
#################################################################
shell_command:
wol_bd_br: wakeonlan EE:BB:BB:EE:00:FF
change_to_tv: python3 /home/pi/.homeassistant/tv.py 15
power_off_tv: python3 /home/pi/.homeassistant/tv.py 8
input_boolean:
television:
name: Bedroom
initial: off
icon: mdi:television
group:
Television:
#################################################################
#################################################################
automation 3:
alias: ‘turn on tv’
trigger:
platform: state
entity_id: input_boolean.television
state: ‘on’
action:
service: script.powerontv
alias: ‘turn off tv’
trigger:
platform: state
entity_id: input_boolean.television
from: ‘on’
to: ‘off’
action:
service: script.powerofftv
#################################################################
#################################################################
script:
powerontv:
alias: poweron_tv
sequence:
- alias: ‘turn on tv’
service: shell_command.wol_bd_br
- delay:
seconds: 20
- alias: ‘change input to tv’
service: shell_command.change_to_tv
powerofftv:
alias: poweroff_tv
sequence:
- alias: ‘turn off tv’
service: shell_command.power_off_tv[/b][/color]
In the tv.py add your pairing key and your good to go. Of course restart HASS
This is the tv.py script.
[color=#0080FF]#!/usr/bin/env python3
import http.client
from tkinter import *
import xml.etree.ElementTree as etree
import socket
import re
import sys
lgtv = {}
dialogMsg =""
headers = {“Content-Type”: “application/atom+xml”}
lgtv[“pairingKey”] = “DDDDDD”
def getip():
strngtoXmit = ‘M-SEARCH * HTTP/1.1’ + ‘\r\n’ +
‘HOST: 239.255.255.250:1900’ + ‘\r\n’ +
‘MAN: “ssdp:discover”’ + ‘\r\n’ +
‘MX: 2’ + ‘\r\n’ +
‘ST: urn:schemas-upnp-org:device:MediaRenderer:1’ + ‘\r\n’ + ‘\r\n’
bytestoXmit = strngtoXmit.encode()
sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
sock.settimeout(3)
found = False
gotstr = 'notyet'
i = 0
ipaddress = None
sock.sendto( bytestoXmit, ('239.255.255.250', 1900 ) )
while not found and i <= 5 and gotstr == 'notyet':
try:
gotbytes, addressport = sock.recvfrom(512)
gotstr = gotbytes.decode()
except:
i += 1
sock.sendto( bytestoXmit, ( '239.255.255.250', 1900 ) )
if re.search('LG', gotstr):
ipaddress, _ = addressport
found = True
else:
gotstr = 'notyet'
i += 1
sock.close()
if not found : sys.exit("Lg TV not found")
return ipaddress
def displayKey():
conn = http.client.HTTPConnection( lgtv[“ipaddress”], port=8080)
reqKey = “<?xml version=\"1.0\" encoding=\"utf-8\"?>AuthKeyReq”
conn.request(“POST”, “/hdcp/api/auth”, reqKey, headers=headers)
httpResponse = conn.getresponse()
if httpResponse.reason != “OK” : sys.exit(“Network error”)
return httpResponse.reason
def getSessionid():
conn = http.client.HTTPConnection( lgtv[“ipaddress”], port=8080)
pairCmd = “<?xml version=\"1.0\" encoding=\"utf-8\"?>AuthReq”
+ lgtv[“pairingKey”] + “”
conn.request(“POST”, “/hdcp/api/auth”, pairCmd, headers=headers)
httpResponse = conn.getresponse()
if httpResponse.reason != “OK” : return httpResponse.reason
tree = etree.XML(httpResponse.read())
return tree.find(‘session’).text
def getPairingKey():
displayKey()
root = Tk()
root.withdraw()
dialogMsg = “Please enter the pairing key\nyou see on your TV screen\n”
d = MyDialog(root, dialogMsg)
root.wait_window(d.top)
lgtv[“pairingKey”] = result
d.top.destroy()
def handleCommand(cmdcode):
conn = http.client.HTTPConnection( lgtv[“ipaddress”], port=8080)
cmdText = “<?xml version=\"1.0\" encoding=\"utf-8\"?>”
+ lgtv[“session”]
+ “HandleKeyInput”
+ cmdcode
+ “”
conn.request(“POST”, “/hdcp/api/dtv_wifirc”, cmdText, headers=headers)
httpResponse = conn.getresponse()
#main()
lgtv[“ipaddress”] = getip()
theSessionid = getSessionid()
while theSessionid == “Unauthorized” :
getPairingKey()
theSessionid = getSessionid()
if len(theSessionid) < 8 : sys.exit("Could not get Session Id: " + theSessionid)
lgtv[“session”] = theSessionid
#displayKey()
result = str(sys.argv[1])
handleCommand(result)
[/color]
Until someone works the script into a component I’ll keep using this and add shell commands for volume , channel changing, etc.
Turning TV on and off via HASS was what I needed.
Hi
My LG TV is a 2011 model too and I’m trying to make it work with homeassistant. I’d like to use your config, but the forum page messed with your copy/paste. May you attach the original files? Or upload them to some place? Thank you!
Continuing the discussion from [WORKAROUND] LG TV Remote:
Are you in the US?
I have an LG LW5600 and from what I’ve read, there is an alternate firmware which only applies to European models.
http://openlgtv.org.ru/wiki/index.php/Achievements
I’ve tried to telnet to my TV on port 1900 as shown in the script but the TV doesn’t respond.
Wow. Okay will do it again.
In configuration.yaml add
#################################################################
## Customize
#################################################################
customize:
script.powerofftv:
hidden: true
script.powerontv:
hidden: true
**
**
Exposes service shell_command.wol_bd_br
#################################################################
## Shell commands
#################################################################
shell_command:
change_to_tv: python3 /home/pi/.homeassistant/tv.py 15
power_off_tv: python3 /home/pi/.homeassistant/tv.py 8
wol_bd_br: wakeonlan EE:BB:BB:EE:00:FF
**
**
input_boolean:
television:
name: Bedroom
initial: off
icon: mdi:television
group:
Television:
- input_boolean.television
**
**
#################################################################
## Automations
#################################################################
automation:
- alias: 'turn on tv'
trigger:
platform: state
entity_id: input_boolean.television
state: 'on'
action:
service: script.powerontv
- alias: 'turn off tv'
trigger:
platform: state
entity_id: input_boolean.television
state: 'off'
action:
service: script.powerofftv
**
**
#################################################################
## Scripts
#################################################################
script:
# Turns on the TV and then changes input 20 seconds later
powerontv:
alias: poweron_tv
sequence:
- alias: 'turn on tv'
service: shell_command.wol_bd_br
- delay:
seconds: 20
- alias: 'change input to tv'
service: shell_command.change_to_tv
powerofftv:
alias: poweroff_tv
sequence:
- alias: 'turn off tv'
service: shell_command.power_off_tv
In the tv.py add your pairing key instead of DDDDDD copy and paste the entire script into a file named tv.py and your good to go. Of course restart HA
This is the tv.py script.
#!/usr/bin/env python3
import http.client
from tkinter import *
import xml.etree.ElementTree as etree
import socket
import re
import sys
lgtv = {}
dialogMsg =""
headers = {"Content-Type": "application/atom+xml"}
lgtv["pairingKey"] = "DDDDDD"
def getip():
strngtoXmit = 'M-SEARCH * HTTP/1.1' + '\r\n' + \
'HOST: 239.255.255.250:1900' + '\r\n' + \
'MAN: "ssdp:discover"' + '\r\n' + \
'MX: 2' + '\r\n' + \
'ST: urn:schemas-upnp-org:device:MediaRenderer:1' + '\r\n' + '\r\n'
bytestoXmit = strngtoXmit.encode()
sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
sock.settimeout(3)
found = False
gotstr = 'notyet'
i = 0
ipaddress = None
sock.sendto( bytestoXmit, ('239.255.255.250', 1900 ) )
while not found and i <= 5 and gotstr == 'notyet':
try:
gotbytes, addressport = sock.recvfrom(512)
gotstr = gotbytes.decode()
except:
i += 1
sock.sendto( bytestoXmit, ( '239.255.255.250', 1900 ) )
if re.search('LG', gotstr):
ipaddress, _ = addressport
found = True
else:
gotstr = 'notyet'
i += 1
sock.close()
if not found : sys.exit("Lg TV not found")
return ipaddress
def displayKey():
conn = http.client.HTTPConnection( lgtv["ipaddress"], port=8080)
reqKey = "<?xml version=\"1.0\" encoding=\"utf-8\"?><auth><type>AuthKeyReq</type></auth>"
conn.request("POST", "/hdcp/api/auth", reqKey, headers=headers)
httpResponse = conn.getresponse()
if httpResponse.reason != "OK" : sys.exit("Network error")
return httpResponse.reason
def getSessionid():
conn = http.client.HTTPConnection( lgtv["ipaddress"], port=8080)
pairCmd = "<?xml version=\"1.0\" encoding=\"utf-8\"?><auth><type>AuthReq</type><value>" \
+ lgtv["pairingKey"] + "</value></auth>"
conn.request("POST", "/hdcp/api/auth", pairCmd, headers=headers)
httpResponse = conn.getresponse()
if httpResponse.reason != "OK" : return httpResponse.reason
tree = etree.XML(httpResponse.read())
return tree.find('session').text
def getPairingKey():
displayKey()
root = Tk()
root.withdraw()
dialogMsg = "Please enter the pairing key\nyou see on your TV screen\n"
d = MyDialog(root, dialogMsg)
root.wait_window(d.top)
lgtv["pairingKey"] = result
d.top.destroy()
def handleCommand(cmdcode):
conn = http.client.HTTPConnection( lgtv["ipaddress"], port=8080)
cmdText = "<?xml version=\"1.0\" encoding=\"utf-8\"?><command><session>" \
+ lgtv["session"] \
+ "</session><type>HandleKeyInput</type><value>" \
+ cmdcode \
+ "</value></command>"
conn.request("POST", "/hdcp/api/dtv_wifirc", cmdText, headers=headers)
httpResponse = conn.getresponse()
#main()
lgtv["ipaddress"] = getip()
theSessionid = getSessionid()
while theSessionid == "Unauthorized" :
getPairingKey()
theSessionid = getSessionid()
if len(theSessionid) < 8 : sys.exit("Could not get Session Id: " + theSessionid)
lgtv["session"] = theSessionid
#displayKey()
result = str(sys.argv[1])
handleCommand(result)
If the LG remote apk works for you (the 2011 supporting one) then the script will work for you as well.
anyone get this script work with 2013 models? mine respond “Unauthorized” to pairing request:
POST http://10.182.22.5:8080/hdcp/api/auth HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/xml
Content-Length: 36
Host: 10.182.22.5:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
<auth><type>AuthKeyReq</type></auth>
and response:
<envelope>
<ROAPError>401</ROAPError>
<ROAPErrorDetail>Unauthorized</ROAPErrorDetail>
</envelope>
Try this one
#!/usr/bin/env python3
import http.client
from tkinter import *
import xml.etree.ElementTree as etree
import socket
import re
import sys
lgtv = {}
dialogMsg =""
headers = {"Content-Type": "application/atom+xml"}
lgtv["pairingKey"] = "DDDDDD"
class MyDialog:
def __init__(self, parent, dialogMsg):
top = self.top = Toplevel(parent)
Label(top, text = dialogMsg, justify="left").pack()
self.e = Entry(top)
self.e.pack(padx=5)
self.e.focus_set()
b = Button(top, text="Ok", command=self.ok)
b.pack(pady=5)
top.bind("<Return>", self.ok)
top.title("Lg 2012")
top.geometry("410x280+10+10")
def ok(self,dummy=None):
global result
result = self.e.get()
self.top.destroy()
def getip():
strngtoXmit = 'M-SEARCH * HTTP/1.1' + '\r\n' + \
'HOST: 239.255.255.250:1900' + '\r\n' + \
'MAN: "ssdp:discover"' + '\r\n' + \
'MX: 2' + '\r\n' + \
'ST: urn:schemas-upnp-org:device:MediaRenderer:1' + '\r\n' + '\r\n'
bytestoXmit = strngtoXmit.encode()
sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
sock.settimeout(3)
found = False
gotstr = 'notyet'
i = 0
ipaddress = None
sock.sendto( bytestoXmit, ('239.255.255.250', 1900 ) )
while not found and i <= 5 and gotstr == 'notyet':
try:
gotbytes, addressport = sock.recvfrom(512)
gotstr = gotbytes.decode()
except:
i += 1
sock.sendto( bytestoXmit, ( '239.255.255.250', 1900 ) )
if re.search('LG', gotstr):
ipaddress, _ = addressport
found = True
else:
gotstr = 'notyet'
i += 1
sock.close()
if not found : sys.exit("Lg TV not found")
return ipaddress
def displayKey():
conn = http.client.HTTPConnection( lgtv["ipaddress"], port=8080)
reqKey = "<?xml version=\"1.0\" encoding=\"utf-8\"?><auth><type>AuthKeyReq</type></auth>"
conn.request("POST", "/roap/api/auth", reqKey, headers=headers)
httpResponse = conn.getresponse()
if httpResponse.reason != "OK" : sys.exit("Network error")
return httpResponse.reason
def getSessionid():
conn = http.client.HTTPConnection( lgtv["ipaddress"], port=8080)
pairCmd = "<?xml version=\"1.0\" encoding=\"utf-8\"?><auth><type>AuthReq</type><value>" \
+ lgtv["pairingKey"] + "</value></auth>"
conn.request("POST", "/roap/api/auth", pairCmd, headers=headers)
httpResponse = conn.getresponse()
if httpResponse.reason != "OK" : return httpResponse.reason
tree = etree.XML(httpResponse.read())
return tree.find('session').text
def getPairingKey():
displayKey()
root = Tk()
root.withdraw()
dialogMsg = "Please enter the pairing key\nyou see on your TV screen\n"
d = MyDialog(root, dialogMsg)
root.wait_window(d.top)
lgtv["pairingKey"] = result
d.top.destroy()
def handleCommand(cmdcode):
conn = http.client.HTTPConnection( lgtv["ipaddress"], port=8080)
cmdText = "<?xml version=\"1.0\" encoding=\"utf-8\"?><command>" \
+ "<name>HandleKeyInput</name><value>" \
+ cmdcode \
+ "</value></command>"
conn.request("POST", "/roap/api/command", cmdText, headers=headers)
httpResponse = conn.getresponse()
#main()
lgtv["ipaddress"] = getip()
theSessionid = getSessionid()
while theSessionid == "Unauthorized" :
getPairingKey()
theSessionid = getSessionid()
if len(theSessionid) < 8 : sys.exit("Could not get Session Id: " + theSessionid)
lgtv["session"] = theSessionid
dialogMsg =""
for lgkey in lgtv :
dialogMsg += lgkey + ": " + lgtv[lgkey] + "\n"
dialogMsg += "Success in establishing command session\n"
dialogMsg += "=" * 28 + "\n"
dialogMsg += "Enter command code i.e. a number between 0 and 1024\n"
dialogMsg += "Enter a number greater than 1024 to quit.\n"
dialogMsg += "Some useful codes (not working with 2012 models):\n"
dialogMsg += "for EZ_ADJUST menu enter 255 \n"
dialogMsg += "for IN START menu enter 251 \n"
dialogMsg += "for Installation menu enter 207 \n"
dialogMsg += "for POWER_ONLY mode enter 254 \n"
dialogMsg += "Warning: do not enter 254 if you \ndo not know what POWER_ONLY mode is. "
result = "91"
while int(result) < 1024:
root = Tk()
root.withdraw()
d = MyDialog(root, dialogMsg)
root.wait_window(d.top)
handleCommand(result)
thanks, this one works for me
You’re welcome
Has anyone gotten this to work with a WebOS 2014 model?
Not sure what’s included and it doesn’t specify the year, but there are separate steps for LG WebOS
Media Player might have power options
I’ve set both of those up but no power on option. It’s just pause/play but it can turn it off. I’d like to remotely be able to turn it on though. I was thinking something to do with wake on LAN?
hi all… i followed this manual but unfortunately nothing works with it… how could i figure out whats wrong ? I have a 2011 model and remote apk works pretty good on my phone.
Yes, you need to use wake on lan to power on a Web OS tv. Make sure you enable waking the tv in the settings menu of the tv.
You could solve this without shell scripts with the native wake_on_lan component of homeassistant. I did the following:
To switch sources, use the media_player.select_source service.
Btw, I haven’t figured out is how to detect when the tv is off but recording.
Switches config:
- platform: template
switches:
tv_switch:
friendly_name: TV
value_template: '{{ states.media_player.lg_webos_smart_tv.state != "off" }}'
turn_on:
service: switch.turn_on
entity_id: switch.wol_lg_tv_eth
turn_off:
service: media_player.turn_off
entity_id: media_player.lg_webos_smart_tv
entity_id: media_player.lg_webos_smart_tv
- platform: wake_on_lan
name: wol_lg_tv_eth
mac_address: '00-08-00-00-00-00'
host: 192.168.1.123 #Irrelevant, will monitor the state of host to set the switch state.
turn_off:
service: switch.turn_off
entity_id: switch.tv_switch
Hello there the stuff written on top is for 2011 and 2012 models. Basically pre 2012 models.
As they don’t have WOL you would have to wake your TV via connected device like Bluray player that supports LAN (for WOL.)
You then wake the Bluray player that in turns wakes the TV through Simlink.
Then you can use the above work around to chance channels turn volume up and down or turn it off.
I posted more key commands here
You should just use the LG TV Component
Did you created the tv.py to be called?