Home Automation With Android Things & Kotlin
My Android Things Home Automation Hub, the green dongle is the TI CC2531
Jul 08 2019 · 7 min read
We’re spoiled for choice these days when it comes to choosing a Home Automation system. We could go voice controlled with Alexa or Google Assistant, or choose from well established ecosystems like that from Phillip’s Hue. All these systems have one thing in common, proprietary hubs that act as the center of our smart homes. Some more extensible than others, however it’d be nice if we could build our own hubs independent of these proprietary systems and administer them as we wish.
Android is an extremely versatile operating system with APIs for a smattering range of technologies used in IOT from Bluetooth to WiFi, along with USB host mode to interface with other peripherals quite conveniently, making it a great candidate to build a Home Automation hub with. If that weren’t enough, Android Things is even less stringent than Android on phones and tablets as it eschews permission prompts for Bluetooth and USB, implicitly granting them on request on the device it runs on. So, let’s start cooking.
Parts & Supplies
Raspberry Pi 3, please do not get the B+, only the B is supported for Android Things ($35).
Rf Transmitter and Receiver for RF modules ($7)
RF wall plugs from Etekcity (3 pack $24)
Texas Instruments CC2531 ZigBee Dongle ($14)
CC Debugger to flash CC2531 ($15) the official one from Texas Instruments costs $50, but you can find generic ones like that linked above for less. If you don’t mind springing more, I’d advise to get the official debugger.
Gledopto multicolor ZigBee Bulb ($25). Hue bulbs should work too, but a Hue bulb is almost twice the price!
First, there needs to be a way for client devices (Android phones owned by you or your guests) to send instructions to the hub. Since this is a home automation system, let’s keep things local; Android supports Network Service Discovery or NSD, which is a fantastic way for realtime communications with devices on the same local network. It’s based on DNS-SD which is how wireless printing works on a LAN. Essentially each client will open a socket on the hub, and write instructions to it directly, and receive responses on that same socket allowing for duplex communication.
ServerThread managing concurrent communication with multiple clients
Note that the SocketThread is blocked waiting for a client to connect. This however doesn’t stop clients from writing back to the server as the other methods are called on their own separate threads.
Connection class managing IO between the Server and its clients
Client side, the class responsible for managing the socket is the
Note again that the client uses a separate ExecutorService to send messages to the server, while the main thread itself manages the socket opened between it and the server and broadcasts any server responses using the
Broadcaster class which is just a wrapper around an Rx
ClientThread are hosted in instances of Android
Service classes to keep them running in the background.
Since communication will be over a raw input and output streams, there needs to be a a method of serializing and deserializing each communication
Payload. We can use a simple Kotlin data class of the same name to do this:
Simple Payload class
Next we need an abstract way for our hub to communicate with whatever peripherals it may care about, both synchronously to respond directly to client requests, and asynchronously if a peripheral broadcasts an update. Synchronously, our previous
Payload data class class works, a
Payload comes in as input, is processed, and an output
Payload goes out. For asynchronous commands, each instance of a
CommsProtocol class has a
PrintWriter it can directly write out of. It’s important that whatever is written out is a serialized representation of a
Payload, else the client won’t be able to interpret it.
The Base class for responding to client request server side
Now that data can be sent to and received from the client, implementations of the CommsProtocol can be written. Simple RF wall sockets and ZigBee bulbs cover my basic home automation needs for now, and so that’s all I have implemented, however, the system is designed to be extensible to support whatever peripheral.
Android Things unfortunately, is quite slow, making it impossible to interface directly with RF transceivers and essentially duplicate the packets sent out by cheap wireless switches. An Arduino however, is perfect for this, and it’s as easy as adding a USB serial dependency to use serial over USB to communicate with an Arduino; and that’s exactly what this protocol does. It sends commands to the Arduino to sniff switches, and when the packet sniffed, it replicates it letting you use your phone as a universal remote. The video below is the original implementation that uses BLE instead of a wired serial connection, which still works but is a bit over engineered and contrived. I’ve since moved to a direct wired connection.
This protocol creates a ZigBee network that ZigBee peripherals can join. It again uses Serial over USB to communicate with Texas Instruments’ CC2531 dongle running their Z-STACK ZigBee 3.0 solution. All of the heavy lifting is done by ZSmartSystems’ ZigBee Cluster library. It essentially ports their CLI application to an Android GUI along with conveniences for switching light bulbs on and off. The real fun part was writing an implementations of their
ZigBeePort for Android. Again it uses the excellent USB Serial for Android library for managing serial communications. A video of its operation is shown below.
So, that’s one way to build a home automation hub for a little under $100. Full source follows: