A nightstand clock as a programming project.
| Item | Note | Link |
|---|---|---|
| raspberry pi | model B+ (40-pin); latest model (in link) is much more capable, same price | Adafruit |
| PaPiRus Screen HAT | 2.7" screen, 4 buttons | US UK |
| microSD card | 16GB SanDisk (boot media) | Amazon |
| USB WiFi adapter | Raspberry Pi official version; newer boards have embedded WiFi | Amazon |
| USB power supply | 5V 2A recommended | Adafruit |
| Library | Link |
|---|---|
| PiSupply Papirus | papirus |
| Python Imaging Library | PIL |
| Python API for WeMo | pywemo |
| Python client library for 3M50 Radio Thermostat | radiotherm |
| Python Requests library | native package (online docs) |
- write code in python
- this is, among other things, a programming exercise
- cache data from unreliable sources
- connections to remote APIs are not guaranteed
- when imaging the display, pull from cache
- use separate routines to update cache
- in this application, having old data is better than having no data
- use in-memory filesystem (
/dev/shm) for temporary files- prevent wear to fragile SD cards
- reboots wipe this filesystem, and that's okay
- use JSON to format data at rest
- single standard format simplifies troubleshooting
- yes, you can create JSON using shell scripts
- create separate programs for each task (a la microservices)
- leverage OS-level tools (
bash,cron,cal) where appropriate
This is a shell script I wrote to read the on-board temperature sensor. It provides the board temperature, which is regularly higher than the room temperature, and not much use in this project. Merged with the vendor repo (see history, below). Since then, a python version has also been contributed.
This is a python program that monitors the buttons on the PaPiRus Screen HAT:
- checks a PID file to make sure it's not already running
- event loop waits for keypress
- keypress is de-bounced
- first detected WeMo plug is toggled
- quits on error
A cron job launches this every minute. While not perfect, works 90% of the time (when I push a button, the light toggles). It's been suggested that I squirt XML directly to the device's IP address and skip the library, but I'd rather understand what's going on. This will need to support more WeMo devices in the near future.
This is a python program that loads the image on the e-ink display once it is generated by papigen, below.
- Full refresh on boot (timestamp file missing)
- Full refresh at top of hour (flashes screen, takes longer)
- Partial refresh all other times (smooth update)
This is the core, pulling together various data and formatting the display. This is also executed via cron every minute.
- polls my thermostat for current house temperature
- polls openweathermap every twenty minutes for outside temperature near me
- Note: API key and location data have been sanitized
- You can derive the coordinates of your device manually from Google Maps
- Or automatically from your public IP address
- Or dynamically by adding a GPS dongle
- executes the GNU cal utility to generate a calendar with a predictable text layout
- uses Python Imaging Library for screen layout (fonts, sizes, positions)
- creates bitmap image file for loading to display (by
papirus-image, above)
In English, the stanza below:
- checks to see
papigenis executable- if it is (logical
AND), executepapigen - if it excuted cleanly (exit code
0), also executepapirus-image - dump all output (including errors) in the garbage
- if it is (logical
- checks to see that
papiswitchis executable- if it is (logical
AND), executepapiswitch - dump all output (including errors) in the garbage
- if it is (logical
The cron package runs this once a minute, per the first five asterisks in each line. If you put these lines in a text file (let's call it picron.txt), you can load it directly with the command: crontab picron.txt, and inspect it with crontab -l.
# m h dom mon dow command
* * * * * [ -x bin/papigen ] && bin/papigen && bin/papirus-image >/dev/null 2>&1
* * * * * [ -x bin/papiswitch ] && bin/papiswitch > /dev/null 2>&1 &
| Date | Note |
|---|---|
| 9 Feb 2016 | ordered papirus from pisupply |
| 20 Mar 2016 | submitted merge request for papirus-temp to PiSupply |
| 17 Nov 2018 | started nightstand clock idea instead of shoveling snow; initial commit |
| 15 Dec 2018 | pressing button toggles wemo lightswitch |
| 4 May 2019 | sanitized, commited to public repository |
