After getting buy-in from my officemates, I began work on the proof of concept. Since IT dept had not yet blessed me hooking this box into their systems, I wanted to go cheap and quick for the PoC. I bought some inexpensive RGB LEDs that looked bright enough and flat enough to easily mount behind the name plates, sacrificed an old PC parallel port header for the ribbon cable, and wrote some VERY quick and dirty Python. Pidgin is a free IM client that, with the right plugins, can work with Microsoft OCS. The Pidgin project provides a console/ncurses client called Finch. I knew that I could use their library, libpurple, but I was much more familiar with using DBus and finch, so that's what I used at first. It was ugly but completely functional, like the best and worst of hacks.
The hardware is the easy part, of course - I used the RPI's GPIO and power pins and 8 NPN transistors. Why only 8? Because the colors I require, Red, Amber, and Green, only require two colors on each RGB LED. I played with resistor choices until I found a good pairing of red and green for a pleasing amber; if you do this yourself, you will need to find your own preferred values to match your LEDs and your aesthetic wishes.
The LEDs are mounted in some leftover perfboard, the only piece I had that was long enough to cover all 4 nameplates. I positioned the LEDs to fit behind silver dots on our nameplates, resulting in an indirect backlighting. It's not perfect, but it's very visible without being too bright. Magnets, washers, and double-sided tape hold the LED board to the glass, and the box itself is held to the wall with 3M Command velcro strips.
Once I had the blessing of IT, I replaced the software with a program written in C++ using libpurple from Pidgin. The people and server credentials are hardcoded, but it rarely changes. It's fun to watch the LEDs dim when I compile.
Problems encountered:
1. OCS does not share 'location' value, so when we work remotely we still show up as green.
2. Lync for Mac does not recognize the screen lock, so user must depend on idle timeout for status changes.