Around last year, we started encountering a frequent problem at XION. The winters can get somewhat chilly in San Francisco, and thanks to “Karl The Fog”, it can be pretty chilly during the summer as well. Fortunately, we have a heater installed at the arcade, but it suffers from a lot of the same problems Internet-connected thermostats promised to solve. Notably, the ability to start heating up the space before arrival. Although the problem I personally encountered pretty often was forgetting to turn the heat off when leaving.

This typically isn’t an issue in people’s homes, because people usually want their homes at a constant temperature. At XION though, being in an industrial zone, gas bills can be quite expensive. So to save on the cost of heating the space all the time, we often leave the heat off when nobody’s there. Forgetting to turn off the heat before leaving then can be quite a hassle.

In my home at the time, I was using the Nest thermostat and was fairly happy with it. However, at that time there were some growing concerns with choosing to run Nest at home that made me hesitate about installing one at the arcade. Nest’s products were getting hacked, I’ve been noticing an increasing number of reports online of malware targeted towards IoT devices, and the increasingly sluggish web app offered by Nest is now apparently loading an entire game engine just to change the temperature.

A couple of years ago I had backed a cool Kickstarter project for a handheld device called the Pocket C.H.I.P. It’s an amazing tiny computer with a resistive touchscreen, 480x272 display, headphone jack, full QWERTY keyboard, built-in WiFi, and a row of GPIO pins right at the top of the screen. All for only $69.

The company behind the Pocket C.H.I.P. was also based nearby in Oakland, and had some really great marketing behind it. With the offer to “Cyberpunk my summer”, I absolutely couldn’t refuse.

The other thing that appealed to me about the Pocket C.H.I.P. was the fact that it ran the mainline Linux kernel, a full X11 desktop environment, and included some really neat software such as PICO-8, a “fantasy game console”. I didn’t know about PICO-8 before buying the Pocket C.H.I.P., but after playing around with it I realized it’s really the perfect device for it.

So of course, the first thing I did was write a DDR emulator.

It was fun playing with PICO-8 on the C.H.I.P., but it did get pretty tiring to type on that strange keyboard after a while, so I put it down for a few months and it started to gather dust. Unfortunately, a lot of other people must’ve also ran out of uses for it and the company ended up going bankrupt, and they even closed down the website. Fans of the C.H.I.P., like myself, were devastated.

A few more months go by, and I start thinking about this thermostat project. Noticing the dusty Pocket C.H.I.P. sitting on my workbench at XION, I suddenly got very excited about turning it into the thermostat I’ve always wanted.

The Pocket C.H.I.P. is really the perfect device for a DIY thermostat. It already has that touchscreen, it runs Linux, it has exposed GPIO pins right at the top, plus it looks really cool. The only missing piece was the actual temperature sensor. Once I had that, I can just connect an electronic relay to the GPIO pins and use that to control the switch that goes to the heater.

I figured the criteria for a successful thermostat were pretty simple too. It needed to control the heater (obviously), but it should also be able to automatically control it based on a set temperature. Additionally, I thought it should have a very cyberpunk UI to fit in with the rest of the XION aesthetic. And most importantly, I also need to be able to turn it on and off remotely.

The first thing I started to do was work on the UI. At first I experimented with writing the UI using the GTK library, which is a really popular UI toolkit on Linux. GTK was working out fairly well, but I found myself customizing so many aspects of the built-in widgets in order to make it both look more cyberpunk and function better with touch (so the controls needed to be enlarged).

In the end, I decided to write my own basic UI toolkit for this project since I was customizing so much of GTK anyway. I ended up calling it Bubbles. With my own library, I was able to make nice large buttons that fit the aesthetic I was looking for. I was even able to add some eye candy like a graph visualizer, spinning 3D thing and a clock.

The next thing to do was to write the controller logic for when to turn on and off the heater. When you’re heating a space, you actually don’t necessarily want to turn off the heat as soon as the thermometer reads the target temperature. Otherwise, the heat would shut off, the room would start to cool and the heater would turn on again almost immediately (depending on how well insulated your room is). To solve this, I made it so the temperature would fluctuate like a sine wave around the target temperature instead. This posed some interesting challenges in the UI as well; it’d be kind of confusing if the thermostat indicated that 73 is the target temperature, and the current temperature is actually 74 and the heater is still running. I ended up programming the UI to essentially lie to the user about the current temperature to avoid this confusion.

I assume other electronic thermostats do this as well, although I haven’t confirmed it. I did notice the Nest thermostat does an interesting trick in its UI regarding the current temperature reading. Displayed as a radial dial, normally both the target and current temperatures are both visible as “stops” on the dial. However, when the current temperature is close to the target temperature, I noticed that the current temperature is hidden. Pretty clever! I think that’s a good indication that Nest is allowing for this temperature hysteresis as well.

Finally, the last bit of work to do is the remote control interface. The first iteration of this was just a simple UNIX socket exposed on the filesystem that allowed you to send commands to it by writing to the socket. For example,

echo "set_enabled 1" | socat - UNIX-CONNECT:/var/run/user/1000/chipotherm/socket

Exposing this first as a UNIX socket would allow me to build any kind of remote interface on top of it. Ultimately, I ended up also creating a web interface which was capable of communicating via this socket, but offered a much more user friendly UI. Here’s what it ended up looking like.

Pretty simple, and obviously inspired by the UI that actually runs on the device. The remote control UI can actually run on a different “command and control” server, and the C.H.I.P. will connect to the server when it boots up and long-poll for commands. This level of indirection is nice because I didn’t have to expose the actual thermostat itself to the Internet or open any ports on my router.

I ended up writing the thermostat code all in C++, and is available on my GitHub. The command and control server is written in Go and is also on GitHub.

So far, “Chipotherm” has been a huge success! I’ve been running it for several months now and have had hardly any issues. Most recently, I even added sound effects just for fun. The Pocket C.H.I.P. has a built-in headphone jack, so I might as well use that too!

I even have a spare Pocket C.H.I.P. that I haven’t found a use for yet. If you have any ideas, definitely shoot me an email. Who knows, I might even start using it as a replacement for my Nest at home.

Posted 10 February 2020