← Zurück zum Blatt korell.org · Heft Nr. 62 · Mai 2026
Sonderdruck · IT-Beilage S.1
Korell
Gratis
27 Seiten
Pi-Inventar
LLM-Vault MagicMirror Wetter KorellMusik Galerist PyroMan RaspiBackup
Diagnose & Tüftelei

Eine Raspi-Flotte mit sehr eigener Geschichte und einem eigenen Gedächtnis.

Eine Bestandsaufnahme aus der Praxis — was die Geräte können, was sie nicht können, und was man dabei über Architektur und Lebenszyklen lernt.

Eine Werkstatt entsteht selten planvoll. Sie wächst, wenn man einem Gerät zuhört, das eigentlich für einen anderen Zweck gedacht war, und dabei feststellt, dass es noch eine andere Aufgabe übernehmen kann. Diagnose nennt man in der ärztlichen Praxis den genauen Blick auf das, was funktioniert und was nicht. Beim Tüfteln gilt dasselbe — nur dass am Ende der Untersuchung keine Verordnung steht, sondern eine Lötstelle, eine Konfigurationszeile oder ein Programm, das ein Problem aus der Welt schafft.

Mit dem Raspberry Pi habe ich 2015 auf einem Pi 2B begonnen — damals war das Ökosystem noch übersichtlich, die dicken Handbücher gerade in zweiter Auflage erschienen. Erster Anwendungsfall war ein elektronisches Zündsystem. Das wollte ich so sicher und so komfortabel wie irgend möglich erledigen. Heute tut eine ganze Familie davon bei uns ihren Dienst — jeder einer einzigen Aufgabe gewidmet, obwohl er alle könnte: Bildbetrachtung, Wetterauswertung, Datensicherung, Funkzündung, Wandanzeige — nicht als Spiegel, sondern als Bilderrahmen, der bei Anwesenheit aufwacht. Jedes Gerät hat eine eigene Geschichte. Alle aber haben ein gemeinsames Gedächtnis — mein persönlicher Anwendungsfall einer zentralen Wissensbasis.

Dieses „zweite Gehirn" ist die jüngste Idee für die Pi-Familie: Was ich an einem Gerät lerne — eine Lösung, eine Konfiguration, ein gefundener Stolperstein — steht den anderen sofort zur Verfügung. Das Heimnetz wirkt dadurch nicht wie ein Verbund einzelner Maschinen, sondern wie eine verteilte Praxis mit einem gemeinsamen Karteikasten. Wer in eines der Geräte hineinsieht, kennt zumindest in Umrissen alle anderen.

In der Werkstatt verfeinert man dieselben Begriffe, mit denen man tagsüber Verträge verhandelt: Architektur, Schnittstelle, Lebenszyklus.
Beispiel-Aufbau im Hobby-RZ.Photo · RK

Was man in einer solchen Werkstatt lernt, lässt sich kaum durch ein Seminar ersetzen. Es sind nicht die oft hergenommenen Begriffe — Architektur, Schnittstelle, Lebenszyklus —, sondern die kleinen Reibungsstellen, an denen sie sich konkretisieren und in handfeste Erfahrung übergehen. Architektur wird plötzlich greifbar — ein Mount kommt nach einem Neustart nicht von selbst zurück, weil das Funknetz beim Booten noch nicht da ist; die Lösung liegt nicht in einem teureren Gerät, sondern in einer kleinen Konfigurationszeile, die das System auf das Netz warten lässt. Schnittstelle wird greifbar, wenn der Mirror plötzlich keine Wetterdaten mehr anzeigt — weil ein Update auf dem Sensor-Pi sein Datenformat verändert hat, der Server zwischen ihm und dem Mirror diese neue Form nicht mehr lesen kann und deshalb auch nichts an den Mirror ausliefert. Lebenszyklus wird sichtbar, wenn ein automatisches Update eine Konfigurationsdatei überschreibt, die man vor zwei Jahren angepasst hatte und seitdem nie wieder anfassen musste — bis zu jenem Update.

Solche Begegnungen sind nicht spektakulär, sie sind zumeist sogar banal. Aber sie hinterlassen eine Form von Wissen, die man in keinem Datenblatt findet: das leise Gefühl dafür, wo ein System hält und wo es schiebt. Aus diesem Gefühl entsteht, was Bücher Architektur nennen — und was im Alltag den Unterschied macht zwischen einem System, das funktioniert, und einem, das man bedienen muss.

Und genau hier schließt sich auch der Kreis zur Tagespraxis. Wer beruflich mit Forschungseinrichtungen über Architektur und Lebenszyklus spricht, kann das nicht abstrakt tun. Eine Werkstatt im Haus übersetzt diese Begriffe ins Konkrete — und liefert das Vokabular, das im Vertriebsalltag oft fehlt. Diagnose und Tüftelei sind keine Gegensätze zur Berufsarbeit, sondern ihr stilles Übungsfeld.

Das Inventar
01 Wissensbasis · Multi-Agent LLM-Vault & Pi-Fleet Kontext is Key. Hardware6 Raspberry Pis · Pi 3B+ bis Pi 5 StackObsidian · Claude Code · rclone/GDrive · MCP-Server

Problemstellung

Jeder Pi im Heimnetz hat eine eigene Aufgabe: Display-Server, Wetter-Aggregator, Zündpult, Bilderrahmen. Mit dem Einzug von Sprachmodellen und resultierender Multi-Lokations-Entwicklung verschwammen diese Grenzen: Dokumentenerstellung läuft mal hier, mal dort; schnittstellenintensive Themen wie der Korell-Wetterdienst berühren mehrere Geräte gleichzeitig. Was wo angefasst wurde, ist dadurch immer schwieriger nachvollziehbar — insbesondere, wenn Zeit vergangen ist.

Erste Versuche im Sommer 2025 mit ChatGPT und Gemini, später Claude Web, brachen jenseits einer gewissen Komplexität regelmäßig ab — sichtbar an Halluzinationen, an stiller Ersetzung echten Codes durch Pseudo-Code, an Optimierungen, um die niemand gebeten hatte. Erst Claude Code lieferte ab Ende 2025 belastbare Ergebnisse und wurde zur Arbeitsumgebung. Aber auch dort bleibt ein strukturelles Problem: ein KI-Kontext lässt sich kaum sauber warten, läuft voll, wird invalide.

Die Inspiration kam von außen: Andrej Karpathys „LLM Wiki"-Skizze — ein Markdown-Wiki als Wissensbasis, in der ein Sprachmodell nachschlagen kann. Karpathys Implementierung stellt Benutzerlesbarkeit in den Vordergrund: Der menschliche Wissenskonsument stellt Informationseinheiten beliebiger Art in einem Eingangskorb zur Verfügung, das LLM ingestiert diese Informationen und stellt beim Ingest die notwendigen Verbindungen zur bereits bestehenden Datenbasis her. Das Konzept ist also zentriert auf das Lesen durch einen Menschen. Das Anwendungsprofil im Korell-Heimnetz ist anders.

Hier arbeiten mehrere LLMs — eines auf jedem dafür geeigneten Pi und zwei auf den PC/Mac-Arbeitsplätzen — und sie sollen über Sessions und Geräte hinweg auf einer gemeinsamen Wissensbasis arbeiten. Das verschob den Fokus — weg vom primär lesbaren Wiki, hin zu primär (LLM-)findbaren Informationen.

Architektur

Das Vault hat vier Schichten.

  1. Quellen (raw/) sind menschlich eingebrachte Rohmaterialien, die nach dem Ingest wieder gelöscht werden (analog zu Karpathys Konzept).
  2. Meta (meta/) enthält Thesaurus, Wissenslücken, Inventar — gepflegt von jeder Claude-Instanz im Haus.
  3. Wiki (wiki/) ist das eigentliche Gedächtnis, gegliedert in sechs Kategorien: Fleet, Projekte, Konzepte, Schnittstellen, Architekturen, Betrieb.
  4. Schema (CLAUDE.md im Vault-Root) beschreibt die Regeln, nach denen all das geführt wird.

Der entscheidende Architektur-Grundsatz lautet: das Vault erzeugt sich selbst.

