Rust Thermometer – Part 1

I’ve decided to build a thermometer from scratch. I know, I can buy it, but it’s not fun. I found it as a perfect occasion to please my wife (she wants it) and to try new things. What new things? Mainly resin.io and resinOS.

Goals

Here’re the main goals:

  • Measure temperature (two rooms & outside).
  • Forecast for a day (if I find a service, which offers it for free via some nice API).
  • Check if terrace doors are open / closed.
  • Show all available info on some nice coloured display.
  • Write it in the Rust programming language.
  • Test resin.io (even with one device).

For today, we will just setup the toolchain, deployment, local development and some Rust application prototype.

Components

I’ve decided to go with following components:

Assembly

It’s easy, don’t worry. Just follow instructions in the A Raspberry Pi Thermometer you can Access Anywhere article. And if you’d like to have more than one thermometer, check the Multiple DS18B20 temperature sensors forum post.

resin.io and resinOS installation

Create resin.io account and go to applications dashboard where you can create a new one. Application name is also used as a Git repository name. My application name is rust-thermometer.

Select application, click on the Add device button and:

  • select your device type,
  • switch edition to Development,
  • setup networking and
  • download resinOS image.

You can use Etcher (or any other tool, this one has 81MB, Electron, yay) to flash downloaded resinOS image to your SD card. Insert SD card into your Raspberry Pi device and turn it on. Wait for a couple of minutes until your device appears.

Works like a charm, resinOS installed and device is up and running.

Resin CLI installation

CLI stands for Command Line Interface. Follow installation instructions. Unfortunately, these instructions didn’t work for me and I had to download latest release, unzip it and install manually. Probably some npm, nvm, node, brew and macOS mess. Will investigate and report issue later.

Find your device

resinOS is installed, device is running, visible in our resin.io application. Let’s check if we can find it with sudo resin local scan command.

It’s here. Host name cae15d3.local with IP address 10.11.12.133.

1-Wire configuration

In order to make DS18B20 thermometer working, we have to add dtoverlay=w1-gpio line to /boot/config.txt (documentation). It’s not possible now (boot partition mounted as read-only). Actually, it’s possible, you can remove SD card, mount it on your computer, etc. But resin.io provides better way named Advanced boot settings. To make it short, open your fleet configuration and add RESIN_HOST_CONFIG_dtoverlay variable with w1-gpio value. Device will be automatically rebooted with new boot configuration in a few seconds.

Rust project

Found just one example  – resin-rust-hello-world. I took it, modified it little bit and introduced rust-thermometer. How it differs from standard Rust project? Not much, just two additional files.

resin-sync.yml – it’s for local push where we just define device target architecture, build it and move the resulting binary to a common location.

Dockerfile.template – template for Dockerfile where we can use variables like %%RESIN_MACHINE_NAME%%. These variables are automatically replaced when we deploy application to a device fleet.

Rest is Tim’s temperature-serve-pi rewritten to the Rust programming language.

Local development

Dockerfile.template is not supported in local push command. Create Dockerfile (copy & paste) and replace %%RESIN_MACHINE_NAME%% with raspberrypi3. List of supported devices. Then you can run sudo resin local push cae15d3.local -s . –force-build command to run your application on the device.

Or use local-push.sh script which does all these things for you.

Why –force-build? Old version was always pushed without it even if I modified Rust source code.

Fleet deployment

Every application has associated Git origin within resin.io. Mine is gh_zrzka@git.resin.io:gh_zrzka/rust-thermometer.git. Add resin origin as a first step:

  • git remote add resin gh_zrzka@git.resin.io:gh_zrzka/rust-thermometer.git

You have to do it just once. If you’d like to deploy application to your fleet, just push master branch to the resin origin:

  • git push resin master

Wait for a while and …

… that’s it. Open application and wait for deployment (couple of minutes). Open your device and you should see temperatures in the logs.

Troubleshooting

I wasn’t able to deploy rust-thermometer for the first time. And that was because rustup doesn’t understand armv8l (Raspberry Pi 3 B+). Fixed it with this workaround. Not nice, but I’m happy with it now, because I have just one device for this project.

Conclusion

I like it. There’re still some bugs, but generally, it’s a very nice service and I’ll keep testing it.

Part 1 goal was achieved:

  • setup toolchain,
  • setup deployment,
  • setup local development and
  • simple temperature reader with hardcoded devices, … (released as v0.0.1, to track progress).

Next part will be about Raspberry Pi display and some Rust graphics library (didn’t choose one yet). Wish me luck, because I do not expect that it will be an easy ride like this initial setup.