Open aregart opened 6 months ago
Unfortunately not, the Teams API does not have this data. You can see the data available here. I have not checked how verbose the logs are recently but it was also not available by parsing the logs a couple of months back (which is another approach altogether). If the logs now log that information I would be investigate this further.
Good news I just saw that the logs have the status, they are now in:
C:\Users\<youruser>\AppData\Local\Packages\MSTeams_8wekyb3d8bbwe\LocalCache\Microsoft\MSTeams\Logs\
The ones matching MSTeams_*.log
I will see what I can do for this.
Closed the wrong issue, my bad
Already played with the log-files you identified as well prior to finding your new version. Got that log-thing part up-and-running for indicating status, meeting, webcam etc, BUT, and that was the reason for further investigating and finding your new solution, this was quite unstable. The reason for that ist, that the log-files rotate in an irregular time / intvervall, which let the log-crawler regularly crash and therefore unavailable sensors in HA.
That was my adopted piece of code:
# Configuring parameter for interactive run
Param($SetStatus)
# Import Settings PowerShell script
. ($PSScriptRoot + "\TSFunctions.ps1")
. ($PSScriptRoot + "\Settings.ps1")
$locLang = GetFirstNonEmpty -firstString $env:TSLANG -secondString "en"
. ($PSScriptRoot + "\Lang-$locLang.ps1")
# Some variables
$HAToken = $env:TSHATOKEN
$HAUrl = $env:TSHAURL
$appDataFolder = GetAppDataFolder
#$logFolder = "$appDataFolder\Local\Packages\MSTeams_8wekyb3d8bbwe\LocalCache\Microsoft\MSTeams\Logs"
$logFolder = "C:\Users\tgroene\AppData\Local\Packages\MSTeams_8wekyb3d8bbwe\LocalCache\Microsoft\MSTeams\Logs"
$logFile = Get-ChildItem -Path $logFolder -Filter "MSTeams_*.log" | Sort-Object LastAccessTime -Descending | Select-Object -First 1
$userName = GetUserName
$teamsStatusHash = @{
# Teams short name = @{Teams long name = HA display name}
# Can be set manually in Teams
"Available" = @{"Available" = $tsAvailable}
"Busy" = @{"Busy" = $tsBusy}
"Away" = @{"Away" = $tsAway}
"BeRightBack" = @{"BeRightBack" = $tsBeRightBack}
"DoNotDisturb" = @{"DoNotDisturb" = $tsDoNotDisturb}
"Offline" = @{"Offline" = $tsOffline}
# Automated statuses
"Focusing" = @{"Focusing" = $tsFocusing}
"Presenting" = @{"Presenting" = $tsPresenting}
"presentertoolbar" = @{"Presenting" = $tsPresenting}
"InAMeeting" = @{"InAMeeting" = $tsInAMeeting}
"OnThePhone" = @{"OnThePhone" = $tsOnThePhone}
}
# Ensure these are initialized to null so the first hit triggers an update in HA
$currentStatus = $null
$currentActivity = $null
$currentCamStatus = $null
# Some defaults
$camStatus = $csCameraOff
$camIcon = "mdi:camera-off"
$defaultIcon = "mdi:microsoft-teams"
# Run the script when a parameter is used and stop when done
If($null -ne $SetStatus){
InvokeHA -state $SetStatus -friendlyName $entityStatusName -icon $defaultIcon -entityId $entityStatusId
break
}
Write-Host "Used Log Files: $logFile"
# Start monitoring the Teams logfile when no parameter is used to run the script
#Get-Content -Path "$appDataFolder\Microsoft\Teams\logs.txt" -Encoding Utf8 -Tail 1000 -ReadCount 0 -Wait | % {
Get-Content -Path $logFile.fullName -Encoding Utf8 -Tail 1000 -ReadCount 0 -Wait | % {
# Get Teams Logfile and last icon overlay status
$TeamsStatus = $_ | Select-String -Pattern `
'Received Action: UserPresenceAction:',`
'Navigation starting: about:blank?entityType=presentertoolbar' | Select-Object -Last 1
# Get Teams Logfile and last app update deamon status
$TeamsActivity = $_ | Select-String -Pattern `
'WebClientStatesModule',`
'Attempting to play audio for notification type 1' | Select-Object -Last 1
# Get Teams application process
$TeamsProcess = Get-Process -Name *Teams* -ErrorAction SilentlyContinue
# Check if Teams is running and start monitoring the log if it is
If ($null -ne $TeamsProcess) {
If($null -ne $TeamsActivity){
If ($TeamsActivity -like "*new_state=Active*" -or `
$TeamsActivity -like "*new_state=Inactive*" -or `
$TeamsActivity -like "*new_state=LongInactive*") {
$Activity = $taNotInACall
$ActivityIcon = $iconNotInACall
If ($currentStatus -eq $tsPresenting) {
$Status = $tsDoNotDisturb
} ElseIf ($currentStatus -eq $tsInAMeeting) {
$Status = $tsBusy
}
}
ElseIf ($TeamsActivity -like "*new_state=VeryActive*") {
$Activity = $taInACall
$ActivityIcon = $iconInACall
}
ElseIf ($TeamsActivity -like "*Attempting to play audio for notification type 1*") {
$Activity = $taIncomingCall
$ActivityIcon = $iconInACall
}
}
If($null -ne $TeamsStatus) {
$teamsStatusHash.GetEnumerator() | ForEach-Object {
If ($TeamsStatus -like "*, availability: $($_.value.keys[0])}" -or `
$TeamsStatus -like "*Navigation starting: about:blank?entityType=$($_.key)*") {
$Status = $($_.value.values[0])
If ($Activity -eq $taInACall -And $Status -eq $tsDoNotDisturb) {
$Status = $tsPresenting
} ElseIf ($Activity -eq $taInACall) {
$Status = $tsInAMeeting
}
}
}
}
}
# Set status to Offline when the Teams application is not running
Else {
$Status = $tsOffline
$Activity = $taNotInACall
$ActivityIcon = $iconNotInACall
}
If($null -ne $TeamsStatus) {
Write-Host "Teams Orig-Status: $TeamsStatus"
Write-Host "Teams Status: $Status"
}
If($null -ne $TeamsActivity) {
Write-Host "Teams Orig-Activity: $TeamsActivity"
Write-Host "Teams Activity: $Activity"
}
# Webcam support (sensor.teams_cam_status)
# While in a call, we poke the registry for cam status (maybe too often), but I could not find a log entry to use as a trigger
# to know when to check the camera status so it might be hit or miss.
# When leaving a call it maybe not trigger as something non-camera related needs to get logged to trigger the check.
If($Activity -eq $taInACall -or $camStatus -eq $csCameraOn) {
$registryPath = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam\MSTeams_8wekyb3d8bbwe\"
$webcam = Get-ItemProperty -Path $registryPath -Name LastUsedTimeStop | select LastUsedTimeStop
If ($webcam.LastUsedTimeStop -eq 0) {
$camStatus = $csCameraOn
$camIcon = "mdi:camera"
}
Else {
$camStatus = $csCameraOff
$camIcon = "mdi:camera-off"
}
}
# Call Home Assistant API to set the status and activity sensors
If ($currentStatus -ne $Status -and $Status -ne $null) {
$currentStatus = $Status
InvokeHA -state $currentStatus -friendlyName $entityStatusName -icon $defaultIcon -entityId $entityStatusId
}
If ($currentActivity -ne $Activity) {
$currentActivity = $Activity
InvokeHA -state $Activity -friendlyName $entityActivityName -icon $ActivityIcon -entityId $entityActivityId
}
If ($null -ne $camStatus -and $currentCamStatus -ne $camStatus) {
$currentCamStatus = $camStatus
InvokeHA -state $camStatus -friendlyName $entityCamStatusName -icon $camIcon -entityId $entityCamStatusId
}
}
Thanks for the info, I have started work on this but as you mentioned log files are being rotated so I am taking time ensuring rotations will be detected as quickly as possible (I am currently attempting with the notify
crate).
Once that's stable I will work on the parsing of the file, at which point what you posted will be quite helpful!
a small remark: I was using the powershell as also described here . That does require admin rights, I do not have these (and expect this move for more people/companies), it would (at least for me) be nice if this is also not required in the future.
(I installed this solution today, thanks a lot!! I'm really happy!)
I don't plan on having admin rights required for this! I did run into an issue with the log parsing, it seems there is no log entry when manually changing the status back to 'Available' so for the time being there is no point in continuing the integration with the log file :(
It seems that around April 29, they added logging for status changes; I an example from my logs (user id scrubbed). For each change in status, at least when I manually set (or reset) my status, all three entries below are captured in the log.
2024-04-30T16:29:56.670497-04:00 0x000100c8 <INFO> native modules::UserDataCrossCloudModule: Received Action: UserPresenceAction: {cloud_context: https://teams.microsoft.com , user id: 000a00aa-0000-0a00-a000-a0aa00000a0a, availability: Available}
2024-04-30T16:29:56.672498-04:00 0x000100c8 <INFO> native modules::UserDataCrossCloudModule: CloudStateChanged: New Cloud State Event: UserDataCloudState total number of users: 1 { user id : 000a00aa-0000-0a00-a000-a0aa00000a0a, availability: Available, unread notification count: 2 }
2024-04-30T16:29:56.673497-04:00 0x000100c8 <INFO> native_modules::UserDataCrossCloudModule: BroadcastGlobalState: New Global State Event: UserDataGlobalState total number of users: 1 { user id : 000a00aa-0000-0a00-a000-a0aa00000a0a, availability: Available, unread notification count: 2 }
Now that statuses are logged is this something that can be included? I desperately miss being able to see my teams status through HA
It should, though I have been busy with a ton of other projects these days so I have not looked into it yet. I'll see what I can do.
Ok so I encountered some new issues:
Notify
crate I am using to pick up on file changes does not seem to work as Teams is not closing the log file after each write, issue described here, hoping someone has a work around as I could not find any other means of getting a tail-like system done in Rust (except polling which would not be a good approach). 😕Ugh that's a shame! Hopefully a solution can be figured out one day
Just stumbled across this https://learn.microsoft.com/en-us/microsoftteams/log-files#end-user-configuration
I will test whether enabling it creates a continuous stream.
It would be great to have an additional sensor in HA that reflects the actual user status. The "Away", "Busy", "Available" etc statuses I mean. Is that possible?