Some people at my workplace have these little USB IM status lights at their cubicle to let others in the area know if they are busy, available, etc. There is accompanying software which monitors the current status set on their instant messaging (IM) client and configures the LED on the device to emit a color which corresponds to the status: green for available, red for busy, and so on.

Wireshark

Today a friend gave me one of these devices, and I wanted to see if I could hack it somehow to do more interesting and useful things than just relaying my IM status. Mainly, I wanted the ability to control the color of the light using my own software.

My first step was to see how the OEM software talks to the device to change the color emitted by the LED. As it’s Windows/macOS only, I installed the software on a Windows 7 VM, running on VirtualBox, on an Ubuntu system, and used USB pass-thru to let the OEM software do its thing with the device.

Back on my Linux host system, I ran lsusb to determine some basic details about the device.

$ lsusb
Bus 003 Device 012: ID 0e53:2516

Next, I fired up Wireshark (on the Linux host system) to observe the USB traffic between the OEM control software and the USB device (found at Bus 3, Device 12 as indicated by lsusb). I changed the status in my Windows IM client several times and captured the corresponding packets sent to the device.

Wireshark

It turned out that changing my IM status resulted in a series of simple control packets being sent to the device. For all of these packets, the control packet Request Type was 0x21, Request was 0x09, Value was 0x0200, Index was 0x0, and Length was 0x8. The 8-byte data payload portions of the packets sent to the device were as follows. Each line corresponds to the data payload of the next subsequent packet.

For “Available” status (green):

ff 00 00 00 00 00 ff ff
ff 00 00 00 00 00 ff ff
ff 00 00 00 00 00 ff ff
00 00 00 00 00 00 ff ff
00 00 96 00 00 00 ff ff
00 00 96 00 00 00 ff ff

For “Busy” status (red):

00 00 96 00 00 00 ff ff
00 00 96 00 00 00 ff ff
00 00 96 00 00 00 ff ff
ff 00 96 00 00 00 ff ff
ff 00 00 00 00 00 ff ff
ff 00 00 00 00 00 ff ff

For “Do Not Disturb” status (purple):

ff 00 00 00 00 00 ff ff
ff 00 00 00 00 00 ff ff
ff 00 00 00 00 00 ff ff
80 00 00 00 00 00 ff ff
80 00 00 00 00 00 ff ff
80 80 00 00 00 00 ff ff

For “Be Right Back” status (yellow):

80 80 00 00 00 00 ff ff
80 80 00 00 00 00 ff ff
80 80 00 00 00 00 ff ff
ff 80 00 00 00 00 ff ff
ff 80 3c 00 00 00 ff ff
ff 00 3c 00 00 00 ff ff

For “Offline” status (LED off):

ff 00 3c 00 00 00 ff ff
ff 00 3c 00 00 00 ff ff
ff 00 3c 01 00 00 ff ff

Next I cooked up a simple controller script in Python using PyUSB which would replay these data back to the device, and voila: it worked! I could now set the color on the device to the colors used for the IM client status.

I figured this device probably supported arbitrary RBG colors, so I started modifying the bits that were different between these packets to see where the color information is stored.

After some experimentation, it was apparent that first three bytes contain the red, blue, and green intensities, respectively. Now by crafting custom packets, the device supports any 24-bit RBG color! Well, that was easy.

Side note: For some reason, the OEM software sends multiple packets to the device when changing the color. I experimented with sending just one packet, and it seems to work fine.

Finally, I cleaned up and added some features to my demo script such as color cycling, color pulsing, and solid color setting. Now the Blynclight can be trivially scripted to indicate anything you can think of. Some ideas: alerts, weather, unread e-mails, etc.

You can find the source and instructions on how to get started over at GitHub. Let me know in the comments below if you come up with anything good.

Happy hacking.