For a long time, I thought about a great use case for a raspberry pi. Beginning of 2021 I found a great article of Elio Struyf on how he created such a light. I thought: “I want one of those! This is a great use case to get my first raspberry pi.”. So that’s when I decided to create a Teams status indicator light of my own.
Unfortunately, his setup and approach weren’t usable for me. In the following blog post, I will explain my setup and show step by step how one could create its own status indicator light.
My goal was to create some kind of indicator I could have outside of my room so that my wife and son know when I am in a meeting and therefore unavailable. It should show when my teams status is changed to “Busy”.
Not that I in that case close the door anyway. So it might be that it is more for me to test new things out.
First things first. I had to order the hardware. I bought the following stuff:
Pimoroni is sending from the UK. My delivery to Sweden took nearly 2 months. I do assume the issue is that the UK isn’t in the EU any longer. Therefore the package went through Swedish customs which isn’t very fast. Please calculate some delivery time.
Since I don’t have any other Raspberry Pi (at the moment) I wanted to have my solution completely on the one Raspberry Pi I ordered to implement this.
Since I am way more familiar with NodeJs than Python I tried to implement as much as possible in NodeJs. Actually, I was able to do everything in it and not use Python at all.
Basically, I created a NodeJs application using TypeScript which runs on a cron schedule. It then polls the Graph API for the user’s Teams presence and changes the LED colour accordingly. Since there is no possibility of the user logging in on the Raspberry Pi I use the Device Code flow of Microsoft Authentication Library (MSAL). The Application is able to send an email with the code to a given email adress, the user can then login there.
You can find the code to the Application on my GitHub.
I will create a separate blog post dedicated to the described application soon. For now, we just have to use it as is.
With this setup the Raspberry Pi can be used self-sufficient and just needs the power supply.
So enough with the chit chat. Let’s get into the real fun and create a Teams status indicator light.
Basic Raspberry Pi setup
First of all we have to do the basic setup of our Raspberry Pi. Since it will be self-sufficient and to save resources I would like to have a “headless” installation. This means that there is no graphical UI and we have to connect to the Raspberry Pi via SSH.
I followed, more or less, this tutorial. I will describe the process here as well.
To “burn” the image to the SD Card I used “Raspberry Pi Imager“. The first thing is to choose the right Operating System. To do so we click on “CHOOSE OS”, select “Raspberry Pi OS (other)” and then “Raspberry Pi OS Lite (32-bit)”.
Next step would be to choose the correct SD card (which should be inserted) by clicking “CHOOSE STORAGE” and then selecting the correct SD card.
The last step is to write the image to the SD card by clicking “WRITE”.
After a few minutes this will be ready.
Since the Raspberry Pi will be headless we have to connection to it via SSH. For security reasons SSH is disabled as the default. We have to enable it.
This is as easy as creating a file called “ssh” in the root of the SD card.The file should only contain one space. Make sure you don’t have any file extension.
Some card readers aren’t able to see the SD card at all after the image was written. I had to change to a different laptop. If that happens to you it might be as easy as updating your SD card reader software.
The Raspberry Pi has to connect to the wifi on startup automatically. To achieve this you have to create a second file called “wpa_supplicant.conf” in the root of the SD card. It should contain the following conent.
In the create form, which appears, you choose a name for the App Registration and the second option under Supported Account types (Accounts in any organizational directory).
After clicking “Register” you will come to the Overview page. There you should copy the Application ID and the Directory ID. We need both later when setting up the light.
Now that we have created the App Registration we have to add the needed permissions to it. We open “API permissions” (1) in the new App Registration in the azure portal. In this screen we:
Select “Add a permission” (2)
Select “Microsoft Graph”
Select “Delegate permissions”
And make sure that “offline_access”, “Presence.Read” and “User.Read” is selected
Click “Add permissions”
After that the list of API permissions should look like this.
The last thing to do with the App Registration is to set the “Allow public client flows” flag to “Yes”. This can be found at the end of the “Authentication” page.
Setup Status Indicator
Now we come to the real part of this blog post. We will finally setting up our status indicator light application.
As mentioned earlier you can find the source code of it on GitHub.
Everything we do in this section is on the Raspberry Pi via the PuTTY terminal.
Actually it isn’t really an installation. It is more downloading the source, building it and then running it.
To structure our applications in a good way we create a new folder called “projects” in our home folder and opening it.
Then we have to clone the application from GitHub and open the folder of it.
git clone https://github.com/BenediktBergmann/StatusIndicator
After that we need to install all the npm packages.
The applications uses a npm packege, node-blinkt, to change the LEDs. This npm packages does need “Wiring Pi” (which we installed earlier) and therefore can only be added on the Pi. To do this we execute the following command.
npm install node-blinkt
The install process can take some minutes. It will also generate quite a lot of output in your terminal. That is normal.
When the installation is done we have to change the ledService file. Since the npm packaged to change the LEDs wasn’t installed I commented out the needed lines.
Open the ledService.ts file, which is located in src/services, with vi.
By pressing “i” for insert you will be able to change the file in vi. Uncomment (delete the leading //) in the rows 3,4,14-17 and 32-34. The file should then look like this.
If you are ready with that you can exit vi by first pressing “Esc” and then typing “:wq” which will write the changes and quit vi.
The last step to create a Teams status indicator light is to create our configuration. To achieve that we create a new file called “.env” by executing the following command.
This will again open vi. Here you can copy and paste the following code (paste in vi with shift + insert).
TENANT_ID=<Tenant ID we copied earlier>
APP_ID=<App Registration ID we copied earlier>
# General Config
# Email settings
EMAIL_HOST="<Your SMTP Host>"
EMAIL_PORT=<Your SMTP Port>
EMAIL_USER="<Your SMTP Username>"
EMAIL_PASSWORD="<Your SMTP Password>"
Here you have some possibilities to configure your Teams status indicator light.
Should contain the ID of your tenant. You have copied that in one of the previous steps.
Should contain the ID of the created App Registration. You have copied that in one of the previous steps.
Defines how often the light should poll for the Teams status/presence. You can configure something between 1 and 60. Default is every minute.
Whether or not to poll the status on the weekends.
The time of the day when the polling should start. I usually do that at 07:00. You can configure something between 00:00 and 23:59.
The time of the day when the polling should end. I usually do that at 17:00. You can configure something between 00:00 and 23:59.
Defines whether or not to output debug logs.
Configures how bright the LEDs should be.
Says how long (in minutes) the device code should be valid.
Whether or not the application should send emails when you have to login. If disabled your only possibility to see the device code is in the logs.
The hostname of your SMTP server.
The port of your SMTP server.
Username you use to login to your SMTP server.
The Password of the user you use to login to your SMTP server.
The email address the status indicator should send the mails to.
npm run build
This command will take some minutes to exeute.
Start the status indicator light
Now that we have finished all the steps to configure and create a Teams status indicator light we have to start the application. This can be done by running the following command.
This will fire up the application. After a while you will see a message to login. It will contain a link and a code. You have to open the link on your normal device, enter the code and login to your Microsoft Work or School account.
The lights will become the correct color after a short time, depending on your poll interval.
If you are outside of the configured time interval or offline the lights will not be on.
Add to Autostart
Since we don’t want to connect to the Pi to start the application every time we start it, we can add the Status light indicator light to the auto start.
We create a new file called statusIndicator.service by executing the following command.
Last step for this setup is to enable the service which will then start it on every start of the Pi.
sudo systemctl enable statusIndicator
You can manually start or stop the service with the following commands.
sudo systemctl start statusIndicator
sudo systemctl stop statusIndicator
To access the logs of our Teams status indicator light you can execute the following command.
sudo journalctl -u statusIndicator
There is a lot more you can do with journalctl. For example you can filter on certain timeframes.
Now you have learned how to create a Teams status indicator light using a Raspberry Pi. There are quite a few steps needed to set everything up (way more effort went into creating the used application though). At the end this can help to show everyone when you are available and when not.
I hope this post was useful. Feel free to contact me if there are any additional questions.
This is just 1 of 39 articles. You can browse through all of them by going to the main page. Another possibility is to view the categories page to find more related content. You can also subscribe and get new blog posts emailed to you directly.
Privacy & Cookies Policy
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.