Instructions on setting up a Raspberry Pi Zero WH with a Waveshare ePaper 7.5 Inch HAT. The screen will display:

  • Date and time
  • Weather icon with high and low temperature
  • Google Calendar or Outlook Calendar entries

Here it is in action

In a picture frame Generated image
epaper dashboard

Shopping list

E-Paper Display

The most important component is the Waveshare display, which is a 7.5 inch e-paper HAT with SKU: 13504 and UPC: 614961951068. A quick search will also show similar displays available, with a single additional color. As tempting as they may be, the problem with those displays is the refresh rate, in part due to the way the third color is ‘pushed’ to the surface when displaying a color. While the black and white display isn’t very fast, the colored ones are much, much slower and are only suitable for frequently-refreshing dashboards.

E-Paper Display

Raspberry Pi

Although any Raspberry Pi can be used, the best one to get here is the Raspberry Pi Zero W - it’s thinner and more portable. Since it’s a HAT (Hardware Attached on Top), you can save some time by buying it with the GPIO presoldered. Of course you’ll also need a microSD card.

Raspberry Pi Zero WH microSDHC card

Picture frame

You’ll need a 6”x4” picture frame to hold everything together. This is the best size just larger than the e-paper display. The back needs to be made of cheap material so that it can be cut out for the e-paper display’s connection mechanism.

Picture frame

Instructions on setting up a Raspberry Pi Zero WH with a Waveshare ePaper 7.5 Inch HAT. Date/Time, Weather, Google/Outlook Calendar

Setup the PI

Prepare the Pi

I’ve got a separate post for this, prepare the Raspberry Pi with WiFi and SSH. Once the Pi is set up, and you can access it, come back here.

Connect the display

Turn the Pi off, then put the HAT on top of the Pi’s GPIO pins.

Connect the ribbon from the epaper display to the extension. To do this you will need to lift the black latch at the back of the connector, insert the ribbon slowly, then push the latch down. Now turn the Pi back on.

Setup dependencies

The display as well as the code that talks to the display has quite a few dependencies. Here we’re installing a few fonts, some Python dependencies.

sudo apt install git ttf-wqy-zenhei ttf-wqy-microhei python3-pip python-imaging libopenjp2-7-dev libjpeg8-dev inkscape figlet wiringpi python3
sudo pip3 install python-dateutil astral spidev RPi.GPIO Pillow  # Pillow took multiple attempts to install as it's always missing dependencies
sudo pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib msal

Enable SPI

SPI is how the Raspberry Pi will send data over the ribbon to the e-paper display. You will need to enable it and reboot the device.

sudo sed -i s/#dtparam=spi=on/dtparam=spi=on/ /boot/config.txt  #This enables SPI
sudo reboot

Get the BCM2835 library

The BCM2835 library provides access to the GPIO pins and it needs to be manually installed.

sudo tar zxvf bcm2835-1.58.tar.gz
cd bcm2835-1.58/
sudo ./configure
sudo make
sudo make check
sudo make install

Using this application

You can now use the code from this repo

Clone it

Clone this repository to your Raspberry Pi

git clone --recursive [email protected]:mendhak/waveshare-epaper-display.git

Waveshare version

Modify the file and set the version of your Waveshare 7.5” e-Paper Module (newer ones are version 2)


Pick a Weather provider

You can pick between OpenWeatherMap, Met Office, AccuWeather, and Climacell to provide temperature and weather forecasts.
You can switch between them too, by providing the keys and commenting out other ones, but remember to delete the weather-cache.json if you switch weather providers.


Register on the OpenWeathermap website, and go to the API Keys page, that’s the key you’ll need. Add it to the file.


Met Office (UK)

Create an account on the Met Office Weather DataHub site.
Next, register an application - just call it Raspberry Pi or Home Project.
You’ll be shown a Client Secret, and a Client ID. Copy both of these somewhere, you’ll need it later.

After registering an application, you then “subscribe” to an API by going to the API Usage Plans.
Pick “Global spot data bundle” which includes the “Global daily spot data” API. Choose the Basic (free) plan and when prompted, pick that application you previously registered.

Finally, add the Met Office Client ID and Secret to the file.

export METOFFICEDATAHUB_CLIENT_ID=xxxxxx-xxxxxx-....


Register on the AccuWeather site.
Next, register a new application.
I just named it Personal, marked it as Limited Trial, Internal App, Business to Consumer. Once you do this you’ll get an API Key, save it.

You’ll also need an AccuWeather Location Key.
Do a normal AccuWeather search for your location.
The last number in the URL is the Location Key. In the example of London, it’s 328328.

Add the API Key and Location Key to the

export ACCUWEATHER_LOCATIONKEY=328328’s Terms of Service requires you to identify yourself. The purpose is to ensure they can contact you in case you overload or abuse their servers. For this reason, you just need to set your email address in like so:

Note that the API provides 6 hours of forecast, rather than a full day.

