Automatic Webcam Lighting with Elgato and Automator
Published Jan 16, 2026
#home-automation
Cheap ring light problems
Like many working in tech, I went fully remote at the outset of the COVID-19 pandemic, and my home turned into my office. It became apparent that looking presentable over a webcam meant having a good lighting setup. So, I bought a cheap ring light from Amazon, and for the first few years, it did the job.
But at the start and end of every meeting, I had to press this ugly plastic blue button to toggle the light on and off. Over time and lots of meetings, this got pretty annoying, so I attempted to automate it.
At first, I tried to make my ring light “smart” with a HomeKit-compatible plug. My goal was to use a shortcut to control the light’s power from the outlet, toggling it on whenever I was in a meeting. This dream was short-lived. Each time the light lost power, its limited chipset would reset; meaning that once the power was back, the light would always start in the off position. After testing a couple of other ring lights, this seemed to be the standard. If I wanted automation, a cheap ring light just wasn’t going to cut it.
I then searched for smarter (and more expensive) lights — eventually settling on an Elgato Key Light (the now discontinued Key Light Air). As a product, I was impressed by the Elgato’s build quality and software, but I was most excited to take advantage of its Wi-Fi capabilities. With the help of a Home Assistant plugin, I was able to successfully toggle the light using Apple’s HomeKit and Shortcuts. In just a couple of keystrokes, I could toggle the lights on and off whenever I need them.
This solution worked well at first. But like most IoT devices, it proved to be pretty slow, with a 2 or 3 second delay. Plus, it still required manual effort on my part to trigger it for meetings. I considered tweaking the Shortcut to be more automated, by using events on my calendar to trigger the light, but it felt like overkill. I don’t need my webcam for every event on my calendar, and I didn’t want my light on when I didn’t need it.
In the end, I wanted a simpler, more automated solution without ANY manual effort on my part. When my webcam turns on, turn the light on… when my webcam turns off, turn the light off. I quickly abandoned the Shortcut idea and focused on finding a more streamlined solution.
Sending commands to Elgato Lights
Since Apple nor Elgato provide user-friendly settings for this type of automation, I knew that I would need to get creative. After scouring search results and forum sites, I discovered that Elgato lights (both Key Lights and Light Strips) have API endpoints1 that can read and write to a device to set state, brightness, and temperature/color. By sending requests to: your device’s IP Address + port 9123, followed by /elgato/lights (example: http://192.168.X.X:9123/elgato/lights) you can use the command line to control your device.
Here’s how to test it. Download and open the Control Center app from Elgato on your Mac and make sure your light is ON. Locate the device in the Control Center UI and click the options button to the right of the device name. In the next view, your device’s IP address will be listed at the bottom.
Elgato makes it pretty easy to locate device IP addresses.
Next, copy the command below and paste it into a terminal window, but replace 192.168.X.X with your device’s IP Address. When ready, hit enter to send the request.
curl --location --request GET 'http://192.168.X.X:9123/elgato/lights'If entered correctly, it should return a JSON response that looks something like this (the “on” key has a value of 1 for ON, and 0 for OFF).
{"numberOfLights":1,"lights":[{"on":1,"brightness":10,"temperature":288}]}%Utilizing that same JSON format, you can also send PUT requests! Copy the request below and replace with your device’s IP address (plus the values for brightness and temperature) and submit the command again.
curl --location --request PUT 'http://192.168.X.X:9123/elgato/lights' \
--header 'Content-Type: application/json' --data '{
"numberOfLights": 1,
"lights": [
{
"on": 0,
"brightness": 10,
"temperature": 288
}
]
}'Your light should now be off. To toggle it back on, swap the 0 for 1 as the “on” value. Tweak the brightness and temperature/color to your liking.
Monitoring webcam events on macOS
I was fortunate that Elgato made their endpoints accessible, but for my ideal solution to work, I would need a way to track the status of my webcam on macOS. My expectations for this were low. For good reasons, Apple provides limited access to peripherals, and by their nature, webcams require an even stronger layer of permissions.
Luckily, in my search, I came across some like-minded folks who were trying to solve similar problems and are much smarter than me2. The answer lied in macOS’ event logs, which capture all types of activity on our machines. Using a particular shell command exec log stream --predicate, one can filter the log messages and flag key events as they happen.
For my use case, I discovered that I needed AVCaptureSessionDidStartRunningNotification for when the webcam starts running, and AVCaptureSessionDidStopRunningNotification for when the webcam stops running. The best part is that this event applies to any webcam (built-in or third-party), and should work with any application (Zoom, Google Meet, Microsoft Teams, etc.). As long as the system detects that a webcam’s activity, it should log these events.
To check for these events on your Mac, paste the following shell script into your terminal and hit enter. As you toggle your webcam on and off in Zoom, Photo Booth, etc., you should be able to see filtered messages streaming in your terminal window.
exec log stream --predicate 'process == "VDCAssistant" || (eventMessage CONTAINS "AVCaptureSessionDidStartRunningNotification" || eventMessage CONTAINS "AVCaptureSessionDidStopRunningNotification")'Putting it all together
With all of the pieces to the puzzle, I just needed a way to connect and automate them. I needed a lightweight shell script that:
-
Monitors macOS event logs to watch for when the webcam is toggled on or off
-
Filters the log messages to only the key data, specifically event phrases ‘Start’ or ‘Stop’
-
Use that key data to trigger the
curlrequests to the Key Light’s IP address for on and off -
And have it always running silently in the background, so that it works every time, without any user interaction
With all of this in mind, here’s the finished shell script:
exec log stream --predicate 'process == "VDCAssistant" || (eventMessage CONTAINS "AVCaptureSessionDidStartRunningNotification" || eventMessage CONTAINS "AVCaptureSessionDidStopRunningNotification")' |
/usr/bin/grep -vE --line-buffered '^Filter' |
tee /dev/stderr |
/usr/bin/sed -Eu 's/.*(Start|Stop).*/\1/' |
while read -r event; do
echo "Camera $event"
if [ "$event" = "Start" ]; then
echo "Light on"
curl --location --request PUT 'http://192.168.X.X:9123/elgato/lights' \
--header 'Content-Type: application/json' \
--data '{"numberOfLights":1, "lights":[{"on":1,"brightness":25,"temperature":250}]}' &
else
echo "Light off"
curl --location --request PUT 'http://192.168.X.X:9123/elgato/lights' \
--header 'Content-Type: application/json' \
--data '{"numberOfLights":1, "lights":[{"on":0,"brightness":25,"temperature":250}]}' &
fi
doneTry testing this in your terminal. Remember to edit both IP addresses to your light, and tweak the brightness and temperature values to your liking. As you turn your webcam on and off, your light should now respond accordingly!
As long as this shell script is running in your terminal, it should continue to work. But to make sure the script is always running in the background, I needed to set it up as an Automator app.
Run it with Automator
If you’re unfamiliar, Automator is a tool for Mac that allows for automation of repetitive tasks and deep control of the macOS system. Luckily, one of its capabilities is running shell scripts as apps in the background. The process for creating it is pretty straightforward.
On your Mac, launch Automator. You may initially see a dialog to open an existing file, but you’ll want to go to File > New to create a new document. Next, select Application as the type of document to create, then click Choose.
From there, you’ll see a library of different actions that are possible within Automator — but for this use case, you only need one action: Run Shell Script. Double-click or drag this item to add to the main panel. Make sure that Shell is set to /bin/bash and then simply paste your finished shell script that you tested before into the text field. This should be all you’ll need to run your app.
Before you save the app, it’s always good to test that it will run properly within Automator. Be sure to quit any previous terminal sessions that might still be running.
In the top right of the Automator UI, click Run. If the script is formatted correctly, you should see a log message below that it is now running. Once again, toggle your webcam on and off repeatedly — your light should respond accordingly. If the script doesn’t run or the light fails to respond, double-check that your shell script has the correct values for IP address, eventMessage, etc. and doesn’t include any bugs (you can test your script for bugs at shellcheck.net).
If you made it this far, then hopefully your test run was successful! From here, you’ll want to give your app a memorable name (e.g. Keylight.app) and then save it to your Applications folder. Quit the process in Automator if it’s still running. Find your newly created app, and double-click to launch it. You should now see a spinning gear icon in the menubar — your app is now running in the background!
Last step: let’s make sure the app always runs upon login. From the menu, launch System Settings and then navigate to General > Login Items & Extensions. Under the Open at Login section, click the + button, select your newly created app, and click Open.
You can test that this works by restarting your Mac
Congratulations 🎉 your lighting setup is now fully automated.
A few tips:
-
I recommend designating a
fixedorstaticIP address for your Elgato light(s). Default behavior for some routers is to make IP addressesdynamic, meaning that your Key Light’s IP address might change at any point and break your script. You should be able to configure the fixed IP address in your router’s settings. -
If you have multiple Key Lights/Light Strips, this solution should still work for you. In your finished script, add another
curlrequest for each device using their respective IP address — be sure to add them to both start and stop events, and change temperature to color as needed. -
With major macOS releases, Apple will sometimes modify the messages for logged events.
AVCaptureSessionDidStartRunningNotificationandAVCaptureSessionDidStopRunningNotificationworked as of macOS Sonoma 14.5 – Tahoe 26.2, but future software updates may break the script. -
I initially tried a more technical approach by running the shell script in the background as a LaunchDaemon based on this post from Jessica Deen. However, in my testing, the LaunchDaemon setup was less reliable than the Automator app and used more CPU.
-
Shell scripts can be finicky with certain characters and formatting, depending on your text editor. If your script fails to run, be sure to double-check that it is correct, or test for bugs in a tool like shellcheck.net.
-
If you use multiple apps like Zoom, Google Meet, Microsoft Teams, etc., it might be worth testing your webcam + light setup with each of them. I personally haven’t noticed any disparities, but haven’t tested every app.
Footnotes
-
Link to Elgato light API Github Repo ↩
-
Link to forum page on StackExchange ↩