My girlfriend is a large animal veterinarian and has to park her vet truck at home. Her truck comes equipped with a “vet box” which provides climate control for her equipment. To ensure the vet box does not drain the truck’s battery, we must plug it in whenever its parked. We live at an older apartment and have found ourselves discovering the vet box’s outlet having been abruptly turned off. This requires either a fuse to be reset or the reset button on the outlet itself to be pressed. Rather than having us manually check if the outlet is ever turned off, I figured I could automate this process with a little Python!

The hardest part about this project was figuring out how to determine if the outlet was off. I decided that simplest solution would be to leverage a Kasa Smart Plug. I leverage a bunch of these throughout our apartment, mostly to control lights, as many of our rooms do not have traditional light switches.

kasa-smart-plug

The plan being, we can leverage a Kasa Smart Plug to sit between the outlet and the truck’s extension cord. There are some handy tools for interacting with Kasa Smart Plugs, which allow us to query if the plug is turned on or off. Additionally, leveraging some Python we can determine if the plug is not responding to our requests. If we determine that the plug is off, or not responding, we can send an alert via email or Pushover. I was thinking that running this script every hour would be sufficient. Additionally, we could run this script on our Unraid Home Server, which means I should probably update this post.

Here’s the code that I’ve written.

Disclaimer
This code could be refactored and made prettier, but I only allocated myself one hour to develop this.
import asyncio

from email.mime.text import MIMEText
import os
import smtplib
import sys
import typing

from kasa import SmartPlug
from pushover import init, Client


async def fetch_plug_is_on(ip_address: str) -> bool:
    smart_plug = SmartPlug(ip_address)
    await smart_plug.update()
    return smart_plug.is_on


def send_alert(message: str):
    with open("user_key", "r") as user_key:
        with open("api_token", "r") as api_token:
            client = Client(
                    user_key=user_key.read().replace("\n", ""),
                    api_token=api_token.read().replace("\n", "")
            )
            print(user_key.read().replace("\n", ""))
            print(api_token.read().replace("\n", ""))
            client.send_message(message, title="Vet Truck")


def send_email(to_email_addresses: typing.List[str], subject: str, body: str):
    """Sends an email address from our sender email address."""
    # so we can get path based on where this script is located
    # and not from where we execute it from
    from_email_address="sender-email-address@domain.com"

    with open("gmail_password.txt", "r") as myfile:
        gmail_password=myfile.read().replace("\n", "")

    smtpserver = smtplib.SMTP("smtp.gmail.com",587)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo

    smtpserver.login(from_email_address, gmail_password)

    msg = MIMEText(body)
    msg["Subject"] = subject
    msg["From"] = "sender-email-address@domain.com"

    for to_email_address in to_email_addresses:
        msg["To"] = to_email_address
        smtpserver.sendmail(from_email_address, [to_email_address], msg.as_string())
        smtpserver.quit()


if __name__ == "__main__":
    ip_address = "some-ip-address"  # Can find this IP address by running kasa in a shell.
    try:
        is_plug_on = asyncio.run(fetch_plug_is_on(ip_address))
        if not is_plug_on:
            message = "The vet-truck plug is turned off!"
            print(message)
            send_alert(message)
            send_email(
                    to_email_addresses=["personal-email-address@domain.com"],
                    subject="Vet-Truck Plug",
                    body=message
            )
    except:
        error_message = "The vet-truck plug is not reachable, check internet connection or if plug is plugged in"
        print(error_message)
        send_alert(error_message)
        send_email(
            to_email_addresses=["personal-email-address@domain.com"],
            subject="Vet-Truck Plug",
            body=message
        )

The script essentially queries the specific outlet we’ve setup for the truck, asking if the plug is turned on or not. If we fail to speak to the plug, or if the plug says that its not on, then we’ll send an email and pushover notification to alert us that the outlet needs to be reset. We can couple this script with Unraid’s User Scripts, allows us to easily run this every hour of every day.

Overall, I’m satisfied with how quick this was to throw together, and how it can grant us a peace of mind that the truck’s battery is safer.