Climacell (

Register on the Climacell site, and when you do you should be given an API Key.
Modify the file and put your Climacell API key in there.

export CLIMACELL_APIKEY=xxxxxx

Location information for Weather

Whichever weather provider you’ve picked, you’ll need to provide the location and units to display in.

Modify the file and update with the latitude and longitude of your location.
As needed, change the temperature format (CELSIUS or FAHRENHEIT).

export WEATHER_LATITUDE=51.3656

Pick a Calendar provider

You can use Google Calendar or Outlook Calendar to display events.

Google Calendar setup

The script will by default get its info from your primary Google Calendar. If you need to pick a specific calendar you will need its ID. To get its ID, open up Google Calendar and go to the settings for your preferred calendar. Under the ‘Integrate Calendar’ section you will see a Calendar ID which looks like [email protected]. Set that value in

export GOOGLE_CALENDAR_ID=[email protected]

Google Calendar token

In order to display Google Calendar events, we’ll need an OAuth Token. However Google have not made the process of obtaining one simple at all. The Oauth process needs to complete once manually in order to allow the Python code to then continuously query Google Calendar for information.

Go to the Python Quickstart page and enable Google Calendar API. When presented, download or copy the credentials.json file and add it to this directory.

Next, on the Raspberry Pi, run:


The script will prompt you to visit a URL in your browser and then wait. Copy the URL, open it in a browser on another PC, and you will go through the login process. When the OAuth workflow tries to redirect back (and fails), copy the URL it was trying to go to (eg: http://localhost:8080/...). Open up a brand new SSH session to the Raspberry Pi, and curl that URL.

curl "http://localhost:8080/..." 

On the first SSH session, you should now see the auth flow complete, and a new token.pickle file appears. The Python script should now be able to run in the future without prompting required.

I also have a post here with screenshots walking through the process.

Outlook Calendar setup

The setup is much simpler, just run this script which will give instructions on how to login:


Login with the Microsoft account you want to get the calendar from, and accept the consent screen. After a moment, the script will then display a set of Calendar IDs and some sample events from those Calendars. Copy the ID of the calendar you want, and add it to like so:


Note that if you set an Outlook Calendar ID, the Google Calendar will be ignored.

Run it

Run ./ which should query Climacell, Google/Outlook Calendar. It will then create a png, then display the png on screen. After a few runs, if everything is working well, you should then make this a cron job.

* * * * * cd /home/pi/waveshare-epaper-display && bash > run.log 2>&1

Putting it in a picture frame

The picture frame I got had a cheap backing. Using a box cutter (Stanley knife) I was able to remove a square portion from the bottom. This allowed me to put the e-paper display inside the picture frame while its connector hung outside.

The ribbon from the connector loops upwards and over to the picture frame’s stand. The Raspberry Pi Zero WH is light enough that it could be taped right to the stand.

The only bit of wire in the whole setup is the USB to power the Raspberry Pi.

Cutout for e-paper connector Topdown view or Raspberry Pi attached to picture frame stand
Picture frame details

How it works

Everything starts with the screen-template.svg which holds the labels and layout for the final image to be produced. SVGs are simply XML files which are understood by renderers. Being text files makes them easy to work with from dynamic scripts.

API Calls

The first part of calls on the script which queries Climacell API, gets the weather info and substitutes icons and temperatures in the SVG. It also sets the date and time. The SVG is then written out to screen-output-weather.svg. The API response is stored in

The last API call is to Google Calendar, the upcoming 2 calendar entries are written to the same SVG.

Due to API rate limits, you will see various .pickle files which store the Google/Outlook Calendar and Dark Sky API responses for a few hours. This means that any new entries in your target calendar won’t show up immediately. Similarly weather info will be up to a few hours delayed.

Image conversion and display

The image is converted from the intermediate SVG to PNG, and then the renders it to screen using the e-Paper libraries. It’s slow, it takes about 30 seconds to write to screen.

It’s possible to use the C libraries to make this process faster, but it requires writing and compiling the display binary yourself. It could further be sped up by converting the PNG to a 1-bit BMP so that there’s less data to send over the wire. The C way would take about 6-8 seconds.

The reason for sticking with the Python way is that I’ve got a v1 Waveshare display, while most users have a v2 Waveshare display, and it’s easier to cater to both this way. Curse of the early adopter!


If the scripts don’t work at all, try going through the Waveshare sample code linked below - if you can get those working, this script should work for you too.

You may want to further troubleshoot if you’re seeing or not seeing something expected.
If you’ve set up the cron job as shown above, a run.log file will appear which contains some info and errors.
If there isn’t enough information in there, you can set export LOG_LEVEL=DEBUG in the and the run.log will contain even more information.

The scripts cache the calendar and weather information, to avoid hitting weather API rate limits.
If you want to force a weather update, you can delete the weather-cache.json.
If you want to force a calendar update, you can delete the calendar.pickle or outlookcalendar.pickle.
If you want to force a re-login to Google or Outlook, delete the token.pickle or outlooktoken.bin.

Learn more: Waveshare documentation and sample code

Waveshare have a user manual which you can get to from their Wiki

The Waveshare demo repo is here. Assuming all dependencies are installed, these demos should work.

git clone
cd e-Paper

This is the best place to start for troubleshooting - try to make sure the examples given in their repo works for you.

Readme for the C demo

Readme for the Python demo