added shitty roku integration
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
from roku import Roku
|
||||
import os
|
||||
import json
|
||||
import threading
|
||||
|
||||
ROKU_IP = os.environ.get("ROKU_IP")
|
||||
if not ROKU_IP:
|
||||
raise Exception("Roku IP not found in env!")
|
||||
|
||||
COMMANDS = {
|
||||
# Standard Keys
|
||||
"home": "Home",
|
||||
"reverse": "Rev",
|
||||
"forward": "Fwd",
|
||||
"play": "Play",
|
||||
"select": "Select",
|
||||
"left": "Left",
|
||||
"right": "Right",
|
||||
"down": "Down",
|
||||
"up": "Up",
|
||||
"back": "Back",
|
||||
"replay": "InstantReplay",
|
||||
"info": "Info",
|
||||
"backspace": "Backspace",
|
||||
"search": "Search",
|
||||
"enter": "Enter",
|
||||
"literal": "Lit",
|
||||
# For devices that support "Find Remote"
|
||||
"find_remote": "FindRemote",
|
||||
# For Roku TV
|
||||
"volume_down": "VolumeDown",
|
||||
"volume_up": "VolumeUp",
|
||||
"volume_mute": "VolumeMute",
|
||||
# For Roku TV while on TV tuner channel
|
||||
"channel_up": "ChannelUp",
|
||||
"channel_down": "ChannelDown",
|
||||
# For Roku TV current input
|
||||
"input_tuner": "InputTuner",
|
||||
"input_hdmi1": "InputHDMI1",
|
||||
"input_hdmi2": "InputHDMI2",
|
||||
"input_hdmi3": "InputHDMI3",
|
||||
"input_hdmi4": "InputHDMI4",
|
||||
"input_av1": "InputAV1",
|
||||
# For devices that support being turned on/off
|
||||
"power": "Power",
|
||||
"poweroff": "PowerOff",
|
||||
"poweron": "PowerOn",
|
||||
}
|
||||
|
||||
class RokuWrapper():
|
||||
def __init__(self, parent):
|
||||
self.parent = parent
|
||||
|
||||
# eh maybe close the connection? Not really needed
|
||||
self.timer: threading.Timer | None = None
|
||||
|
||||
try:
|
||||
self.rapp = Roku(ROKU_IP)
|
||||
print(f"Roku client connected to {ROKU_IP}", flush=True)
|
||||
except Exception as e:
|
||||
self.parent.log_error("Failed to create Roku client: %s", e)
|
||||
return self.parent._send(500, json.dumps({"error": "roku connection failed"}).encode())
|
||||
|
||||
def run_command(self, command: str):
|
||||
if not command:
|
||||
return self.parent._send(404, json.dumps({"error": "command not given"}).encode())
|
||||
command = command.split('/')[0]
|
||||
|
||||
# If command is not known, nothing to do
|
||||
if command not in COMMANDS:
|
||||
return self.parent._send(404, json.dumps({"error": "unknown command"}).encode())
|
||||
|
||||
if hasattr(self.rapp, command):
|
||||
attr = getattr(self.rapp, command)
|
||||
if callable(attr):
|
||||
attr()
|
||||
return {"result": f"{command} executed"}
|
||||
|
||||
# Fallback: send the Roku key name using common API methods
|
||||
key_name = COMMANDS[command]
|
||||
# common method names in Roku libs
|
||||
for send_fn in ("press", "keypress", "send_key", "send_keypress", "button"):
|
||||
if hasattr(self.rapp, send_fn):
|
||||
fn = getattr(self.rapp, send_fn)
|
||||
try:
|
||||
fn(key_name)
|
||||
return {"result": f"{command} sent as {key_name} via {send_fn}"}
|
||||
except TypeError:
|
||||
continue
|
||||
|
||||
self.parent._send(404, json.dumps({"error": "unknown endpoint"}).encode())
|
||||
Reference in New Issue
Block a user