Skip to content

Instantly share code, notes, and snippets.

@cmer
Last active September 21, 2023 10:08
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cmer/bd40d9da0055d257c5aab2e0143ee17b to your computer and use it in GitHub Desktop.
Save cmer/bd40d9da0055d257c5aab2e0143ee17b to your computer and use it in GitHub Desktop.
Wake TV when MacOS wakes from sleep (Hammerspoon)
-- -------------------------------------------------------------------
-- THIS SCRIPT IS NOW DEPRECATED IN FAVOR OF A MORE ROBUST SOLUTION --
-- Please refer to https://github.com/cmer/lg-tv-control-macos/
-- -------------------------------------------------------------------
local tv_identifier = "LG TV"
local mac_address = "aa:bb:cc:dd:ee:ff"
local tv_found = (hs.screen.find(tv_identifier) ~= nil)
local debug = false -- Set to true to enable debug messages
if debug then
print("List of all screens: " .. hs.inspect(hs.screen.allScreens()))
if tv_found then print("TV with identifier '"..tv_identifier.."' was detected.") end
end
watcher = hs.caffeinate.watcher.new(function(eventType)
if (eventType == hs.caffeinate.watcher.screensDidWake or
eventType == hs.caffeinate.watcher.systemDidWake or
eventType == hs.caffeinate.watcher.screensDidUnlock) and tv_found then
if debug then print("TV was turned on.") end
hs.execute("/opt/homebrew/bin/wakeonlan "..mac_address)
end
end)
watcher:start()
@tonycassara
Copy link

@cmer I'm running into the same wall the API does not make it seem like I can simply send a command over network but I know someone did this on Windows with https://github.com/JPersson77/LGTVCompanion so it must be possible. I unfortunately am not a C/Lua developer so I have to spend more time combing through.

@cmer
Copy link
Author

cmer commented Oct 18, 2022

Yes it is possible. The Nodejs implementation of the API is a good starting point.

@tonycassara
Copy link

@cmer do you happen to know any good resources for handling async actions in Lua? I feel like I'm close, I was able to figure out what commands to send via WebSockets but it seems I cannot await the initial connection of hs.websocket.new before sending the commands needed to turn off the screen.

@cmer
Copy link
Author

cmer commented Oct 19, 2022

I don't know jack about Lua, so I can't help much here. Sorry.

@iKindle
Copy link

iKindle commented Oct 26, 2022

Not very well. Is not everyone wakeonlan's path on /opt/homebrew/bin/wakeonlan .
My wakeonlan path on /usr/local/bin/wakeonlan

ON Terminal Run whereis wakeonlan,find out your path. And change line 17 of the code.

@cmer
Copy link
Author

cmer commented Oct 26, 2022

That’s because you are on an Intel CPU. Apple Silicon is a different path.

@greyshi
Copy link

greyshi commented Jan 18, 2023

The original script would only wake the display but not turn it off when going to sleep, locking, or powering off the computer. I extended it to trigger a TV power off on these actions.

You first need to install LGWebOSRemote and have it set up already by running the command lgtv auth <host> MyTV after installation. This auth is only required a single time and is remembered after you confirm the device on your TV.

local tv_identifier = "LG TV"
local mac_address = "80:5B:65:6D:AF:D4"
local tv_found = (hs.screen.find(tv_identifier) ~= nil)
local debug = false  -- Set to true to enable debug messages

if debug then
  print("List of all screens: " .. hs.inspect(hs.screen.allScreens()))
  if tv_found then print("TV with identifier '"..tv_identifier.."' was detected.") end
end

watcher = hs.caffeinate.watcher.new(function(eventType)
  if (eventType == hs.caffeinate.watcher.screensDidWake or
      eventType == hs.caffeinate.watcher.systemDidWake or
      eventType == hs.caffeinate.watcher.screensDidUnlock) and tv_found then

    if debug then print("TV was turned on.") end
    hs.execute("/opt/homebrew/bin/wakeonlan "..mac_address)
  end

  if (eventType == hs.caffeinate.watcher.screensDidLock or
      eventType == hs.caffeinate.watcher.screensDidSleep or
      eventType == hs.caffeinate.watcher.systemWillSleep or
      eventType == hs.caffeinate.watcher.systemWillPowerOff) and tv_found then

    if debug then print("TV was turned off.") end
    hs.execute("/opt/lgtv-venv/bin/lgtv MyTV off")
  end
end)
watcher:start()

@tonycassara
Copy link

tonycassara commented Jan 18, 2023

@greyshi you the GOAT!! Amazing I didn't know this repo existed! I did find a weird bug where screensDidSleep and screensWillSleep cause my TV to turn off and then immediately back on. By removing screensWillSleep I get a clean turn off now. Also I don't want it to turn off the TV immediately on lock because I sometimes press it by accident. So here's the snippet I came up with: https://gist.github.com/tonycassara/1db2df972e557046c5cccf6349a9bcc6

@greyshi
Copy link

greyshi commented Jan 18, 2023

Nice! Yeah, there are a ton of CLI tools for controlling the TV. The one used in the script doesn't support OLED backlight control, but this one does which means you can control the hardware screen brightness using the CLI and map that to hotkeys if you want. I have my ideal setup now with the ability to have auto on/off, brightness control, and TV input settings all working as I want.

@tonycassara
Copy link

Ooooo switching the TV input setting if I could automate that would be endgame. Just not sure how I go about it in my workflow 🤔 thanks for the ideas!

@greyshi
Copy link

greyshi commented Jan 19, 2023

Here's a new version that automatically switches input on wake that is really helpful for my workflow: https://gist.github.com/greyshi/89d06eb52b1ac19a5e09ef6ffafa1cd5

