# Eink family calendar ## What is it? I needed to have an updatable calendar to keep track of my children's school agenda, as well as some post-school activities. So instead of using a whiteboard, I thought it would be a nice holiday project to do it with a Raspberry Pi 2 and an e-ink screen. I got some inspiration from [this similar project](https://github.com/zli117/EInk-Calendar) and went for it, and here's the result: ## What do you need - A Raspberry Pi (any model would do, I did it with a Pi 2), with the Raspberry Pi OS. - Eink display: [640x384, 7.5inch E-Ink display HAT for Raspberry Pi, yellow/black/white three-color](https://www.waveshare.com/product/displays/e-paper/epaper-1/7.5inch-e-paper-hat-c.htm). - A [1x4 matrix keypad](https://www.adafruit.com/product/1332) to allow you to switch between the different calendars. There are multiple clones in different shops. - A photo frame to house the setup. I bought one at a local shop, just make sure it has enough depth to host all the hardware. - One or more Caldav calendars to display. By default, the e-ink display includes a hat to connect it directly on top of the GPIO connectors. However, since we want to connect the keypad too, we need to use the cables directly. Refer to [the vendor notes](https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT_(B)) to check the GPIO pins you need to connect them to. The keypad will be connected to GPIO pins 29, 31, 33, 35 and 37. ## Configuring Once the basic setup and connections are done, you will need to set up the `config.ini` file. This is its syntax: ```ini [DEFAULT] video = pygame keyboard = pygame [weather] owm_api_key = owm_location = [calendar] urls = http://example.com/caldavcal1, http://example.com/caldavcal2, http://example.com/caldavcal3 names = user1, user2, user3 username = user password = password ``` ### Driver configuration We can use two different drivers to be used for both video output and keyboard input. This allows us to hack and tests locally without using the e-ink screen all the time. - For video, we can use `pygame` for the [Pygame](https://github.com/pygame/pygame) driver, or `eink` to use the e-ink screen. - For keyboard input, we can use `pygame` to get input from your computer's keyboard, or `gpio` to use the 1x4 keypad connected to the GPIO pins 29, 31, 33, 35 and 37 (5, 6, 13, 19 and 26 if you use the BCM2835 pin notation). ### Open Weather Map API configuration You need to subscribe to the "Current Weather Data" [API](https://openweathermap.org/api). Note that you need to sign in as a user (it's free). Once you get the API key and the location id for your town, add them to the `owm_api_key` and `owm_location` keys in the configuration file. ### Calendar configuration You can use any CalDav link; in my case, I set up 3 calendars in a [Synology](https://www.synology.com) DiskStation using Synology Calenar. The code should adapt to any number of calendars, but keep in mind the resolution and font size. The `urls` parameter is a comma-separated list of CalDav URLs. Since each of those calendars will correspond to an actual person, `names` will contain the list of names for each url. Make sure you spefify the same number of URLs and names. The `username` and `password` fields are self-explaining: include the user and password to access the calendars. If you want to use a different type of calendar, such as Google Calendar, you will need to create a new driver. Patches are welcome :). ## Running The scripts directory contains a simple launcher script using a virtual environment, and a systemd unit file you can use to ensure the program runs on startup. When the application is stopped, it should clear the e-ink display, which is a good idea to avoid displa burnout. In some cases, it may not happen (for example if you get a power disruption). You can use the `reset_eink.py` script in those cases to clear the screen. ## Usage When started, the calendar will show today's calendar for everyone, from 8:00 to 21:00 (times are not configurable at the moment). You can switch to a weekly, Monday-to-Friday calendar for each person by pressing the 2, 3 or 4 buttons in the keypad, and switch back to the daily calendar by pressing 1. Yes, that means that having more than 3 calendars could require code changes ;). After 9 PM, the calendar will enter in screensaver mode, and display the image in the `img/night_image.jpg` file. The image will be converted to a 1-bit format, so it's better if you use a 1-bit image already. If there is a JPG or PNG file named after today's date, in DD-MM-YYYY format (for example, 01-01-2022.png for January 1st, 2022), the screensaver will use that image instead of the default one. Be creative! ## License Refer to the LICENSE file for licensing details. The weathericons-regular-webfont font is licensed under the [SIL OFL 1.1](http://scripts.sil.org/OFL) license. The [DejaVuSansMono-Bold font](https://dejavu-fonts.github.io/) is licensed under the Bitstream Vera and Public Domain. The `epd7in5bc.py` and `epdconfig.py` files are taken from the [Waveshare e-Paper repository](https://github.com/waveshare/e-Paper/), including patches inspired by [this pull request](https://github.com/waveshare/e-Paper/pull/104) to improve screen refresh performance. ## Anything missing? Feel free to contact me. This project was mainly created to scratch a personal itch, but if it can be helpful to anyone, I'd be more than happy to improve it and its documentation. ## Author Javier Peña (@fj_pena).