Building an automated Microsoft Teams status light – Part 3

In “Building an automated Microsoft Teams status light – Part 2“, I demonstrated the process to retrieve your teams status via a REST call. In this post, I will be taking the returned status information to then make an additional REST call to the HomeAssistant instance to update the colour displayed by the light.

Status information

The REST API call returns a number of status and availability values. I am interested in the following combinations:

AvailabilityActivity
AvailableAvailable
BusyInACall
BusyInAConferenceCall
DoNotDisturb<n/a>

As I have a second ring light for the webcam, I am tracking the activity. So, if I am “Available”, the light is green. If I am “Busy” or “DoNotDisturb”, then the light is red. However, if I am in a call, then the system also activates additional lighting for the webcam.

HomeAssistant Information

In order to connect with HomeAssistant, I needed two key pieces of information:

  • HomeAssistant Access Key
  • Light Entity details

Access token

To create an access token, the menu can be found at the bottom of the User Profile section:

Create a new token and copy the token key as it will not be displayed again. The other piece of information required is the Entity ID for the light:

Updating the status light state

Updating the state of the status light is a relatively straight forward matter. Firstly HomeAssistant REST interface requires the bearer token to passed via the header:

$hasstoken = "<insert token here>"
$headers = @{ Authorization = "Bearer $hasstoken"
            contenttype = "application/json"
        }

The payload for the REST call sets the entity, the colour and the brightness for the light, and as the content type indicates, the payload will be in JSON:

$payload = @{"entity_id"="<Insert Entity ID here>";
    "color_name"="red";
    "brightness"=255}

We now have all of the information we need, but the content is JSON, so it is converted in the REST call:

Invoke-RestMethod -Headers $headers -Method Post -Body ($payload|ConvertTo-Json) -Uri 'http://<home assistant server>:<home assistant port>/api/services/light/turn_on'

Putting it all together

We now have all the pieces required to poll Microsoft Teams status and then update our light:

# Import PSMSGraph
Import-Module PSMSGraph

# Tenant and Client IDs
$tenantID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$clientID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

# Create Secret
$clientSecret = (ConvertTo-SecureString "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -AsPlainText -Force)

# Call the Graph App
$GraphApp = New-GraphApplication -Name "presence-app" -Tenant $tenantID -ClientCredential $creds -RedirectUri "http://localhost/" 

# This will prompt you to log in with your O365/Azure credentials and authorise access
$AuthCode = $GraphApp | Get-GraphOauthAuthorizationCode
$GraphAccessToken = $AuthCode | Get-GraphOauthAccessToken -Resource 'https://graph.microsoft.com'

$laststatus = $null
$pollinterval = 5

while ($true)
{
    $presence = Invoke-RestMethod -Headers @{Authorization = "Bearer $($graphaccesstoken.GetAccessToken())" } -Uri 'https://graph.microsoft.com/beta/me/presence' -method Get    
    
    if ($presence.availability -ne $laststatus)
    {
        if ($presence.availability -eq "Available")
        {
            $color=0,0,255
            $payload = @{"entity_id"="light.neopixel_light";
                "color_name"="green";
                "brightness"=255}
        }
        elseif ($presence.availability -eq "Away") {
            $payload = @{"entity_id"="light.neopixel_light";
                "color_name"="yellow";
                "brightness"=100}
        }
        else 
        {
            $payload = @{"entity_id"="light.neopixel_light";
                "color_name"="red";
                "brightness"=255}
        }
        $returninfo = Invoke-RestMethod -Headers $headers -Method Post -Body ($payload|ConvertTo-Json) -Uri 'http://homeassistant:8123/api/services/light/turn_on'
        $laststatus = $presence.availability
    }
    Start-Sleep -Seconds $pollinterval
    if ($GraphAccessToken.IsExpired)
    {
        $GraphAccessToken | Update-GraphOAuthAccessToken -Verbose    
    }
}


And there you have it, a script that polls Microsoft Teams and updates a light in HomeAssistant to reflect your current status.