Skip to content

Commit

Permalink
Add sendButton command to send remote button presses
Browse files Browse the repository at this point in the history
This makes it possible to send a sequence of button presses (among the current
options) to the TV which can help automate actions that can't otherwise be
achieved with the normal API.
  • Loading branch information
Tenzer committed Dec 10, 2023
1 parent 95c289e commit b39bb7e
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 8 deletions.
14 changes: 11 additions & 3 deletions LGTV/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .scan import LGTVScan
from .remote import LGTVRemote
from .auth import LGTVAuth
from .cursor import LGTVCursor


search_config = [
Expand Down Expand Up @@ -158,9 +159,10 @@ def main():
else:
try:
kwargs = parseargs(args.command, args.args)
except Exception as e:
parser.print_help()
sys.exit(1)
except Exception:
if args.command not in {"sendButton"}:
parser.print_help()
sys.exit(1)

if args.name:
name = args.name
Expand All @@ -170,6 +172,12 @@ def main():
print("A TV name is required. Set one with -n/--name or the setDefault command.")
sys.exit(1)

if args.command == "sendButton":
cursor = LGTVCursor(name, **config[name], ssl=args.ssl)
cursor.connect()
cursor.execute(args.args)
return

try:
ws = LGTVRemote(name, **config[name], ssl=args.ssl)

Expand Down
53 changes: 48 additions & 5 deletions LGTV/cursor.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,57 @@
# Stub for cursor support.

import inspect
from time import sleep

from .remote import LGTVRemote
from ws4py.client.threadedclient import WebSocketClient


class LGTVCursor(WebSocketClient):

def __finalize(self, response):
self.remote.close()
address = response['payload']['socketPath']
super(LGTVCursor, self).__init__(address, exclude_headers=["Origin"])

def __init__(self, name, ip=None, mac=None, key=None, hostname=None):
self.remote = LGTVRemote(name, ip, mac, key, hostname)
def __init__(self, name, ip=None, mac=None, key=None, hostname=None, ssl=False):
self.remote = LGTVRemote(name, ip, mac, key, hostname, ssl)
self.remote.connect()
self.remote.getCursorSocket(self.__finalize)
self.remote.execute("getCursorSocket", {"callback": self.__finalize})
self.remote.run_forever()

def _list_possible_buttons(self):
buttons = []
self_class = self.__class__.__name__

for name, method in inspect.getmembers(self, predicate=inspect.ismethod):
if name.startswith("_"):
continue

if name in {"execute"}:
continue

if not method.__qualname__.startswith(f"{self_class}."):
continue

buttons.append(name)

return buttons

def execute(self, buttons):
if not buttons:
print("Add button presses to perform. Possible options:", ", ".join(self._list_possible_buttons()))
return

for i, button in enumerate(buttons):
if not hasattr(self, button):
print(f"{button} is not a possible button press, skipped")
continue

if i != 0:
sleep(0.1)

getattr(self, button)()

def up(self):
self.send("type:button\nname:UP\n\n")
Expand All @@ -34,5 +72,10 @@ def back(self):
self.send("type:button\nname:BACK\n\n")

def enter(self):
self.remote.sendEnterKey()

self.send("type:button\nname:ENTER\n\n")

def home(self):
self.send("type:button\nname:HOME\n\n")

def exit(self):
self.send("type:button\nname:EXIT\n\n")
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ All devices with firmware major version 4, product name "webOSTV 2.0"
lgtv --name MyTV --ssl openYoutubeURL <url>
lgtv --name MyTV --ssl openYoutubeLegacyId <videoid>
lgtv --name MyTV --ssl openYoutubeLegacyURL <url>
lgtv --name MyTV --ssl sendButton <button>
lgtv --name MyTV --ssl serialise
lgtv --name MyTV --ssl setInput <input_id>
lgtv --name MyTV --ssl setSoundOutput <tv_speaker|external_optical|external_arc|external_speaker|lineout|headphone|tv_external_speaker|tv_speaker_headphone|bt_soundbar>
Expand Down

0 comments on commit b39bb7e

Please sign in to comment.