It’s ALIVE

Setting up wireless

Capturing weather data is useless without saving / displaying it. Lake Effect will send the data it captures to a Phoenix application over HTTPS in JSON format. I did not want to dig a trench to run power/Ethernet to the shed, it is around 100 feet from the house. Life is too short to dig holes for fun! Wireless will be used for connectivity and solar for power (future project). Setting up the wireless connection within Nerves is easy.

Nerves Network provides wired and wireless network setup for Nerves projects. As with any hex package, add it to your mix.exs file and run MIX_TARGET=rpi3 mix deps.get.

{:nerves_network, "~> 0.3.6"}
$ MIX_TARGET=rpi3 mix deps.get

Configuration takes place in config/rpi3.exs because I only want wireless enabled for the rpi3 target.

Configuration begins with setting your regulatory domain, US in my case. The key type is obtained from your environment vars (at build time) and defaults to WPA-PSK. I use the same approach for the wireless ssid/psk configuration to avoid committing any secrets to the repo. Wired Ethernet is configured to use DHCP, for the event that I need to plug in a cable. Doing so saves me time not having to flash it to configure the port.

I was concerned that the distance between the router and the pi would be too large. Using a wifi strength app on my phone, I determined we had plenty of signal in the shed, dodged a bullet there!

Enabling remote firmware flashing

Once the hardware was mounted in the shed, the nightmares began where I had to shovel a 100 foot path through 4 feet of snow to flash changes. That is simply not happening, and during Lonestar Elixir 2018 Brien Wankel mentioned that he flashed his Jeep remotely. A quick duckduckgo search and I found Nerves.Firmware.SSH. To use Nerves.Firmware.SSH in your project add the hex package to your mix.exs file and run MIX_TARGET=rpi3 mix deps.get.

{:nerves_firmware_ssh, "~> 1.2"}
$ MIX_TARGET=rpi3 mix deps.get

Configuration was tricky

After an hour of testing different configurations, I found that my mixture of ssh keys with and without passphrases caused some sort of issue. Only after I created a directory under ~/.ssh, generated a new key, and used --user-dir was I able to flash the weather station over ssh.

The ssh key is configured by setting the NERVES_FIRMWARE_SSH_KEY env. var on the machine building the firmware. Reading the key in versus adding the key to your config was my preference, YMMV.

Note to self: I need to build a test application and send in a bug report…

Creating the Thunder Snow server

Having a personal weather station does me no good if I cannot view the data that is being collected. The first HTTPS interface would be a very basic Phoenix application. Bearer token authentication would be used because I could write a very small plug to block access to the single JSON endpoint that the weather station would be POST’ing to. Data would be displayed on the index page using bootstrap to make things look :ok.

Authentication / Authorization

When the plug is called it must determine if the requester is the weather station. If the bearer token from the request matches the token from config, it’s safe enough to assume the requester is the weather station. For anything other then a toy project, you should evaluate your needs and determine the appropriate auth scheme to use. Refreshing the auth token requires a deploy for both projects, not ideal, but it’s a pet project.

Routing

An API pipeline is necessary for the auth plug to be scoped to the correct request. All API requests will be served under the /api namespace. The root (index) page will be served under / and the standard phoenix browser pipeline.

Database

Wind speed and temperature need to be persisted in Postgres, time for ecto! I decided to index the table based on inserted_at with NULLS LAST due to the fact I plan on selecting on the newest data. If inserted_at is NULL then we have other issues and the data should be weighed the least.

Controller

Phoenix automatically generated the controller code, and I don’t recall making many (if any) changes to it. The reports controller allows the weather station to create a report, which is wind speed / temperature data. This can be slimmed down, but at the moment, it’s not a huge concern for a side project.

Moving the hardware over to a soldered board

I didn’t trust the breadboard to stand the test of time in my shed. Adafruit has a full sized protoboard that I used to move the parts over to and soldered all connections. This reduced the error I was seeing in wind speed data to match the specs 🙂 That was unexpected but very much welcomed. Moving the parts over was a simple copy/paste with some improved routing of wiring. My soldering skills are improving. I purchased a cheaper unit from Amazon that allows me to change tips and temperature control. Please save yourself the headache and get an iron with temperature control, you will thank me later.

Mounting hardware in shed

The wind speed sensor should be extended up and away from the shed. Iron gas pipes and iron pipe floor mounts were used to build a mount.

Temperature sensor needs to measure air not trapped within the shed. I found a space between the roof and wall to slid it through.

Being exposed to the hot/cold/dusty outdoors may not treat the board right. I was excited to finally install the weather station but I needed a container for the board. Looking around the kitchen I spotted the plastic container for baby formula. Cut a path for the wires to exit and you have a great storage container. The Raspberry Pi already had a snazzy plastic case.

Wiring consisted of extending the wires between all the sensors and providing power.

Power was ran from the garage to the shed, soon to be replaced with a solar panel. If you ever notice the weather data not updating it’s probably because someone ran over the extension cord with a lawn mower (looking at you babe).