My windows PC has this functionality as well using LGTVCompanion, so now whichever system I start up will automatically switch to the correct input. My TV now has 1 less manual step than my old monitor did!

Also, I found that the immediate power on after power off issue was happening from time to time until I got rid of both the screensWillSleep as well as the screensDidLock. I verified that running the off command while the TV is off it actually turns it on for whatever reason, and that's exactly what's happening when multiple events are matched. First the computer is locked, and then the screen sleeps which each trigger it.

Now the only issue for me is that none of these commands function when my work VPN is active since it blocks LAN access. I don't think there's any way to get around that though, since all communication to the TV is through the local network. I'm not quite ready to go through the internet to control my monitor 😄

@tonycassara
Copy link

@greyshi I have the exact same setup, LGTV Company on my Windows PC I use for gaming, and Hammerspoon with the script for my work MacbookPro. Thank you for coming in and adding onto this, my ideal setup is finally complete 😄

@cmer
Copy link
Author

cmer commented Jan 19, 2023

Thanks so much @greyshi, awesome work! I never knew this CLI tool existed despite spending quite a bit of time looking for one. Excited to give this a try soon.

@greyshi
Copy link

greyshi commented Jan 19, 2023

@cmer Thanks a bunch for putting the original script together!

@tonycassara I guess that's a pretty common use of the TV. Thanks for the help with testing things out and let me know if you run into any other issues I haven't noticed yet.

@cmer
Copy link
Author

cmer commented Jan 20, 2023

Thanks so much for your contribution. I created a new repo combining @greyshi's ideas. I was able to simplify the script quite a bit and reduce dependencies. Let me know what you think. https://github.com/cmer/lg-tv-control-macos/

@tonycassara
Copy link

Nice stuff @cmer !

@tonycassara
Copy link

Hey are either of you hitting an issue where the LGTV Web OS Remote package doesn't stay installed on your machine? I keep having to reinstall it. Maybe it's a work thing.

@cmer
Copy link
Author

cmer commented Jan 20, 2023

It should definitely stay installed. Are the files just getting deleted?

@greyshi
Copy link

greyshi commented Jan 20, 2023

Nice work on the repo. One option that I eventually want to add is a check to see if the current TV input is set to the mac's input before actually turning the TV off. This feature is on the windows LGTVCompanion app and avoids the TV turning off because your mac goes to sleep while you're on a different input.

I haven't had any issue with needing to reinstall anything. Could try changing the install method/location to see if that helps avoid whatever is removing it.

@tonycassara
Copy link

I'm taking it up with my IT department, yes the files get deleted and the library.

I also thought about checking the Input before switching, haven't had time to implement.

@cmer
Copy link
Author

cmer commented Jan 20, 2023

This is an amazing idea, @greyshi — I mostly use the TV as a monitor for my Mac, but can see how that’d be annoying.

I’ll try to see if I can whip this together. Or feel free to submit a PR!

@cmer
Copy link
Author

cmer commented Jan 20, 2023

Your wishes have been answered, @greyshi!

@greyshi
Copy link

greyshi commented Jan 21, 2023

Wow that was quick! Going to give it a try.

@Mike076
Copy link

Mike076 commented Jan 28, 2023

LG's latest C2 update requires SSL enabled. LGWebOSRemote dev has updated the code to support ssl, but now the Lua code needs to reflect "lgtv path command ssl" to pass commands to the TV.

@tonycassara
Copy link

I tried appending ssl to the commands in Lua and still not working for me... I will hopefully have time to play with it more later today.

@jmart987
Copy link

Wondering if I could get some help. I have installed Hmmerspoon & brew. I am reviewing the instructions to install LGWebOS (https://github.com/klattimer/LGWebOSRemote) but it says I have to have several other things installed (Requires wakeonlan, websocket for python (python3-websocket for python3), and getmac. python-pip (python3-pip for python3) and git are required for the installation process.). Is this correct? I'm not sure how to install all of these things on my Mac

@tonycassara
Copy link

@jmart987 have you seen the latest repo here? https://github.com/cmer/lg-tv-control-macos

hope that helps!

@jmart987
Copy link

@jmart987 have you seen the latest repo here? https://github.com/cmer/lg-tv-control-macos

hope that helps!

Appreciate that, I'm not sure if I had the latest repo. But how do I install lgtvcontrol from this?

Do I just put this in terminal after installing hammer spoon and brew?

mkdir -p ~/opt
python -m venv ~/opt/lgtv
cd ~/opt/lgtv
source bin/activate
pip install git+https://github.com/klattimer/LGWebOSRemote

When I do that nothing really happens. I get a zsh: command not found

@tonycassara
Copy link

@jmart987 try it one line at a time instead of copying and pasting the whole thing.

@Appzelof
Copy link

Appzelof commented Sep 21, 2023

@jmart987 have you seen the latest repo here? https://github.com/cmer/lg-tv-control-macos

hope that helps!

Works great! If you want to change inputs by using keyboard events/taps you could also add this in the .lua file ( I have this line at the top ) :

local control_inputs = true -- Switch inputs by events from keyboard

And then add this :

event = hs.eventtap.new({hs.eventtap.event.types.keyDown, hs.eventtap.event.types.systemDefined}, function(event)
    local type = event:getType()
    if type == hs.eventtap.event.types.keyDown then
      local keyCode = hs.keycodes.map[event:getKeyCode()]
        if keyCode == "f1" then
          exec_command("setInput HDMI_1")
        elseif keyCode == "f2" then
          exec_command("setInput HDMI_2")
        elseif keyCode == "f3" then
          exec_command("setInput HDMI_3")
        elseif keyCode == "f4" then
          exec_command("setInput HDMI_4")
        end
      end
end)

if control_inputs then
  event:start()
end

If you want other keys and not f1,2,3,4, just replace the strings with desired keys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment