Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional status sensor #7

Open
aregart opened this issue Dec 13, 2023 · 16 comments
Open

Additional status sensor #7

aregart opened this issue Dec 13, 2023 · 16 comments
Assignees
Labels
enhancement New feature or request

Comments

@aregart
Copy link

aregart commented Dec 13, 2023

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?

@AntoineGS
Copy link
Owner

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.

@AntoineGS AntoineGS added the enhancement New feature or request label Jan 9, 2024
@AntoineGS
Copy link
Owner

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.

@AntoineGS AntoineGS reopened this Jan 11, 2024
@AntoineGS
Copy link
Owner

Closed the wrong issue, my bad

@itchensen
Copy link

itchensen commented Jan 27, 2024

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
    }
}

@AntoineGS
Copy link
Owner

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!

@AntoineGS AntoineGS self-assigned this Jan 29, 2024
@pvmil
Copy link

pvmil commented Mar 20, 2024

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!)

@AntoineGS
Copy link
Owner

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 :(

@AntoineGS AntoineGS added the stuck Uncontrollable variable prevents resolving the issue. label Apr 4, 2024
@kmcbride3
Copy link

kmcbride3 commented May 5, 2024

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 } 

@PablaV
Copy link

PablaV commented May 16, 2024

Now that statuses are logged is this something that can be included? I desperately miss being able to see my teams status through HA

@AntoineGS
Copy link
Owner

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.

@AntoineGS AntoineGS removed the stuck Uncontrollable variable prevents resolving the issue. label May 17, 2024
@AntoineGS
Copy link
Owner

Ok so I encountered some new issues:

  • The log file is not written on every log entry, Teams seems to fill up a buffer and will eventually write to the disk, but that can take quite some time if nothing happens in Teams.
  • The 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). 😕

@PablaV
Copy link

PablaV commented May 17, 2024

Ugh that's a shame! Hopefully a solution can be figured out one day

@kmcbride3
Copy link

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.

@tamimology
Copy link

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.

maybe this could be of a help
https://learn.microsoft.com/en-us/answers/questions/1350627/logs-are-not-updated-in-new-teams-client-in-public

@rickitaly
Copy link

Hello, just installed the app and everything what i missed is there... except this :-(
Any progress since July?
Thanks!

@AntoineGS
Copy link
Owner

Hey! I mostly gave up hoping for a solution on this, the issue according to the other repo is that this is a Windows behavior (the lack of notifications when the file is written to).
I could implement a "dumb" watcher that would just constantly re-read the file but it would be highly inefficient :( so I would rather leave it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants