Skype for Business Status in Home Assistant

I would like to present my Skype for Business (formerly Lync) status in Hass so my family can tell when I’m busy or on a conference call and not disturb me when I work from home. Does anyone know if this is achievable? I’m thinking the problem is getting the status itself - maybe a tool or service that publishes my status to a website or webook so Hass can either display it in an iframe or through scripting. Does anyone know if such a thing exists for SFB?

1 Like

I think that is a Microsoft question.
I do know they are working to replace Skype for Business with Microsoft Teams. We are in that transition now.

1 Like

maybe able to also pull into HA

Got it! :smiley:

I was able to accomplish this by building a Powershell script in Windows.

Tested with Windows 10, Skype for Business 2016

  1. Setup an input_boolean in HA to digest your state and to trigger the automation that you want (Or something similar).
  2. Download/Install Lync 2013 SDK. If the installer gives you an error that you do not have Lync 2013 installed, you will need to open the lyncsdk.exe file with an archiver such as 7Zip or WinZip. With it open you will find 3 files inside: files15.cat, lyncsdk64.msi, lyncsdk86.msi. I extracted and installed the lyncsdk64.msi and got all the files that I needed. You’re only installing this to get the needed .dll files that are required to pull data from Skype For Business. I don’t think you need anything else.
  3. Edit my script to your needs. Save as plain text with file extension .ps1.
    *Note that the script logs to a file in the same directory as the script skype_status_monitoring.log, but the file is always appended and never deleted… you might want to delete occasionally it if the file size gets out of control. I’m sure you could automate this with a powershell command of some sort.
# Hide Powershell window
# Since this is executed after powershell launches. The window will flash for 
# a second. I kind of like that though, since it reminds me that it is running.
$t = '[DllImport("user32.dll")] public static extern bool ShowWindow(int handle, int state);'
add-type -name win -member $t -namespace native
[native.win]::ShowWindow(([System.Diagnostics.Process]::GetCurrentProcess() | Get-Process).MainWindowHandle, 0)

# Logfile <https://stackoverflow.com/a/38738942>
$LOGFILE = "$PSScriptRoot\skype_status_monitoring.log"
Function LogWrite {
	[CmdletBinding()]
    Param(
	[Parameter(Mandatory=$True)]
    [string]
    $Message,
	
    [Parameter(Mandatory=$False)]
    [ValidateSet("INFO","WARN","ERROR","FATAL","DEBUG")]
    [String]
    $Level = "INFO",

    [Parameter(Mandatory=$False)]
    [string]
    $logfile = $LOGFILE
    )

    $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
    $Line = "$Stamp $Level $Message"
    If($logfile) {
        Add-Content $logfile -Value $Line
    }
    Else {
        Write-Output $Line
    }
} 

# Import required dlls
$lync_dir = 'C:\Program Files (x86)\Microsoft Office 2013\LyncSDK\Assemblies\Desktop'
Import-Module -Name $lync_dir\Microsoft.Lync.Model.dll
Import-Module -Name $lync_dir\Microsoft.Lync.Controls.Framework.dll
Import-Module -Name $lync_dir\Microsoft.Lync.Utilities.dll
Import-Module -Name $lync_dir\Microsoft.Office.Uc.dll

# Update your API call to the service you need
#  More info: https://developers.home-assistant.io/docs/en/external_api_rest.html
$HA_URI_ON = 'http://hassio.local:8123/api/services/homeassistant/turn_on'
$HA_URI_OFF = 'http://hassio.local:8123/api/services/homeassistant/turn_off'

# Update to the entity_id on your HA that you want to manipulate
$HA_BODY = '{"entity_id":"input_boolean.notify_skype_call"}'

# All API calls have to be accompanied by the header 
# Authorization: Bearer ABCDEFGH, # where ABCDEFGH is replaced by your token. 
# You can obtain a token ("Long-Lived Access Token") by logging into the 
# frontend using a web browser, and going to your profile 
# http://IP_ADDRESS:8123/profile.
$HA_HEADER = @{
'Authorization' = 'Bearer ABCDEFGH'
'Content-Type' = 'application/json'
}

# Needed for SSL: Uncomment if your URI contains https
# [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Give skype time to login
do{
	sleep 5
	LogWrite "New Session Initiated."
	LogWrite "Connecting to Skype..."
	$S4B_Client = [Microsoft.Lync.Model.LyncClient]::GetClient()
}while(!$S4B_Client)
LogWrite "Skype Connected!"

