Building a product based on an embedded device with Elixir, Nerves & Phoenix — Part 1

Adrián
4 min readSep 25, 2018

--

We are facing some changes in Europe regarding data protection. The EU General Data Protection Regulation (GDPR) has changed some rules, and has made some advancements protecting the citizens data. This is very good from an user perspective, but it requires work for the companies. Data must be treated very carefully, with contracts with every customer & provider, security is considered very important and consents to use people’s data need to be explicit.

Slowly, companies are more and more concerned about the data they manage, and they want to protect it and be GDPR compliant. This led to one of those companies to ask us for a product to sign digital contracts, consents with the users/patients, and other features they needed. One constraint was that they want to hold the data in their offices. No cloud, external servers or SAAS. Basically they wanted a box with the software running, and that’s what we did.

We could have used the traditional pre-cloud era approach. Buy them a server and put it in their installations. But even a normal server is over-dimensioned for their needs, it’s big -physically-, consumes electricity, it’s noisy sometimes… so we thought about it and concluded that we could try to embed it in a small box with a Raspberry Pi 3, that they could just plug and use. For them is pretty cool because they are using an iPad, so they just plug the box, and they have the app in their iPad through the browser, which can move with them through the installations.

We were going to do it using Elixir & Elm and it happens that Elixir has an awesome project, the Nerves Project, that would be perfect for our needs. We were excited by the fact of device ruled by the Erlang VM, with a very small footprint and the concurrency and reliability that makes the Erlang VM glorious.

The truth is that coming from years of pure web developments, starting to develop taking the OS and the hardware into consideration wasn’t a piece of cake. But I can tell you it was pretty fun. We had an amazing support from the community, we couldn’t have done it otherwise. We asked a lot in the Elixir Forum, and two core developers were specially helpful, so I want to thank to Connor Rigby, Greg Mefford, Tim Mecklem, Frank Hunleth…and some others… for their help. They are doing an awesome job.

After this introduction, let’s go with the technical details of the project.

We started setting up nerves in a Raspberry Pi 3, and no problem here. It worked! But we were just beginning :-)

The buildroot image is not what we were used to. The device had no network, no ssh access, no shell, we couldn’t debug easily, not easy to upgrade the firmware, we had to take the SDCard out of the device, burn the new image, insert it again and reboot… Not what we expected.

We found the nerves init gadget listed in the libraries page of the nerves web, it provides several useful tools for making the device more useful, so after we set it up we had a device connected to a network, with over-the-air (OTA) upgrades via ssh, an IEx shell accessible through ssh, and a mDNS domain published in our network.

Next we installed the UI using Phoenix and it was very satisfying to find out that introducing the local domain name in the browser showed our UI! Very exciting!

At this point we focused efforts on the UI. We build what we were asked for. Nothing new from what we were used to do, just developing a web app. But there was a point where I felt a bit different, from previous cloud developments. I wanted to show in the UI the usage of the storage. Showing hardware information wasn’t something usual for us. At that point, I felt comfortable with the sense of control that we got managing the whole stack: Hardware, OS and software. I finally understood Apple :-)

I can tell you something, OTP in an embedded device gives me a great peace of mind!

From here we had to face som other problems:

  • We needed a better way to debug the console without connecting the device to a monitor. We connected the Raspberry Pi to a console using a TTL USB Serial Cable.
  • We planned to sell the device in all the country, and who knows if in other countries too in the future. What if once the device is in the customer installations we needed to debug or fix something? Should we go to their installations? We can’t afford that. We need to connect remotely to the device. We have access to an elixir shell, but we need the public IP for the device, and a properly configured network that allow us to access the device. How do we get that IP?
  • What if we ever need a very basic ssh access to the device? Could we get access the busybox utils?
  • The project was based on a SQLite3 database. It was a very good idea for our initial requirements. All the data in a single file, easy to backup, portable, and it fit perfectly for the expected load. But as the project grows, potential customers asked us to make other developments, and I decided to use PostgreSQL in the device. What a fascinating journey is installing PostgreSQL in busybox…

Every point deserves their own post, and this one got already bigger than I expected, so let’s split them up. In the upcoming posts I’ll talk how we resolved those problems:

In the following days I’ll be publishing my notes on those topics, I hope you find them useful!

--

--

Adrián

Software developer.Python and Django expert moving to functional programming with elixir and elm.I read about many topics,from technology to self improvement