3

SAP Community meets e-ink display: an RSS story

 1 year ago
source link: https://blogs.sap.com/2023/01/22/sap-community-meets-e-ink-display-an-rss-story/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

SAP Community meets e-ink display: an RSS story

In this blog post, I will share a project that I worked on during the X-mas break. The project involves a Raspberry Pi, an e-ink display, the SAP Community RSS (Really Simple Syndication) feed (https://blogs.sap.com/feed/), some python 🐍, and even a 3D printer.

SAP%20Community%20blog%20posts%20feed%20in%20e-ink%20display

SAP Community blog posts feed in e-ink display

I personally love RSS. For me, there isn’t a better way to be informed of what’s going on on my preferred websites/blogs than by reading the RSS entries on my favourite feed reader – Miniflux (of course self-hosted :-).

RSS (RDF Site Summary or Really Simple Syndication) is a web feed that allows users and applications to access updates to websites in a standardized, computer-readable format. Subscribing to RSS feeds can allow a user to keep track of many different websites in a single news aggregator, which constantly monitor sites for new content, removing the need for the user to manually check them. Source: Wikipedia.

I remember fondly the days when every single website published an RSS feed and it was simple to subscribe to them. Google Reader was the most popular feed reader at that time until big G decided to kill the product. A sad day, if you ask me. Unfortunately, RSS lost some momentum when this happened and its adoption slowed down significantly. That said, there are still many websites that publish an RSS feed. In some websites, you’ll find a link/icon to the RSS feed visible in the UI but I would say that most have it somewhat hidden/not that accessible. I found myself going to the source of the web page (Right click > Web Page source) to find a link to the RSS feed. You’ll normally find it in the head section of the HTML.

SAP%20Community%20-%20RSS%20feed%20link

SAP Community – RSS feed link

As you can imagine, I’m subscribed to the SAP Community blogs section RSS feed. This is to learn from what other members of the community share/write about. Now, whenever I want to know what’s happening in SAP Community, I go to my feed reader and select the SAP Community feed and I can see all the blog posts published since the last time I checked my feed.

There is a lot going on in SAP Community and it is possible to filter your feed by you favourite tag, e.g. SAP Buiness Technology Platform – https://content.services.sap.com/feed?type=blogpost&tags=8077228b-f0b1-4176-ad1b-61a78d61a847&title=Latest%20blog%20posts%20for%20SAP%20Business%20Technology%20Platform. To get a topic feed go to to https://blogs.sap.com, select a tag you are interested and copy the link from the RSS link that’s in the header.

I’m able to read the entries on Miniflux but I was thinking if there was a way to consume the feed in a passive way and not have to go and check a website. Enter an e-ink display.

e-ink display

Prototype

Prototype – Raspberry Pi inside the cardboard box

I do most of my reading on an e-ink device (Kindle). I’ve had a couple and have always enjoy the experience of reading on an e-ink display. Unfortunately, there is no SDK for the device so it is not possible to create an app/program to extend its capabilities. That said, I’ve always wanted to play with an e-ink display but I just never had a nice little project to justify buying one.

Given my new “want” to check the feed in a passive way, I thought it will be cool to use an e-ink display to keep me informed of what’s going on in SAP Community. Obviously, some coding is required to display something on the display which add to the fun of the project.

The e-ink display that I got for my project is a Waveshare – 7.5inch E-Paper E-Ink Display Module (B) for Raspberry Pi Pico, 800×480, Red / Black / White. Its size is similar to a photo frame, so it will easily be on my desk (yes, I also have a photo of my family on my desk ❤️). Waveshare has a library that allows you to interact with the display from different programming languages. This is available on their public repo, waveshare / e-Paper, and it contains many examples of how you can use the display. Let’s look at some code now.

Script

After testing the display and making sure I was able to communicate with the display from the Raspberry Pi, I developed a python script that gets the SAP Community blogs feed and shows the latest entries on the display. The display will only refresh if there is a new entry. If there aren’t new entries there’s no need to refresh what’s on display.

I refer to the script below as the skills script. Any new functionality I want to add to the program, e.g. display a dashboard, the status of a device, a quote, a message, etc., will be a new “skill” in the script, which can be triggered on demand if needed.

import logging
import os
import sys
import textwrap
from PIL import Image, ImageDraw, ImageFont

import epaper
import feedparser

PIC_DIR = os.path.join(os.getcwd(), 'pic')
FONTS_DIR = os.path.join(os.getcwd(), 'fonts')
LIB_DIR = os.path.join(os.getcwd(), 'lib')

if os.path.exists(LIB_DIR):
    sys.path.append(LIB_DIR)

logging.basicConfig(level=logging.DEBUG)

# e-Paper instance
epd = epaper.epaper('epd7in5b_V2').EPD()

# e-Paper dimensions
EPAPER_WIDTH = epd.width
EPAPER_HEIGHT = epd.height

LAST_FEED_ITEM = ""


def poll_sap_community_rss():

    black_image = Image.open(os.path.join(PIC_DIR, 'sap-community-classic.png'))
    red_image = Image.new('1', (EPAPER_WIDTH, EPAPER_HEIGHT), 255)

    font_title = ImageFont.truetype(
        os.path.join(FONTS_DIR, 'BentonSans-Bold.ttf'), 18)
    font_additional_text = ImageFont.truetype(
        os.path.join(FONTS_DIR, 'BentonSans-RegularItalic.ttf'), 14)

    draw_black = ImageDraw.Draw(black_image)
    draw_red = ImageDraw.Draw(red_image)

    blogs_url = "https://blogs.sap.com/feed/"

    parsed_feed = feedparser.parse(blogs_url)

    # Position where text rendering will start
    y = 100

    global LAST_FEED_ITEM

    # Check that there are new feeds
    if parsed_feed.entries[0].id != LAST_FEED_ITEM:
        LAST_FEED_ITEM = parsed_feed.entries[0].id

        for entry in parsed_feed.entries:
            print(entry.title)

            draw_black.text((20, y), entry.title, font=font_title, fill=0)
            draw_red.text((EPAPER_WIDTH - 160, y + 25), entry.category,
                          font=font_additional_text, align='right', fill=0)
            draw_black.text((20, y + 25), entry.author,
                            font=font_additional_text, fill=0)

            y += 60

            if y > 440:
                break

        black_image.save("Sample.png")

        logging.debug("EPD init")
        epd.init()

        logging.info("Render RSS details")
        epd.display(epd.getbuffer(black_image), epd.getbuffer(red_image))

        logging.debug("EPD sleep")
        epd.sleep()


def init_screen():
    logging.info("Initialising...")

    logging.info("init")
    epd.init()
    logging.info("clear")
    epd.Clear()

Of course, I wasn’t satisfied with just having a program running and displaying the latest feed entries. I want to be able to show different things on the display, at different times of the day….. enter APScheduler and its API 🙂

Flask and the Advanced Python Scheduler (APScheduler)

With APScheduler I’m able to schedule different tasks on my program. In my case, checking for new feed entries in the SAP Community blogs feed happens every 5 minutes. The API is provided by the Flask-APScheduler package. Via the API I can control the scheduler, e.g. start/stop jobs, trigger functionality on demand, etc.

Having an API and a scheduler gives the device a lot of flexibility. Meaning, I can use it for a lot of different purposes,e.g. display an inspirational quote, show me how I’m doing on my habit tracker at a particular point in time or enable it so that my family can send me an important message straight to the display.

#!/usr/bin/env python3

import time

from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from flask import Flask

from flask_apscheduler import APScheduler

from skills import init_screen, poll_sap_community_rss


class Config:
    """App configuration."""

    JOBS = [
        {
            "id": "sap_community_rss",
            "func": "skills:poll_sap_community_rss",
            "trigger": "interval",
            "replace_existing": True,
            "seconds": 300
        }
    ]

    SCHEDULER_JOBSTORES = {
        "default": SQLAlchemyJobStore(url="sqlite:///jobs.db")}

    SCHEDULER_EXECUTORS = {"default": {
        "type": "threadpool", "max_workers": 20}}

    SCHEDULER_JOB_DEFAULTS = {"coalesce": False, "max_instances": 3}

    SCHEDULER_API_ENABLED = True


if __name__ == "__main__":
    app = Flask(__name__)
    app.config.from_object(Config())

    scheduler = APScheduler()
    scheduler.init_app(app)
    
    print("Init screen")
    init_screen()
    time.sleep(1)

    print("SAP Community RSS")
    poll_sap_community_rss()
    time.sleep(5)

    # Start scheduler
    scheduler.start()

    app.run(host="0.0.0.0")

Running as a service

It is likely that I will need to unplug the Raspberry Pi but whenever I turn it on again I want my program to refresh the display with new data. For this, I created a simple service that will start whenever the Raspberry Pi reboots. See the sample e-ink-display.service below.

[Unit]
Description=e-Ink Display
After=multi-user.target

[Service]
WorkingDirectory=/home/pi/repos/github.com/sap-community-e-ink-rss/
ExecStart=/usr/bin/python3 /home/pi/repos/github.com/sap-community-e-ink-rss/scheduler.py
User=pi

[Install]
WantedBy=multi-user.target

For more details on how do create a service like the one above in a Raspberry Pi, check out this blog post – How to create a systemd service in Linux.

3D printing

Ok, so I got an e-ink display working, the code is running fine but, as shown in the “prototype” photo above, the Raspberry Pi is in a cardboard box and nothing protects the delicate e-ink display. I wanted a case for it so that it will look nice on my desk but there is nothing available to purchase online. Fortunately, there is a massive 3D printing community and I was able to find a “thing” in Thingiverse that could help get me started with the case needed for this project.

I don’t have a 3D printer, at least not yet, but I do know someone who has one (Thanks Pablo!). He was kind enough to help with some adjustments required in the STL (Standard Triangle Language) as the original design is for an LCD display, which has different dimensions, and the e-ink display is a bit thinner and smaller.

If you are into 3D printing, stop motion or playmobil, I highly recommend checking out Pablo’s posts.

After a few hours of 3D printing, sanding down some screws, and a bit of glue…. Check out how the case with the display and Raspberry Pi looks like in the photos below.

Front Right%20side
Back
Left%20side

I think the device looks amazing on my desk. I’m now able to passively read what’s going on in SAP Community by just checking out the display. It’s what’s normally on the display but I also have some other “skills” that display information on it.

3D%20printer%20frame%20on%20my%20desk

3D printed frame on my desk

I’m quite happy with the current state of this little project. The display now sits next to my home office display and I’m able to passively know if there is something happening in the SAP Community. Let me know what you think of the project in the comments below and please share some ideas with me on other cool skills that I can code on this thing. Thanks for reading!


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK