Digitaler IKEA-Bilderrahmen mit dem Raspberry Pi – Erstellen der Kalenderanzeige

Dieser Artikel „Erstellen der Kalenderanzeige“ beschreibt wie ich die Kalenderanzeige realisiert habe und wie ich die Daten von einem ownCloud-Server auslese.

Die Anzeige des Bildschirms erfolgt über zwei Skripte. Das erste Skript holt die Daten vom owncloud-Server und erzeugt ein Bild. Das zweite Skript zeigt das Bild an.

Erstellen einer VCAL-Datei aus dem Kalender

#!/usr/bin/python # -*-coding: utf-8 -*- ''' Python Skript to get the next appointments from owncloud database ''' import time import mysql.connector from PIL import Image, ImageDraw, ImageFont from icalendar import Calendar, Event from datetime import datetime, timedelta from pytz import UTC # timezone from dateutil.rrule import rrulestr, rruleset from PIL import Image, ImageDraw, ImageFont import os,sys #Anzahl der Tage für Termine in der Vergangenheit NUMBER_OF_DAYS_BEFORE = 10 # Anzahl der Tage für Termine in der Zukunft NUMBER_OF_DAYS_AFTER = 30 # die ID des Kalenders in owncloud CALENDAR_ID = 1 NOW = int (time.time()+0.5) FROM = (NOW - ( NUMBER_OF_DAYS_BEFORE * 24 * 60 *60) ) TO = (NOW + ( NUMBER_OF_DAYS_AFTER * 24 * 60 *60) ) # set screenwidth if (len(sys.argv) > 1): screenwidth=int(sys.argv[1]) else: screenwidth=640 if (screenwidth != 640): screenheight=624 else: screenheight=480 header = """BEGIN:VCALENDAR VERSION:2.0 CALSCALE:GREGORIAN PRODID:-//SabreDAV//SabreDAV//EN X-WR-CALNAME:Personal (kiosk) BEGIN:VTIMEZONE TZID:Europe/Berlin BEGIN:DAYLIGHT TZOFFSETFROM:+0100 TZOFFSETTO:+0200 TZNAME:CEST DTSTART:19700329T020000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3 END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:+0200 TZOFFSETTO:+0100 TZNAME:CET DTSTART:19701025T030000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 END:STANDARD END:VTIMEZONE """ # # get the current serverstatus from the mysql db on rpi0 # and write it to a ics file # # Bitte die Parameter für die Datenbankverbindung ersetzen cnx = mysql.connector.connect(user='myusername', password='mypassword', host='myhostname', database='mydatabasename') cursor = cnx.cursor() query_template ="select calendarid, from_unixtime(firstoccurence) as start, from_unixtime(lastoccurence) as ende, calendardata as event from oc_calendarobjects where calendarid = '%s' and lastoccurence >= '%s' and firstoccurence <= '%s' and componenttype = 'VEVENT'" query = query_template % (CALENDAR_ID, FROM, TO) cursor.execute(query) file = open("curr_cal1.ics","w+") file.write(header) for (calendarid, start, ende, event) in cursor: spos = event.find("BEGIN:VEVENT") epos = event.find("END:VEVENT") event = event[ spos : epos ] +"END:VEVENT\n" if event != "": file.write(event) file.write("END:VCALENDAR\n") file.close() cursor.close() cnx.close()

Das Skript verbindet sich mit der owncloud-Datenbank, liest die Kalendereinträge aus und schreibt sie im VCAL-Format in die Datei curr_cal1.ics. Dafür wird das Python icalendar-Modul verwendet. Der Code muss bzgl. der Parameter für die Datenbankverbindung angepasst werden (s.o.). Weiterhin können die Einstellungen für den Zeitraum der auszulesenden Termine und die Kalender-ID eingetragen werden. Der zweite Teil des Skripts erzeugt ein Bild mit den ausgelesenen Daten.

Die Kalenderanzeige erzeugen

