TIL: sqlite statt MySQL

Hier im Haus läuft auf einem Raspberry Pi eine Volkszähler-Instanz, welche mit allerlei Daten gefüttert wird: die Werte diverser Strommengenzähler und Wetterdaten laufen in die Volkszähler-Datenbank hinein.

  • Hauptstromzähler: vzlogger mit Infrarot-Interface an Logarex-Stromzähler, per USB an einem alten Raspberry Pi 1 angeschlossen (in etwa so)
  • diverse Nebenstromzähler: FRITZ!DECT 200 und FRITZ!DECT 210 (zum Beispiel am Brunnen für Gartenwasser)
  • Wetterdaten: direkt vom DWD (Temperatur, Taupunkt, Luftfeuchte, Luftdruck, Wind usw.)

Der vzlogger am Hauptstromzähler liest regelmäßig den Zählerstand aus und sendet ihn direkt an den Volkszähler. Sollte die Volkszähler-API einmal nicht erreichbar sein, werden die Daten gepuffert, bis sie erfolgreich abgeschickt werden können. Soweit so gut.

Die FRITZ!DECT-Stromzähler lassen sich über die FRITZ!Box-API auslesen (und auch schalten). Hierfür habe ich mir zwei kleine Skripte geschrieben, welche die Daten ebenfalls lokal vorhalten:

  1. ein Skript liest die Zählerstände alle 5 Minuten von der FRITZ!Box aus (mit harpax/fb_http). Die Daten werden dann in JSON-Dateien in einer Directory-Struktur abgelegt (YYYY-MM/<TIMESTAMP>-<DEVICE-AIN>.json).[1]
  2. das andere Skript sucht neu hinzugekommene Dateien, parst den Zählerstand und schickt ihn an die Volkszähler-API. Bei Erfolg wird eine State-Datei mit dem aktuellen Timestamp gespeichert, sodass beim nächsten Durchlauf wieder nur neu hinzugekommene Messungen gesendet werden.

Das Auslesen und Wegschreiben der Daten lief absolut problemlos, das Iterieren über die Directories war auf dem alten Raspberry Pi mit SD-Card-Filesystem aber sehr langsam (mit symfony/finder).

Als Alternative zum Flatfile-Storage kam mir eine Datenbank als Zwischenspeicher in den Sinn, da hiermit das gesamte Management der Datenablage und -abgfrage gelöst ist. Ein MySQL-Server ist meist meine erste Wahl, wäre in diesem Fall aber totale Übertreibung.

Also nutzte ich die Möglichkeit, das erste Mal in meinem Leben sqlite selbst einzusetzen. sqlite ist eine SQL-Datenbank, welche in nur einer Datei lebt. Es gibt keine Netzwerk-Komponente, keine Benutzerverwaltung usw., dafür spricht sie normales SQL. Meine Skripte waren sehr schnell auf das neue Storage-Backend umgebaut, als ORM habe das gut abgehangene idiorm genutzt, welches ich schon in zig Projekten (mit MySQL) erfolgreich eingesetzt habe.

Statt minutenlangem Herumsuchen nach neuen Messwert-Dateien auf der langsamen SD-Card stehen die neuen Daten jetzt in Sekundenbruchteilen zur Verfügung.

Die DWD-Wetterdaten werden ebenfalls mit einem Skript abgeholt und mit einem zweiten Skript an die Volkszähler-API geschickt. Auch hier kommt jetzt sqlite als Zwischenspeicher zum Einsatz.

Ich hätte natürlich auch selbst das Flatfile-Storage optimieren können – und hätte es sicher auch auf eine vergleichbare Performance bekommen. Der Aufwand dafür ist aber um einiges höher als einfach sqlite als Drop-In-Storage zu nutzen. Die gesparte Zeit habe ich dann einfach an der frischen Luft verbracht 🚴‍♂️

tl;dr

Wenn ein Projekt nach einer SQL-Datenbank verlangt, MySQL aber zu schwer ist und zu viel kann, dann sollte man sich einfach mal sqlite anschauen. Es ist wahrscheinlich, dass sqlite alle auftretenden Probleme vernünftig lösen kann.


  1. hier fallen täglich 288 Dateien an, das macht im Monat gut 8.500 Dateien – pro erfasstem Zähler