SystemSix is an e-Ink "desk accessory" running on a Raspberry Pi. It is a bit of nostalgia that can function as a calendar, display the weather

Overview

SystemSix

SystemSix is an e-Ink "desk accessory" running on a Raspberry Pi. It is a bit of nostalgia that can function as a calendar, display the weather, the current phase of the moon or just be generally fun to look at.

To be clear, despite how it looks, it is not interactive. It changes every day to display a new "desktop", will update to show local weather, your calendar events, phase of the moon. But you cannot click on it.

It was wrtitten as a love-letter to my first Macintosh. Hopefully it is nostaglic, somewhat informative, and fun.

SystemSix screenshot.

Features

• Calendar date is displayed.

• Retrieves and displays your first six calendar events for the day, refreshes in the evening.

• Retrieves and displays the local weather forecast at the start of each day.

• Current phase of the moon displayed. (New moon? Maybe you get a Calculator instead.)

• Specify "trash day" and on that day of the week, the trash can icon will display full. Can be a handy reminder.

• Several different overall layouts and a random selection from over 100 classic icons means you wake up to a surprise desktop every day.

SystemSix

The display is 5.83" e-ink display from Waveshare.

More (exhaustive) details on how SystemSix was created are on my blog.

Running

If you are new to Python as I was: briefly, you pull down the sources and open systemsix.py in a Python IDE (example: Thonny, that generally comes pre-installed on the Raspberry Pi — on a desktop OS, PyCharm is a popular one). Then you run it.

Hopefully the requirements.txt file covers the needed Python modules and you have no problems running SystemSix. (Hopefully too your Python environment already is pointing to Python3 and not an older Python implmentation.)

In systemsix.py, there is a flag at the top: USE_EINK_DISPLAY. Set this to False and you can run systemsix.py in any environment, even without an e-ink display attached. The workflow for updating the e-ink display involves first creating the image that you want displayed. Most of the code in SystemSix is doing just that: creating the final image of the desktop. When you set USE_EINK_DISPLAY to False the final image is instead opened in your current OS environment, not sent to the e-ink driver. (On MacOS it is Preview that is launched to display the resulting image.)

See the Settings section below on how to customize SystemSix and personalize it.

To dedicate a Raspberry Pi to run SystemSix headless, I had to learn about crontab. This is the program that is run to schedule automatic tasks on the computer. Once set up, it requires no human interaction.

In the Terminal app on a Raspberry Pi I entered:

crontab -e

This brings up a text editor in Terminal. Then I scrolled down to the bottom of the file and added this line:

@reboot sleep 60 && /home/pi/SystemSix/run_systemsix.sh

This says that 60 seconds after booting, the computer will run the shell script named run_systemsix.sh located at the path /home/pi/SystemSix/. If you pulled the files down somewhere else you will have a different path to the shell script file.

Settings

"Trash day" is defined in Settings.py as an integer. Set the value to 1 for Monday, 2 for Tuesday, etc. Setting the value to None will cause the trash to never be shown full. Set to any other value to indicate that "trash day" should be random.

For the weather API I use, LATITUDE and LONGITUDE should be supplied in Settings.py. I query api.weather.gov to turn the LAT/LONG into an office ID and grid X and Y that weather.gov uses to retrieve local forecasts.

To display your upcoming calendar events the settings and code are the same as the implementation from 13Bytes. I can only speak to my experiences with MacOS Calendar. WEBDAV_IS_APPLE I set to True and for WEBDAV_CALENDAR_URL I entered the URL to fetch my public calendar.

Figuring out my calendar URL turned out to be a challenge. In the end I had to create a new calendar in Apple's Calendar app and make sure to mark it as public. Then I found the sharing affordance in Calendar and "shared" the calendar with myself (I emailed it to myself). The link in the email contained the (150+ character) URL that I was then able to paste into Settings.py. Mine started out like this: webcal://p97-caldav.icloud.com/published/2/NDYyNT.....

Technical