# Status numbers for Client
$Available = 3500
$Busy = 6500
$Do_Not_Disturb = 9500
$Be_Right_Back = 12500
$Away = 15500
$Off_Work = 16000
$Appear_Offline = 18500

$Last_my_status = ''
do{
	# Pull Status from Skype for Business
	if ($S4B_Client.self.Contact.GetContactInformation("Availability") -eq $Busy `
		-Or $S4B_Client.self.Contact.GetContactInformation("Availability") -eq $Do_Not_Disturb)
	{
		$My_status = 'Busy'
	}
	else
	{
		$My_status = 'Available'
	}
	# If changed, post state to HA
	if ($Last_my_status -ne $My_status)
	{
		LogWrite "New status: $My_status ; Previous status: $Last_my_status"
		if ($My_status -eq 'Available')
		{
			$restOutput = Invoke-RestMethod -Uri $HA_URI_OFF -Method Post -Headers $HA_HEADER -Body $HA_BODY | Out-String
		}
		else
		{
			$restOutput = Invoke-RestMethod -Uri $HA_URI_ON -Method Post -Headers $HA_HEADER -Body $HA_BODY | Out-String
		}
		if ($restOutput){LogWrite "Rest Response from HA: $restOutput"}
	}
	# LogWrite "Heatbeat status: $My_status"  # print status to log - heartbeat
	$Last_my_status = $My_status
	sleep 5
	if ($S4B_Client.State -ne "SignedIn")
	{
		do{
			LogWrite "Connection Lost! Waiting for reconnection..."
			sleep 60
			$S4B_Client = [Microsoft.Lync.Model.LyncClient]::GetClient()
		}while(!$S4B_Client)
		LogWrite "Reconnected.👍"
	}
}while(1 -eq 1)

  1. Run the script from Powershell. Optionally, you can run the script in the background using Task Scheduler

I setup my script to execute from Task Scheduler when I login to my computer. The script will run until I shutdown. As you can see in the script, there is a forever loop that checks to see if I got logged out or if Skype for Business is not running.

Optionally you could setup Task Scheduler to execute the script when Skype for Business starts, but make sure to modify the script so you don’t have multiple instances running. Here is a guide to set up Task Scheduler: https://superuser.com/a/745336

Looks good but wont work with my setup. Work laptop is Windows 7 with Skype for Business Office 365 (v16.0), so the SDK wont install as it says Lync 2013 is not installed. I’m not sure if having Lync 2016 and Skype for Business will cause problems.

I can install Lync 2013 on my home Windows 10 PC, but again the SDK wont install as it says it needs Visual Studio 2010 or higher to install, which leads to a dead Microsoft URL.

Oh sorry. I forgot about that.

I have the same version of S4B installed. I got the same error as you. I got around it by opening up the installer lyncsdk.exe with 7zip and executed the x64 installer in the archive. By opening the archive first, you get around the check for Lync 2013 being installed.

I just checked and WinZip works as well to open the archive lyncsdk.exe.

Once you open it up, there are 3 files in there. I ran the lyncsdk64.msi installer to get the 64 bit version.

It is worth to mention that I found another solution by using this windows software:
https://github.com/jongio/beakn/releases.
If properly configured it publishes on MQTT the Skype Status. I don’t have admin privilege on my windows machine so I cannot install Powershell. Actually I can neither install Beakn, but after installing it on another machine I simply copied the software folder and everything works.

1 Like

This is awesome. Thx a lot for sharing. Beakn works perfect for me!

The only issue I’m having is that if Beakn got disconnected from MQTT Server it is not going to reconnect, but it still shows “Send Success”.
When I connect to my company VPN I need to restart the program when I’m back.
It was in any case very easy to setup a Busy lamp with a 433MHz plug connected with a led stripe out of my door. :wink:

Thank you so much for sharing this approach… everything “almost” works like clock work… But HomeAssistant is complaining

2021-07-15 23:44:21 WARNING (MainThread) [homeassistant.components.http.ban] Login attempt or request with invalid authentication from 192.168.1.208 (192.168.1.208). (Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.19041.1023)
2021-07-15 23:46:55 WARNING (MainThread) [homeassistant.components.http.ban] Login attempt or request with invalid authentication from fe80

Did you come across this before? The good news it’s talking to HA…

@gremblin

Eric,

Figured out the problem. I removed the “Bearer” portion before the token.

Another Q: Update your API call to the service you need

More info: https://developers.home-assistant.io/docs/en/external_api_rest.html

This link isn’t working. I have everything working, but the script as is seems to either be On of Off… I would prefer to have some additional states, mimicking the actual Presence… Is that possible? Or maybe I missed something?