Monday, January 6, 2020

On Air via HomeKit

I work remote from home and spend a large portion of my day in web meetings with my camera on so my coworkers can see into my home office. Mrs.Chaos frequently wants to wander into the office, but doesn't really want to do so during done of these video meetings and I've always wondered if I could create some sort of "On Air" so that when I'm in a video meeting, I could notify people outside of the office. I have finally jury-rigged something together to do it and it's a great testament to the future of home automation. I can't wait until we can use natural language to describe this, "Hey Siri, setup an automation so that when my work computer is in a web meeting the Eve Flare turns red and when the meeting is over it turns off again."
One of the good (and the bad) things about HomeKit is that I can't just use a script on my computer to fire events into HomeKit or to set scenes, only automations built inside the Home App can do this sort of thing by querying HomeKit accessories. So here was the process I went down to do this fun project:
  1. Write a script to check if it's working hours, than ssh'es to my work computer and tests if a video conference is on
  2. Use Homebridge to have a HomeKit Switch accessory that runs a shell script every 5 minutes
  3. Video conference means, "the switch is on" otherwise "the switch is off."
  4. Home Automation in the Home App so if the switch is controlled to "on" the light turns on, if it's controlled to "off" the light turns off.
The script was a tad trickier than I expected, but not especially difficult. Checking if an app is running, "GoToMeeting" or "zoom.us" or others is just a simple process check:
ps aux|more | grep "${processName}" | grep -v grep | wc -l
In this modern day of web meeting programs (Google Hangouts) how do you tell that is running? I had to determine if Chrome or Safari or Firefox had turned on the webcam. This is just a matter of using lsof to search fo VDC (Video Connection?). An interesting trick is that all the browsers automatically make a least one connection to VDC when they are running without using the camera, so they show two connections when the camera is going. Also, if you have another logged in user on your computer running Keybase, then the Keybase OS throws errors in lsof so I have route stderr to null.
lsof -n 2>/dev/null | grep -i "VDC" | grep -i "${processName}" | wc -l
Cool, right? So if the first command returns more than 1 result or the second command returns more then 2 results per process, there must be a web meeting running.
Homebridge is the gem of the HomeKit ecosystem for the hobbyist. It is a HomeKit hub written in node that can do anything a Node server can do, like call out to web apis or making internet requests. I have my WeMo, SamsungTVs, NetAtMo, Dropcams, and Connected by TCP lights all running inside of Homebridge and part of my HomeKit system, even though none of them support HomeKit.
For this setup I installed a package called cmdSwitch2 which shows up as a HomeKit switch and runs shell commands for "turn on," "turn off," and "get state." It will also poll the "get state" command on an interval, so I used to this to have it poll for a state every 5m. Just this easy:
{
  "platform": "cmdSwitch2",
  "name": "CMD Switch",
  "switches": [{
    "name" : "Web Meeting",
    "state_cmd": "webmeetingStatus.sh -r me@192.168.1.1:webmeetingStatus.sh",
    "polling": true,
    "interval": 300
   }]
}   
The final step of setting up the Home automation is done inside the Home app on iOS and it all "just works."