I went the Powershell route here and I think my code is quite optimized: it requires only one line and works flawlessly!
Get-Content $env:APPDATA\Microsoft\Teams\logs.txt -Wait -Tail 0 | ? { $_ -match "(?<=StatusIndicatorStateService: Added )(\w+)" } | % { if($matches[0] -ne "NewActivity") {& "C:\Scripts\TeamsColor.ps1" $matches[0] }}
Get-Content -Wait -Tail 0
retrieves every line of the Teams log file, waits for new lines, while ignoring previous content of the file. These lines are then fed into a regex match filter. (After multiple tries, I found that this filter works best, as it still reports the updated status on top of a NewActivity status. It retrieves a single word after the matched expression.) For each matched object that is not NewActivity, another script (TeamsColor.ps1) is called with the status as argument.
This second script calls the HomeAssistant API at
/api/states/sensor.teams_raw
with the state passed as argument:
$newval = [Convert]::ToString($args[0])
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer your_bearer_code")
$headers.Add("Content-Type", "application/json")
$body = "{`"state`": `"$newval`"}"
$response = Invoke-RestMethod 'https://your_domain/api/states/sensor.teams_raw' -Method 'POST' -Headers $headers -Body $body
This might not be necessary depending on your needs, but I also created a second template sensor sensor.teams which allow me to easily customize the displayed values from the raw values sent to HA:
sensor:
- platform: template
sensors:
teams:
friendly_name: "Microsoft Teams"
unique_id: sensor.teams
value_template: >-
{% if states("sensor.teams_raw") in ["Available"] %}
Available
{% elif states("sensor.teams_raw") in ["DoNotDisturb","Presenting","Focusing"] %}
Do not disturb
{% elif states("sensor.teams_raw") in ["Busy","OnThePhone","DoNotDisturb","Presenting","Focusing","InAMeeting"] %}
Busy
{% elif states("sensor.teams_raw") in ["Away","BeRightBack"] %}
Away
{% else %}
{{ states("sensor.teams_raw") }}
{% endif %}
Finally, I simply created an automation that is based on the sensor.teams_raw status:
- id: '1608509876133'
alias: Update status light with Teams
description: ''
trigger:
- platform: state
entity_id: sensor.teams
condition: []
action:
- service: light.turn_on
data:
entity_id: light.statuslamp
rgb_color: '{% if states("sensor.teams_raw") in ["Available"] %} [146, 195,
93] {% elif states("sensor.teams_raw") in ["DoNotDisturb","Presenting","Focusing"]
%} [255, 30, 50] {% elif states("sensor.teams_raw") in ["Busy","OnThePhone","DoNotDisturb","Presenting","Focusing","InAMeeting"]
%} [255, 30, 50] {% elif states("sensor.teams_raw") in ["Away","BeRightBack"]
%} [252, 209, 22] {% else %} [0, 0, 0] {% endif %}
'
entity_id: light.statuslamp
mode: single
In addition to a sleep/shutdown scheduled script, I am also going to add a simple ping sensor as a condition for the lights, that pings my work laptop every 10 seconds or so to determine if it is online. Low tech, but I expect it to work quite nicely. Note that the Teams status sets itself to Away before putting the computer to sleep anyway, and depending on your purpose, that could be enough by itself!
Here is a small video demonstration: https://youtu.be/8kBtrowtfmk. I can provide more details if you are interested!