Like a lot of people nowadays, I'm set up in a home office and I'm often on video calls on my MacBook Pro. My partner sometimes wants to come into my office, but doesn't want to interrupt a video call. We've got a Hue bulb in the landing outside my office, so I was wondering whether I could use that to show whether I'm on a call. Can I trigger a HomeKit scene based on whether my laptop's camera is turned on or off?

2 Answers 2


It doesn't seem possible to do this with HomeKit, but it is possible to make a script that communicates with IFTTT, and IFTTT will communicate with Hue directly. If you have a Hubitat hub or Home assistant that will also work as a webhook-in-the-middle.

I got through the first part easily: getting a push when camera is opened or closed. To detect camera on:

while true; do log stream | grep -o -m 1 "Post event kCameraStreamStop" > /dev/null && echo STOPPED; done

And camera off:

while true; do log stream | grep -o -m 1 "Post event kCameraStreamStart" > /dev/null && echo STARTED; done

These can be easily converted into a silent, single script that launches at startup. To communicate with the bulbs, we will replace "echo STARTED/STOPPED" with curl to an IFTTT webhook. So you need to make an IFTTT account (If you have used up more than one of your 3 free rules, create another account unless you're paying for premium already), and link up Hue with a webhook. Curl will call this webhook and set your hue bulb to whatever color, Kelvin, and brightness you want or turn it off. If you need more specific guidance then I can help you.

  • This answer mentions IFTTT working with Hue, but the question asks for HomeKit?
    – grg
    Commented Jul 28, 2021 at 20:48
  • Sorry for the vagueness, I don't think it's possible with home kit and needs a webhook to function, and communication with home kit is very hard (using Siri via terminal, which involves virtual keystrokes). To simplify things, I found that communicating with Hue through IFTTT instead of HomeKit works better Commented Jul 28, 2021 at 21:27

With the Shortcuts app and its shortcuts command line utility, it's now possible to trigger specific shortcuts that control your HomeKit scenes and accessories.

Overall steps

  1. Identify events for your triggers.
  2. Use the Shortcuts app to create shortcuts that trigger your desired HomeKit actions.
  3. Create a script that triggers shortcuts when the camera turns on/off.
  4. Run the script manually or automatically.

Identify events for your triggers

As of MacOS 12.1 Monterey, the Post event kCameraStreamStart and kCameraStreamStop events referenced in the answer by anonymous are no longer logged, but there are new equivalents. It's likely that the event logs may change over time, so first check that these are still correct.

In Terminal, run this to filter the logs to the expected messages as of Monterey:

log stream | /usr/bin/grep -E 'UVCAssistant:.*(stop|start) stream'

While that's running, open the Photo Booth app. You'll hopefully see lines like these output from the filtered log stream when the camera starts and stops (when you quit the app).

2022-01-04 14:56:58.628006-0500 0xb35b3    Default     0x18025b             266    0    UVCAssistant: (UVCFamily) [com.apple.UVCFamily:device] UVCUSBDeviceStreamingInterface: 0x1000005a6 [0x7fcd7bd08260] [start stream] format : UVCDeviceStreamFormat:[1280 * 720 (YUV420_420v)] [0x7fcd7bd08e90] [subtype 4] frameInterval : 333333
2022-01-04 14:57:31.179027-0500 0xb2227    Default     0x1803a4             266    0    UVCAssistant: (UVCFamily) [com.apple.UVCFamily:device] UVCUSBDeviceStreamingInterface: 0x1000005a6 [0x7fcd7bd08260] [stop stream] format : UVCDeviceStreamFormat:[1280 * 720 (YUV420_420v)] [0x7fcd7bd08e90] [subtype 4] frameInterval : 333333

If you get output, you're done with this step and can use the the regular expression matchers I provide in the next steps.

If you get no output, you'll need to broaden the filter to search for event logs that appear when the camera starts and stops. This might be a good starting place:

log stream | /usr/bin/grep -iE 'UVCAssistant|camera|stream|tccd'

Ensure the events you choose are emitted for any camera use (e.g. Zoom, Meet), not just PhotoBooth.

You'll need to come up with a regular expression for grep that matches only when your camera is toggled on or off. If you have multiple cameras, you may also want to test switching between cameras.

Create Shortcuts to trigger HomeKit actions

First, confirm that you're able to use the Home app on your Mac to trigger changes to whatever accessories or scenes you're interested in.

In the Shortcuts app, create a new shortcut (+ button). For toggling a light, you'll need a separate shortcut for each state (e.g. on/off). Give the shortcut a name such as Turn on lamp.

For each shortcut, select the Home app and add its Control <home name> action to your shortcut (drag or double-click). Select the specific scene or accessory you want to control, and select a state for you to set it to when the shortcut runs.

shortcut configuration

When complete, you should see your shortcuts in your shortcuts list and be able to run them and trigger your expected behavior.

both shortcuts

Last, confirm that you can trigger these successfully via the Terminal command line:

shortcuts run 'Turn on lamp'
shortcuts run 'Turn off lamp'

Trigger shortcuts on camera state

Create a script file (e.g. camera-lamp.sh) that, while running, will toggle your light based on whether the camera is running. A starter example:

exec log stream |
  /usr/bin/grep -E --line-buffered 'UVCAssistant:.*(stop|start) stream' | # filter log events
  tee /dev/stderr |                           # output matching events for debugging
  /usr/bin/sed -Eu 's/.*(start|stop).*/\1/' | # reduce the log message down to a single word identifying the event/state
  while read -r event; do                     # store that word in the $event variable
    echo "Camera $event"
    if [ "$event" = "start" ]; then
      echo "Lamp on"
      shortcuts run 'Desk lamp on' &
      echo "Lamp off"
      shortcuts run 'Desk lamp off' &

Replace my shortcut names Desk lamp on and Desk lamp off with your own, if different. Feel free to alter messages like "Lamp on" to fit your scenario.

If you needed to choose a different filter in step 1:

  1. replace the grep regular expression with one that matches both your camera on and camera off event log messages,
  2. replace the sed substitution regular expression with one that matches the equivalent word that indicates the camera state, and
  3. if that word is not start when the camera turns on, update the if conditional that matches the start word.

Run the script

Run the script, and test it out. If you named it camera-lamp.sh, run

bash camera-lamp.sh

While the script is running, your HomeKit shortcuts should trigger whenever your camera turns on or off.

Optional steps:

  • Once the script is stable, run it in the background, and close the terminal.

    bash camera-lamp.sh &
  • Drop the extension, make the file executable, and relocate it to /usr/local/bin or elsewhere in your $PATH, so you can just run camera-lamp as a command.

  • Find a way to run the script in the background as a daemon on login. How to accomplish this is beyond the scope of this answer. Importantly though, this cannot run as a launchctl daemon, as these daemons cannot run shortcuts due to Error: Couldn’t communicate with a helper application. If you find a good approach, feel free to comment.


If you use log's internal filtering instead of grep, CPU usage will decrease, per @alloy's comment.

exec log stream --predicate 'process == "UVCAssistant" && (eventMessage CONTAINS "start stream" || eventMessage CONTAINS "Stop Stream")' |
  /usr/bin/grep -vE --line-buffered '^Filter' | # filter out the informational output at launch
  tee /dev/stderr |                             # output matching events for debugging
  /usr/bin/sed -Eu 's/.*(start|stop).*/\1/' |   # reduce the log message down to a single word identifying the event/state
  while read -r event; do                       # store that word in the $event variable
    echo "Camera $event"
    if [ "$event" = "start" ]; then
      echo "Lamp on"
      shortcuts run 'Desk lamp on' &
      echo "Lamp off"
      shortcuts run 'Desk lamp off' &

See https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html for log's predicate syntax.

  • Running in the background is doable via a user LaunchAgent. Create a new plist file in ~/Library/LaunchAgents and configure it to run the script. I would post the contents of the file here, but comments do not allow block code.
    – Sean256
    Commented Sep 23, 2022 at 16:35
  • 2
    You should look at using log's own abilities to filter, rather than piping all output to grep. This example—which uses my iPhone as webcam—reduced CPU usage from 7% to 0% when idle, for me: log stream --predicate 'process == "ContinuityCaptureAgent" && type == userActionEvent && (eventMessage ENDSWITH "start]" || eventMessage ENDSWITH "stop]")'.
    – alloy
    Commented Jan 10, 2023 at 15:01
  • @alloy Excellent suggestion. I've added an addendum to my answer with your suggestion. Commented Jan 11, 2023 at 17:27
  • I edited your answer to include the new predicate for macOS Sonoma (14.2), which was released in 2023, and I also wrote down some new test cases for future readers. I hope this helps
    – Roger Oba
    Commented Jan 12 at 10:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .