6 Min. Lesezeit

Wie ich einmal mit Claude Code ein altes iPad zum Strompreis-Dashboard gemacht habe

Nach dem alten iPhone als Server-Monitor kam das alte iPad mini dran. Es zeigt jetzt Strompreis und Verbrauch aus der Tibber-API, inklusive Lastspitzen und Preisprognose für morgen. Gebaut habe ich es wieder im Gespräch mit Claude Code.
Vor kurzem habe ich ein altes iPhone zum Server-Monitor gemacht. Ein kleiner Rust-Server auf meinem Büroserver liefert dort eine schlichte Seite aus, die auch ein Safari von 2015 noch versteht. Das hat so gut funktioniert, dass ich gleich das nächste Gerät aus der Schublade geholt habe: ein iPad mini 2. Es läuft mit iOS 12, Updates gibt es keine mehr.
Diesmal ging es um Strom. Mein Anbieter ist Tibber. Dort zahle ich keinen festen Preis, sondern den Börsenpreis, der sich jede Viertelstunde ändert. Ein Tibber Pulse am Zähler meldet den Verbrauch live. Die Tibber-App zeigt das alles schön an, aber eben auf dem Handy. Ich wollte es dauerhaft auf dem Schreibtisch sehen. Und ich wollte etwas, das die App so nicht kann: Preis und Verbrauch in einem Diagramm. So sehe ich direkt, zu welchem Preis meine Lastspitzen angefallen sind.
Der Auftrag
Meine erste Nachricht an Claude Code war wieder ein ungeordneter, gesprochener Absatz. Dazu drei Screenshots aus der Tibber-App: die Startseite, die Pulse-Ansicht mit dem Verbrauch über den Tag und die Strompreis-Ansicht mit heute und morgen. Sinngemäß:
Wir haben neulich schon so eine kleine Webseite für ein altes iPhone gebaut. Jetzt habe ich ein altes iPad mini, gleiche Situation. Auf meinem Büroserver soll wieder eine Rust-App auf einem kuriosen Port eine HTTP-Seite ausliefern, ohne Verschlüsselung, mit einfachem JavaScript. Thema ist Tibber. Ich möchte den aktuellen Verbrauch sehen, den Tagesverlauf, die Preisprognose für die nächsten 24 Stunden und die Preise der letzten Stunden. Und im selben Diagramm meinen tatsächlichen Verbrauch. Kombiniere die Diagramme aus zwei der Screenshots. Was hältst du davon?
Claude hat sich zuerst das alte Projekt angesehen. Es hat die Bauweise übernommen: ein Rust-Programm ohne großes Framework, ein Hintergrund-Thread für die Daten, ein systemd-Dienst auf dem Büroserver. Dann kamen vier Rückfragen. Ich habe nur eine davon beantwortet, nämlich das Modell des iPads. Bei den anderen hat Claude seine Empfehlung genommen und das im Plan offen dazugeschrieben.
Die Frage nach dem Modell war wieder die wichtigste. Ein iPad mini 2 kommt maximal auf iOS 12. Dessen Safari kann JavaScript, aber kein modernes. Also kein fetch, keine Pfeilfunktionen, keine Template-Strings. Stattdessen XMLHttpRequest und var, wie vor zehn Jahren. Damit konnte die Seite, anders als beim iPhone, ohne ständiges Neuladen auskommen. Die Live-Leistung aktualisiert sich alle paar Sekunden, ohne dass die Seite flackert.
Eine Entscheidung, die ich nicht getroffen hätte
Bei der Planung fiel Claude ein Problem auf, an das ich nicht gedacht hatte. Tibber liefert den Verbrauch über die API nur stündlich. Eine kurze Spitze, etwa wenn morgens der Durchlauferhitzer anspringt, verschwindet im Stundenmittel. In der App sieht man solche Spitzen nur, weil sie die Live-Daten des Pulse nutzt.
Die Lösung: Der Server hört den Livestream des Pulse selbst mit. Jeder Messwert landet in einer Minuten-Tabelle mit Durchschnitt, Minimum und Maximum. Die Tabelle reicht zwei Tage zurück und wird regelmäßig auf die Festplatte geschrieben. So entsteht nach und nach ein Verlauf, der die echten Spitzen zeigt.
Die zweite Entscheidung betraf mein Wunschdiagramm. Ich wollte Preis und Verbrauch übereinander in einem Diagramm. Preis in Cent und Leistung in Watt brauchen aber zwei verschiedene Skalen. Ein Diagramm mit zwei Y-Achsen liest sich schlecht. Claude hat das gesagt und stattdessen zwei Felder übereinander gebaut, auf genau derselben Zeitachse. Oben der Preis als Stufenkurve, orange über dem Durchschnitt, türkis darunter. Unten die Leistung. Eine Spitze steht immer direkt unter ihrem Preis. Tippt man ins Diagramm, zeigt ein Fadenkreuz Preis, Spitze und Stundenverbrauch zu genau dieser Uhrzeit. Ich fand das besser als meine Idee.
Erst mit Fantasiedaten, dann mit echten
Weil der Token noch fehlte, hat Claude einen Demo-Modus eingebaut. Er erzeugt Fantasiepreise mit zwei Tagesgipfeln und einen Verbrauch mit gelegentlichen Spitzen. Damit hat Claude die Seite im Browser in der Auflösung des iPads geprüft, im Quer- und im Hochformat. Ein paar Beschriftungen überlappten, die wurden gleich korrigiert.
Dann habe ich meinen Tibber-Token in eine lokale Datei geschrieben, ausdrücklich nicht in den Chat. Der erste Test mit echten Daten brachte gleich drei Überraschungen:
  • Zwei Wohnungen im Konto. Ich habe bei Tibber zwei Zähler, nur einer davon hat einen Pulse. Der Server nahm einfach den ersten und bekam deshalb keine Live-Daten. Claude hat das an der Meldung „Echtzeit: nein" erkannt, direkt bei der API nachgefragt und die Auswahl geändert. Jetzt nimmt der Server automatisch die Wohnung mit Pulse.
  • Falsche Tageswerte. „Max. heute" zeigte 407 Watt. Die eigene Aufzeichnung lief ja erst seit einer Minute. Jetzt gilt der Tageswert, den der Pulse selbst meldet, bis die eigene Aufzeichnung den Tag abdeckt.
  • Fehlende Preise von gestern. Das Diagramm zeigt die letzten 24 Stunden. Die Preise von gestern Abend fehlten aber. Claude hat ausprobiert, welche Abfragen die API anbietet, und eine gefunden, die vergangene Preise liefert. Seitdem ist das Diagramm schon beim ersten Start vollständig.
