Rumkee.me A Dev Manager's Perspective

Teams Status Tally Light, Part 2: From Concept to Creation

Technical illustration of the finished Raspberry Pi tally light hardware with its custom fan-control HAT, LED strip and large desk fan.
What better for the best fan ever than to have its own API, right? Plate I
Prototype circuit board, finished Raspberry Pi and green custom HAT with a small Noctua fan, LED strip and wiring, plus a spare bare PCB laid on grey carpet.
Fig. 1

The Backstory continued...

In Part 1, I documented the creation of the hardware module, and it's connection to the Raspberry Pi, along with the software running on the Pi. In this part, we'll add some additional features, make a significant hardware revision and finally bring it all together with integration toMicrosoft Teams.

The Hardware Part 2

I was a little frustrated with the cooling fan control that I had added. Sometimes the Pi felt hot, and other times, not so much, since the fan just had direct power from the circuit board, meaning it would run at a fixed speed proportional to the resistor. It occurred to me that I could use all the same code and circuitry to set the fan speed dynamically that I currently use to set the led brightness. I would just need another MOSFET, and since the fan is 12v, just like the LED strips, I would not need another buck converter.

I also saw an opportunity for some good old-fashioned scope creep and thought, why stop at one fan when I could control two? I had an Idea. A fair while ago, feeling frustrated with cruddy 5v USB fans, I decided to put together a nice powerful but quiet fan for colling myself - surprisingly, sitting next to an 18U rack of computer equipment, as I do, can get quite hot. Who knew? So I was in need of a fan and ideally something quiet.

Brown Noctua 120mm fan held in a black 3D-printed laminar-flow housing and stand on top of a computer.
A Noctua NF-A12x25 120mm fan - held in a 3d printed holder Fig. 2

This fan makes for a silent and powerful laminar airflow fan, the 'best fan ever' - yes, I'm looking at you, Dyson! What better for the best fan ever than to have its own API, right? At this point, I might as well since it's trivial extra effort on top of what I've already completed and would give me variable control to dial in just the right strength I wanted.

So altogether, I have two additional PWM signals needed for the fans, and I also wasn't happy with the PI cooling fan just kind of hanging out there, not afixed to anything. That's when I decided to go all in. In the past, I have had Chinese fabs create PCBs to my specification, and it's not as complicated as you might imagine. Design your PCB, then send the design files to anyone of a number of Chinese companies, and they'll print you out a real PCB along with thousands of other small batch PCB's and send them in the post. This levels up the reliability of the circuit and will certainly make it neater as all the wires are replaced with traces in the board. It is also possible to shrink the size of the PCB relative to a prototype since you can use SMD - surface mount devices - which are tiny, in place of the larger through-hole components used in breadboards at the expense of needing more expertise and equipment to make it work, although in this case, I'll stick with through-hole components - the same as I have on the perma-proto board as I have plenty of spares to use.

I used an online PCB Design tool called EasyEDA

EasyEDA board layout showing the central fan opening, component footprints, two LED outputs and two fan outputs.
schematic of the circuit board designed in EasyEDA Fig. 3
EasyEDA 3D render of the square green PiLED HAT PCB with a central fan opening and labelled connector positions.
3D render of the circuit board Fig. 4

After about a week of following a fedex delivery around the world, I received the manufactured PCB (in fact 5 of them since that's the smallest quantity to order)

Bare square green PiLED HAT circuit board on grey carpet, with a large central fan opening and white component markings.
Circuit board freshly delivered from China. Fig. 5
Populated green PiLED HAT mounted on a Raspberry Pi, with white connectors, a voltage converter, capacitor and five metal power devices.
(Looking past the mediocre soldering) The final populated circuit board in place on the Pi. Fig. 6

The Software Part 2

After some coffee drinking and debugging, that actually seems to work great. I can create any colour I like by hitting that endpoint. As I said, though, in Part 1, I want to be linked up to my Microsoft Teams status so I don't have to concern myself with manually setting the appropriate status colour. Microsoft does have a graph API which does allow for querying of teams' status. There are some complications around authentication that are problematic, though, but fortunately for us.....

Microsoft Teams Local API !

The good people at Microsoft read my mind and conveniently announced the release of a local API for teams, precisely what I wanted, and then promptly pulled it 24hrs later due to a security bug!

About a month later, it reappeared, and with a little under-the-hood investigation, it was clear that this takes the form of a simple local WebSocket which relays small JSON objects back and forth.

Developer-tools view of the JSON object used to query the Microsoft Teams meeting state.
query status Fig. 7
Developer-tools view of a JSON response containing the Microsoft Teams meeting state and permissions.
receive status Fig. 8

As we can see, it's easy enough to query for the current meeting status, and we can receive responses pushed back to us from teams when our meeting status changes. We just need to establish a connection to the WebSocket, knowing the machine address, the relevant port, and a token issued from the new Teams setting's menu - so teams' knows it's us asking.

Data-flow diagram from Teams on a laptop, through Python and HTTP on a Raspberry Pi, to PWM-controlled LED strips and a fan.
Diagram showing data flow. Fig. 9
Animated demonstration of an LED strip above the Teams window changing from green to red during a call and back to green afterwards.
Fig. 10

In the short clip above, we can see the LED strip alongside my Teams status. I briefly join a call and then drop off the call. You can see the LED's status changes to red during the meeting and back to green after I leave. In fact, the LEDs update much quicker than Teams itself!

Conclusion

In part 2, we've delved deeper into improving the Tally light system by refining the hardware, adding fan control, and integrating the system with Microsoft Teams. We've covered the process of setting up the Raspberry Pi to control the LEDs and fans remotely, as well as explored the local Microsoft Teams API to synchronize the system with your meeting status. With the combination of hardware improvements and software integration, we've created a even more versatile and powerful Tally light system. As usual you can find both of the Python scripts and the PCB design files on my GitHub page.

But wait, there's more!

If you've seen my other blog Stream Deck: My Secret Productivity Tool you'll know I'm a big fan of the Elgato Stream Deck, which is a macro pad where each button is an actual physical button with an LED screen in it.

This tool is very versatile, and one of the plug-ins for it allows for a button press to be configured to make an API call.

This gives the potential to have a manual override for the LED lights and to control the fan from this one device!

Stream Deck configuration software showing four buttons and an API Ninja GET request for decreasing the large fan speed.
Screen shot from Streak Deck software Fig. 11

Above, we can see the stream deck configuration application with 4 configured buttons, and we can see the lower button with the fan icon is set to make a GET to

http://192.168.1.101:5003/bigfan?decrement=32

The fan icon above it is set to make the same call with the parameter ?increment=32. This way each button press steps us or down the fan speed in 1/8th increments.

The red and green buttons make a call to the same API endpoint shown in part 1, so force the LED's to a specific colour.

Animated demonstration of a Stream Deck button toggling the large desk fan on and off.
Gif showing Stream Deck making API call to toggle fan on and off Fig. 12
Animated demonstration of Stream Deck buttons overriding the Teams-status LED strip to red, green and back to red.
Gif showing Stream Deck overriding the teams status LED to red, then green and back to red. Fig. 13