Die für das Ingestieren des Wissens erstellten Skills sind lokal dünne Clients („stub", „bootloader"). Sie kennen nur den Pfad zum Vault und lesen dort das Schema — alles weitere kommt ebenfalls aus dem Vault: welche sechs Kategorien existieren, welche Frontmatter-Felder pro Eintrag Pflicht sind, wann ein Thema in mehreren Kategorien stehen darf, welche Namensmuster für Dateien gelten, wie Wikilinks gesetzt werden. Ändert sich das Schema, ändert sich das Verhalten aller Clients beim nächsten Aufruf — ohne dass ein einziger Client neu deployt werden muss. Die Single Source of Truth steht in einer einzigen zentralen Datei.

Die Vorgehensweise für jede einzelne LLM-Session auf jeglichem Rechner steht als ultimative Regel im lokalen Schema: Jede Frage, die das Modell nicht aus seinem unmittelbaren Kontext beantworten kann, muss zuerst über den Aufruf query_wiki geklärt werden — bevor irgendetwas anderes passiert.

Vault-Struktur in Obsidians Graph-Ansicht
Abb. 1 Vault-Struktur in Obsidians Graph-Ansicht

Umsetzung

Drei Skills decken die Wissensgewinnung ab. /vcrawl durchsucht die Pi-Fleet systematisch nach einem genannten Thema. Über parallele Agenten — höchstens fünf gleichzeitig, jeder mit Timeout — werden die verfügbaren Quellen auf den Pis durchsucht und das Gefundene zu einer Crawl-Datei zusammengeführt. Diese Datei ist noch kein Wiki-Eintrag, sondern Rohmaterial für den nächsten Schritt. In einem zweiten Modus dient /vcrawl nach einem Ingest als QS-Werkzeug: es vergleicht die Crawl-Datei mit dem entstandenen Wiki-Eintrag und meldet, was übersehen oder verzerrt wurde.

/vingest schreibt erarbeitetes Wissen ins Vault. Die Eingabe ist ein Freitext-Prompt, der den Skill in eine von drei Richtungen lenkt: einen vollständigen Session-Kontext als Wiki-Eintrag schreiben — alles, was in einer Sitzung diskutiert, recherchiert oder gebaut wurde; gezielt einzelne Teile übernehmen — eine bestimmte Erkenntnis, ein spezifisches Problem; oder eine zuvor erzeugte /vcrawl-Datei in das Wiki überführen.

Der Skill öffnet das Vault, liest erst Index, Thesaurus und die Liste offener Wissenslücken, dann die fachlich betroffenen Wiki-Seiten — und ergänzt sie nach festen Redaktionsregeln. Was ein Modell morgen auf einem Pi maschinell braucht (Dateipfade, Konfig-Werte, Tabellen-Schemata, Befehle), wird vollständig übernommen; narrativer Kontext (Hintergrund, Motivation, chronologische Abläufe) darf zusammengefasst werden; temporäre Zwischenstände werden weggelassen.

/vresolve arbeitet eine Liste offener Fragen ab, die im Vault selbst geführt wird. Modelle, die an einer Stelle keine Antwort haben, hängen den Punkt dort ein; /vresolve versucht jede einzelne maschinell zu klären, parallelisiert mit höchstens fünf Agenten gleichzeitig und einem Timeout pro Frage. Was nicht maschinell ermittelbar ist, landet aufbereitet beim Menschen.

Für erfolgreiche Recherche reichte Obsidians eingebaute Suche nicht aus — sie kennt nur Wortgleichheit, keine Begriffsverwandtschaft. Eine Suche nach „Verteilung" fand „Deployment" nicht, eine nach „Mosquitto" fand „MQTT" nicht. Die Antwort war eine Synonym-Schicht: etwas über 6.000 Wortpaare aus drei Quellen — Microsoft Terminology Collection für IT-Termini, OpenThesaurus für deutsche Allgemeinsynonyme, dazu rund 230 wiki-spezifische Ergänzungen für eigene Begriffe. Listing 1 zeigt einen Auszug.

Listing 1 · Synonym-Paare im Suchindex (Auszug)
deployment       ↔ bereitstellung · verteilung · rollout
authentication   ↔ authentifizierung
threshold        ↔ schwellenwert
mosquitto        ↔ mqtt
passwort         ↔ kennwort · zugangscode · codewort
verzeichnis      ↔ ordner · dateiverzeichnis
verschlüsselung  ↔ chiffre · chiffrierung
cache            ↔ puffer · zwischenspeicher
wetterdaten      ↔ messwerte · sensordaten
aggregator       ↔ sammler

An einer Stelle des Aufbaus war eine technische Entscheidung zu treffen: greifen die Synonyme zur Indexierungszeit oder zur Query-Zeit? Hier wurde der erste Weg gewählt. Synonyme werden beim Indexieren in den Volltext-Vektor eingewoben, nicht bei der Query-Expansion zur Laufzeit. Der MCP-Server query_wiki, den jede Claude-Instanz direkt anspricht, bleibt damit frei von Wissen — er nimmt den Suchbegriff entgegen, fragt die Datenbank, liefert das Ergebnis. Die Intelligenz steckt im Trigger, der beim Schreiben jeder Wiki-Seite läuft (Listing 2).

Die Schnittstelle für den Menschen ist ein schlichtes Web-Suchformular, das denselben Suchalgorithmus nutzt.

Listing 2 · Synonyme zur Indexierungszeit in den FTS-Vektor
search_vector :=
    setweight(to_tsvector('german',
              title || ' ' || synonyme_text), 'A') ||
    setweight(to_tsvector('german', summary),  'B') ||
    setweight(to_tsvector('german', content),  'C')

Den Aktualitätsstand sichert ein Indexer-Cronjob: alle vier Stunden läuft er über die Wiki-Dateien, bildet pro Seite einen SHA-256-Hash und indexiert nur die geänderten Seiten neu. Eine Bearbeitung schlägt damit spätestens vier Stunden später in der Suche auf — ohne dass jemand manuell etwas anstoßen muss.

Betrieb

Heute ist das Vault aktiv auf zwei Heads (Mac und Windows) und auf fünf Pis. Jeder dieser fünf Pis hat das Vault per rclone in sein lokales Dateisystem eingebunden.

Damit die operative Grundlage — Vault-Pfad, Pflichtregel, Skill-Verweise — auf allen Pis identisch bleibt, gibt es einen eigenen Distributions-Mechanismus über die CLAUDE.md jedes Pi. Im Vault liegt ein Header-Template, das diese Grundlage enthält. In den CLAUDE.md-Dateien auf den Pis ist der Bereich zwischen zwei Markern (<!-- VAULT-HEADER-START --> und <!-- VAULT-HEADER-END -->) für diesen Header reserviert. Bei einem Rollout wird auf jedem Pi der gesamte Inhalt zwischen den Markern ersetzt; alles davor oder dahinter — Pi-eigene Konfiguration, lokale Notizen — bleibt unberührt. Damit lassen sich Regeländerungen oder neue Skills mit einem einzigen Distributionslauf fleet-weit ausrollen, ohne dass Pi-spezifische Inhalte überschrieben werden.

Die Skill-Stubs auf den Pis müssen dabei nicht angefasst werden. Sie lesen das Schema beim Aufruf aus dem Vault — eine Änderung wirkt unmittelbar und überall, ohne erneutes Deployment auf irgendeinem der Pis.

02 Smart Mirror · Bilderrahmen MagicMirror & Weather-Aggregator Warum ein Spiegel manchmal nicht spiegelt. HardwarePi 5 · 27″-Samsung-Display · Senvolon Radar-Präsenzmelder · 3-D-gedruckter Rahmen mit Passepartout StackMagicMirror² · Node.js · pm2 · iwd · MQTT

Problemstellung

Den Wunsch nach einem intelligenten Anzeigegerät im Haus gab es schon länger. Die Idee, die „smarte" Anzeige auch smart im Wortsinn hinter einem Spiegel zu verstecken, geistert schon lang durch die Maker-Gazetten.

Konkreter wurde es für mich im Weihnachtsurlaub 2024. Im MagicMirror²-Forum fand ich eine flexible, bezahlbare Vorlage — zudem Community-gestützt, was ich sowieso einen interessanten Ansatz finde. Sam (Detweiler) — geschätzter Forums-Guru — stellt Maintenance-Skripte zur Verfügung, die den aufwendigen Installationsprozess vieler Komponenten standardisieren und damit stark vereinfachen.

