Create e-paper calendar connected to Google
It is helpful to check my schedule with a calendar at any time. All I have to do is open Google Calendar on my phone or PC, but I would like to see it with less effort.
Google Nest Hub and Amazon Echo Show are a little different from what I want, and I cannot also find other devices. So I tried to create a calendar connected to Google via API using Raspberry Pi and e-paper.
Procedure
- Get my schedule data from Google Calendar via API
- Generate the image of the calendar showing my schedule
- Get the e-paper
- Display the image on the e-paper
Software
Occasionally I find the example to implement, so I also use Python.
Please check out my GitHub repository if you just want to see implementation.
Create the project directory
terminal
// create the project directory
$ poetry new my-project
// initialize configuration if the directory exist
$ poetry init
// add packages
$ poetry add google-api-python-client google-auth-httplib2 google-auth-oauthlib pillow
Install the packages to authenticate with my Google account, fetch data from Google Calendar, and generate the calendar image.
Fetch the event data from Google Calendar
Fetch data using the Google Calendar API. The basic usage of this API is described in the article below:
I would like to implement the following specification:
- Begin on Sunday and end on Saturday
- Display Sunday and public holidays in Japan in red color
- Mark the day that I have a plan
- Show the list of my schedule about the date and the detail of it in the future
An authentication file is required to connect to Google Calendar. If credentials.json file exists, authentication is required the first time the script is run. Once authenticated, token.pickle file is generated and can be used to authenticate with this file from then on.
Raspberry Pi Zero WH has low processing performance, making it difficult to open a browser and authenticate. So it is better to generate token.pickle file on another PC and transfer it to the Raspberry Pi via SCP.
Generating the image
There are some major libraries to process the image. I use Pillow (PIL) this time.
Sample implementation is published at GitHub.
connect_calendar.py
: fetch the data from Google Calendarmain.py
: generate the image of the calendar and control the e-paper
Note that these programs is optimized for Japanese calendar.
It is slightly more difficult to align the text. It is better to use multiline_textbbox
to get the size of the outer frame of the text and align it.
How to get the e-paper
In this time, I purchased e-paper, which is relatively large in size, from Waveshare Electronics.
I prepared some devices and accessories.
- Waveshare 7.5inch HD (880x528) e-paper black/red/white (B)
- Raspberry Pi Zero WH
- microSD 16GB
- miniHDMI to HDMI Adapter
- microUSB Hub
The e-paper was delivered from Shenzhen after about 10 days when I ordered.
Prepare the Raspberry Pi
I chose Zero WH model because high performance was not necessary. "W" means to be available for Wi-Fi and "H" means to be with the header pin. "W" means available for Wi-Fi and "H" means with the header pin.
In order to control Raspberry Pi, it is necessary to install Raspberry Pi OS (Raspbian before) on the microSD card with Raspberry Pi Imager.
After that, insert the microSD card into Raspberry Pi and power it up to connect a power cable to the "PWR IN" port. If you would like to shut it down, run the following command:
terminal
$ shutdown -h now
Security
It is necessary to change the default configuration not to attack from out of the local network.
First, create new user and add the permissions.
terminal
$ sudo passwd root
$ sudo adduser USERNAME
$ groups pi
$ sudo usermod -G pi,adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,spi,i2c,gpio,lpadmin USERNAME
$ groups USERNAME
$ sudo cp -r /home/pi/* /home/USERNAME
Next, delete the default user. I couldn't select the default user because it was enabled to log in automatically in the initial configuration.
terminal
$ sudo raspi-config
Run the above command and disable it using System Options > Boot / Auto Login > Console. When the setting is complete, reboot the device.
terminal
$ sudo reboot
After the reboot, log in with new user and password, and delete the default user.
terminal
$ sudo userdel -r pi
$ id -a pi
id: 'pi': no such user
Enable the GUI using System Options > Boot/Auto Login > Desktop. Note that automatic login remains disabled.
terminal
$ sudo raspi-config
Finally, reboot again.
terminal
$ sudo reboot
Enable SSH
Enable SSH (port 22) using Interface Options > SSH.
terminal
$ sudo raspi-config
Check local IP address to connect Raspberry Pi from the same local network with the following command:
terminal
$ ping raspberrypi.local
Enable SPI
Enable SPI to control the e-paper using Interface Options > SPI > enable.
terminal
$ sudo raspi-config
$ sudo reboot
Install the packages to use Python. (Almost of all was already installed.)
terminal
$ sudo apt-get update
$ sudo apt-get install python3-pip
$ sudo apt-get install python3-pil
$ sudo apt-get install python3-numpy
$ sudo pip3 install RPi.GPIO
$ sudo pip3 install spidev
It seems that it is not necessary for BCM2835 and WiringPi library when implementing the program with Python.
Test
Run the demo program prepared by Waveshare.
terminal
$ sudo apt-get install git
$ git clone https://github.com/waveshare/e-paper.git
$ cd ./e-paper/RaspberryPi_JetsonNano/python/examples
$ python epd_7in5b_HD_test.py
Implementation
The default Python is an old version. Prepare the virtual environment so as not to break the default one.
Note that it takes very long time to install some packages into Zero WH.
terminal
// install pyenv
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n eval "$(pyenv init -)"\nfi' >> ~/.bashrc
// install poetry
$ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
Install the appropriate version of Python using pyenv.
terminal
$ sudo apt-get install -y build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
$ pyenv install 3.9.0
Install the required package at the same time not to fail to install Pillow package.
Reference:# Building on Linux | Installation - Pillow
terminal
$ sudo apt-get install libtiff5-dev libjpeg8-dev libopenjp2-7-dev zlib1g-dev \
libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev python3-tk \
libharfbuzz-dev libfribidi-dev libxcb1-dev
Create the virtual environment under the project directory.
terminal
$ poetry config virtualenvs.in-project true --local
.env
PYTHONPATH=.venv
Poetry installs almost all the necessary packages, but it is not included that only use in Raspberry Pi.
terminal
$ git clone https://github.com/mktia/e-calendar.git && cd ./e-calendar
$ pyenv local 3.9.0
$ poetry install
$ pip3 install RPi.GPIO
$ pip3 install spidev
Auto update of the calendar
Enable cron
Enable the logs that crontab uses.
terminal
$ sudo vi /etc/rsyslog.conf
rsyslog.conf
###############
#### RULES ####
###############
#
# First some standard log files. Log by facility.
#
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
// uncomment
cron.* /var/log/cron.log
terminal
$ sudo /etc/init.d/rsyslog restart
Create the file to record the logs.
terminal
$ sudo touch /var/log/e-calendar.log
$ sudo chmod 777 /var/log/e-calendar.log
And, check the status of cron service.
terminal
$ sudo /etc/init.d/cron status
● cron.service - Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2021-03-19 14:17:29 JST; 3h 11min ago
Docs: man:cron(8)
Main PID: 262 (cron)
Tasks: 1 (limit: 877)
CGroup: /system.slice/cron.service
└─262 /usr/sbin/cron -f
If cron.service is disabled, run the start
command.
Crontab configuration
Edit the crontab using the following command:
terminal
$ crontab -e
Note that the environment variables are not used because it doesn't run the shell as a user.
First, prepare the script file.
terminal
$ touch ~/e-calendar.sh
$ sudo chmod 755 ~/e-calendar.sh
$ nano ~/e-calendar.sh
e-calendar.sh
#!/bin/bash
SHELL=/bin/bash
PYENV_ROOT=$HOME/.pyenv
POETRY_ROOT=$HOME/.poetry
PATH=$PYENV_ROOT/bin:$POETRY_ROOT/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
if command -v pyenv 1>/dev/null 2>&1; then
eval "$(pyenv init -)"
fi
cd ~/e-calendar
$POETRY_ROOT/bin/poetry run python main.py
Next, add the command to run the script every hour to the crontab.
crontab
0 * * * * /home/USERNAME/e-calendar.sh > /var/log/e-calendar.log 2>&1
With the above settings, the log is overwritten each time it is run with the above settings.
As a desk calendar
To use e-paper as a desk calendar, it would be better to use a photo frame.
GitHub: mktia/e-calendar