E-ink displays, at least the hobbyist-priced ones (or maybe it's their drivers), are both slow and a little unsightly when they refresh. I had wanted to play with them however so chose a project (a calendar/weather app) where infrequent display refreshes were acceptable.

I'm new to both Python and e-ink displays, so forgive me if my explanation here is a little off. As I touched on earlier, I found that the general gist of displaying content to the e-ink display was to build an image of the correct width/height and in the correct bit depth for the display using the graphics library of your choice (PIL or "Pillow" for Python) and then call the e-ink driver code to display that finished image.

There is then a whole bunch of flashing and flickering of the e-ink display that goes on until, some dozen seconds or so later, your image is visible. It is, I find, quite distracting. To that end, the code tries to minimize the refreshes, updates.

At midnight the display gets a refresh. Since the current calendar date is one of the things we display, updating at midnight is a no-brainer. The display is updated.

Morning (currently I have chosen 4:05 AM) gets a special update. It is this update/period when a new layout/desktop is chosen for the day. There will of course always be a display update/refresh in the morning. Further, it is the morning period when both the weather forecast and calendar events are first attempted.

The weather API I am using often fails. Or rather, it often returns a bogus forecast. It's not that the forecast is inaccurate, instead it is a forecast from several months past. I added code to test a date in the forecast that is returned and reject these errant forecasts. Additionally, I note that fetching the weather failed.

Every hour the app awakens and decides whether to update or not. If it had failed to fetch the weather (or calendar events) the previous hour it will kick off another fetch. Only if it succeeds then will it refresh the display. If it fails again it goes back to sleep and will retry an hour later.

An hour between updates (especially failed ones) may seem rather coarse but I kind of like that the app is more patient than I am.

The only other special update is the evening update (currently 5:05 PM). Calendar events are again refreshed (to show the next day's events) and the desktop is refreshed. It is with the evening refresh that the desktop code may display the phase of the moon by bringing up the Moon "desk accessory".

If all the fetches are happy, you are likely never to actually see the display update except perhaps the evening update.

Esoterica

Inspired of course by the early Macintosh (my first Apple computer was a Macintosh Plus, and I loved it). The display is not precisely 512 × 342 pixels as were the early "classic" Macs. There is no e-Ink dispay of this resolution. The 5.83" E-Ink display from Waveshare was close at 648 × 480.

Pixels on the e-ink display are right up to the edge where the metal of the panel meets. I found that if I presented content right up to the edges I could not easily attach a plastic bezel that would hide the metal trim of the panel without obscuring some of the pixels. For that reason I intentionally left a "letterbox", black padding pixels (or a matte if you prefer) on all four sides of the content.

Had I left about 68 pixels of black border all around I could have displayed the content precisely at 512 × 342. I feel the panel is already small and I did not want to shrink the content by that degree. This is a compromise.

This project was my introduction to learning Python. I started from the sources of the beautiful eInkCalendar submitted by 13Bytes. I did a lot of refactoring of 13Bytes code and added a lot of rendering code to display the desktop and icons in various configurations. I added the weather and phases of the Moon. Much of the effort though involved preparing image assets, coming up with visually attractive desktop layouts.

In fact the idea for SystemSix came about when I went to add phases of the Moon to 13Bytes' original eInkCalendar. To display the moon in black and white I decided to dither the grayscale source art. Atkinson dithering was a nice algorithm I remember from the classic Mac days and so I sought that out. Once I saw the moon "Atkinson dithered" on an e-ink display my thoughts for the project went in a whole different direction — and so SystemSix came about.

Issues

The weather API, api.weather.gov is not real reliable in my area. For reasons I don't understand the forecast returned is often, errantly, a forecast from the end of December 2021. It's an odd bug, I know. Nonetheless, I added (BOGUS) code to look for this incorrect forecast and reject it. I designed the code though to re-try failed data fetches every hour. Often when I get the bogus weather forecast it will eventually come back correct some hours later.

I could move to a different weather API, but from having just dipped my toe into web API, it looked like most API require the user to set up an account and then pass a token in the query URL. That seemed pretty user-unfriendly, more hoops to go through to get SystemSix up and running. So for now I passed on looking further into it.

The fonts are not all perfect. Many are missing fairly common glyphs (I had to manually edit the Geneva 9 font to add the degree glyph, for example). Kerning, spacing might not be ideal (the space character in Geneva 9 was way too wide and I had to go in and tighten it up).

I cheated to get a bold "Geneva 12" and just rendered the font twice; offset to the right by one pixel on the second render.

Because the display is ultimately two values (B&W) any sort of aliasing will look bad when displayed. Careful attention therefore has to be made to find the precise font size that will yield glyphs on perfect pixel boundaries.

Acknowledgments

Code base began from eInkCalendar by 13Bytes.

The ChiKareGo2 font is under Creative Commons license.

The artwork came from taking screenshots of the excellent MiniVMac emulator.

"Good enough for 1.0…"

Comments
  • Cannot Open Display

    Cannot Open Display

    Per my last message I hooked up a slightly larger 7.5in display. I altered the epd name in the systemsix.py file and the eink_utils.py file as well as the display size to 800, 480. It seems to successfully pull the weather and calendar info, but unfortunately I can't get it to display. I get the following error:

    INFO:app:systemsix.update_display(); updating display. option parsing failed: Cannot open display: ^CTraceback (most recent call last): File "/home/pi/SystemSix/systemsix.py", line 557, in main() File "/home/pi/SystemSix/systemsix.py", line 553, in main time.sleep(5)

    Any ideas on where I might be going wrong? I know you said to try turning off the display to test run it, but I'm running this out of a Mac terminal and I'm not sure how to get that to display without the e-ink screen. Thanks!!

    opened by holmesha 13
  • Question

    Question

    Not an issue, but I didn't see another way to ask questions. I love the look of your SystemSix project. It is very nostalgic for me as my first computer experiences were with this version of an Apple. I'm new to programming / micro computing, so forgive my basic questions. I was wondering if it matters what size of screen (other than for the case), or can I use a bigger version of the screen (7.5") that I already have? Also, is there a way to show more calendar items, or have the screen refresh more than once per day? Thanks!!

    opened by holmesha 5
  • Calendar issue

    Calendar issue

    I jumped through the same hoops as mentioned in the readme to get the URL for my iCloud calendar, however the call to retrieve the events (event_list = events(...)) results in an error:

    INFO:app:calendar_module.get_events(); trying.... CRITICAL:app:can't compare offset-naive and offset-aware datetimes

    Any thoughts what this means?

    opened by pocketscience 1
  • Use non-Retina resolution to avoid needing to downsample screenshots

    Use non-Retina resolution to avoid needing to downsample screenshots

    Fantastic project! Thanks for sharing. Loved reading your write-up.

    You spent some time talking about using GraphicsMagick to downsample Retina-resolution (pixel-doubled) Mini vMac screenshots. (Its cousin ImageMagick is another choice.) Wanted to let you know you can avoid the need for that step by setting your screen to a non-Retina (non-HiDPI) resolution prior to making the screenshots using a utility such as RDM. Or connect an external non-Retina display to your computer and drag the Mini vMac window onto that display before screenshotting it.

    opened by ryandesign 1
  • Newspaper image is not a mockup

    Newspaper image is not a mockup

    Not an issue, but I couldn't find another way to leave a message. In your blog post about SystemSix you include a screenshot of the New York Times on a big e-ink screen, with the caption: "An expensive e-ink newspaper project, this one possibly a mock-up?"

    I believe it's not a mockup, you can find more details about the project here: https://alexanderklopping.medium.com/an-updated-daily-front-page-of-the-new-york-times-as-artwork-on-your-wall-3b28c3261478

    opened by lucaswillering 1
  • Trash indication and Bank Holidays (in the UK)

    Trash indication and Bank Holidays (in the UK)

    More a for info (as I probably won't build your project), but I saw it on the Raspberry Pi blog and I've done something vaguely related.

    In the UK at least, some councils will offset their rubbish collection when there is a Bank Holiday (and a day for each Bank Holiday on the rare event there are two before your collection that week), so a Tuesday collection becomes Wednesday etc.

    There's a nice JSON feed here thankfully: http://www.gov.uk/bank-holidays.json

    opened by peternewman 0
Owner
John Calhoun
After a 30-year hiatus, back to writing shareware, ha ha.
John Calhoun
Design and build a wrapper for the Open Weather API current weather data service

Design and build a wrapper for the Open Weather API current weather data service that returns a city's temperature, with caching, also allowing for the temperature of the latest queried cities that are still validly cached to be retrieved.

Duan Rafael Ribeiro 1 Jun 27, 2022
Insane Weather Bot is here! Give suggestions, fork, and do much more to help us enhance the abilities of Insane Weather Bot.

Insane_Weather_Bot Insane Weather Bot is here! Give suggestions, fork, and do much more to help us enhance the abilities of Insane Weather Bot. Weathe

null 1 Jan 2, 2022
Weather Tracker, made with Python using Open Weather API

Weather Tracker Weather Tracker, made with Python using Open Weather API

Sahil Kumar 1 Feb 7, 2022
An information scroller Twitter trends, news, weather for raspberry pi and Pimoroni Unicorn Hat Mini and Scroll Phat HD.

uticker An information scroller Twitter trends, news, weather for raspberry pi and Pimoroni Unicorn Hat Mini and Scroll Phat HD. Features include: Twi

Tansu Şenyurt 1 Nov 28, 2021
An information scroller Twitter trends, news, weather for raspberry pi and Pimoroni Unicorn Hat Mini and Scroll Phat HD.

uticker An information scroller Twitter trends, news, weather for raspberry pi and Pimoroni Unicorn Hat Mini and Scroll Phat HD. Features include: Twi

kottuora 5 Oct 31, 2022
Lambda-function - Python codes that allow notification of changes made to some services using the AWS Lambda Function

AWS Lambda Function This repository contains python codes that allow notificatio

Elif Apaydın 3 Feb 11, 2022
A simple discord bot written in python which can surf subreddits, send a random meme, jokes and also weather of a given place

A simple Discord Bot A simple discord bot written in python which can surf subreddits, send a random meme, jokes and also weather of a given place. We

null 1 Jan 24, 2022
Jalali version of python calendar :date:

jcalendar jcalendar is Jalali implementation of Python's calendar module Status Install pip install jcalendar Documents This module almost follows Py

Iman Kermani 7 Aug 9, 2022
Market calendar RESTful API with holiday, late open, and early close. Over 50+ unique exchange calendars for global equity and futures markets.

Trading Calendar Market calendar RESTful API with holiday, late open, and early close. Over 50+ unique exchange calendars for global equity and future

Apptastic Software 1 Feb 3, 2022
📅 Calendar file generator for triathlonlive.tv upcoming events

Triathlon Live Calendar Calendar file generator for triathlonlive.tv upcoming events. Install Requires Python 3.9.4 and Poetry. $ poetry install Runni

Eduardo Cuducos 4 Sep 2, 2022
Apps related to Odoo it's calendar features

calendar Apps related to Odoo it's calendar/appointments features: online_appointment_locations: allow setting an online URL per employee online_appoi

Yenthe Van Ginneken 3 Oct 27, 2022
A discord bot that utilizes Google's Rest API for Calendar, Drive, and Sheets

Bott This is a discord bot that utilizes Google's Rest API for Calendar, Drive, and Sheets. The bot first takes the sheet from the schedule manager in

null 1 Dec 4, 2021
Bezlik Year Calendar Planner

Bezlik Year Calendar Planner Scribus script for creating year planners on one page A1 paper format. Script is based on Year-Calendar-Script-for-Scribu

Bohdan Bobrowski 2 May 24, 2022
Takes upcoming items from a Google Calendar and posts them to Slack.

Google Calendar to Slack by Jason Snell - [email protected] This Python script scrapes upcoming items from Google Calendar HTML and posts them to S

null 6 Aug 21, 2022
PyHoroscope - Observational Indian lunisolar calendar, horoscope and matching using the Swiss ephemeris

PyHoroscope Observational Indian lunisolar calendar, horoscope and matching usin

null 4 Jun 5, 2022
An incomplete add-on extension to Pyrogram, to create telegram bots a bit more easily

PyStark A star ⭐ from you means a lot An incomplete add-on extension to Pyrogram

Stark Bots 36 Dec 23, 2022
A thin Python Wrapper for the Dark Sky (formerly forecast.io) weather API

Dark Sky Wrapper This is a wrapper for the Dark Sky (formerly forecast.io) API. It allows you to get the weather for any location, now, in the past, o

Ze'ev Gilovitz 414 Nov 16, 2022
Python wrapper library for World Weather Online API

pywwo Python wrapper library for World Weather Online API using lxml.objectify How to use from pywwo import * setKey('<your_key>', 'free') w=LocalWeat

World Weather Online 20 Dec 19, 2022
Wetterdienst - Open weather data for humans

We are a group of like-minded people trying to make access to weather data in Python feel like a warm summer breeze, similar to other projects like rdwd for the R language, which originally drew our interest in this project.

null 226 Jan 4, 2023