Vivint Smart Garage Auto Close
My car recently got stolen out of my garage so I wrote a script to automatically close the garage whenever both of our phones are not connected to the home Wifi.
Thanks to Nate K Spencer and this repository for the Vivint API integration needed to make this possible: https://github.com/natekspencer/vivintpy
To check that our phones are on our home WiFi, I used DHCP reservations so that they always have the same IP addresses. I had already done this for other purposes, so this was an easy step.
This all being said, I don't recommend Vivint Smart Home as they do not integrate well with other smart home vendors.
The script:
import asyncio
import logging
import os
import pubnub
import subprocess
from vivintpy.account import Account
from vivintpy.devices import VivintDevice
from vivintpy.devices.garage_door import GarageDoor
from vivintpy.exceptions import VivintSkyApiMfaRequiredError
pubnub.set_stream_logger(name="pubnub", level=logging.ERROR)
# Check if phone is on WiFi
def on_wifi():
logging.debug("Checking for devices...")
briana_phone = False
trevor_phone = False
try:
briana_phone = subprocess.check_output(["ping", "-c", "1", "-t", "1", "192.168.1.7"])
except subprocess.CalledProcessError:
pass
try:
trevor_phone = subprocess.check_output(["ping", "-c", "1", "-t", "1", "192.168.1.6"])
except subprocess.CalledProcessError:
pass
if not briana_phone and not trevor_phone:
logging.debug("Devices not present!")
return False
else:
logging.debug("Devices present...")
return True
async def main():
logging.getLogger().setLevel(logging.DEBUG)
logging.debug("Demo started")
def camera_motion_callback(device: VivintDevice) -> None:
logging.debug("Motion detected from camera: %s", device)
account = Account(username='[email protected]', password='mypassword')
try:
await account.connect(load_devices=True, subscribe_for_realtime_updates=True)
except VivintSkyApiMfaRequiredError:
code = input("Enter MFA Code: ")
await account.verify_mfa(code)
logging.debug("MFA verified")
try:
while True:
if not on_wifi():
logging.debug("Discovered systems & devices:")
for system in account.systems:
logging.debug(f"\tSystem {system.id}")
for alarm_panel in system.alarm_panels:
logging.debug(
f"\t\tAlarm panel {alarm_panel.id}:{alarm_panel.partition_id}"
)
for device in alarm_panel.devices:
logging.debug(f"\t\t\tDevice: {device}")
if isinstance(device, GarageDoor):
logging.debug("Closing garage door")
await device.close()
await asyncio.sleep(10)
await account.refresh()
except Exception as e:
logging.debug(e)
finally:
await account.disconnect()
if __name__ == "__main__":
asyncio.run(main())