Controlling Elgato Key Light with Hammerspoon

Here’s a quick automation that I’ve been hacking idly on for months: having my Elgato Key Air Light be automatically controlled from my Mac.

While perusing hammerspoon’s API, I noticed that it has a Bonjour API and wound up writing this snippet:

hs.bonjour.networkServices(function(t) print(hs.inspect(t)) end)

When I ran this in the Hammerspoon console, I saw a list of findable services including the Elgato light… so it was only a matter of time before I found the right commands. Thanks to this blog post I found some working TypeScript that I was eventually able to adapt after I had grokked more of Hammerspoon’s Bonjour implementation.

(It turns out that the Elgato Key runs an unsecured web server that takes HTTP requests in a very simple fashion. It’s kind of refreshing. Most of the code just finds the IP and port of the light, the rest sends the HTTP requests with a different JSON payload for on or off.)

I use this on and off switch when I enter and leave my meeting Headspace.

I quickly realized that my quick and dirty hack would turn on and off all lights on the same network with your laptop… so I decided to restrict the code to only when I’m plugged into my trusty CalDigit TS3+ dock:

IsDocked = function()
  return hs.fnutils.some(hs.usb.attachedDevices(), function(device)
    return device.productName == "CalDigit Thunderbolt 3 Audio"
  end)
end

That function returns true if my laptop is docked. In my meeting space automation I use something like:

if IsDocked() then
  spoon.ElgatoKey:off()
end

I pulled my naive implementation into a baby spoon library, so you can hack on it if you want.