Nach der Basis-Installation beginnt Sisyphos-Arbeit: die eigentliche Sichtung. Ganz schön viele Community-Module — alte und neue, gepflegte und längst vergessene, solche mit aktivem Maintainer und solche, deren letzter Commit von 2018 ist. Lange (sehr lange) ausprobiert, verworfen, modifiziert.

Der MagicMirror als gerahmtes Bild an der Wohnzimmerwand
Abb. 1 Spieglein, Spieglein an der Wand …

Die geplante Hardware stand bereit: ein 27-Zoll-Display, das ich eigentlich hinter einem 120x60 qcm-Spiegel im Flur verstecken wollte.

Bis März 2025 stand der Monitor im Testaufbau im Wohnzimmer, ohne Spiegel — schlicht als Bildschirm. Manchmal aber hält sich ein Provisorium.

Das entscheidende Ereignis — etwa Mitte Januar — war die Feststellung meiner Frau: „Über dem Globus fehlt doch der Mond!" Das war ein einfaches Suchwort, das auch einen sofortigen Treffer ergab, und nach ein bisschen Rumprobieren mit den — ja noch neuen — Regionsbezeichnungen war der WAF (Wife Acceptance Factor) am „Mirror" sichtbar: Die Erde hatte an der richtigen Stelle ihren Trabanten, der ebenfalls die Phase anzeigt.

In Verbindung mit unserem Familienkalender, der Aufgabenliste und dem Müllabfuhr-Plan wurde klar: Dort schauen wir öfter hin. Der Spiegel aber — im Flur — ist ein Ort, an dem wir nicht so häufig vorbeikommen — „öfter" also ging da nicht. Und einen Spiegel im Wohnzimmer? Nein.

Daher haben wir dem Monitor schließlich einen schönen, antik anmutenden Holzrahmen geschenkt und ihn an prominenter Stelle ins Wohnzimmer gehängt. „Fertiggestellt" (smarte IT-Projekte sind nie fertig) habe ich das im März 2025. Was als Spiegel begann, hängt seitdem als Bilderrahmen an der Wand. Das Projekt heißt weiterhin MagicMirror — gespiegelt wird nichts.

Architektur

Das Framework MagicMirror² stellt nur die Bühne zur Verfügung. Die eigentliche Substanz steckt in den Modulen — kleine Node.js-Bausteine, jeder einer bestimmten Aufgabe gewidmet. Pro Modul (fast immer) ein node_helper.js im Hintergrund, der die Daten beschafft (REST-API, lokale Datei, MQTT-Subscription, GPIO-Event), und ein MMM-modulname.js im Frontend, das die Anzeige im Browser-Renderprozess übernimmt. Datenverarbeitung findet üblicherweise im Backend statt (bei den Korell-Modulen: ausschließlich); das Frontend ist in der Regel passiv und reagiert nur auf Notifications. Beide Hälften kommunizieren über die im Framework eingebaute Socket-Schicht. Über allem läuft pm2 als User-Space-Prozessmanager — kein systemd-Service, sondern ein eigenes Werkzeug, das den Node-Prozess startet, beobachtet, neu auflegt.

3-D-Modell des Rahmenhalters in Fusion360
Abb. 2 Fusion360-Entwurf des gedruckten Rahmenhalters.

Konfiguriert wird zentral, in einer einzigen Datei: config.js. Sie listet, welche Module geladen werden, an welcher Bildschirm-Region sie erscheinen und welche Parameter sie bekommen. Für die Steuerung des Aussehens der Module wird intensiv CSS genutzt — das funktioniert nicht in den Modul-Skripten selbst, sondern die lokale User-custom.css überschreibt zur Laufzeit die Modulvorgaben, sodass individuelle Anpassungen sehr einfach möglich sind (sofern man die passenden CSS-Deskriptoren findet; die Browser-Developer-Konsole ist dabei manchmal unersetzlich).

Displays haben üblicherweise keinerlei Vorrichtung, sauber in einen Bilderrahmen integriert zu werden. Ein aus unserem 3-D-Drucker stammender Zwischenrahmen löst dieses Problem: Er umfasst den unregelmäßig gestalteten Teil des Monitors, bildet damit die Brücke zwischen Monitor und Holzrahmen und dient gleichzeitig einem optisch vergrößernden Passepartout als Auflagefläche.

Umsetzung

Heute läuft auf dem System eine kuratierte Auswahl an Modulen — vier eigene Repos (siehe Listing 1), sieben weitere Community-Module mit eigenen Anpassungen, die über das CSS-Modding hinausgehen, und der Rest unverändert aus der Community.

Listing 1 · Modul-Inventur (25 aktive Module, Stand 2026)
EIGENE REPOS (4)
    MMM-My-Actual-Weather      Live-Anzeige der Wetterstation, 4-Stufen-Fallback
    MMM-Best-Weather           45 deutsche Städte, Open-Meteo, HCI-Scoring
    MMM-PresenceScreenControl  PIR + MQTT, Auto-Dimming, Cron-Fenster
    MMM-Unnuetzes-Wissen       2.716 deutsche Fakten, Zufallsanzeige

  COMMUNITY MIT EIGENEN ANPASSUNGEN (7)
    MMM-Profilepicture         schwarzer Hintergrund mit Initial-Logo (Snille)
    MMM-MyGarbage              Mülltermine nach Tonne (htilburgs)
    birthdaylist               Geburtstagsliste (sdetweil)
    MMM-Strava                 Trainingsstatistik (ianperrin)
    MMM-Pinfo                  Pi-Hardware-Info (SalekurPolas)
    MMM-Globe                  EUMETSAT-Satellitenbild, Küstenlinien (Fork von LukeSkywalker92)
    MMM-NowPlayingOnSpotify    laufender Spotify-Track (raywo)

  COMMUNITY UNVERÄNDERT (8)
    MMM-CalendarExt3Agenda     Agenda-Ansicht des Google-Familienkalenders
    MMM-Todoist                Aufgabenliste aus ToDoist
    MMM-MoonPhase              aktuelle Mondphase
    MMM-FRITZ-Box-Callmonitor-py3  eingehende Anrufe der FritzBox
    MMM-SystemInfo             OS- und Netzwerkstatus, NVMe nativ
    MMM-MagicMover             Anti-Burn-In durch Bildwanderung
    MMM-Logging                erweitertes Modul-Logging
    MMM-Remote-Control         Web-Frontend zur Modul-Steuerung

  MAGICMIRROR-DEFAULTS (6)
    alert, clock, weather (Forecast), newsfeed,
    calendar (Feiertage), calendar (Google)

Präsenz

Eine Funktion stand für mich von Anfang an außer Diskussion: Das Display sollte nicht durchgehend leuchten, sondern dann und nur dann an sein, wenn auch jemand davorsteht. Das war tatsächlich gar nicht so einfach, wie gedacht.

Der naheliegende und auch häufigste Implementierungsweg ist ein (günstiger) PIR-Sensor. Dieser ist gerade am Pi schnell angeschlossen und kalibriert, und das Zusammenspiel mit dem Modul MMM-Pir funktioniert prima und optisch sehr schön — mit einem Progressbar, der die Einschaltzeit herunterzählt, und einem netten Dimm-Effekt vor dem endgültigen Abschalten des Monitors. Bei unserem Anwendungsfall zeigten sich jedoch die Schwächen des PIR-Ansatzes ziemlich bald: Wer eine Weile ruhig auf dem Sofa sitzt, ist für PIR nicht mehr „anwesend", und der Bildschirm schaltet nach der eingestellten Deaktivierungszeit ab.

Günstige GPIO-Ultraschall- und Infrarot-Module erwiesen sich tatsächlich als noch schlechter geeignet, da sie gar keine Konfigurationsmöglichkeiten bieten und demzufolge das erkennen, was sie erkennen können — das aber reichte nicht aus.

Rückseite des MagicMirror mit PIR-Sensor und Raspberry Pi während des Aufbaus
Abb. 3 Bau des Mirrors: Rückseite mit Komponenten — PIR und Pi oben.

Senvolon stellt mit dem Radar-Präsenzmelder eine recht hochpreisige Lösung zur Verfügung, die allerdings granular Erkennungsradien für Anwesenheit einstellen lässt und daher für unser Szenario sehr gut funktioniert. Der Sensor stellt allerdings seine Daten über MQTT zur Verfügung: der Grund für den Einzug eines entsprechenden Brokers in meine Infrastruktur.