# # parse ics file and store relevant calendar entries to dict # edict={} today = datetime.today() date_from = (today - timedelta(days=NUMBER_OF_DAYS_BEFORE)).strftime("%Y%m%d%H%M") date_to = (today + timedelta(days=NUMBER_OF_DAYS_AFTER )).strftime("%Y%m%d%H%M") g = open('/home/pi/kiosk/curr_cal1.ics','rb') gcal = Calendar.from_ical(g.read()) for component in gcal.walk(): if component.name == "VEVENT": if component.get('rrule'): rules = rruleset() first_rule = rrulestr(component.get('rrule').to_ical(), dtstart=component.get('dtstart').dt) # in some entries, tzinfo is missing if first_rule._until and first_rule._until.tzinfo is None: first_rule._until = first_rule._until.replace(tzinfo=CET) rules.rrule(first_rule) exdates = component.get('exdate') if not isinstance(exdates, list): # apparently this isn't a list when exdates = [exdates] # there is only one EXDATE for exdate in exdates: try: rules.exdate(exdate.dts[0].dt) except AttributeError: # sometimes there is a None entry here pass now = datetime.now(tz=UTC) dff = now - timedelta(days=NUMBER_OF_DAYS_BEFORE) dft = now + timedelta(days=NUMBER_OF_DAYS_AFTER) dfr = rules.between(dff,dft) if dfr != []: for i in dfr: event_key = i.strftime("%Y%m%d%H%M") entry= i.strftime("%d.%m.%y %H:%M") + " " + component.get('summary') edict[event_key]=entry else: event_key = component.get('dtstart').dt.strftime("%Y%m%d%H%M") if (event_key >= date_from and event_key <= date_to): entry = component.get('dtstart').dt.strftime("%d.%m.%y %H:%M") + " " + component.get('dtend').dt.strftime("%d.%m.%y %H:%M") + " " + component.get('summary') edict[event_key]=entry g.close() # # draw image with calendar entries on it # img = Image.new('RGB', (screenwidth, screenheight), color = (73, 109, 137)) fnt = ImageFont.truetype('/usr/share/fonts/truetype/noto/NotoMono-Regular.ttf', 18) d = ImageDraw.Draw(img) x=20 d.text((x,10), "Unsere Termine", font=fnt, fill=(255, 255, 0)) d.text((x,20), "_________________________________", font=fnt, fill=(255, 255, 0)) now = today.strftime("%Y%m%d%H%M") nowout=0 y=44 for key in sorted(edict): #print "%s: %s" % (key, edict[key]) if (key >= now and nowout==0): d.text((x,y), edict[key], font=fnt, fill=( 0, 255, 0)) nowout=1 else: d.text((x,y), edict[key], font=fnt, fill=(255, 255, 0)) y += 22 img.save('/tmp/curr_cal1.png')

Jetzt steht das Bild im Verzeichnis /tmp mit dem Namen curr_cal1.png und muss nur noch angezeigt werden.

#!/bin/bash # display current calendar image sudo fbi -d /dev/fb0 -T 1 -a --noverbose /tmp/curr_cal1.png

Dieses kleine Skript zeigt das Bild mittels fbi an. Das Programm fbi muss mit sudo ausgeführt werden, da der Framebuffer root-Rechte für den Schreibzugriff benötigt.

Grundsätzlich ist es möglich das Skript so anzupassen, dass es auch aus anderen Kalendern die Termine ausliest. Um den Rest des Skripts weiter zu verwenden, ist es am Einfachsten, die Daten ebenfalls im VCAL-Format abzulegen und dann mit den vorhandenen Code weiter zu verarbeiten.

Die Artikelserie besteht aus acht Teilen. Dem Überblick „Digitaler IKEA-Bilderrahmen mit dem Raspberry Pi“ und den sieben Artikeln zum Bau des digitalen Bilderrahmens mit dem Raspberry Pi.

  1. Einbau der Teile in den IKEA-Rahmen
  2. Grundlegende Einstellungen für den Raspberry Pi
  3. Steuerung der Anzeige
  4. Automatische Dia-Show
  5. Erstellen der Kalenderanzeige
  6. Generieren der Wetteranzeige
  7. Ermitteln und Anzeigen des Server-Status

Keine Antworten

    Schreibe einen Kommentar

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

    :bye: 
    :good: 
    :negative:  
    :scratch: 
    :wacko:  
    :yahoo: 
    B-) 
    mehr...
     

       Mit der Nutzung dieses Formulars erklärst Du Dich mit der Speicherung und Verarbeitung Deiner Daten durch diese Website einverstanden. Mehr Informationen dazu findest Du in der Datenschutzerklärung.

    ALL-INKL.COM - Webhosting Server Hosting Domain Provider TinyURL.com - Free URL Shortener

    Diese Seite verwendet Cookies. Mit der Nutzung von tuxlog erklärst Du Dich mit der Verwendung von Cookies einverstanden. Detaillierte Informationen über die Verwendung von Cookies auf dieser Website findest Du in der Datenschutzerklärung.