Zoom Meeting Monitoring to HA

Tags: #<Tag:0x00007f3267e6b928> #<Tag:0x00007f3267e6b770>

Preview

Recorded in real time!
2020-11-18 11.46.11

Note

This is not a turn-key solution, but it should get the grey matter thinking about your own meeting presence solution!

What?

With the whole WFH climate, I simply wanted to detect when I was in a Zoom meeting so I could push a notification and an LED change

Why?

To let family know I wasn’t available to speak or so they can reduce noise.
Also, to wear pants when entering the office …

Setup

Computer/OS: MacBook Pro/Catalina
Languages: Python, Bash
Applications: Zoom, BitBar, MQTT

How?

I did a random probe on ps in the terminal and discovered that the zoom process creates a child which declares the meeting ID (silly idea) only when you are in a meeting, so running filter for:

ps x | grep -E "\-key [0-9]{10,10}"

returns:

your.user     53663   0.0  0.1  4454492  12204   ??  S    12:20pm   0:00.08 /Applications/zoom.us.app/Contents/Frameworks/cpthost.app/Contents/MacOS/CptHost -pid xxx -evtname CptHostxxx-key 0000000000

When there is no meeting, you simply get (on ps x):

your.user     67658   0.0  0.1  4465672  14048   ??  S    11:01am   0:00.26 /Applications/zoom.us.app/Contents/Frameworks/caphost.app/Contents/MacOS/caphost -pid xxx -evtname caphostxxx -key rpc

Python Script

With this info, I wrote a quick Python application to monitor for this case and publish out to MQTT:

import subprocess
import paho.mqtt.client as mqtt
#import time

mqttBroker ="xxx.xxx.xxx.xxx"

client = mqtt.Client("Zoom_Meetings")
client.connect(mqttBroker)

# Keep 'while True' and 'time.sleep()' if this script needs to loop

#while True:
p1 = subprocess.Popen(['ps', 'x'], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["grep", "-E", "\-key [0-9]{10,10}"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close()

output = p2.communicate()[0]

if output:
    code = output.split()[-1].decode()
    print("Meeting ID:", str(code))
    client.publish("home/person/xxx/meeting_status", "ON")
else:
    print("Avail.")
    client.publish("home/person/xxx/meeting_status", "OFF")

# time.sleep(5)

BitBar Integration

In my case, I have BitBar which allows me to put anything I can script into my status bar, so I leveraged that to poll every 5 seconds.
But this could easily be replaced with allowing the Python script above loop to check.

In case anyone else wants to replicate this on BitBar:

#!/bin/bash

# <bitbar.title>Zoom Meeting Status</bitbar.title>
# <bitbar.version>v1.0</bitbar.version>
# <bitbar.author>fanuch</bitbar.author>
# <bitbar.author.github>fanuch</bitbar.author.github>
# <bitbar.desc>Simply run a Python script to detect an active meeting</bitbar.desc>

pythonenv="/Users/your.user/Documents/Code/Python/ZoomMonitor"
script="main.py"

$pythonenv/venv/bin/python $pythonenv/$script

Not that is is needed, but I get a nice little status with BitBar
image

Comments, questions, criticisms welcome.
Just note that I whipped this up in 30 minutes and it serves its intended purpose.

4 Likes

Are you aware of this component?


I think your method has the benefit that it does not require setting up a Zoom app.
1 Like

I wasn’t!
This was one of those “what if I can detect Zoom meeting?” through to completed PoC.

Couple of other benefits:

  • This is local only
  • Some organisation prevent creation of “apps” (I.e I can’t create Slack apps without approval)

I like how that one would cover all devices with one flow; if I needed to take a meeting on mobile phone or something.
I am impressed reading though that component, that’s exactly what I originally wanted accomplish!

1 Like

My organization limits this, but I can still create oauth2 which is the one that works.