My house heater has a REST API with phidgets, scala, swagger, akka, MongoDB

Summary:  My single-board computer runs linux and connects to the internet.  It has lots of sensors and can monitor and control 11 zones of hydronic heat in my house.  It is programmed with scala and has a REST API through scalatra.  It exposes the swagger spec and has an HTML5 sandbox UI.  It saves data over the cloud into MongoDB via MongoLab!

TL;DR

I had a problem with the effectiveness of my hydronic heater control in the house and took action, hacker style.  The goal: take in real inputs and apply a proper PID control loop to avoid excessive heating of the house.

I started out by planting these temperature sensors in the walls around the house:

I then took a Phidgets SBC2 running Debian and screwed it to the wall.  Why go with a Phidget instead of arduino?

  • It runs on nearly zero power.  This is the problem with re-purposing your old crappy desktop as a home-server—the Phidgets SBC2 takes between 13 and 500mA of power to run, has 64MB RAM, 400MB SSD, ethernet, and runs fricken Debian.  It has full access to the package APT repository.  Read again!  You SSH to this SBC, not use a shitty serial cable you got from your grandpa!
  • It has 8 analog inputs, 8 digital inputs, 8 digital outputs and 6 USB ports.  If you want more IO you plug in an expansion board.  I put an LCD on (more on that in a minute) and am adding another IO board.  They also have GPS, gyroscopes, AC/DC current sensors, servo controllers, etc.
  • You don’t have to learn some crappy, unsupported/un-tooled language to program this.  Remember, it runs Linux!  There are drivers to communicate with the IO on the board and the rest is good-old-fashioned programming.  It supports perl, ruby, flash (yes, really), java, c# out of the box.  It’s Debian!

I plugged the temp sensors into the analog inputs and tried out the simple java-based test programs.  They worked well (but dear lord, I’m over writing java).  And programming a 4 line X 20 char LCD?  It’s easy with this thing but it’s hard to write a decent UI.  I bought a joy-stick interface (also, easy) but still, ghetto UI is not blog-worthy.

So I got to thinking—there is a network port on here, it runs java, so… how about put a REST API on it?  I could easily write a UI with backbone, iOS, etc to communicate with the SBC!

Experiments followed, along with a lot of SCP’ing of files to the phidget.  First, I tried to run a simple java-based REST API with Jersey.  I grabbed this sample from github:

Wordnik Swagger Sample app

It would barely start.  Jersey needed too much RAM—I adjusted the max memory settings but the app server was swapping like crazy—it eventually started but would take 10 seconds to respond to a request.  The JVM w/64MB RAM wasn’t looking so good.

I went lean on the Phidget and followed these fantastic (yet involved) instructions to get node.js running:

Node JS running on a phidgets SBC2 board

It worked after some trail and error—soon node + npm were working well.  It was responding quickly with this sample service:

Wordnik nodejs sample app

But the driver support from node with the phidget IO boards just isn’t baked.  There is great work from some folks on github but was I comfortable with relying on them to do the driver integration?  I’ve been there before and writing low-level drivers is simply no fun.

So I tried the JVM another time, after @casualjim started sitting next to me at Wordnik.  We took the scalatra framework and built a stand-alone executable with sbt assembly—after all scalatra IS called a “tiny sinatra-like web framework for scala” (emphasis on the “tiny”).  The scalatra app packed down to 30MB and started without a hitch.  And guess what?  It runs extremely fast!

I took it further—saving data!  I added the mongodb driver to the dependencies and connected to the excellent MongoLab service.  No problem!  I then added Akka schedulers to make the calls to save data periodically.  OH and started using salat to serialize the data structures for MongoDB.  You can see where this is going.

So now I have a fully functional interface to my home heating system.  It will get the PID control loop after I save some data and build up the model, followed of course by a better UI (Swagger-UI is nice for now).  That’s the easy part!

The entire source is available here (yes, my home heater control is FOSS):

https://github.com/fehguy/swagger-for-the-home

I’ll get into the structure of the server more in a follow up post, as well as the PID control (when done) and client app.  Until then, why, I ask, are there not more APIs in YOUR house?

Notes

  1. fehguy posted this