Skip to content

Instantly share code, notes, and snippets.

@ppdms
Created March 22, 2025 20:49
Show Gist options
  • Select an option

  • Save ppdms/38450a2ee6c28e15b41b96b709e47b34 to your computer and use it in GitHub Desktop.

Select an option

Save ppdms/38450a2ee6c28e15b41b96b709e47b34 to your computer and use it in GitHub Desktop.
.hammerspoon/init.lua
local ha_token = "" -- Home Assistant API token
local lg_display_name = "LG HDR 4K" -- External monitor name
local internal_display_uuid = "" -- Internal display UUID
local ha_url = "http://X:8123/api/services/light/turn_" -- Home Assistant API base URL
local light_entity = "light.screen" -- Replace with your actual entity ID
local last_state = false -- Track monitor connection
local locked = false -- Track screen lock state
local previous_brightness = 1 -- Default brightness before dimming
local lid_closed = false -- Track if lid is closed
function callHomeAssistant(action)
local cmd = string.format(
"curl -X POST -H 'Authorization: Bearer %s' -H 'Content-Type: application/json' -d '{\"entity_id\": \"%s\"}' '%s%s'",
ha_token, light_entity, ha_url, action
)
os.execute(cmd)
end
function getCurrentBrightness()
local handle = io.popen("curl -s 'http://localhost:55777/get?UUID="..internal_display_uuid.."&brightness'")
local result = handle:read("*a")
handle:close()
return tonumber(result)
end
function setBrightness(value)
os.execute("curl -s 'http://localhost:55777/set?UUID="..internal_display_uuid.."&brightness="..value.."'")
end
function enforceBrightnessRules()
local screens = hs.screen.allScreens()
local lg_connected = false
for _, screen in ipairs(screens) do
if screen:name() == lg_display_name then
lg_connected = true
break
end
end
if lg_connected then
if previous_brightness == nil then
previous_brightness = getCurrentBrightness() or 1
end
hs.timer.doAfter(0.5, function() setBrightness(0) end)
else
if previous_brightness then
setBrightness(previous_brightness)
previous_brightness = nil
end
end
return lg_connected
end
function checkMonitorState()
local screens = hs.screen.allScreens()
local lg_connected = false
for _, screen in ipairs(screens) do
if screen:name() == lg_display_name then
lg_connected = true
break
end
end
if lg_connected and not last_state then
if not locked then
callHomeAssistant("on")
end
enforceBrightnessRules()
elseif not lg_connected and last_state then
callHomeAssistant("off")
if previous_brightness then
setBrightness(previous_brightness)
previous_brightness = nil
end
end
last_state = lg_connected
end
function handleSystemEvent(event)
if event == hs.caffeinate.watcher.systemWillSleep or event == hs.caffeinate.watcher.systemWillPowerOff then
locked = true
callHomeAssistant("off")
elseif event == hs.caffeinate.watcher.systemDidWake or event == hs.caffeinate.watcher.screensDidWake then
locked = false
hs.timer.doAfter(1, function()
if enforceBrightnessRules() and not locked then
callHomeAssistant("on")
end
end)
elseif event == hs.caffeinate.watcher.screensDidLock then
locked = true
callHomeAssistant("off")
elseif event == hs.caffeinate.watcher.screensDidUnlock then
locked = false
if last_state then
callHomeAssistant("on")
enforceBrightnessRules()
end
elseif event == hs.caffeinate.watcher.screensaverDidStart then
callHomeAssistant("off")
elseif event == hs.caffeinate.watcher.screensaverDidStop then
if last_state and not locked then
callHomeAssistant("on")
end
elseif event == hs.caffeinate.watcher.lidDidClose then
lid_closed = true
if last_state then
enforceBrightnessRules()
end
elseif event == hs.caffeinate.watcher.lidDidOpen then
lid_closed = false
hs.timer.doAfter(0.5, function()
enforceBrightnessRules()
hs.timer.doAfter(1, enforceBrightnessRules)
hs.timer.doAfter(2, enforceBrightnessRules)
end)
end
end
-- Make watchers global so they won't be garbage-collected
displayWatcher = hs.screen.watcher.new(function()
checkMonitorState()
if last_state then
enforceBrightnessRules()
hs.timer.doAfter(0.5, enforceBrightnessRules)
hs.timer.doAfter(1.5, enforceBrightnessRules)
end
end)
displayWatcher:start()
caffeinateWatcher = hs.caffeinate.watcher.new(handleSystemEvent)
caffeinateWatcher:start()
brightnessEnforcer = hs.timer.new(5, function()
if last_state then
enforceBrightnessRules()
end
end)
brightnessEnforcer:start()
checkMonitorState()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment