Creating a Monzo Pot e-paper tracker

Description

This project started as a tracker for my boys’ pocket money, so money can be added for doing various chores, and subtracted for spending. To start with it was fine, the equivalent change existed in their money boxes, but with us needing spare change to pay for their jobs ended up with being paid monthly having a piece of paper on the fridge to keep track. This got messy, things where missed and having exactly £6.75 in change for example just never happened. When out and about, the spur of the moment spending resulted in me or my wife buying on their behalf, without firstly knowing if they had enough, and never recuperating the spent money. This was never a big deal, but as they get older it is worth trying to get some sensible money sense instilled in their minds – In short, you can’t spend what you don’t have. This is where Monzo came in to play, as being a member of their Beta pre-paid card since March 2017, they released pots just before Christmas (2017) for current account users. Effectively separate money boxes you can quickly and easily transfer money in to from your main account, I thought this would be a far better solution, as 95% of my payment whilst out and about is always on card, mostly on my Monzo card. “Daddy, I want (insert first thing picked up here), I’ve always wanted one of these my whole life!” – Even though you have never seen that (insert thing here) before, I can quickly open my Monzo app, flick to Account, “You have £3.50 in your money box”. If he wants it, a 2 second withdrawal is made whilst queueing – Done, up-to-date and my boy walks away with a new (again, insert whatever he wanted his whole life here) and is happy!

Notes

This guide is using a 3 colour (red, black and white) e-paper pHAT, the e-paper libraries used aren’t compatible with other sized e-paper displays, or monochrome displays – As I don’t have others to hand I can’t advise best on how to use these yet.

Requirements

Firstly you need a Monzo account Raspberry Pi (any flavour works) and an SD card 3 colour e-paper pHAT (Inkyphat would be easiest, but this guide uses a Waveshare pHAT)

Getting Started

Creating the SD card

For this guide, we will be using Raspbian Stretch Lite, as the Pi will be running headless (without screen, mouse or keyboard) so there is no need for a full fat Raspbian image. Follow this guide for writing the above image to the SD card if you are new to the Pi scene. Assembling the hardware Whilst the SD card is being created, pop the Waveshare e-paper or Inkyphat to your Raspberry Pi. If you are using a Zero W, you’ll need to solder a GPIO header. There are plenty of solder guides on this process, so we’ll gloss over this by saying, solder the header and push on your choice of e-paper pHAT.

Setting up WiFi and SSH access

Once the image has finished writing, and before removing the SD card, we will need 2 files put in the boot partition. On the SD card, create a txt file, open and enter the following;

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
 ssid="NETWORKNAME"
 psk="WPAPASSWORD"
}

Make sure you change the NETWORKNAME and WPAPASSWORD to your actual WiFi information, in between the quotations. Save and close the text editor. Now rename the full filename to wpa_supplicant.conf. Lastly create an empty file, named just ssh. This file present upon first boot will enable SSH access, which is normally disabled. As this is a headless setup, this is the only way we can access the Pi. Now with these 2 files, remove the SD card, insert in to your Pi, add the e-paper pHAT if not already done so and finally add power. The first boot will take about 2 minutes. Best to pop the kettle on.

Update and Upgrade

As I’m an avid Windows user, I need to use PuTTY to access SSH connections, so your mileage may vary on this step depending on your system/preferences but all the command will be the same – I hope. As you won’t know its IP address, either use your routers’ devices page, or something like SoftPerfect Network Scanner (free trial) to scan and find the new device. Mine is showing up as 192.168.0.20, so using this to login; Default login details for Raspbian is;

Username: pi
Password: raspberry

Once we have logged in, we’ll change the password, otherwise if you power off, reboot etc you will need to restart from the beginning with a fresh image, it is likely SSH will not let you back in due to lack of generated SSH keys; also it is good security practice!

passwd

You’ll be prompted to enter the old password (raspberry), now enter the new one, twice. As with any software, lets make sure it is fully up-to-date;

sudo apt-get update && sudo apt-get upgrade -y

This will update the apt packages available, making sure we download the latest packages, and update any that are currently installed. This process will takes anywhere from a few seconds to aeons, depending on number of updates, internet speed, current moon phase in a direct tangent to the number of earthworms in the nearest field… So we’ll wait until it is done, by now the kettle should have finished boiling and you can make a hot drink.

Enabling SPI

As the e-paper display communicates over SPI, we need to first enable this, type;

sudo raspi-config

Scroll down to 5) Interfacing Options, then to 4) SPI. Select Yes, OK and Finish. This will bring you back to the command prompt.

Installing all the libraries

NOTE: If you are using PuTTY, you can copy (CTRL + C) as normal, then right click the PuTTY window to paste! CTRL + V doesn’t work.

There are a few libraries needed, mostly to run the e-paper display, so follow these, one line at a time – be warned, pillow and especially numpy will take a long time to compile!

sudo apt-get install python-dev git libjpeg-dev python-pip python-spidev -y
sudo easy_install pillow
sudo pip install numpy

Now lets grab the libraries for the e-paper display and pyMonzo;

git clone https://github.com/pimoroni/inky-phat.git
sudo pip install pymonzo

The e-paper library is provided by Pimoroni for their Inkyphat e-paper display, if you are using the Waveshare display, still download the library but a couple of amendments are required later on. pyMonzo is provided by Paweł Adamczak allowing python easy access to the Monzo API.

Using a Waveshare pHAT

If you are using the Pimoroni Inkyphat, skip this section as you are good to go!

Waveshare e-paper pHAT

We have already downloaded the library, so let modify 3 lines;

nano ~/inky-phat/library/inkyphat/inky212x104.py

Scroll down until you find the lines;

RESET_PIN = 27
BUSY_PIN = 17
DC_PIN = 22

And change the values to;

RESET_PIN = 17
BUSY_PIN = 24
DC_PIN = 25

That’s all, hold CTRL and press X to exit, and then Y + enter to save the file.

Installing the e-paper library

Now lets install the library, for both Waveshare and Inkyphat displays;

cd inky-phat/library/
sudo python setup.py install
cd ~

This shouldn’t take too long to complete, we can check everything is working;

python inky-phat/examples/test.py

After a few seconds, the display will change to the word Test in different sizes, if so lets continue! If not check back through the previous steps.

Installing pyMonzo library

Again, some minor adjustments are needed, at present pots aren’t fully integrated in the library, so we will add this in manually (this is work in progress with the developer so just a temporary measure).

cd pymonzo/src/pymonzo
rm monzo_api.py
wget https://raw.githubusercontent.com/Boeeerb/pymonzo/fd672743187fcdf266f0b1986f85ec9d8ff1148f/src/pymonzo/monzo_api.py
cd ../..
sudo python setup.py install

We are removing the current API file, and replacing this with a version containing the pots API endpoint, then installing this version for us to use. The pyMonzo library has been updated to include Pots, so we no longer need this step.

Setting up the Monzo authentication

This is where it gets a bit tricky, we have all the software ready, but Monzo now needs to know we want to obtain information, and this is done using the OAuth2 method. Thankfully Paweł has done a lot of the work, so lets get started… First step is create a client, go to the Developer Portal. You’ll be asked to enter your email address, this is the one you used to create your Monzo account – This doesn’t need to be done on the mobile with the Monzo App, this is best done on the computer you are using as it’ll involve copy and pasting of codes! Once you receive your email, click the link contained, you’ll be taken to the Monzo Playground. Click Clients on the top right of the screen, then click New OAuth Client. For Name, give this something you will know, as well as the description (if you use many API’s this helps keep track of what is what). Redirected URL will be needed to get hold of the last code, put https://github.com/pawelad/pymonzo here. ,   Click Submit, and then the name on the left, here you will have more information – Here the important ones to make a note of are the Client ID and Client Secret. Last code we will get shortly. For now we will store these two on the Pi; We will create a one-off authentication file;

cd /home/pi
nano auth.py

In this new file, type the following;

from pymonzo import MonzoAPI
monzo = MonzoAPI(
    client_id = '',
    client_secret = '',
    auth_code = '',
)

In the Client ID and Client Secret part, you can paste the codes so far.

NOTE: When using PuTTY, select the code as normal, and copy (CTRL + C), then to paste is just a right click of the mouse in PuTTY.

Now lets get the Auth Code. Open a new tab/window in your browser, and using this link – Replace CLIENTID with your Client ID from before followed by enter – You’ll be asked to authorise again – This time to allow PotsInfo (or your own name) access.

https://auth.getmondo.co.uk/?response_type=code&redirect_uri=https://github.com/pawelad/pymonzo&client_id=CLIENTID

As before, enter your email address again and authorise and await the next email; Once this arrives, click the link and you’ll be taken to Pawel’s github page. If this happens, perfect, as the code we want for the final Auth Code is in the URL (address bar), and it’ll be a big one so take care when copying it. In the address bar, copy everything in between (but not including) code= until &state=. This code is the Auth Code, the last piece to the puzzle to go in the Python auth.py file, so paste this in the auth_code. Now save the file with CTRL + X, then Y, Enter. Now we need to run this script once, this will generate the token that is stored on the Pi in a file called .pymonzo-token. If no errors appear, we are good to go!

python auth.py

Creating the script

As your pot name will vary, as well as number of active pots, we are going to display just the one pot – A Rainy Day pot. Open Monzo, click Account and create a Pot, call it Rainy Day and pop in some change. Back to the Pi in PuTTY, lets create the main python script;

nano potdisplay.py

Copy and right click paste the following code (check the indentation further down);

from PIL import ImageFont
from pymonzo import MonzoAPI
import inkyphat

font = ImageFont.truetype(inkyphat.fonts.FredokaOne, 18)
name = "Monzo Pots"
w, h = font.getsize(name)
x = (inkyphat.WIDTH / 2) - (w / 2)
y = 0
inkyphat.text((x, y), name, inkyphat.RED, font)

font = ImageFont.truetype(inkyphat.fonts.FredokaOne, 24)
name = "Rainy Day Fund"
w, h = font.getsize(name)
x = (inkyphat.WIDTH / 2) - (w / 2)
y = 28
inkyphat.text((x, y), name, inkyphat.BLACK, font)

font = ImageFont.truetype(inkyphat.fonts.FredokaOne, 28)
monzo = MonzoAPI()
pots = monzo.pots()
for item in pots:
  if item.name == "Rainy Day":
    balance = item.balance / float(100)

balance = '{0:.2f}'.format(balance)

w, h = font.getsize(str(balance))
x = (inkyphat.WIDTH / 2) - (w / 2)
y = 60
inkyphat.text((x, y), str(balance), inkyphat.BLACK, font)

inkyphat.show()

CTRL + X and Y + Enter to save and exit, now *fingers crossed* running this will result in the screen coming alive with your current pot balance;

python potdisplay.py
Ignore the missing USB ports – or lack of, they aren’t important for this project.

Auto update

Logging in and typing python potdisplay.py every time you want the display to refresh is a bit tedious, so by using the power of crontab, we will tell the screen to update every 15 minutes – Not that my Rainy Day fund will update that often! Lets create a cron job;

crontab -e

If this is the first time on this installation (which if you’ve followed every step so far – you will be), you’ll be asked which editor to use, unless your a VI wizard, we’ll stick with nano and press enter. Use the arrow keys to go right to the bottom, after all the instructions to create a new line. Cron can do many wonderful, and sometimes very exotic things, but for now we’ll stick with every 15 minutes, every hour, every day, every day of the week and every month, which looks like this;

*/15 * * * * python /home/pi/potdisplay.py

Now exit (CTRL + X, Y+ Enter) and you’ll see the note to let you know that the new cron job has been accepted. That is it, the display should refresh automatically, even after a reboot every 15 minutes. Enjoy!  

Other Adaptions

Here are a few others that have created their own trackers;

A raspberry-based fridge magnet for tracking pocket money – by Nicholas Mercouroff
Monzo Bank “Pot” ePaper Tracker – by Vincent Wilcox