Zum Inhalt springen

Fallstudie

BooxPlanner

Eine bidirektionale Handschrift-Schleife zwischen einem E-Ink-Tablet und Notion.

Jahr
2025—
Status
in Arbeit
Rolle
Architekt & Umsetzer
Stack
Python, WeasyPrint, Jinja2, n8n, Gemini Vision, Notion API, Google Fit

Eine bidirektionale Schleife zwischen einem papierhaften E-Ink-Tablet und einem Notion-Aufgabengraphen — die Morgen-Generierung läuft, die Abend-Rücklesung ist in Arbeit. Stift als Eingabe, strukturierte Daten als Quelle der Wahrheit, ein LLM, das Ziele in den Tagesdetail herunterbricht.

Auf einen Blick: Notion-Ziele werden zu einem täglichen PDF, auf einem E-Ink-Tablet beschrieben und dann zurück in Notion gelesen.
Auf einen Blick

2026-05-12

erster Produktivlauf

Die technische AufschlüsselungAufklappen · ~3 Min.

Das geschäftliche Problem

Ich habe immer von Hand geschrieben — Todos, Pläne, Notizen —, aber ab einer gewissen Last skalierte das nicht mehr. Notion hielt die Struktur; eine Handy-App hielt die Bequemlichkeit; das Papierheft hielt das Eine, worauf es wirklich ankam, den physischen Akt des Schreibens. Jedes löste einen Teil des Problems und brach einen anderen.

Stift auf dem Bildschirm als Eingabe, eine strukturierte Datenbank als Quelle der Wahrheit und etwas dazwischen, das übersetzt. Im KI-Zeitalter muss man sich nicht entscheiden — man baut beides.

Die harte Randbedingung ist die Hierarchie: ein Quartalsziel, das identisch auf der Monats-, Wochen- und Tagesseite erscheint, untergräbt den Grund, überhaupt einen Planer zu drucken. Ein LLM, das Ziele in eine ebenen-gerechte Detailtiefe herunterbricht, ist also keine Deko — es ist der Teil, der die gedruckte Seite druckenswert macht.

Die Architektur

Eine Morgen-Pipeline hinter einem FastAPI-Dienst in einem Docker-Container auf einem Home-Server. Ein Cron schickt ein POST an /generate; der Dienst liest die Notion-Datenbanken, bittet ein LLM, Quartalsziele in einen Monatsfokus, Wochenziele und einen Tagesfokus herunterzubrechen (wöchentlich gecacht, sodass der tägliche Lauf größtenteils kostenlos ist), rendert ein Jinja2-Template, übergibt das HTML an WeasyPrint und lädt ein Wochen-PDF in einen Cloud-Drive-Ordner hoch, den das Tablet abholt.

Der Morgen-Generierungspfad (deployed) liest Notion, bricht Ziele mit einem LLM herunter, rendert ein PDF und schiebt es über einen Cloud-Ordner auf das E-Ink-Tablet. Der Abend-Rücklesepfad (gestrichelt — geplant/Stub) gibt Annotationen über einen separaten Ordner zurück, pixel-difft die geänderten Seiten und OCRt sie zurück nach Notion.
Der Morgen-Generierungspfad (deployed) liest Notion, bricht Ziele mit einem LLM herunter, rendert ein PDF und schiebt es über einen Cloud-Ordner auf das E-Ink-Tablet. Der Abend-Rücklesepfad (gestrichelt — geplant/Stub) gibt Annotationen über einen separaten Ordner zurück, pixel-difft die geänderten Seiten und OCRt sie zurück nach Notion.

Die Abend-Hälfte — geplant, noch nicht live — liest die Annotationen zurück: ein Drive-Änderungs-Trigger, ein Pixel-Diff, um nur die Seiten zu finden, die ich tatsächlich beschrieben habe, dann Vision-OCR nach Notion. Darunter sitzt ein reverse-engineerter .note-Punkt-Binär-Parser: 16-Byte-Strich-Datensätze hinter einem 80-Byte-Header, mit einem Inter-Strich-Trenner, der die Ausrichtung verschiebt, und einer Resynchronisierung bei unmöglichen Koordinaten.

Entscheidungen & Abwägungen

Zwei Ordner, nicht einer. Generierte Seiten gehen über einen Cloud-Ordner hinunter; annotierte Seiten kommen über einen anderen hinauf. Sie können sich physisch nicht gegenseitig speisen, sodass der Morgen-Generator seine eigene Ausgabe nie wieder einlesen kann — die einfachstmögliche Absicherung gegen eine Sync-Schleife.

Diff, bevor du zahlst. Bevor irgendetwas an ein Vision-Modell geht, pixel-difft das System die saubere und die annotierte PDF und schickt nur die geänderten Seiten — typischerweise eine bis drei von zwölf. Die Kosten folgen den Änderungen, nicht der Dokumentgröße.

Der größte Teil von „KI-Engineering" mit Budget ist zu wissen, wo man das Modell nicht aufruft.

Der Abend wird zurückgestellt, bis der Morgen steht. Der /process-annotations-Endpunkt ist bewusst ein 501-Stub. Beide Hälften gleichzeitig online zu bringen, verdoppelt die Angriffsfläche für halb-funktionierende Abhängigkeiten — ein wackeliger OCR-Schritt würde einen wackeligen Generierungsschritt verdecken. Eine Richtung muss im Produktivbetrieb solide sein, bevor die andere von ihr abhängt.

Was gebrochen ist

Der Gesundheitsdaten-Pfad brauchte zwei Anläufe: ein direkter Geräte-Login fragte nach einem MFA-Code, was an einem Terminal funktioniert, aber nicht unter Cron, sodass der Abruf hinter eine REST-API wanderte. Der Annotations-Speicher des Tablets erwies sich als feindlich gegenüber Überschreibungen — die App schreibt ihre Caches aus dem Speicher neu, sofern sie nicht geschlossen ist —, sodass eine wöchentliche Dateinamen-Rotation der sauberste Ausweg wurde. Und der .note-Parser läuft um vier Byte daneben, sobald sein Inter-Strich-Trenner zufällig wie der Anfang eines Datensatzes aussieht — deshalb resynchronisiert er bei Koordinaten, die nicht auf dem Bildschirm sein können.

Das Ergebnis

Die Morgen-Generierungs-Hälfte ist deployed und läuft (erster Produktivlauf 2026-05-12). Die Abend-Rücklesung ist in Teilen gebaut, aber nicht live verdrahtet/process-annotations ist noch ein Stub —, und es gibt noch keine Messung der OCR-Genauigkeit.

Das ehrliche offene Problem ist nicht der Code — es ist die Gewohnheit. Tägliche Akzeptanz ist ebenso sehr verhaltensbezogen wie technisch, und das ist der Teil, den ich nicht gelöst habe.