Ein dazu passendes Modul — MMM-MQTTScreenOnOff — ist vorhanden, schlank und funktional, aber ohne die Cron-Möglichkeiten und vor allem ohne den Progressbar und das Dimmen von MMM-Pir. Bedauerlicherweise eskalierte exakt in dieser Zeit ein Community-Streit, und der Entwickler von MMM-Pir verließ wutschnaubend das Forum und stellte die Entwicklung aller seiner Module ein.

Aus dieser Konstellation entstand ein eigenes Modul, das die Stärken beider Module vereint: MMM-PresenceScreenControl — eine Synthese aus MMM-Pir (bugsounet / Coernel82) und MMM-MQTTScreenOnOff (olexs).

Die Implementierung räumt eine Altlast weg: GPIO-Events liest das Modul nicht mehr über ein native-kompiliertes Node-Modul (was bei jedem Electron-Update einen electron-rebuild verlangte und auf Trixie regelmäßig brach), sondern über das CLI-Werkzeug gpiomon aus dem gpiod-Paket. Wo gpiomon fehlt, fällt das Modul automatisch auf einen Python-Fallback (gpiozero.MotionSensor) zurück.

Globus

Das Modul MMM-Globe von LukeSkywalker92 zeigt seit zehn Jahren das aktuelle Satellitenbild der Erde aus dem EUMETSAT/Meteosat-Strom. Es gab Ende 2025 und das ganze erste Halbjahr 2026 wieder und wieder lange Aussetzer des ursprünglichen Abfrage-URLs, der dazu führte, dass am Mirror immer dasselbe Bild zu sehen war.

Das stehengebliebene Bild stört tatsächlich, sodass ich recherchiert und herausgefunden habe, dass bei Meteosat offenbar einiges im Umbruch ist — es aber Alternativen gibt. Daher habe ich vom originalen MMM-Globe einen Fork erzeugt, den ich weiterentwickle: MMM-Globe.

Erste Iteration (v2.0.0) — es gibt zwei alternative Bezugswege der Meteosat-Bilder: die CIRA-SLIDER-API der Colorado State University, die als style: "meteosat" Vollscheiben-GeoColor mit Tag/Nacht-Übergang und Stadtlichtern liefert und alle 60 Sekunden schaut, ob ein neuer Zeitstempel verfügbar ist (und nur dann tatsächlich herunterlädt), sowie den neuen EUMETSAT-WMS-Endpunkt view.eumetsat.int als generische ownImagePath-Quelle in geostationärer Projektion.

Zweite Iteration (v3.0.0) — Architektur-Redesign entsprechend der Korell-Fleet-Hausregel: Frontend wird zur reinen Anzeige, die zwei Polling-Pfade pollSlider (für die SLIDER-Satelliten) und pollStatic (für alle anderen Styles und ownImagePath) münden beide in eine gemeinsame downloadAndServe-Pipeline und jede HTTP-Anfrage bekommt Timeouts (15 s für JSON, 30 s für Bilder), damit ein abgestürzter Socket nicht mehr die ganze Abfragekette einfriert.

Aufgrund einer Forumsdiskussion stellte auch ich fest, dass die Erde keine Scheibe ist und es außer der in meinem Mirror gezeigten Perspektive drei weitere Satelliten-Lokationen gibt (GOES-19, GOES-18 sowie Himawari), deren Abruf ebenfalls implementiert wurde — inklusive Self-Recovery, also sofortiges Laden von current.png beim Browser-Refresh, ohne auf den nächsten Poll warten zu müssen.

Dritte Iteration (v3.2.0) — nach einem über fünf Tage andauernden EUMETSAT-Ausfall habe ich einen Fallback-Mechanismus implementiert. Der Parameter switchToStaticIfStale regelt jetzt, ob ein Wechsel der Anzeige auf ein lokales Bildarchiv erfolgt. Erkennt das Backend anhand des Last-Modified-Headers, dass vom Server länger als 90 Minuten kein neues Bild mehr zur Verfügung gestellt wird, werden zeitlich passende Archivbilder eingeblendet. Die Auto-Recovery-Logik schwenkt zurück auf die Live-Quelle, sobald frische Daten kommen.

