UnderControl: A home automation suite

I was fed up with having several different apps to control my TV, lights, plug sockets and monitor my RPi servers. I decided to build a suite of tools, built around 3rd party APIs to bring this all together in one place.

Key Technologies

Python | FastAPI | TypeScript | React | SocketIO | TOML

What did I Learn?

I’ve been meaning to learn TypeScript for a while, as I’ve previously only worked with JavaScript and have been told by a number of people that TS is the future. I decided to write the frontend using TS and React.

I’ve used SocketIO in the past, but I fancied a refresher, so I enjoyed re-learning how to use that to enable a lower-overhead streamed update of system stats.

How does it Work?

As mentioned above, the application is split into a number of components…

The Backend [Python 3]

The backend is written in Python, using FastAPI as a wrapper around FLASK and OpenAPI. As part of this, I wrote an extensible plugin layer to make it quick and easy to add new “adapters” for new APIs.

Each adapter encompasses all the functionality for a given API. At the time of writing, there are two that I’ve written:

  • TP-Link KASA: Performs device discovery and offers status feed and control capabilities to all detected devices on the local network.
  • LG WebOS TV: Allows the user to pair their TV(s) to the server and offers a reasonable subset of features from the WebOS control protocol.

FastAPI allows us to use Pydantic to define our response models, which then integrates automagically with the incorporated OpenAPI layer to publicise the APIs.

The Frontend [TypeScript / React]

The frontend uses TypeScript and React to read data from the various adapters and services and display it to the user in a clear way.

Currently the only part of this that is written is the system stats visualisation frontend. This connects to the UnderControl System Monitor services running on computers on the local network, and streams system information stats direct to the frontend using a socket connection.

System Monitor Dashboard

Since I’m using TypeScript, it’s really easy to validate the data models coming from the different devices and ensure that the data coming through is correct to display. I mirrored the Pydantic models created for the backend into TypeScript.

Note: The frontend is currently under development, so I’ll try to remember to come back to this and update later.

The System Monitor [Python]

This is essentially a FastAPI wrapper around the psutil Python library, which gathers a number of system statistics and listens for socket connections from the front-ends. It stores the stats in an internal state, which is updated periodically, and emits them to any listening clients over SocketIO sockets.

The application is configurable using TOML files, and any config parameters can be overridden on the terminal. The module setup script includes a custom action to install the module as a user or system daemon (designed for Linux systems, primarily Raspberry Pis).