The world has changed a lot in the last few months. Personally I've been very lucky that my job can be carried out entirely remotely and so I've been working from home full time since early March. I don't expect we'll be going back to the office for quite a while. There's no real reason for us to go back, so there's not much incentive to risk returning to the office.

That means I've been working out of my apartment for the last few months, and I've completely taken over our spare room with my desk.

I spend much of my time on Webex Teams video calls during the day. Since the door to my makeshift office opens up behind me, I wanted a way to signal to others in the house that I'm on a call to cut down on unexpected visitors during work calls. I also wanted a project to help fill some time while the world was on pause due to Covid-19.

Hardware

I've never had a use for a Raspberry Pi Zero, but was always really impressed with the level of functionality you get for a tiny price tag, especially the W version with built in WiFI. I figured it would be a good time to give one a try. I picked up the following parts from The Pi Hut;

Construction was very straightforward, just requiring a bit of header soldering, and pretty soon I had the nifty little device below. I'm blaming the terrible solder joints on my cheap soldering iron.

Hardware done, now for software.

Raspberry Pi

Firstly I got Raspberry Pi OS set up headlessly by modifying a couple of files on the SD card to have it automatically bring up SSH, and connect to my wifi network.

Pimoroni provides excellent instructions for getting started with the pHAT and pretty soon I was up and running with the examples and making the pHAT light up with all sorts of colours and patterns.

Webex Teams API

Webex Teams provides a straightforward API for getting your current status, and returns simple responses like "meeting", or "active". The website is also really handy since it lets you play with the APIs directly from the site itself when you're signed in. So I used python to write a script that queries the Webex people API periodically, and sets the colour of the status light to different values depending on what status it sees.

Currently I'm using the following statuses;

Green = Active
Red = On a video call or Do Not Disturb
Rainbow = Inactive

I get the value from Webex Teams using the python requests library like so;

import requests

url = "https://api.ciscospark.com/v1/people/<your user id>"
headers = { "Authorization": "Bearer <your API token>" } 

response = (requests.get(url, headers = headers).json())
status = response['status']
Webex Teams status API check

This should respond with your current status.

However, if we do this, the request locks up the script while it waits for the response from the API, which means that if you want to use dynamic displays on the pHAT, like the 'Rainbow' effect, it will freeze while it waits for the request to return.

So, we can implement the API check in a thread instead, and just periodically check the returned value to see if we need to change the display.


import threading

class StatusThread(threading.Thread):
    def __init__(self,url,headers):
        threading.Thread.__init__(self)
        #Initiate the thread variables
        self.url = url
        self.headers = headers
        self.running = False
        self.status = "Start"

    def run(self):
        while True:
            try:
                response = (requests.get(self.url, headers=self.headers).json())
                self.status = response['status']
                #Let's sleep the thread for 30 seconds before we check again
                time.sleep(30)
            except:
                print ("Exception occurred = ", sys.exc_info()[0])
                print ("Status is now = ", self.status)
Threaded Webex status API check

This way we can initiate the thread, and go off and do what we like and the status will continue to update in the background by checking the threading object variable. I know I'm using except too broadly here, but I'm not too worried about catching specific errors for a project like this.


# Create and start thread object
wxt_status_thread = StatusThread(url, headers)
wxt_status_thread.start()

# Access the status variable from the thread.
print wxt_status_thread.status

Start thread and access the current status

Now it's a simple case of using the sample code from the Pimoroni page above to display whatever colour we like on the Pi.

import unicornhat as uh

uh.brightness(0.5)
uh.set_layout(uh.PHAT)

for x in range(8):
	for y in range(8):
    	uh.set_pixel(x,y, 255, 0, 0)
    uh.show()
Show fully red unicorn pHAT

This has been working away nicely for the last couple of months and I'm very happy with it. The nice thing is that it's also just a Raspberry Pi sitting on my network, so I can use it for other projects too, instead of just being a single purpose status light like you'd buy off the shelf.