I thought it would be interesting, and incredibly useful, to build a device that displays a visual cue when my laptops webcam is turned on. I work from home and I’m in a large amount of video meetings either on Zoom or Google Meet. This handy device helps others in the household know when I’m on a video call without needing to see the screen.

GitHub Repository containing full code

I based my work largely on another great tutorial I found here on medium:


The principle is the same, but things are a bit updated and expanded. I needed this to work on both my MacBook and my Linux laptop.


  1. ESP32 microcontroller
  2. Neopixel LED strip
  3. Wooden box
  4. Translucent Plexiglass (3mm)
  5. Micro USB cord
  6. Mosquitto Broker Server

Mosquitto Server:

The original tutorial utilizes an Arduino to run the broker. However, Arduinos are currently like gold because of the chip shortage and are both hard and expensive to find. Since I already have a server at home running TrueNAS, I spun up a broker server there from the community repository.

Checking the camera (Linux):

I’m sure there may be a more efficient way to write this, but I created a quick bash script that checks for a 1 or 0 on the uncvideo output under lsmod.

camera_on=$(lsmod | awk '{print $1,$3}' | grep uvcvideo | awk '{if ($2 == 1) print "true"; else print "false";}')

Once the camera turns on, I publish a message to the broker with the JSON displaying 1 for onair.

mosquitto_pub --topic sensor/camera/laptop -h --message "{\"onair\": 1}"

I setup the script (full code below) to run in a cron job on reboot, continuously checking for the status of the camera.

#!/usr/bin/env bash
echo 'Running Script'

while :

  until [ $camera_on = true ]
    camera_on=$(lsmod | awk '{print $1,$3}' | grep uvcvideo | awk '{if ($2 == 1) print "true"; else print "false";}')
    sleep 2

  mosquitto_pub --topic sensor/camera/laptop -h --message "{\"onair\": 1}"

  until [ $camera_on = false ]
    camera_on=$(lsmod | awk '{print $1,$3}' | grep uvcvideo | awk '{if ($2 == 1) print "true"; else print "false";}')
    sleep 2

  mosquitto_pub --topic sensor/camera/laptop -h --message "{\"onair\": 0}"


Checking the camera (MacOS):

The original tutorial utilizes a slightly different check in the log stream. In my version of MacOS, the kCameraStreamStart event simply wasn’t in the logs – so I set out to find what I could utilize.

For my OS – I found the proper log message being displayed for on and off under appleh13camerad. I’m not sure how future-proof this may be, but it works for now.

log stream | grep "ISP_PowerOnCamera: powered on camera"

log stream | grep "PowerOffCamera : ISP_PowerOffCamera"

With that knowledge I edited to the final script below and setup a ‘Run Shell Script’ task in Automator to run at login.

log stream | awk '
                    /ISP_PowerOnCamera: powered on camera/  { system("/opt/homebrew/bin/mosquitto_pub --topic sensor/camera/laptop -h --message \"{ \\\"onair\\\": 1 }\"") }
                    /PowerOffCamera : ISP_PowerOffCamera/   { system("/opt/homebrew/bin/mosquitto_pub --topic sensor/camera/laptop -h --message \"{ \\\"onair\\\": 0 }\"") }'

Arduino Source Code

The source code has been modified slightly from the original. The loop will continually check for WIFI and Moquitto connections. If WIFI is lost/connecting then the box will glow Yellow, and if the Mosquitto Broker connection is lost/connecting then the box will glow Blue. The box glows red when the camera turns on.

Project Box Build

The build was straight forward. I found a hollow wooden cube at a craft store and cut it open, drilling out a window and filing until it was smooth. Then I found some 3mm Acrylic/Plexiglass from Amazon that was translucent and cut to shape.