On the last post, I introduced my new home automation project and the reasons why I started it. This article provides more details on the software running on the concentrator that controls the devices present in the home.
As a reminder, here is the global design of the project:
Today we will focus on the concentrator component. The hardware I use to run it is a cubox-i2 ultra, connected via ethernet (wifi may come later). This board is based on the popular Freescale i.MX6 chipset. It is much more powerful than needed but I had one that I did not use. Moreover it is now directly supported in yocto. So it runs a linux system based on the « core-image-minimal» layer with an additional layer containing the new components. Each component is running in a dedicated process. Using yocto should prove to be very useful in the future to support several boards quite easily. It typically expect the Raspberry Pi to just work directly.
The concentrator is composed of 3 daemons :
Flockd is the daemon that manages the RF controllers connected. It currently supports the enocean and RFXCom usb transceivers. All messages specific to each protocol are translated to a common message format. These messages are then transferred to another process : mastiffd.
Mastiffd is the daemon handling the messages coming from flock. Its task is to analyse and process them. It especially has to map the ids and features of the devices to something more meaningful to an end-user. So it contains a database of all installed sensor/actuators with their friendly names and current states/values. Mastiff is the component that will automatically control actuators when « intelligence» will be developed.
Finally xmpp-frontend is the xmpp client that connects to the cloud so that the mobile application can view and control the devices. A second front-end will be added later so that the concentrator can be controlled on the LAN without using the cloud.
Flockd is currently the most developed component (although still in early stage). Mastiff and the xmpp frontend currently run in the same process and still contain a lot of hardcoded values. All components are written in python, based on twisted. This is not the most performant or memory efficient choice for an embedded system, but considering the hardware specs of all available boards this should not be an issue. On the other side python allows to develop and debug much faster compared to C++, especially since for this project most code is IO based. Each python daemon consumes about 10MB of resident memory which is very acceptable. The uptime is also promising : The cubox-i already ran for more than 30 days without issue before I restarted it for a firmware upgrade.
Most of the code in flock is managing the controllers. Here is a class diagram overview of it:
There are 3 parts in flock:
- The controllers.
- The frontend.
- The message router.
The controllers are the most important elements in flock: They transform the RF specific messages to a common message format (FlockMessage). The controllers are implemented as twisted protocols. The current controllers are implemented as 2 protocols for each controller :
- The Receiver protocol is in charge of assembling complete RF packets. It receives some bytes and concatenates them until a full packet is received.
- The controller protocol is in charge of handling these packets and creating FlockMessage objects from them. The controller protocol inherits from the receiver protocol.
Based on the twisted principles, the protocols are associated to transports. Both Enocean and Rfxcom transports inherit from the twisted serial transport (They both use an FTDI usb/serial interface). Transports are automatically discovered during startup via the ControllerFactory class. The ControllerFactory scans all the serial devices and searches for known entries to create the controllers. This allows to automatically use the controllers that are plugged.
The Frontend is a network server exposing the messages on a local TCP socket. AMP is currently used as a message protocol, but I will probably replace it with protobuf in the future. There are only two types of messages defined for the moment : Report and State. Report messages are events coming from the sensors/actuators. They are publised to the clients. State messages are requests coming from the clients to change the state of an actuator.
The link between the frontend and the controllers is done via a message router. The message router is in charge of routing the messages from the frontend to the correct controller. The message router in composed of 2 lists: The controller list and the frontend list. Finding the correct controller is simply done with a protocol identifier that is present in the messages. If several controllers handle the same protocol, then the first available controller is used.
The Flock code is already available on github.
The Next Steps
There is still plenty of work to do on these components, but they already allow to monitor the temperature and control some power plugs. The next steps that I will work on are:
- Support for the Rfxcom RFY protocol (aka Somfy RTS).
- Remove hardcoded part of mastiff.
- Split mastiff and create an independent xmpp component.
- Replace amp with protobuf over unix socket.
Even if only flock is published today, you can already start to play with it: When the daemon is started in verbose mode, it prints information of all received messages. This is a good start to play with it as a library from your own tools.