February 19, 2020

522 words 3 mins read

Introducing pyLegLight – A Python module for the Elgato Key Lights

At work, I’ve been spending more time on video calls with our Eastern European office. In order for it to be a reasonable time of day for the team, my calls are either very early in the morning or very late at night. To make sure that both sides get the most out of the limited time we have in the calls, I want the call quality to be the highest possible. That means a clean background, a Logitech C920S HD Pro Webcam and lighting — specifically two Elgato Key Light panels. The panels work super well, perhaps I’ll review them another time, but my first interest was how I can control these lights (which operate over wifi) in a programmatic fashion. Queue some basic reverse engineering and Python — Enter pyLegLight!

The lights work over wifi and have control software on mobile (Android/iOS) and Desktop (Windows/Mac). Before I could implement my own remote control tools, there were two major questions I had to answer: How are the lights detected by the controller, and how do you actually tell it to make a change? To answer these I fired up Wireshark on my desktop and used that platform’s Elgato “Control Center” software. Once I had isolated the IP addresses of the lights on my network, the “reverse engineering” work was quick and trivial.

For question #1 — How are the lights detected? In a way many, many devices communicate local discovery information: mDNS (aka Zeroconf, aka Bonjour). My desktop sends a network broadcast asking, “Who’s on first _elg._tcp.local.?” And the lights answer directly, easy as that.

As for question #2 — We live in a time where there are easy to use “standards”. If this was some sort of SaaS product you’d, of course, expect to use a JSON REST API. While that isn’t the case, these lights are running what I’m fairly confident is an ESP32 chipset. That chip can support an HTTP server and, in this case, Elgato chose exactly that. All the control of the lights is done via HTTP GET/POST/PUT. Piece of cake.

With the answers in hand I got to work on code that became pyLegLight. Part of the side-benefit of this adventure was learning new python-adjacent skills. First was creating a proper Python package — in the past I’ve only developed stand-alone applications or scripts. Second, of course, was publishing that new package on PyPi. Last was generating API documentation that works with ReadTheDocs.

How do you use this package? Just a couple easy steps!

  • python3 -m pip install leglight
  • python3
    >>> import leglight
    >>> myLight = leglight.LegLight('',9123)
    >>> myLight.on()
    >>> myLight.brightness(14)
    >>> myLight.color(3500)
    >>> myLight.off()

More examples (including autodiscovery) are available on GitLab. The current Elgato Key Lights are simple to control, so my Python API is similarly simple. I do plan to add some new features, like proper testing, but the Package is totally functional as is. However, should you find any issues, I’d really appreciate an issue or merge request be filed. Last, if you find this module useful, let me know ShakataGaNai, it helps inspire me to keep working on the project!