Eine Sache wurde nicht gelöst, sondern nur benannt: Der Pulse meldet als Tagesspitze gut 25 Kilowatt, die App zeigte etwa 14. Vermutlich misst der Pulse den kurzen Momentanwert, während die App glättet. Claude hat das als Vermutung gekennzeichnet und nicht als Tatsache verkauft.
Deployment auf den Büroserver
„Ja, deploy" war die ganze Anweisung. Claude hat per SSH geprüft, dass Rust auf dem Server installiert ist und der gewünschte Port frei ist. Dann hat es das Projekt kopiert, gebaut, einen eigenen Systembenutzer angelegt und den Dienst eingerichtet. Neben dem Server-Monitor vom iPhone läuft jetzt ein zweiter kleiner Dienst.
Beim Token gab es eine Rückfrage: selbst eintragen oder aus der lokalen Datei übertragen lassen? Ich habe mich für das Übertragen entschieden. Claude hat den Token direkt von Datei zu Datei geschoben, ohne ihn anzuzeigen, und anschließend nur geprüft, dass er drinsteht und nur für root lesbar ist.
Danach habe ich die Seite auf dem iPad geöffnet und zum Home-Bildschirm hinzugefügt. Sie läuft im Vollbild, wie eine App. So sah sie am ersten Abend aus. Oben der Preis von heute 0 Uhr bis morgen 24 Uhr, unten der Verbrauch. Die grauen Balken sind die Stundenwerte aus der API, das kleine grüne Stück kurz vor der Jetzt-Linie sind die ersten Minuten aus dem Livestream.
Feinschliff
Wie beim iPhone ging es danach im Gesprächston weiter.
„Mach ein eigenes Home-Screen-Icon." Claude hat ein Icon entworfen: ein Blitz mit Farbverlauf über einer Preis-Stufenkurve, in den Farben des Dashboards. Das Tibber-Logo hat es bewusst nicht nachgebaut. Die Vorlage liegt als SVG im Projekt, das PNG wird daraus erzeugt.
„Rüste das Speichern beim Beenden nach." Den Hinweis hatte Claude selbst gegeben: Bei jedem Neustart gingen die letzten Live-Daten verloren, weil der Server nur in festen Abständen speicherte. Jetzt speichert er auch, wenn systemd ihn stoppt. Getestet wurde das zweimal: lokal und auf dem Server mit einem echten Neustart. Im Log stand danach „beim Beenden gespeichert" und beim Start „geladen".
Zwischendurch kamen noch ein Git-Commit, ein privates Repository auf GitHub und jeweils ein neues Deployment. Darum musste ich mich nicht kümmern.
Fazit
Das iPad steht jetzt neben dem iPhone auf dem Schreibtisch. Oben zeigt es die aktuelle Leistung, den Preis der laufenden Viertelstunde und den Tagesverbrauch in Kilowattstunden und Euro. Darunter das Diagramm: der Preis von gestern bis morgen und darunter mein Verbrauch. Wenn der Preis morgen Nachmittag in den türkisen Bereich fällt, weiß ich, wann die Waschmaschine laufen sollte.
Gegenüber dem iPhone-Projekt sind mir zwei Dinge aufgefallen:
  • Claude hat mir widersprochen, und zwar zu Recht. Mein Wunsch nach einem Diagramm mit zwei Achsen wurde nicht einfach umgesetzt. Ich bekam eine bessere Lösung und eine kurze Begründung.
  • Die echten Daten haben das Projekt geformt. Zwei Wohnungen, fehlende Tageswerte, fehlende Preise von gestern: Nichts davon stand in meinem Auftrag. Alles wurde beim ersten Test mit echten Daten gefunden und sofort behoben.
Wieder habe ich keine Zeile Code geschrieben. Ich habe beschrieben, was ich sehen will, eine Frage zum iPad beantwortet und ein paar Mal „Ja" gesagt.

Alle Artikel

Rufen Sie einfach an.

Ein unverbindliches Erstgespräch reicht, um zu klären, ob und wie ich Ihnen helfen kann. Kein Formular, kein Verkaufsdruck.

Oder per E-Mail an rene.fuerstenberg@gmail.com

Ich rufe zurück, wenn ich gerade im Termin bin.