Die statischen Bilder können parametergesteuert eine Punktmarkierung (z. B. Standort) oder eine Textmarkierung (z. B. „Archivbild") erhalten, sodass mehr oder weniger auffällig erkennbar ist, ob man auf ein Live- oder ein Archivbild schaut.

In v3.2.1 kommt eine saisonale Korrektur archiveSunPhase hinzu, die per SunCalc die tagesaktuelle Sonnenauf- und -untergangszeit für die konfigurierbare lat/lon berechnet und die Archivbilder interpoliert, damit das Wandern der Tag/Nacht-Grenze auf dem Globus den jahreszeitlichen Bedingungen entspricht — der Tag und die Nacht also die korrekte Länge haben.

Wetter

Die Hauptarbeit der Wetter-Module läuft im Aggregator auf dem Zentralserver der Fleet. Da das Wetter-Thema sehr viele Komponenten und Schnittstellen enthält, ist diesem Thema ein eigener Artikel gewidmet — die Details dazu auf der Karte „Der Korell-Fleet-Wetterdienst".

Der Mirror zeigt zwei Wettermodule — beide Eigenentwicklungen auf der Grundlage des Standardmoduls für Wetter: MMM-My-Actual-Weather als Live-Anzeige meiner lokalen Wetterstation (mit vierstufigem Fallback) und MMM-Best-Weather als Anzeige der Stadt, in der im Moment das „angenehmste Wetter" herrscht. Verglichen werden Städte, die mit ihren Geo-Koordinaten in einer JSON konfiguriert und über die Open-Meteo-API abgefragt werden. Algorithmisch habe ich mich für eine angepasste Variante des HCI-Scorings (Human-Comfort-Index) entschieden; in meiner Konfiguration schaue ich auf 45 deutsche Städte aus allen Regionen.

Betrieb

Im laufenden Betrieb war das WLAN das zäheste Kapitel. Der Mirror hängt funkgebunden im Netz. Andere Pis laufen im selben WLAN ohne Auffälligkeiten, die Verbindung des Mirrors brach dagegen wiederholt zusammen.

Das Problem sitzt im WLAN-Stack des Pi 5. Das Haus-Netz unterstützt 802.11r („Fast Transition" = FT) für das schnelle Weiterreichen mobiler Clients zwischen seinen Funkknoten. Der im Pi 5 verbaute Broadcom-Chip beherrscht 802.11r nicht — der zuständige WPA-Daemon meldet diese Fähigkeit unter Trixie trotzdem als verfügbar, NetworkManager übernimmt die Capability ungeprüft und schreibt sie in jedes WLAN-Profil. Bietet ein AP dem Pi ein FT-Roaming an, kommt es zum Konflikt: die Aushandlung scheitert, der AP weist die Assoziation zurück, der Pi versucht erneut — mit demselben Ergebnis.

Die strukturelle Lösung war ein anderer WLAN-Stack: iwd, der iNet Wireless Daemon (Intel). iwd ermittelt die FT-Fähigkeit über die Treiber-API und meldet sie nur, wenn der Chip sie tatsächlich besitzt — die Falschmeldung im Profil entfällt.

Als Recovery-Instanz läuft seit Mai 2026 ein Watchdog mit drei Eskalationsstufen — sanfte Reassoziation, Interface-Neustart, Treiber-Reload — jeweils mit Cooldown gegen Aufschaukeln und mit Bypass bei aktiver SSH- oder VNC-Session.

Auch mit iwd und Watchdog blieb das Roaming-Verhalten am Haus-Mesh unbefriedigend. Die endgültige Lösung liegt in der Topologie: ein dedizierter Access Point ausschließlich für den Mirror, auf einer eigenen, dem Mesh fremden SSID. Der Mirror ist damit aus dem Mesh des Hauses herausgenommen, sieht nur noch diesen einen Knoten und damit auch keine Roaming-Angebote mehr. Die Anbindung läuft seitdem störungsfrei.

03 Sensorik · Hauswetter Der Korell-Fleet-Wetterdienst Wenn die Anzeige nicht stimmt. HardwareDNT-Wetterstation (Ecowitt-Klon) · Ecowitt-Gateway · AAG CloudWatcher · zwei ESP-Temperaturfühler (Schatten + Sonne) · Raspberry Pi als CloudWatcher-Host StackPHP · PostgreSQL · MQTT · Python/Flask · RS232

Man blickt auf seinen MagicMirror und das Standard-Wettermodul signalisiert Sonnenschein mit ein paar Wölkchen – und beim Blick aus dem Fenster sieht man Nieselregen.

Der Grund ist banal: Die üblichen, cloudbasierten Wetter-APIs nutzen grobmaschige Vorhersagemodelle und weit entfernte Messstationen. Für die Mikroklimata der Eifel ist das oft nicht mehr als ein gut gemeintes Schätzen - damit bieten die Standarddienste eigentlich nie eine Wetterinformation an, die mit dem Draußen etwas zu tun hat.

Die logische Konsequenz: Schluss mit Drittanbieter-Daten aus dem Netz.

Mein Ergebnis daraus ist eine vollständige, lokale Mess-Pipeline, die im Modul MMM-My-Actual-Weather und einem separaten Wetter-Dashboard visualisiert wird. Die zugehörige Backend-Architektur funktioniert inzwischen sehr solide und vor allem: realitätsnah.

Die Hardware: Von der Station zum CloudWatcher

Die Basis bildet eine DNT-Wetterstation (Ecowitt-Klon), die klassische Parameter wie Temperatur, Luftfeuchtigkeit, Windgeschwindigkeit, Niederschlagsrate, UV-Index und Solarstrahlung erfasst. Da die Station selbst die Daten leider nicht regelmäßig genug sendet, habe ich ein Ecowitt-Gateway hinter die Station gesetzt - dieses stabilisiert den Push-Takt der Messdaten. Ein zusätzlicher, ESP-basierter Microcontroller bringt die Daten zweier weiterer Temperaturfühler ein (jeweils für Messungen im direkten Sonnenlicht und im Schatten).

Die eigentliche Herausforderung beim lokalen Wetter ist der Himmel. Woher weiß das System, ob es klar, bewölkt oder bedeckt ist? Die typische Wetterstation für den Hausgebrauch sieht keine Wolken. Die Lösung ist der AAG-CloudWatcher. Dieser Himmelssensor misst mit einem Infrarot-Pyrometer die Strahlungstemperatur des Himmels. Über eine serielle Schnittstelle an einem Raspberry Pi gekoppelt, wird der CloudWatcher Bestandteil des Korell-Wetterdienstes, um den aktuellen Bewölkungsgrad exakt zu bestimmen.

Das Backend: Lokale WMO-Code-Berechnung ohne Cloud

Architekturskizze des Korell-Wetterdienstes: Wetterstation, Gateway, CloudWatcher, ESP-Fühler, PHP-Aggregator, PostgreSQL, MQTT-Broker, MagicMirror
Abb. 1 Der Korell-Wetterdienst im Überblick.

Den Kern der Software-Infrastruktur bildet ein lokaler PHP-Aggregator, der auf einem Apache-Server läuft. Hier laufen alle Datenströme zusammen:

  • (DNT)/Ecowitt-Gateway: Senden die Daten per HTTP-POST direkt an einen VHost des Aggregators.
  • CloudWatcher & ESP: Der Aggregator pollt die Flask-API des CloudWatcher-Pi, welcher gleichzeitig die Werte des ESP-Sensors erfasst und mitliefert.

Der PHP-Aggregator berechnet aus den angelieferten Daten den offiziellen WMO-Wettercode (World Meteorological Organization). Über eine mehrstufige Entscheidungslogik werden zuerst der Niederschlag, dann Nebel/Dunst und schließlich die Bewölkung analysiert – basierend auf dem berechneten Taupunkt und der Differenz zur Himmeltemperatur.

Nach der Klassifikation speichert der Aggregator den Datensatz in einer PostgreSQL-Datenbank ab, um eine lückenlose Zeitreihen-Historie zu ermöglichen.

Der Datenfluss: Push-Infrastruktur für den MagicMirror

Damit die aktuellen Werte ohne Verzögerung auf dem Mirror landen, setzt das System auf MQTT statt auf zyklisches Pollen. Sobald der PHP-Aggregator einen neuen Datensatz verarbeitet hat, publisht er diesen auf einem dedizierten Topic des Mosquitto-Brokers.

Auf dem Mirror abonniert MMM-My-Actual-Weather den Mosquitto-Broker. Die Daten werden aktuell alle 60 Sekunden publiziert.

Fazit: Es funktioniert!

Der Aufwand hat sich gelohnt. Die Kombination aus exakter lokaler Sensorik, dem CloudWatcher und der eigenständigen WMO-Logik im Backend liefert nun eine halbwegs solide Wetterdarstellung.

Das System zeigt, dass man mit Standard-Komponenten, etwas PHP/Python-Code und einer klaren Architektur eine autarke Infrastruktur aufbauen kann, die völlig unabhängig von externen Cloud-Diensten operiert.

04 Audio-Streamer KorellMusik Das Auge isst mit. HardwarePi 5 (8 GB · NVMe 500 GB) · HiFiBerry DAC+ Pro · BT-Fernbedienung StackVolumio · Playing-Now-Plugin · Spotify-Plugin · GPIO-Drehregler · Touch-Display

Man sagt, die besten Partys enden in der Küche. Bei mir beginnen sie dort — und zwar seit über vierzig Jahren. Denn so lange stehe ich bereits mit Leidenschaft am Herd, und mindestens ebenso lange gilt die Regel: Ohne Musik bleibt die Küche kalt. Doch während sich meine Kochkünste über die Jahrzehnte verfeinert haben, erlebte die akustische Untermalung im Laufe der Zeit einen spürbaren technologischen Rückschritt.

Es begann mit dem schleichenden Tod der Hausantenne, gefolgt von der Ernüchterung namens DAB+, das in vielen Regionen eher für digitales Schweigen als für rauschfreien Genuss sorgt. Der Markt bietet als Ausweg eine unüberschaubare Flut moderner „Internet-Radios". Wer sich diese Geräte jedoch genauer ansieht, staunt: Die verbauten Displays haben oft das Format einer Briefmarke. Für jemanden meines Alters keine Informationsquelle, sondern ein Sehtest.

Dazu kommt der inhaltliche Tiefpunkt des modernen Rundfunks: Radiosender, die mich ungefragt duzen, gefolgt von denselben zehn Werbeblöcken in Dauerschleife alle 30 Minuten. Wenn man gerade versucht, ein halbwegs genießbares Essen auf den Teller zu bekommen, ist das nervtötend. Es musste also eine Lösung her, die mir die volle Kontrolle erlaubt — optisch wie akustisch.

Die Entdeckung: Open Sauce statt Consumer-Frust

Vor gut zwei Jahren stolperte ich über Volumio. Ähnlich wie das bewährte MagicMirror-Projekt setzt dieses System auf den Community- und Maker-Gedanken. Genau meine Kragenweite. Anstatt sich mit Fertiggeräten abzufinden, baut man sich sein Audiosystem nach exakten Wunschvorstellungen einfach selbst.

Die Basis bildet ein Raspberry Pi 5. Wer die kleinen Einplatinenrechner kennt, weiß um ihre Achillesferse: die MicroSD-Karte. In einer Jukebox, die im Dauerbetrieb (24/7) eingeschaltet ist, damit bei Musikwunsch keine Boot-Zeit verloren geht, ist das Ausfallrisiko der billigen Speicherkarten hoch. Aus diesem Grund setzt mein Volumio auf eine solide SSD als Speichermedium.

Für den guten Ton sorgt ein HiFiBerry-DAC-HAT, der auf die GPIO-Leiste gesteckt wird und dem Pi audiophile Qualität verleiht. Weil der Pi unter Last zusammen mit der SSD ordentlich Eigenwärme produziert, muss gekühlt werden — ein kleiner 5V-Lüfter hält die Chiptemperaturen im vertretbaren Bereich. Zusammen ergibt das ein beachtlich „fettes" Hardware-Paket.

Die Tarnung: Einbauschrank wörtlich

Volumio als Küchenradio
Abb. 1 Volumio als Küchenradio

Ein solch massiver Technik-Block gewinnt im rohen Zustand verständlicherweise keinen Designpreis. Also hieß die Frage: Wie versteckt man eine solche Hardware-Etagere?

Ein 3D-gedrucktes ABS-Gehäuse im Küchenschrank war hier die Lösung — die verbauten GPIO-Drehregler (Rotary Encoder) schauen nach vorn zur Schranktür. Die erforderlichen Kabel werden innerhalb des Schrankes in Kabelkanälen sowie zum Lautsprecher an der Schrank-Rückseite geführt. Damit sind alle wesentlichen Teile „eingebaut". Das Raspi-Touch-Display habe ich flächenbündig in die Schrankseite eingepasst. Damit ist von der eigentlichen „Installation" von außen nichts sichtbar. Gesteuert wird das System vollkommen flexibel: über die bündige Touch-Oberfläche, per Drehregler oder als dritte Möglichkeit über eine Bluetooth-Fernbedienung.

Die visuelle Belohnung

Innenansicht des Küchenschranks mit Raspberry Pi, HiFiBerry-DAC und Verkabelung
Abb. 2 Innenansicht

Dank des „Now Playing"-Plugins wird das 7-Zoll-Display zum echten Blickfang beim Schnippeln: Die linke Hälfte des Bildschirms zeigt die großflächige Darstellung des Album-Covers. Rechts daneben dient ein vergrößertes, unscharfes Detail desselben Artworks als Hintergrund, auf dem die minimalistischen Steuerelemente und Titelinformationen liegen.

Über dieses Interface spiele ich nun meine Spotify-Playlists. Keine nervige Werbung, keine künstlich gut gelaunte Moderation, sondern einfach nur Wunschmusik und purer Koch-Fokus.

Fazit: Das „Maker-Ding" gewinnt

Das Projekt zeigt wieder einmal, warum sich der Griff zu Lötkolben, 3D-Drucker und Säge lohnt. Statt sich mit den Kompromissen der Unterhaltungselektronik abzufinden, lässt sich mit einer klaren Vorstellung und etwas Open-Source-Software eine maßgeschneiderte Lösung bauen, die Funktion und Design zusammenführt. Die Küche bleibt frei von Kabelsalat, der Sound ist dank DAC-Aufsatz hervorragend, die Steuerung über Touch intuitiv, und das Auge isst endlich auf einem standesgemäßen Display mit.

05 Bilderrahmen · Kunst Galerist Ein Rahmen muss auch mal gesprengt werden. HardwarePi 3B+ Rev 1.3 · 1 GB RAM · Display · BT-Fernbedienung StackFlask · flask-sock · libevdev · Chromium-Kiosk · IPTC/XMP · Wikidata SPARQL · Wikimedia Commons

Es war mein Wunsch und ein großzügiges Geschenk meiner Familie zum Geburtstag: der Einzug eines Meural Canvas. Ein digitaler Bilderrahmen im Premium-Segment, der eigentlich klassische Kunst auf ein modernes Display bringen sollte. Die Ernüchterung kam bedauerlicherweise schnell. Für den großzügigen Anschaffungspreis fiel das Display überraschend kompakt aus, und das Werbeversprechen von „Millionen von Kunstwerken" entpuppte sich in der Praxis als herbe Enttäuschung. Trotz eines nicht günstigen Jahresabonnements findet sich der Großteil der kuratierten Meisterwerke weiterhin hinter einer zusätzlichen Bezahlschranke.

Wagt man alternativ den Versuch, eigene Bildbestände auf „seinen" Canvas hochzuladen, landet man in einer Web-Oberfläche, die man getrost als funktionale Katastrophe bezeichnen darf. Warum ich Bilder in die Cloud HOCHladen muss, um sie dann in einem (extrem fragilen) Download lokal zurückzuholen, konnte mir bei Netgear niemand erklären.

Der Impuls, über eine Alternative zumindest mal nachzudenken, kam schließlich aus der Open-Source-Welt: Ein User im MagicMirror-Forum stellte ein Modul vor, das Kunstwerke direkt aus Wikimedia darstellen kann.

Wikimedia war mir neu und die Idee gefiel mir, sodass ich eine Machbarkeitsstudie durchführte mit dem Ziel, einen autarken, digitalen Bilderrahmen zu bauen, der den kommerziellen Canvas nachbildet. So entstand das Projekt „Galerist".

Die Herausforderung: Nicht nur Suchen

Wer schon einmal versucht hat, die Wikimedia-Strukturen programmatisch zu durchsuchen, weiß, dass das Projekt zwar fast jedes bedeutende Kunstwerk der Menschheit „hat" — man muss es aber erst einmal finden. Die Recherche nach Werken in passendem Querformat (1920×1080) glich der sprichwörtlichen Suche nach der Nadel im Heuhaufen.

Es gab etliche Iterationen, Skript-Anpassungen und Filter-Kriterien, bis eine halbwegs vernünftig große Ergebnismenge entstand. Aktuell habe ich einen Kernbestand von rund 1.300 Bildern („Impressionisten" war ein sehr starkes und ergebnisreiches Suchwort), die datenbankgestützt verwaltet und gepflegt werden.

Die Architektur: Maximale Autarkie auf schmaler Hardware

Galerist: Machbarkeitsstudie
Abb. 1 Galerist: Machbarkeitsstudie

Ein wesentliches Kriterium bei der Entwicklung war die Performance. Der eingesetzte Raspberry Pi 3B+ verfügt lediglich über 1 GB RAM. Moderne Frameworks wie Electron fielen damit von vornherein aus — sie würden den Speicher im Kiosk-Betrieb schlicht sprengen. Die Wahl fiel daher auf eine schlanke Python-Hülle kombiniert mit einem optimierten Browser-Kiosk. Das System gliedert sich in zwei wesentliche Blöcke.

Der Metadaten-Cache (XMP statt Live-Datenbank)

Um den Pi autark zu betreiben, nutzt der Galerist keinerlei Fernabfragen.

Alle Bilder liegen lokal auf der SD-Karte des Rechners. Alle Informationen zum Kunstwerk — Künstler, Titel, Entstehungsjahr, Materialien und der Museumsstandort — stehen als standardisierte XMP-Metadaten direkt in den JPEG-Dateien.

Beim Systemstart wird die Kunstwerk-Bibliothek über die Python Imaging Library (PIL) inkl. dieser XMP-Strukturen einmalig aus allen 1.300 Dateien eingelesen, die Bilderliste bezüglich Darstellungsreihenfolge randomisiert und dann — entsprechend der Konfigurationseinstellungen (Anzeigedauer, Aktivitätsfenster) — dargestellt.

Der Single-Process-Kiosk

Als Anzeige-Engine dient ein Chromium-Browser im Kiosk-Modus, der über ein leichtgewichtiges WebSocket-Plugin (flask-sock) an die Flask-Anwendung gekoppelt ist.

Um den 1 GB Arbeitsspeicher nicht zu überlasten, erzwingt die Konfiguration eine Single-Process-Architektur des Browsers samt In-Process-GPU. Dadurch passt der Browser in den knappen RAM, und die GPU-im-Prozess-Konfiguration hält die Übergänge flüssig. Das Frontend rendert das Kunstwerk im Vollbild und blendet auf Wunsch — analog zum Meural-Vorbild — links unten ein Overlay mit den Kunstwerkinformationen ein.

Steuerung: Zwei Wege ohne Touch-Frust

App-Steuerung
Abb. 2 App-Steuerung

Wer die träge Gesten- und Touch-Steuerung des Meural Canvas kennt, weiß, dass man sie nach drei Versuchen nie wieder freiwillig benutzt. Beim Galerist wurde auf eine lokale Touch-Implementierung bewusst verzichtet. Stattdessen kommuniziert die Flask-App über zwei parallele Wege.

Bluetooth-Remote (primär): Eine kompakte Bluetooth-Fernbedienung sendet standardisierte HID-Multimedia-Keycodes über das Bluetooth-HID-Profil an den Pi. Ein event-getriebener Eingabe-Handler fängt die Tastendrücke ab (libevdev + pyudev), sodass ein Druck auf Next oder Pause den Bildwechsel auslöst. Um den im System mehrfach erlebten BlueZ-Multi-Profile-Konflikt zu umgehen (der nach einem Reconnect oft das HID-Profil blockiert), läuft auf dem Pi ein dedizierter Bluetooth-Watcher via D-Bus, der die HID-Verbindung bei jedem Wake-up der Fernbedienung sicherstellt.

Die PWA-Web-App: Über einen integrierten Mini-Webserver stellt der Pi eine Steuerungs-Oberfläche zur Verfügung. Diese ist als Progressive Web App (PWA) direkt z. B. auf dem Smartphone „installierbar". Sie zeigt die Thumbnail-Darstellung des aktuell dargestellten Kunstwerkes, bietet das Vor- und Zurück-Blättern durch den Katalog, und die Auf- bzw. Ab-Taste blenden das Informations-Overlay ein und aus. Die Oberfläche ermöglicht — auch hier Meural-analog — Einstellungsmöglichkeiten für den Galerist (z. B. die Anzeigezeit pro Bild und die Aktivitätsfenster des Bildschirms).

Fazit: Open Source schlägt Closed Shop

Die Machbarkeitsstudie zeigt deutlich: Wer die Kontrolle über seine Hardware und seine Daten behalten möchte, fährt mit dem Maker-Ansatz offenbar um Längen besser. Der Raspberry Pi 3B+ beweist, dass man selbst mit begrenzten Hardware-Ressourcen durch Verzicht auf große Laufzeitumgebungen ein System bauen kann, das kommerziellen Produkten in Sachen Funktionalität und Bedienkomfort vollständig gleichwertig ist.

In Bezug auf Zuverlässigkeit — insbesondere Verfügbarkeit — habe ich hier vollständige Kontrolle.

In Bezug auf Offenheit sprengt der Galerist den Cloud-Rahmen.

06 Pyrotechnik · Funkzündung PyroMan Beim Umgang mit Schwarzpulver dürfen keine Bits umkippen. HardwarePi 5 · Touchdisplay · 433 MHz TX/RX an GPIO 21/27 · 3-D-Druck-Case · Dual-WLAN (Onboard-AP + USB-Client) StackPython 3.13 · Flask · flask-sock · libgpiod v2 · codesend · 5 Arduino-Koffer

In der DIY- und Maker-Szene gilt der Raspberry Pi seit jeher als Allzweckwerkzeug. Dabei gibt es auch Einsatzbereiche, die weit über spielerische Anwendungen hinausgehen und bei denen Fehlfunktionen fatale Folgen haben können. Die Zündung von Schwarzpulver im Rahmen des § 27 Sprengstoffgesetz (SprengG) ist ein solches Szenario. Wer hier leichtsinnig agiert oder bei einer Nichtzündung ungesichert an die Kanone herantritt, begibt sich in Lebensgefahr — tragische Unfälle in der Szene zeigen immer wieder, wie riskant dieses schöne Hobby ist.

Wir haben als Schwarzpulverschützengruppe von Anfang an beschlossen, unsere Begeisterung und Detailverliebtheit für das Hobby auch in die erforderliche Sicherheit zu investieren und ein zuverlässiges, sicheres, funkbasiertes Digitalsystem zu entwickeln, das den Anforderungen entspricht.

Die technische Evolution dieses Funkzündsystems PyroMan über mehr als ein Jahrzehnt hinweg dokumentiert ein spannendes Stück IT-Historie: den Wandel des Raspberry-Pi-Ökosystems von den softwareseitigen Pionierzeiten des Pi 2B+ bis zum jüngsten — recht harten — API-Wechsel im GPIO-User-Space unter Debian Trixie.

Die Fundamente: Physische Absicherung und Dual-WLAN

Da das System — wie oben beschrieben — wirklich 100 % betriebssicher sein musste, kam von der allerersten Überlegung an nur ein mehrstufiges Konzept in Frage, das verschiedene Sicherheitsmerkmale parallel nutzt und mindestens einen physischen und einen logischen Kanal nutzt.

Für die Netzwerk-Kommunikation ist der PyroMan mit zwei getrennten WLAN-Schnittstellen ausgestattet. Der USB-WLAN-Client dient ausschließlich der Wartung, Konfiguration und Code-Pflege in der sicheren Umgebung — dem Heimnetz. Der Onboard-Access-Point (AP) hingegen spannt im Feld ein eigenes, per WPA-PSK (16-stellig) verschlüsseltes Funknetz mit separatem IP-Bereich auf. Nur über dieses isolierte Subnetz sind Zündbefehle überhaupt möglich.

Darüber hinaus riegelt eine dreistufige Freigabelogik das System gegen menschliches Versagen oder Missbrauch ab. Als erste Sicherheitsstufe an der Hardware-Zentrale dient ein physischer Schlüsselschalter am Gehäuse des PyroMan, ohne den das System mangels Stromversorgung gar nicht erst hochfährt.

Die zweite Stufe bildet die netzwerkseitige Authentifizierung, da die Steuerungsoberfläche exklusiv im isolierten Feld-AP erreichbar ist.

Die dritte Stufe liegt direkt an der Peripherie: Jeder der bis zu fünf funkgesteuerten Zündkoffer verfügt über einen eigenen Schlüsselschalter mit den drei Positionen Off, Test und Zünden. In der Stellung Test wird ein Prüfstrom durch die Zündpillen-Kabel geschickt, um den Durchgang zu messen. Ausschließlich das manuelle Umlegen des Schlüsselschalters auf Zünden schaltet die Relais-Bänke frei.

Erste Generation: Minimale Web-UI und die WLAN-Hürden des Raspberry Pi 2B+

In der ersten Version des PyroMan stellte die Konfiguration des Raspberry Pi 2B+ als simultaner WLAN-Client und Access Point eine echte Herausforderung dar. Die damaligen Linux-Kernel und die Verfügbarkeit stabiler Treiber für USB-WLAN-Sticks erforderten diffizile Eingriffe in Konfigurationsdateien wie hostapd und dnsmasq.

Die Software-Architektur war bewusst minimalistisch gehalten: Eine schlanke HTML-Oberfläche, die auf einem lokalen Webserver lief, triggerte bei Touch-Click auf dem Mobile oder dem Pad über das Backend den codesend-Daemon. Dieses Tool modulierte die Befehle über das 433-MHz-Funkmodul, welches die Daten an die Empfangskoffer übermittelte. Der Daemon persistierte aber zusätzlich die Kanalinformation — wenn mehrere Mobilgeräte am PyroMan angemeldet waren, wurde ihr Stand zwischen den Geräten in Echtzeit synchronisiert. In den Koffern arbeitet ein Arduino-Mikrocontroller, der die Signale dekodiert, ein Zeilendisplay zur Statusanzeige bedient und die acht logischen Zündkanäle schaltet. Das System lief über Jahre hinweg tadellos, stieß jedoch optisch (GUI) irgendwann an seine Akzeptanzgrenzen.

Die FHEM-Ära und das Umbruchjahr 2025

Mit dem Wunsch nach einer moderneren Oberfläche folgte eine Portierung auf das Smart-Home-Framework FHEM. Die 433-MHz-Sendelogik blieb bei codesend, event-getriggert. Das FHEM-Web-UI diente als Schaltzentrale — auch hier funktionierte die Synchronisierung mehrerer angeschlossener Endgeräte. Die mit der Migration verbundene Hardwareänderung machte ein Redesign des Gehäuses erforderlich. Der mechanische Schlüsselschalter konnte nicht mehr realisiert werden und wurde durch eine Funk-Autorisierung mit einem 433-MHz-Handsender ersetzt.

Diese Lösung lief ebenfalls störungsfrei bis zu einer — leider nicht angekündigten — Änderung in der Debian-Version Bookworm, die mit der Einstellung der bewährten C-Bibliothek wiringPi vom damaligen Maintainer (Gordon Henderson — drogon.net) zusammenhing.

Diese C-Bibliothek war über fast ein Jahrzehnt der De-facto-Standard, um GPIOs zügig aus dem User-Space anzusprechen. Das Fehlen von wiringPi führte zu einer „stillen" OS-Änderung für GPIO, mit der codesend weiterhin funktionierte, der 433-MHz-Empfang aber nicht.

Der Python-Wrapper rpi-rf-gpiod erwies sich als inkompatibel mit den neuen GPIO-Bibliotheken der Distribution, und die Alternative pigpio wurde komplett aus den offiziellen Paketquellen entfernt. Der PyroMan war auf dem 433-MHz-Kanal plötzlich taub, womit die erste Freigabestufe entfiel.

Um den 433-MHz-Empfang unter Bookworm überhaupt zu retten, musste eine kreative Hilfskonstruktion her: Ein vorgeschalteter Arduino fing die Signale des Handsenders auf, dekodierte sie und leitete sie über die serielle Schnittstelle an den Pi weiter.

Das wiederum sorgte im sowieso stromhungrigen und chronisch unterversorgten Pi 5 für Undervoltages, die ihrerseits zu WLAN-Abbrüchen führten — was das Gesamtsystem vollständig kompromittierte und letztendlich unbenutzbar machte.

Der aktuelle Stack: Native Abstraktion unter Debian Trixie

Das mit zusätzlichem Arduino an der mobilen Stromversorgung nicht mehr funktionierende System wurde bei Erscheinen der neuen Distribution sofort auf Trixie migriert. Zeitgleich wurde auch der doch erhebliche Overhead durch das Framework FHEM wieder aus der Softwareschicht entfernt. Die optisch schöne Floorplan-Funktion von FHEM (die ich mit Böllerfotos hinterlegt hatte) wurde aber mitmigriert.

Das heutige System läuft auf einem Raspberry Pi 5 unter Debian Trixie. Das Besondere an dieser Generation ist die strikte, modulare Trennung. Die Präsentationsschicht basiert auf Flask und flask-sock unter Python 3.13, was ein leichtgewichtiges Web-UI mit bidirektionaler WebSocket-Synchronisation ermöglicht. Direkt darunter agiert die Logikschicht mit einem zentralen RAM-State-Modul als Single Source of Truth. Es verwaltet das Autorisierungszeitfenster des Handsenders und berechnet den Zündstatus live, was eine erneute Auslösung desselben Zündkanals blockiert.

Während der Kernel-Unterbau (das Character Device Subsystem gpiochip) seit Jahren identisch ist, nimmt Debian in Trixie eine Anpassung vor und unterstützt die neue libgpiod-v2-API nativ. Damit entfallen alle unter Bookworm erforderlichen Kunstgriffe zur Ansteuerung der GPIOs für 433 MHz, denn Sende- und Empfangspfad greifen hier nun auf die neue Schnittstelle zu, sodass die Arduino-Hilfsbrücke nicht mehr benötigt wird und die Signalübertragung jetzt wieder direkt an die fünf Koffer-Empfänger erfolgt.

Dieser modulare Aufbau ist auf künftige API-Umbrüche ausgelegt. Die alte Bookworm-Konfiguration ist in der Dokumentation als Fallback-Pfad hinterlegt. Sollte eine zukünftige Debian-Version die GPIO-API erneut verändern, muss lediglich das isolierte Sende- oder Empfangstool angepasst werden. Die gesamte Core-Logik, das State-Modul und die Web-Anwendung bleiben unangetastet — ein Aufbau, in dem kompromisslose Sicherheit und Bastelspaß nebeneinander Platz haben.

07 Backup · Admin-Flotte RaspiBackup Mit (Sicherheits)Netz — aber ohne doppelten Boden. HardwareWebServer (Pi 5) · 1 TB externe SSD (Crucial BX500) StackraspiBackup · rsync · Hardlinks · NFS · PHP-Dashboard · PostgreSQL · SSH-Wrapper · Cron · Callback

Es gibt zwei Arten von IT-Anwendern: diejenigen, die noch keine wirklich wichtige Systeminformation durch plötzliches Hardwareversagen verloren haben, und die Langweiler, die sich um so dröge Themen wie Backup (und Restore-Fähigkeit) kümmern.

Wenn die heimische Flotte aus Raspberry Pis wächst und wichtige Aufgaben übernimmt — von der Wetterberechnung über musikalische Untermalung beim Kochen bis hin zur Steuerung von Zündkreisen — wird das Thema Datensicherung von der lästigen Pflicht zur wichtigen Disziplin.

Für meine gesamte Infrastruktur existiert daher ein geregeltes, zentralisiertes Sicherungskonzept, das auf raspiBackup setzt und dafür sorgt, dass im Ernstfall keine Panik entsteht.

Das Problem mit dem Gedächtnis

Status- und Inventar-Tab des Backup-Dashboards
Abb. 1 Status & Inventar

Wer komplexe Systeme aus möglicherweise sogar mehreren Server-Knoten betreibt, steht bei einem Ausfall vor einem potenziell großen Berg an Fragen. Ich weiß sicher, dass ich in zwei Jahren nicht mehr die leiseste Ahnung habe, welche spezifische Tabelle in welcher PostgreSQL-Instanz mit welchen Rechten angelegt werden muss, damit die Webapplikation des lokalen Wetterdienstes fehlerfrei läuft. Aus diesem Grund habe ich mir eine administrative Schaltzentrale für meine Fleet erstellt, die das gesamte Flotten-Management in vier Tabs einer Web-App bündelt: Status, Backup, DB-Export und Restore.

Die Statusseite fungiert als vollständiges Inventar-Verzeichnis der Flotte. Jedes System besitzt eine eigene Karte, die zweigeteilt ist. Rechts der Hardware-Block mit Betriebssystem-Version, Kernel-Stand, RAM-Bestand und Belegungsbalken für vorhandene Speichermedien. Links wacht eine Alters-Ampel über den Zustand der letzten Sicherung: Leuchtet sie grün, ist alles frisch (1 bis 7 Tage); schlägt sie auf Gelb oder Rot um, wird es Zeit zu handeln. Fehlgeschlagene Läufe melden sich sofort mit einem unübersehbaren roten Fehler-Badge samt Exit-Code.

Die Technik: Inkrementelle Hardlinks

Backup-Verwaltung mit manuellen Auslösern und Logs
Abb. 2 Backup-Verwaltung

Der zentrale Koordinator sitzt auf dem Haupt-Server im Haus. An ihm hängt lokal eine dedizierte, 1 TB große externe SSD, die als globales Speicherziel dient. Der Effizienz-Trick der täglichen und wöchentlichen Sicherungen liegt in der Kombination aus rsync und Linux-Hardlinks.

Wenn ein Pi (sei es der täglich gesicherte Web- und DB-Server oder der wöchentlich gesicherte MagicMirror) seine Sicherung startet, prüft ein umschließendes Wrapper-Skript zunächst den Netzpfad. Ist das Ziel erreichbar, schiebt raspiBackup die Daten über einen NFS-Mount auf die SSD.

Das inkrementelle Backup sorgt für Zeit- und Speicherplatzvorteile: Unveränderte Dateien werden nicht kopiert, sondern im Zielverzeichnis als Hardlink auf die unverändert gültige Version erzeugt.

Ein zentraler Callback-Mechanismus sorgt dafür, dass nach jedem vollbrachten oder fehlgeschlagenen Lauf ein kurzes HTTP-POST-Signal an die Web-UI geht, welches den Backupstatus in einer Datenbank speichert.

Das Wiki: Der Zwei-Wege-Rettungsanker

Der eigentliche Kern des Konzepts ist jedoch nicht so sehr die Backup-Methodik, sondern eher inhaltlich ein ausführliches Wiki. Es liegt als strukturierter /docs/-Ordner direkt im Git-Repository des Backup-Projekts und beschreibt für jeden wichtigen Rechner detailliert zwei völlig unterschiedliche Recovery-Wege.

Weg A: Der einfache Restore

Das klassische Zurückspielen des Speicher-Abbilds aus dem Backup-Verzeichnis, wenn lediglich die Hardware getauscht werden muss, das System aber im Kern identisch bleiben soll.

Weg B: Das komplexe Rebuild-Rezept

Hier wird es für mein „zukünftiges Ich" essenziell. Dieser Pfad dokumentiert in exakter Reihenfolge jede einzelne Systemkomponente, jeden einzugebenden Befehl, jede Paket-Installation und jede Datenbank-Struktur.

Dieser detaillierte Leitfaden dient nicht nur dem Katastrophen-Recovery, sondern auch als nützliches Werkzeug für System-Migrationen. Erst kürzlich habe ich genau diese Einzelanweisungen genutzt, um meinen MagicMirror von Bookworm auf Trixie zu heben — mit doch einigem Aufwand, da sich GPIO-Handling (PIR) und vor allem die Monitor-Ansteuerung verändert haben (in dieser Migration habe ich auch erstmals auf den Wayland-Compositor umgestellt).

Fazit: Beruhigt schlafen

Wer seine Infrastruktur derart absichert, verliert den Schrecken vor dem nächsten Systemupdate oder gar einem Systemausfall.

Das Zusammenspiel aus automatisiertem raspiBackup, dem zentralen PHP-Dashboard samt Hardware-Inventar und den Rebuild-Rezepten im Wiki gibt die Gewissheit: Egal welche Systemkomponenten morgen den Dienst quittieren — der Weg zurück zum funktionierenden System ist gut dokumentiert und begehbar.