Skip to content

An over-engineered weather display. Face the inevitable wind and rain in style!

Notifications You must be signed in to change notification settings

Dachaz/inky-weatherbox

 
 

Repository files navigation

inky-weatherbox

What is it?

An over-engineered weather display. Face the inevitable wind and rain in style!

What does it display?

How does it work?

Hardware

Depending on your preferences, you could either do a full battery-powered build or a simplified, USB-powered build.

Full build:

Minimal build:

  • Any RaspberryPi (pre-soldered GPIO works perfectly)
  • Pimoroni Inky pHAT display
  • Optional: A better-designed case, like the one from Balena Inkyshot

Software

Again, depending on your build, there are two flavours:

Full build:

  • Config-file driven
  • Wakes up PiZero every hour
  • Reports the battery level to NewRelic (so you can get alerted when the battery is low)
  • Updates the display
  • Creates both a local and a remote (NewRelic) log entry for each run
  • Sets PiZero to sleep for an hour (or until next morning, if in quiet time)

Minimal build:

  • A single CLI script that takes various arguments and either updates the Inky pHAT display or outputs image to a file

Setup

  1. Install RaspberryPi Lite OS — you could use the full-blown (desktop) OS but that will needlessly drain your battery on each wake-up.
  2. Configure your wireless networking. Ensure that "Wait for network on boot" is enabled in raspi-config
  3. Enable I2C and SPI in raspi-config
  4. Recommended: Set-up SSH on your RaspberryPi
  5. Install Inky pHAT software. In short: curl https://get.pimoroni.com/inky | bash and say Y to everything (to install all additional packages we'll need later).
  6. Recommended: Verify that your installation works by running one of Pimoroni code examples, e.g. the Name Badge Example.

Minimal build:

  1. Copy weather.py somewhere to your RaspberryPi. e.g. /home/[you]
  2. Set up weather.py to run every half an hour:
    1. Run the crontab editor: crontab -e
    2. Add the following line: */30 * * * * python3 /home/[you]/weather.py (this will give you weather in Amsterdam, see the following section on how to pass parameters)

Full build:

  1. Install PiJuice software. Since we're running headless, that boils down to sudo apt-get install pijuice-base
  2. If you haven't connected the battery yet, power down, connect the battery, connect back to the power and run pijuice_cli.
  3. Set up a free NewRelic account
  4. Create a copy of config.ini.SAMPLE and call it config.ini
    • Copy your NewRelic License API key to config.ini
    • Edit the rest of the file to reflect your preferences.
  5. Copy all of the code from this repository somewhere to your RaspberryPi. e.g. /home/[you]/inky-weatherbox
  6. Set up runandturnoff.py to run on every boot:
    1. Run the crontab editor: crontab -e
    2. Add the following lines: @reboot python3 /home/[you]/inky-weatherbox/runandturnoff.py (make sure to use the same path from the previous step)
  7. Recommended: Set runandturnoff.py to run when you switch from USB power (charging) to battery power:
    1. Enable "No power" System Event and set it to USER_FUNC1
    2. Configure USER_FUNC1 to point to /home/[you]/inky-weatherbox/runandturnoff.py (make sure that the file is executable)
  8. Optional: Create a dashboard in NewRelic to track the battery life:
    • Click + Create a Dashboard > Create a New Dashboard
    • To view the battery level:
      1. Click Add a widget > Add a chart
      2. Add this query: SELECT latest(battery.charge_level) FROM Metric WHERE app.name ='inky-weatherbox' TIMESERIES AUTO (if you changed the app name in config.ini update it here).
      3. Click Run
      4. Set Chart name to "Battery"
      5. Expand Null values and set the dropdown value to Remove
      6. Click Save
    • To view the latest log entries:
      1. Click Add a widget > Add a chart
      2. Add this query: SELECT message,batt FROM Log ORDER BY timestamp DESC
      3. Click Save
  9. Optional: Set up an alert when the battery level is low
    • SELECT latest(battery.charge_level) FROM Metric WHERE app.name = 'inky-weatherbox'

Usage

runandturnoff.py (source)

This file is, essentially, the implementation of the Full Build logic.

If it's run on battery power, it will turn RaspberryPi off after the run. If it's run while being charged via any of the USB ports (on RaspberryPi or PiJuice) it will not turn RaspberryPi off (and will not schedule the next run).

weather.py (source)

This file is either called by runandturnoff.py or it can be executed stand-alone. To see all the CLI parameters, run python3 weather.py -h (or just ./weather.py -h). The --mock mode is useful for testing on a computer that doesn't have Inky pHAT connected as it will output the target image to a file (inky.png).

Usage examples

./weather.py -lat 44.80 -lon 20.47            # Gets weather for Belgrade, RS in ºC and km/h
./weather.py -lat 54.97 -lon -1.61 -w mph     # Gets weather for Newcastle upon Tyne, UK in ºC and mph
./weather.py -lat 25.04 -lon 77.35 -w kn -t F # Gets weather for Nassau, BS in ºF and knots
./weather.py -m v1 # Gets weather for Amsterdam and creates inky.png instead of updating the display

ℹ️ All of the previous examples can be run as python3 weather.py as well.

Known issues and learnings

🪫 The battery life is pretty bad.

Even with all of the unorthodox optimisations, I couldn't get more than ~12 days out of the 1200mAh battery. What drains the battery the most is the OS boot sequence, which takes about 2 minutes. I tried disabling a lot of services, using static DNS and IP address (to not wait for the DHCP server), and getting a blazing fast SD-card — all of which shaved a few seconds off the boot process, but not enough.

🛜 The WiFi is wonky AF.

I've spent many hours fighting with WiFi and trying to make sure that RaspberryPi has internet connection as quickly as possible and that the runandturnoff.py is only run after the internet connection is fully established. With every patch (some of which are outlined in Networking section below) the system became more complex, but not more reliable.

🫥 The battery may not deliver enough power

After being on a holiday for a few weeks, and leaving inky-weatherbox to drain its battery without recharging, I experienced that, upon a new charge, the display gave a washed-out image, and even that red colour wasn't getting displayed at all. At first, I thought that I had damaged the screen, but once I plugged the RaspberryPi into USB, the colours were vivid and sharp again. I remember reading that eInk screens need reliable power supply to properly update the image, and it might be that the battery I'm using got damaged (or that there's a different reason it stopped working after barely 3 12-day cycles). At this point I gave up on running this project off a battery, so I didn't investigate further.

🖼️ Only works sensibly on Inky pHAT

While the code will not break if you try to run it with Inky wHAT or Inky Impression, the output will be all over the place. Contributions welcome!

🧠 In short:

I've picked wrong tools for the task. I was blinded by the idea of having an ultra-tiny easily-programmable computer, and I got carried away equating single-purpose microcontrollers I have around my house, with generic-purpose high-level computer such as RaspberryPi. Still, it was a valuable lesson in building hardware as I had to learn a lot of new skills (how to solder and more so: how to desolder, how RTC/low power consumption works, how to find overly specific components, how to make a simple 3D model, etc).

🤔 Why bother sharing, then?

When I got the idea to build this, the information was very fragmented and spread across many websites. The code in here is patchwork of about 10 different online resources. While it's very far from perfect, at least there are 2 good things about it:

  1. weather.py works without you having to create any weird API keys (kudos to Open-Meteo)
  2. I plan to reuse runandturnoff.py for a different incredibly original project soon. Maybe I generalise it then 🤷‍♂️

Additional reading

Here are some resources that I've been looking into when trying to shave seconds off the RaspberryPi's boot (to prolong the battery life).

Networking:

Power saving / boot optimisation:

License

Copyright © 2023 Dachaz. This software is licensed under the MIT License.

Parts of the image generation code Copyright © 2020 Derek Caelin.

Languages

  • Python 100.0%