During my daylight job I am used to write a lot of complex C++ code that is going to empower high end embedded devices applications. Sometimes i had to work on some of those so called connected devices. A category of devices that everyone is trying to push into the market no matter if it is really useful or not.

Every embedded connected project is facing big technical challenges that developers are struggling to solve: software updates, security, reliability and ease of use. So in my free time I started my own IOT project to see if given no constraints I was able to find some elegant technical solutions to overcome those issues. Here’s what i came up with:

Chik A framework made in GO that allows you to create IOT monolithic applications just by assembling or creating components called Handlers. The framework provides a pub sub based in process communication framework as well as a request reply like framework to communicate with another device over the network and an interface to store/retrieve data. The framework uses Json as the format for messages and stored data.

Why GO?

GO is not so popular on embedded devices. The vast majority of embedded projects i worked for during my daylight job were using C++ but GO has several advantages that are making the whole thing a lot easier:

It is reasonably fast: It is not as fast as C++ but most of the times it is fast enough.

It is easier and faster to write complex applications in GO rather than C++ because go does have a garbage collector and memory management is “assisted” I know these days C++ has improved a lot but it is not meant to be an easy language like GO.

and to write complex applications in GO rather because go does have a garbage collector and memory management is “assisted” I know these days C++ has improved a lot but it is not meant to be an easy language like GO. It is statically linked: every library is bundled within the executable and that simply throws out of the windows all the frustrations an embedded C++ developer is facing everyday: lack of standard toolchains, dynamic linking nightmares and - when developing for embedded devices - even a worse situation.

It does not require an embedded SDK: GO compiler can cross compile for a wide range of architechtures. Let’s suppose you want to cross-compile for your raspberrypy: just issue the following command: GOOS=linux GOARCH=arm GOARM=6 go build and you’re done how easy is that instead of having to spend hours in front of the PC that’s just compiling the yocto embedded SDK hoping this is the last time you are running bitbake

Architecture

The framework allows allows to create monolithic applications by creating an instance of the Controller element. It acts as the bus for messages and the orchestrator for the various building blocks called Handlers. The controller manages the lifetime of handlers, gives them the channel to communicate one each other and allows to send messages to the outer world via a Remote .

Handler is an interface that contains a single function: Run . It gets executed in a goroutine and can communicate and receive messages through the Controller API. Having multiple goroutines helps the application to scale well on different hardwares even being a monolithic one. Here’s an example of an handler

The remote communicates with the outer world and the mobile app (yes there’s one) with a stream of data sent through a persistent TLS connection. the server runs the same software as the client but with different handlers. Currently it is provided only of a routing handler that allows to forward messages to the destination client based on the uuid of the recipient of the message. I choose to run a persistent TCP stream instead of a more common http REST API because I really enjoy having lights to respond immediately to commands I am issuing them from the mobile application.

In addition to the binary for the software a Json configuration file must be provided. If it is not there the application will create a reference one when started. The file contains configuration data for each handler as well as a storage section for the storage of runtime data such as timers. This allows to ease the backup or a migration to another hardware because only a single file needs to be copied.

Configuration file sample

Using Only Json as the stored data format and message payload data format helped a lot because it is a human readable format and there’s no need to write adapter classes to convert data. As a plus GO has great builtin json APIs.

Project status and roadmap

I am currently using a client written with the framework on an old MIPSel device that controls my garden lights. I put it also on a RaspberryPi zero to switch my parents garden lights and irrigation system. Then I have a cheap VPS that runs a server application for every device and does message forwarding. To control the whole system i made an incomplete Qt/QML app for Android that does the basic stuff such as setup timers, turn on/off something and update the remote device when a new version comes out.

Mobile application

The most important thing i want to add in the near future is mutual authentication. Currently clients are checking the validity of the server certificate because that was easy with LetsEncrypt. Client side authentication requires a lot more effort to manage certificates from the various devices so it has to be done with care.

Other than that I want to add more handlers for things like new protocols, and third party access like Google home and Apple HomeKit and give some love to the mobile application but since it is mostly a spare time project I will do what’s more fun first and what I really need second.

As a final note i think GO can be a blast in the embedded world. And this framework is my proof of concept that it is doable. Hope to see some innovations in the embedded field in the years to come.