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.
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
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.