From 3b9ff32edcf02c33d284f3edbe22e9a36d6efa33 Mon Sep 17 00:00:00 2001 From: Rudolf Offereins Date: Wed, 29 Apr 2026 22:10:36 +0200 Subject: [PATCH 1/5] feat: add all media keys, per-box tabbed UI with remote control layout - Add 40+ media key constants to const.py grouped by category (Power, Playback, Navigation, D-Pad, Colour, Digits) - Add /api/keys endpoint to web.py - Redesign web_ui.html: per-box tabs instead of grid, full-page remote control layout with D-pad cross, numpad, colour buttons, and all keys --- lghorizon/const.py | 89 +++- web.py | 9 +- web_ui.html | 1116 +++++++++++++++++++++----------------------- 3 files changed, 613 insertions(+), 601 deletions(-) diff --git a/lghorizon/const.py b/lghorizon/const.py index dddbc22..a756e2b 100644 --- a/lghorizon/const.py +++ b/lghorizon/const.py @@ -8,23 +8,90 @@ BOX_PLAY_STATE_VOD = "VOD" # List with available media keys. +# Power MEDIA_KEY_POWER = "Power" -MEDIA_KEY_ENTER = "Enter" -MEDIA_KEY_ESCAPE = "Escape" # Not yet implemented +MEDIA_KEY_STANDBY = "Standby" +MEDIA_KEY_WAKEUP = "WakeUp" -MEDIA_KEY_HELP = "Help" # Not yet implemented -MEDIA_KEY_INFO = "Info" # Not yet implemented -MEDIA_KEY_GUIDE = "Guide" # Not yet implemented +# Media Playback +MEDIA_KEY_PLAY = "MediaPlay" +MEDIA_KEY_PAUSE = "MediaPause" +MEDIA_KEY_PLAY_PAUSE = "MediaPlayPause" +MEDIA_KEY_STOP = "MediaStop" +MEDIA_KEY_RECORD = "MediaRecord" +MEDIA_KEY_FAST_FORWARD = "MediaFastForward" +MEDIA_KEY_REWIND = "MediaRewind" +MEDIA_KEY_TRACK_NEXT = "MediaTrackNext" +MEDIA_KEY_TRACK_PREVIOUS = "MediaTrackPrevious" -MEDIA_KEY_CONTEXT_MENU = "ContextMenu" # Not yet implemented +# Channel / Navigation MEDIA_KEY_CHANNEL_UP = "ChannelUp" MEDIA_KEY_CHANNEL_DOWN = "ChannelDown" +MEDIA_KEY_TOP_MENU = "MediaTopMenu" +MEDIA_KEY_GUIDE = "Guide" +MEDIA_KEY_HELP = "Help" +MEDIA_KEY_INFO = "Info" +MEDIA_KEY_CONTEXT_MENU = "ContextMenu" +MEDIA_KEY_NEXT_USER_PROFILE = "NextUserProfile" +MEDIA_KEY_TV = "TV" +MEDIA_KEY_TELETEXT = "Teletext" +MEDIA_KEY_SUBTITLE = "Subtitle" +MEDIA_KEY_AUDIO_TRACK = "AudioTrack" -MEDIA_KEY_RECORD = "MediaRecord" -MEDIA_KEY_PLAY_PAUSE = "MediaPlayPause" -MEDIA_KEY_STOP = "MediaStop" -MEDIA_KEY_REWIND = "MediaRewind" -MEDIA_KEY_FAST_FORWARD = "MediaFastForward" +# UI Navigation (D-Pad) +MEDIA_KEY_ARROW_UP = "ArrowUp" +MEDIA_KEY_ARROW_DOWN = "ArrowDown" +MEDIA_KEY_ARROW_LEFT = "ArrowLeft" +MEDIA_KEY_ARROW_RIGHT = "ArrowRight" +MEDIA_KEY_ENTER = "Enter" +MEDIA_KEY_ESCAPE = "Escape" +MEDIA_KEY_BACKSPACE = "Backspace" + +# Colour Buttons +MEDIA_KEY_RED = "Red" +MEDIA_KEY_GREEN = "Green" +MEDIA_KEY_YELLOW = "Yellow" +MEDIA_KEY_BLUE = "Blue" + +# Digit Keys +MEDIA_KEY_0 = "0" +MEDIA_KEY_1 = "1" +MEDIA_KEY_2 = "2" +MEDIA_KEY_3 = "3" +MEDIA_KEY_4 = "4" +MEDIA_KEY_5 = "5" +MEDIA_KEY_6 = "6" +MEDIA_KEY_7 = "7" +MEDIA_KEY_8 = "8" +MEDIA_KEY_9 = "9" + +# Grouped for API/UI consumers +MEDIA_KEYS = { + "Power": [MEDIA_KEY_POWER, MEDIA_KEY_STANDBY, MEDIA_KEY_WAKEUP], + "Playback": [ + MEDIA_KEY_PLAY, MEDIA_KEY_PAUSE, MEDIA_KEY_PLAY_PAUSE, + MEDIA_KEY_STOP, MEDIA_KEY_RECORD, + MEDIA_KEY_FAST_FORWARD, MEDIA_KEY_REWIND, + MEDIA_KEY_TRACK_NEXT, MEDIA_KEY_TRACK_PREVIOUS, + ], + "Navigation": [ + MEDIA_KEY_CHANNEL_UP, MEDIA_KEY_CHANNEL_DOWN, + MEDIA_KEY_TOP_MENU, MEDIA_KEY_GUIDE, MEDIA_KEY_HELP, + MEDIA_KEY_INFO, MEDIA_KEY_CONTEXT_MENU, + MEDIA_KEY_NEXT_USER_PROFILE, MEDIA_KEY_TV, + MEDIA_KEY_TELETEXT, MEDIA_KEY_SUBTITLE, MEDIA_KEY_AUDIO_TRACK, + ], + "D-Pad": [ + MEDIA_KEY_ARROW_UP, MEDIA_KEY_ARROW_DOWN, + MEDIA_KEY_ARROW_LEFT, MEDIA_KEY_ARROW_RIGHT, + MEDIA_KEY_ENTER, MEDIA_KEY_ESCAPE, MEDIA_KEY_BACKSPACE, + ], + "Colour": [MEDIA_KEY_RED, MEDIA_KEY_GREEN, MEDIA_KEY_YELLOW, MEDIA_KEY_BLUE], + "Digits": [ + MEDIA_KEY_0, MEDIA_KEY_1, MEDIA_KEY_2, MEDIA_KEY_3, MEDIA_KEY_4, + MEDIA_KEY_5, MEDIA_KEY_6, MEDIA_KEY_7, MEDIA_KEY_8, MEDIA_KEY_9, + ], +} RECORDING_TYPE_SINGLE = "single" RECORDING_TYPE_SHOW = "show" diff --git a/web.py b/web.py index 3a010f4..7894f99 100644 --- a/web.py +++ b/web.py @@ -18,7 +18,7 @@ from lghorizon.lghorizon_api import LGHorizonApi from lghorizon.lghorizon_models import LGHorizonAuth -from lghorizon.const import COUNTRY_SETTINGS +from lghorizon.const import COUNTRY_SETTINGS, MEDIA_KEYS logging.basicConfig( level=logging.DEBUG, @@ -143,6 +143,12 @@ async def get_countries(request: web.Request): return web.json_response({"countries": countries}) +@routes.get("/api/keys") +async def get_keys(request: web.Request): + """Return all available media keys grouped by category.""" + return web.json_response({"keys": MEDIA_KEYS}) + + @routes.post("/api/login") async def login(request: web.Request): """Authenticate and initialize the API connection.""" @@ -205,6 +211,7 @@ async def login(request: web.Request): "success": True, "devices": device_list, "channels": channel_list, + "keys": MEDIA_KEYS, }) except Exception as e: diff --git a/web_ui.html b/web_ui.html index 7d2f403..5241e6f 100644 --- a/web_ui.html +++ b/web_ui.html @@ -4,7 +4,6 @@ LG Horizon Test UI - - +
-