From b445a4d007b216822100aa209c7a42e9a76af8cf Mon Sep 17 00:00:00 2001 From: Ian Chamberlain Date: Wed, 21 Jan 2026 18:39:57 -0800 Subject: [PATCH] Update for my configs and some minor tweaks --- README.md | 3 ++ magic_mapper.py | 32 +++++++----- magic_mapper_config.json | 104 ++++++++++++++++++--------------------- start_magic_mapper | 6 ++- 4 files changed, 76 insertions(+), 69 deletions(-) mode change 100644 => 100755 magic_mapper.py diff --git a/README.md b/README.md index 5aaa51d..b1a7a63 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # Magic Mapper +> NOTE: this is a personal fork of . +> Use at your own risk. + ## Summary Magic Mapper is a script that will let you remap unused buttons on the LG Magic Remote. The script itself runs on your rooted LG TV, detects button presses, and allows you to control anything available via the [luna-send api](https://www.webosose.org/docs/tools/commands/luna-send/). Note your TV must be rooted to use this. diff --git a/magic_mapper.py b/magic_mapper.py old mode 100644 new mode 100755 index 5dfdee1..b49483e --- a/magic_mapper.py +++ b/magic_mapper.py @@ -5,6 +5,7 @@ import re import time import struct import subprocess +import sys import json import fcntl @@ -16,13 +17,13 @@ except ImportError: SOCKET_AVAILABLE = False BLOCK_MOUSE = False # Set to True to disable the mouse, note EXCLUSIVE_MODE must be True to work -EXCLUSIVE_MODE = True # Prevent bound codes from being seen by WebOS, must be True for BLOCK_MOUSE +EXCLUSIVE_MODE = False # Prevent bound codes from being seen by WebOS, must be True for BLOCK_MOUSE -DEVICE_NAME = 'LGE M-RCU - Builtin [0]' # the exact Name= shown in /proc/bus/input/devices -# DEVICE_NAME = 'LGE M-RCU - Builtin [1]' # UNTESTED - Try this for IR remotes +# INPUT_DEVICE = "/dev/input/event3" # Input device for the magic remote in bluetooth mode +INPUT_DEVICE = "/dev/input/event4" # use this for IR remotes - -OUTPUT_DEVICE = "/dev/input/event4" # unbound codes get resent to this device in exclusive mode +# TBD if this needs to be adjusted more precisely, it causes infinite recursion if input == output +OUTPUT_DEVICE = "/dev/input/event5" # unbound codes get resent to this device in exclusive mode BUTTONS = { @@ -40,6 +41,8 @@ BUTTONS = { 167: "record", 168: "rewind", 208: "fastforward", + 814: "next", # from LG remote app + 813: "previous", # from LG remote app 2: "1", 3: "2", 4: "3", @@ -71,8 +74,9 @@ BUTTONS = { 773: "home", 28: "ok", 412: "back", + 241: "input", - # universal remote buttons + # universal remote buttons event4 172: "uni_home", 158: "uni_back", 418: "uni_zoom_in", @@ -85,7 +89,7 @@ BUTTONS = { 163: "uni_next", 164: "uni_playpause", # Maybe universalish? - # universal remote, from different device + # universal remote, from event3 127: "uni_info", # ? } @@ -498,12 +502,9 @@ def input_loop(button_map): # https://stackoverflow.com/a/16682549/866057 input_format = "llHHi" event_size = struct.calcsize(input_format) + input_device = open(INPUT_DEVICE, "rb") buttons_waiting = {} - input_device_path = resolve_input_device_by_name(DEVICE_NAME) - print("Opening input device: %s" % input_device_path) - input_device = open(input_device_path, "rb") - if EXCLUSIVE_MODE: print("EXCLUSIVE_MODE is enabled, taking over input device") fcntl.ioctl(input_device, EVIOCGRAB, 1) @@ -641,6 +642,15 @@ def main(): print("BLOCK_MOUSE is %s" % BLOCK_MOUSE) + if len(sys.argv) > 1: + global INPUT_DEVICE + INPUT_DEVICE = sys.argv[1] + + global OUTPUT_DEVICE + if OUTPUT_DEVICE == INPUT_DEVICE: + # Prevent infinite recursion + OUTPUT_DEVICE = "/dev/input/event3" + input_loop(button_map=button_map) diff --git a/magic_mapper_config.json b/magic_mapper_config.json index 73cb81a..9629492 100644 --- a/magic_mapper_config.json +++ b/magic_mapper_config.json @@ -1,82 +1,74 @@ { + "red": { + "function": "launch_app", + "inputs": { + "app_id": "netflix" + } + }, + "green": { + "function": "launch_app", + "inputs": { + "app_id": "hulu" + } + }, "yellow": { - "function": "cycle_energy_mode", + "function": "launch_app", "inputs": { - "reverse_order": false, - "notifications": false + "app_id": "spotify-beehive" } }, "blue": { - "function": "toggle_eye_comfort", + "function": "launch_app", "inputs": { - "notifications": true + "app_id": "com.disney.disneyplus-prod" } }, - "red": { - "function": "reduce_oled_light", + "prime": { + "function": "launch_app", "inputs": { - "increment": 10, - "disable_energy_savings": "True" + "app_id": "org.jellyfin.webos" } }, - "green": { - "function": "increase_oled_light", + "uni_movies": { + "function": "launch_app", "inputs": { - "increment": 10, - "disable_energy_savings": "True" + "app_id": "org.jellyfin.webos" } }, - "guide": [ - { - "function": "send_cec_button", - "appId": "com.webos.app.hdmi2", - "inputs": { - "code": 18882565 - } - }, - { - "function": "curl", - "appId": "com.webos.app.hdmi1", - "inputs": { - "url": "http://homeassistant.local:8123/api/webhook/lg-webos-remote-guide-button-hdmi1" - } - }, - { - "function": "curl", - "inputs": { - "url": "http://homeassistant.local:8123/api/webhook/lg-webos-remote-guide-button-common" - } - }, - { - "function": "curl", - "comment": "Special appId of '!' indicates that it would be played if no app-specific entry matched so far. This is like the 'default' in the C switch case.", - "appId": "!", - "inputs": { - "url": "http://homeassistant.local:8123/api/webhook/lg-webos-remote-guide-button-default" - } + "uni_back": { + "function": "press_button", + "inputs": { + "button": "back" } - ], - "9": { - "function": "screen_off" }, - "0-example remove all but the 0 to assign to button 0": { - "function": "send_ir_command", + "uni_home": { + "function": "press_button", "inputs": { - "tv_input": "optical", - "keycode": "IR_KEY_POWER", - "device_type": "audio" + "button": "home" } }, - "1-example remove all but the 1 to assign to button 1": { - "function": "launch_app", + "uni_info": { + "function": "press_button", "inputs": { - "app_id": "netflix" + "button": "input" } }, - "EXAMPLE - replace this text with the button name 'prime' to have the prime button launch plex": { - "function": "launch_app", + "uni_previous": { + "function": "press_button", + "inputs": { + "button": "previous" + } + }, + "uni_next": { + "function": "press_button", + "inputs": { + "button": "next" + } + }, + "uni_playpause": { + "function": "press_button", "inputs": { - "app_id": "cdp-30" + "button": "play" } } -} +} \ No newline at end of file diff --git a/start_magic_mapper b/start_magic_mapper index 7332bbe..7255968 100644 --- a/start_magic_mapper +++ b/start_magic_mapper @@ -7,7 +7,9 @@ if [ -f "/usr/bin/python" ]; then - nohup /usr/bin/python -u /home/root/magic_mapper.py > /tmp/magic_mapper.log 2>&1 & + nohup /usr/bin/python -u /home/root/magic_mapper.py /dev/input/event4 > /tmp/magic_mapper_event4.log 2>&1 & + nohup /usr/bin/python -u /home/root/magic_mapper.py /dev/input/event1 > /tmp/magic_mapper_event1.log 2>&1 & else - nohup /usr/bin/python3 -u /home/root/magic_mapper.py > /tmp/magic_mapper.log 2>&1 & + nohup /usr/bin/python3 -u /home/root/magic_mapper.py /dev/input/event4 > /tmp/magic_mapper_event4.log 2>&1 & + nohup /usr/bin/python3 -u /home/root/magic_mapper.py /dev/input/event1 > /tmp/magic_mapper_event1.log 2>&1 & fi -- 2.54.0