-
-
Save greyshi/89d06eb52b1ac19a5e09ef6ffafa1cd5 to your computer and use it in GitHub Desktop.
local tv_input = "HDMI_2" -- Input to which your Mac is connected | |
local mac_address = "80:5B:65:6D:AF:D4" | |
local switch_input_on_wake = true -- Switch input to Mac when waking the TV | |
local prevent_sleep_when_using_other_input = true -- Prevent sleep when using other input (ie: watching TV) | |
local debug = false -- If you run into issues, set to true to enable debug messages | |
-- You likely will not need to change anything below this line | |
local tv_name = "MyTV" -- Name of your TV, set when you run `lgtv auth` | |
local connected_tv_identifiers = {"LG TV", "LG TV SSCR2"} -- Used to identify the TV when it's connected to this computer | |
local screen_off_command = "off" -- use "screenOff" to keep the TV on, but turn off the screen. | |
local lgtv_path = "/opt/lgtv-venv/bin/lgtv" -- Full path to lgtv executable | |
local lgtv_cmd = lgtv_path.." "..tv_name | |
local app_id = "com.webos.app."..tv_input:lower():gsub("_", "") | |
local lgtv_ssl = true -- Required for firmware 03.30.16 and up. Also requires LGWebOSRemote version 2023-01-27 or newer. | |
function lgtv_current_app_id() | |
local foreground_app_info = exec_command("getForegroundAppInfo") | |
foreground_app_info = string.match(foreground_app_info, '^%b{}') | |
foreground_app_info = hs.json.decode(foreground_app_info) | |
return foreground_app_info["payload"]["appId"] | |
end | |
function tv_is_connected() | |
for i, v in ipairs(connected_tv_identifiers) do | |
if hs.screen.find(v) ~= nil then | |
return true | |
end | |
end | |
return false | |
end | |
function dump_table(o) | |
if type(o) == 'table' then | |
local s = '{ ' | |
for k,v in pairs(o) do | |
if type(k) ~= 'number' then k = '"'..k..'"' end | |
s = s .. '['..k..'] = ' .. dump_table(v) .. ',' | |
end | |
return s .. '} ' | |
else | |
return tostring(o) | |
end | |
end | |
function exec_command(command) | |
if lgtv_ssl then | |
command = command.." ssl" | |
end | |
command = lgtv_cmd.." "..command | |
if debug then | |
print("Executing command: "..command) | |
end | |
return hs.execute(command) | |
end | |
if debug then | |
print ("TV name: "..tv_name) | |
print ("TV input: "..tv_input) | |
print ("LGTV path: "..lgtv_path) | |
print ("LGTV command: "..lgtv_cmd) | |
print ("SSL: "..tostring(lgtv_ssl)) | |
print ("App ID: "..app_id) | |
print (exec_command("swInfo")) | |
print (exec_command("getForegroundAppInfo")) | |
print("Connected screens: "..dump_table(hs.screen.allScreens())) | |
print("TV is connected? "..tostring(tv_is_connected())) | |
end | |
watcher = hs.caffeinate.watcher.new(function(eventType) | |
if debug then print("Received event: "..eventType) end | |
if not tv_is_connected() then | |
if debug then print("TV is not connected. Skipping.") end | |
return | |
end | |
if (eventType == hs.caffeinate.watcher.screensDidWake or | |
eventType == hs.caffeinate.watcher.systemDidWake or | |
eventType == hs.caffeinate.watcher.sessionDidBecomeActive or | |
eventType == hs.caffeinate.watcher.screensDidUnlock) then | |
exec_command("on") -- wake on lan | |
exec_command("screenOn") -- turn on screen | |
hs.execute("/opt/homebrew/bin/wakeonlan "..mac_address) | |
if debug then print("TV was turned on") end | |
if lgtv_current_app_id() ~= app_id and switch_input_on_wake then | |
exec_command("startApp "..app_id) | |
if debug then print("TV input switched to "..app_id) end | |
end | |
end | |
if (eventType == hs.caffeinate.watcher.screensDidSleep or | |
eventType == hs.caffeinate.watcher.systemWillPowerOff) then | |
if lgtv_current_app_id() ~= app_id and prevent_sleep_when_using_other_input then | |
if debug then print("TV is currently on another input ("..current_app_id.."). Skipping powering off.") end | |
return | |
end | |
-- This puts the TV in standby mode. | |
-- For true "power off" use `off` instead of `screenOff`. | |
exec_command(screen_off_command) | |
if debug then print("TV screen was turned off with command `"..screen_off_command.."`.") end | |
end | |
end) | |
watcher:start() |
Wait you're setting the input before turning on the TV? Does that work? Maybe in "Always Ready" mode but I wonder if it does if it's not in that mode...
Another thought: I don't have time currently to test but I suspect that wakeonlan
works regardless of Always Ready
and the lgtv MyTV on
works solely in Always Ready
mode.
Nice catch on that. I had an older version of this saved in the gist from when I was testing things out trying to find the culprit of the screen turning on right after powering off. Just updated it to properly put the wakeonlan as the first command.
I actually don't have Always Ready on, and I'm able to use both wakeonlan
as well as lgtv MyTV on
to turn the TV on from powered on state. Seems like lots of commands will turn the TV on, including the lgtv MyTV off
command surprisingly.
Interesting so the TV is always on in some way, makes sense with the need for the IR receiver to work, there must be other parts also on including the part that lets you connect via CLI!
This extends the original script by @cmer so that it:
tv_input
variable on wake. This is useful for when the last time you used the TV you were on a different input than the one your computer is connected toYou'll need to install the required dependencies for this to work, and @tonycassara has documented those steps here.