1
2
Fork
You've already forked call-detector
0
Very small project to detect meeting calls via Teams and Zoom and activate an indicator lamp via Home Assistant.
  • PowerShell 94.5%
  • JavaScript 5.5%
beandev 38fa64e784 meeting-call.ps1 aktualisiert
Microsoft has changed the MS Teams app again so that a new process name has been added to the list that is monitored.
2024年07月02日 07:39:16 +00:00
LICENSE Initial commit 2023年05月25日 14:12:48 +00:00
meeting-call.js Handles now pwsh.exe (PowerShell core 7.x) and maybe fall back to PowerShell. 2023年05月30日 17:54:05 +02:00
meeting-call.json Added a disconnect test with sleep interval. 2023年06月02日 16:06:56 +02:00
meeting-call.ps1 meeting-call.ps1 aktualisiert 2024年07月02日 07:39:16 +00:00
README.md Added a disconnect test with sleep interval. 2023年06月02日 16:06:56 +02:00
test-lights.ps1 Added a disconnect test with sleep interval. 2023年06月02日 16:06:56 +02:00
test-scripts.ps1 Added a disconnect test with sleep interval. 2023年06月02日 16:06:56 +02:00

call-detector

Very small project to detect meeting calls via Teams and Zoom and activate an indicator lamp via Home Assistant (or do some other usefull stuff).

The principle is actually very simple. A Powershell script is used to search for MS Teams or Zoom processes. If these processes are running, a check is made to see if they have established a (real) UDP connection. This is usually only the case when a meeting call is in progress.

A real UDP connection means, the local address must be not in the list of 127.0.0.1, 0.0.0.0 and ::.

A special case with Zoom: When Zoom is started, it establishes a UDP connection for a few seconds, which cannot be distinguished from a normal call. Thus, the lamp that is controlled by Home Assistant may light up for 2 to 3 seconds.

Disclaimer

  • I can't program in PowerShell at all and probably a lot of people will agree with me when they see the code. Sorry for that. But it seems to work quite well. You can fork and improve it. In case of really bad errors I'm happy about a pull request.
  • I will very likely lack the time to help with problems. Everything that is summarized here in the project, I have googled and tried. As one does in the home automation so. I assume that you are just such enthusiasts and first look around and find out what may not work. For me, it works quite well with MS Teams and Zoom.
  • A few tips: First try everything in the terminal and if necessary in Visual Studio with the debugger and/or give out additional exceptions. If all this works, then use the setup via Taskplanner. And don't forget that you have set it up then. But since I use a mutex, two scripts can not run on the same computer (check log!).

This is not an out-of-the-box project that you just install. It requires some tinkering, which is now explained here. You can find alternative solutions to manage meeting calls (see the document at the end).

Check out

Check out the project on the computer with your MS Teams or Zoom usage. It should be a folder, on which one has access authorization and which is not deleted so fast. The scripts will run there permanently, read configurations and write log files. Administrative permissions are not necessary!

Home Assistant preparation

Is your REST API in Home Assistant activated (typically yes)? Check the documentation: Home Assistant API .

Access Token

First you have to create an access token to be allowed to call the REST API. To do this, click on your account name in the Home Assistant menu at the bottom left and scroll all the way down. There you can create a new token. Copy the complete (very long) token and save it in the file meeting-call.json. Replace the null behind the "token": attribute. don't forget to put the token in "! (in Home Assistant you will never see the token again, so save it immediately).

Now the URL of the Home Assistant must also be entered in the meeting-call.json. If Home Assistant runs on a special port, don't forget it. Also the URL must be put in quotes.

For example, a configuration looks like this:

{
 "hosturl": "http://192.168.0.1:8123",
 "token": "eyJhbGciOiJIUhjfHGHJGHJGhhjghjjjHJJGJ9.jhgHGHGHjhjgjhHJHG.hjjkhJKJHKJHjhJKJJ-hV4",
 "startupSleep": 0,
 "disconnectSleep": 3
}

The startupSleep in seconds is potentially needed to wait for an initial setup of the meeting software. This may be necessary for the business version of MS Teams to not detect incorrect calls (but the current detection works well). With disconnectSleep the scripts waits for # minutes, if Home Assistant is not reachable.

How to test it? You can use Postman or Curl to check the API. You can find a lot of examples in the documentation. The best idea is to check the existing services:

curl \
 -H "Authorization: Bearer eyJhbGciOiJIUhjfHGHJGHJGhhjghjjjHJJGJ9.jhgHGHGHjhjgjhHJHG.hjjkhJKJHKJHjhJKJJ-hV4" \
 -H "Content-Type: application/json" http://localhost:8123/api/services

^- put your token into the curl call and your host name.

But maybe you don't have curl on windows, try it with PowerShell:

$token = "eyJhbGciOiJIUhjfHGHJGHJGhhjghjjjHJJGJ9.jhgHGHGHjhjgjhHJHG.hjjkhJKJHKJHjhJKJJ-hV4"
$base = "http://127.0.0.1:8123/api"
$uri_services = "$base/services"
$headers = @{
 "Authorization" = "Bearer $token"
 "Content-Type" = "application/json"
}
Write-Output "Calling: $uri_services" 
$response = Invoke-RestMethod -Method Get -Uri $uri_services -Headers $headers
$response_json = $response | ConvertTo-Json -Depth 10
Write-Output $response_json

Scripts to activate and deactivate a lamp

There are actually many options.

  1. You call a service with light_on or light_off and pass the entity ID of the lamp in the body (this is what I did first).
  2. You create scenes that you assign to the lamp and activate and deactivate the scene via REST call (I haven't tried this yet).
  3. You create two action scripts in Home-Assistant that turn the lamp on and off (this is what I currently use)

In the end, I chose the third option because I can then set up everything in Home Assistant and I don't have to adjust the Powershell script if I want to change something in my automation.

To do this, go to Home Assistant: Settings -> Automations & Scenes -> Scripts. At the bottom right there is + Add Script.

So that I don't have to explain the whole visual editor now, let us make it simple. On the top right, there is the three-dot menu (kebab menu). Open it and switch to the YAML editor.

Now a text editor appears with the empty script:

alias:New Scriptsequence:[]

We now replace that completely with this script:

alias:CallStartedsequence:- service:light.turn_ondata:color_name:redentity_id:light.messagemode:singleicon:mdi:phone

Now this must be adapted, because with your setup the lamp will be called differently. You have to adjust the entity_id and store the appropriate name of your lamp there. If you don't have a RGB lamp (white only), you have to remove color_name. If you don't like red, enter another color (there are many ways to specify colors, check Google).

It is important that it is called alias: CallStarted. This is what the Powershell script relies on!

Now click on Save Script.

But we still need a script to turn off the lamp.

So again, as described above create a new script and switch to the YAML editor. Then replace the empty template with this script:

alias:CallEndedsequence:- service:light.turn_offdata:{}target:entity_id:light.messagemode:singleicon:mdi:phone-hangup

And again, replace the value for the entity_id attribute with your lamp name.

That's it. Save the script an now check it.

In the list of scripts you have now CallStarted and CallEnded. At the end of the lines you will find the kebab menus again. Just open the menu for 'CallStarted' and click on 'Run'. Now the lamp should light up and hopefully in red (if possible). Next, run the CallEnded - the lamp should switch off.

Gratulation, you can now trigger your meeting call indicatior manually. But that's boring (even if it was complicated).

Pre-Tests

I added two PowerShell scripts to the repository to check the Home Assistant from a terminal.

  • The script test-scripts.ps1 reads the home assistent configuration and searches for CallStarted and CallEnded YAML scripts
  • The script test-lights.ps1 reads all the configuration from the JSON file.

Verify that the YAML scripts exist and/or have the correct names

PS C:\Dev\mc> .\test-scripts.ps1
name description fields
---- ----------- ------
CallStarted
CallEnded

Activate lights with CallStarted

PS C:\Dev\mc> .\test-lights.ps1 on

Deactivate lights with CallEnded

PS C:\Dev\mc> .\test-lights.ps1 off

If everything is ok, let's try now the PowerShell script meeting-call.ps1 together with your meeting app.

Powershell Test Run

With the above preparation we have injected into Home Assistant two scripts to control our lamp. We also changed the meeting-call.json located in the folder. There we added the information to reach the Home Assistant (which, by the way, should be reachable on the same network).

For a test run, just open a Powershell terminal window and switch to the folder of the script meeting-call.ps1.

The call is then simple:

PS C:\dev\mc> .\meeting-call.ps1

If everything goes well, the terminal will not come back because the script is in an infinite loop. Also, the script creates a file meeting-call.log in the same folder. You can look in there and at least that should be readable:

2023年05月25日 16:33:22 Start Call Detector in process 33516.

The script can be terminated with Ctrl-C. But maybe we want to test it first?

In the private MS Teams version you can call the function Talk now via Chat. Simply do not enter anything else (i.e. do not add another person to the call) and Start the meeting.

In the businees MS Teams version it's a litte bit more complicated. Open your Settings -> Devices -> Make a test call. Now an assistant voice talks a little bit, but anyway you started a call.

In both cases, the lamp should be activated. If the call is ended, the lamp goes off.

If not, check the log file!

Now you can stop the script with Ctrl-C.

Install the script in a task planer.

To run the PowerShell in background (on user-login), we use the Windows built-in task planer. The main issue with PowerShell scripts is the visible terminal window. Not very nice for backend processes. We manage it with another wrapper script and a WScript.Shell object.

Please checkout the meeting-call.js script in this repository (which tests for the existence of different versions).

This is a simplified example:

// Runner, for the execution of the Powershell script without terminal window
var wshShell = new ActiveXObject("WScript.Shell");
wshShell.Run('%ProgramFiles%\\PowerShell\7円\\pwsh.exe -ExecutionPolicy Bypass -File ".\\meeting-call.ps1"', 0, false);

First we create a WScript.Shell object, then we call pwsh.exe with some few parameters (and to avoid a terminal window).

Explanation:

%ProgramFiles%\\PowerShell\7円\\pwsh.exe Standard path to pwsh.exe process under Windows
-ExecutionPolicy Bypass The script must not be signed
-File .\\meeting-call.ps1 Our script (Start in folder must be set later in planner)
, 0 WindowStyle = Hide
, false No wait on return

This script must be configured in the task planner. Since I'm too lazy, here's a very general tutorial:

Advanced Task Creation in Windows 11

The following points are important:

  • In general settings set the execution only for the current user.
  • Trigger is: On login
  • Action is: Run program
    • Program/Script: WScript
    • Argument: "meeting-call.js"
    • Start in: C:\Your\Path\To\Your\Script

You can try to manually run the task and then start a call in Teams or Zoom. The lamp should go on (on beginning of the call) and off (at the end). In the log file you find the corresponding outputs.

Alternative solutions

The Pros/Cons comparision is related to this script goal to detect meetings calls immediately. Maybe the pros suit you more, maybe the cons are features for you.

O356 Home Assistant integration

Pure Home Assistant integration with a comprehensive set of features.

https://github.com/RogerSelwyn/O365-HomeAssistant

  • Pro
    • Works well with Business MS Teams
    • Relies on the status of the teams, which is more accurate.
    • In-A-Call status bound to calendar events and live calls.
    • No need to be install anything on your notebook or computer
  • Cons
    • Works only with MS Teams Business and Office 356 account (and this needs a cloud access)
    • Status change needs up to 20 seconds
    • When a meeting is scheduled on a calendar, you do not have to attend the meeting, but the status is set to In-A-Call.

Mutesync

A hardware button to mute/unmute a meeting call and integration in Home Assistant

https://mutesync.com/

  • Pro
    • Works with a lot of meeting apps
    • It's a hardware button with light indicator and Home Assitant integration
  • Cons
    • Must be pressed manually
    • It's a mute-event, not a call event
    • It's a hardware button ;-)

HASS.Agent

An Agent to gather a lot of information from your computer and send it as sensor data to Home Assistant.

https://github.com/LAB02-Research/HASS.Agent

  • Pro
    • Works directly with the microphone
    • A lot of more functionality inside
  • Cons
    • Cannot detect the Teams mute functionality (because the mic is still open)
    • It can detect mute-events, not a call-events (but maybe a combination of running processes and mic handling?)
    • Must be installed locally (like this call-detector script)
    • Needs sometimes Admin rights
    • Some issues with external mics (and mute detections)