- HTML 45.5%
- JavaScript 39.5%
- C++ 10%
- CSS 2.2%
- Python 1.4%
- Other 1.4%
Stand „KH-Nacht (Soda)", obwohl NaOH drin war — der Text nahm die feste Lösung der Pumpe. Jetzt die Sorte der letzten Kanister-Buchung; ist sie unbekannt oder kommt der Kanister nicht aus dem Lager, nur der Pumpenname. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|---|---|---|
| .forgejo/workflows | ||
| aquarien | ||
| assets | ||
| cr-rechner | ||
| entwuerfe | ||
| esp-firmware | ||
| geraete | ||
| icp | ||
| kalk | ||
| khtester | ||
| lager | ||
| nutrient | ||
| pb_hooks | ||
| pb_migrations | ||
| salz | ||
| server | ||
| spurenrechner | ||
| tools | ||
| .gitignore | ||
| datenschutz.html | ||
| deploy.list | ||
| FIRMWARE.md | ||
| impressum.html | ||
| index.html | ||
| KH-TESTER-INTEGRATION.md | ||
| LICENSE | ||
| MEHRERE-AQUARIEN.md | ||
| NAEHRSTOFF-REGLER.md | ||
| README.md | ||
Aquarium Rechner
Werkzeuge für Meerwasser-Aquaristik — von Wasserwechsel-Berechnung bis hin zu vollautomatischer Kalk-Dosierung mit eigener ESP32-Firmware.
Hosting
Selbst gehostet — die Web-Oberfläche wird direkt von einem eigenen PocketBase-Server ausgeliefert (statische Dateien im pb_public/, dazu API + Auth). Es gibt keine zentrale öffentliche Instanz; Details unter Hosting & Daten.
Die einzelnen Rechner liegen unter den Pfaden / (Übersicht), /cr-rechner/,
/spurenrechner/, /salz/, /kalk/, /nutrient/, /khtester/, /icp/ und /lager/.
Inhalt
C&R Aquarium Rechner
Berechnet optimale Wasserwechsel mit C&R Lösungen, um ICP-Messwerte schrittweise zu Optimalwerten zu führen. Mit Max-Δ-Begrenzung pro Schritt für schonende Anpassung empfindlicher Korallen. Historie der Messwerte und ausgeführten Ausgleiche mit Verlaufsgrafik.
Spurenelemente Rechner
Plant Tagesdosen einzelner Spurenelemente basierend auf ICP-Messwerten und Verbrauchshistorie. Jede Dosis wird mit Beckenvolumen und Reichweite der Mischung gespeichert — ein Wechsel des ICP-Rhythmus (monatlich/14-tägig) rechnet die Historie deshalb um, statt die alten Millilitermengen weiterzuschreiben. Geregelt wird je Element unterschiedlich: aus den eigenen Messung-Dosis-Paaren schätzt der Rechner, wie viel an einer Abweichung Laborstreuung und wie viel echte Bewegung des Beckens ist, und wendet nur den entsprechenden Teil einer Korrektur an (Spalte γ). Die Schätzung verfeinert sich mit jeder ICP; der Zielwert bleibt derselbe, nur das Tempo passt sich an. Die Schrittweite folgt der engeren Seite des Zielbands, und wenn ein Element mehrere Runden gegen die Dosierung anläuft, benennt der Rechner die Ursache, statt weiter zu regeln. Daten lokal oder im eigenen Account.
Salz & Salinität
Rechnet Dichte, spezifisches Gewicht, Salinität und Leitfähigkeit ineinander um (EOS-80/PSS-78), passt die Salinität gezielt an — in Schritten von höchstens „Max. Abweichung“, je Schritt mit Haken, der die Salinität danach als neuen Stand übernimmt; Wassermengen wahlweise in Liter oder kg (zum Abwiegen) — und kalibriert Salz sowie Spindel. Verfolgt mit Kalkmanagement zusätzlich den Salzzuwachs beim Balling: wie viel Gramm Salz die Ca-, KH- und Mg-Dosierung seit der jüngsten bekannten Salinität (Messung, ICP oder Zurücksetzen auf das Ziel) hinterlassen hat (Chlorid, Natrium, Sulfat bleiben im Wasser; pb_hooks/salz_lib.js, GET /api/salz/dosiert, Selbstcheck jsc tools/test-salz.js) und wie viel Liter gegen Osmosewasser getauscht werden müssen — fällig erst über dem Zielband (Ziel + „Max. Abweichung“), bis dahin mit Termin aus dem Anstieg der letzten 14 Tage. Die geschätzte Salinität (dieser Wert plus Dosierung seitdem) steht vorbelegt unter „Aktuelle Salinität“; eine eigene Eingabe überschreibt sie und wird, als Messung gespeichert, der neue Startpunkt. Wer im C&R-Rechner einen Ausgleich speichert, wird gefragt, ob der Zuwachs zurückgesetzt werden soll.
Lager & Rezepte
Führt den Vorrat an OSCI-Lösungen (Makro, Custom & Repair, Trace, Nutrition) sowie an Pulvern und Salzen. Bestand ist die Summe einer Buchungsliste: Zugänge trägt man selbst ein, Entnahmen buchen die Rechner automatisch — gespeicherte C&R-Ausgleiche, Spurenmischungen, das Auffüllen der Dosierkanister in Kalk- und Nährstoffmanagement (mit Verdünnung, z. B. Lanthan 100 ml/L) und das Anmischen. Die Stärke der OSCI-Lösungen steht an einer Stelle (assets/cr-loesungen.js), die Verdünnung in den Lager-Einstellungen: Daraus rechnet der Server den Dosierplan, der ESP stempelt die Wirkung an jede Dosis. Ändern lässt sich eine Verdünnung nur bei leerem Kanister. Reichweite und Nachbestell-Termin kommen aus dem tatsächlichen Verbrauch: Erhaltung der Pumpen nach Dosierplan (ohne Auto-Dosierung ihr Dosierprotokoll), letzte Spurenmischung, selbst angemischte Lösungen über ihren Rezeptanteil bis zu den Salzen, dazu C&R-Ausgleiche und Meerwasser im Mittel. Rezepte für Calcium, Magnesium, KH-Tag/-Nacht, Meerwasser und C&R aus Salz, in beliebiger Menge. Trace Fluor und C&R Natriumfluorid sind laut OSCI dieselbe Lösung: beide stehen unter ihrer Gruppe, zählen aber als ein gemeinsamer Bestand. Dazu die Wassertests (KH, Calcium, Phosphat HI736/HI774, Nitrat HI781/HI782) in Stück: jeder von Hand gespeicherte Messwert — Startseite, Kalk- oder Nährstoffmanagement — zieht einen Test ab, beim Nitrat und Phosphat den eingestellten Test; ICP-Werte und der KH-Tester nicht. Das gilt erst, wenn der Test einmal gezählt oder gekauft ist, vorher bleibt er ohne Abzug und Erinnerung. Der Verbrauch kommt aus dem üblichen Abstand der Handmessungen. Der Bestand steht in zwei aufklappbaren Bereichen (Lösungen & Salze, Wassertests) mit je eigener Inventur. Die Erinnerung steht auf der Seite und auf der Startseiten-Kachel; dazu kommt sie je Artikel einmal mit der Tagesmail um 8 Uhr (die nächste erst nach dem Zugang bzw. Anmischen). Unter „+“ hat jeder Artikel zwei Haken, beide von Haus aus an: „Bestand überwachen“ (aus = keine Erinnerung, nirgends) und „Erinnerungsmail“ (aus = nur keine Mail).
Nährstoffmanagement (Web + ESP32-Firmware)
Regelt NO₃ und PO₄ über vier Pumpen (Stickstoff, Phosphat, Kohlenstoff, Lanthan). Lernt den Netto-Verbrauch aus der Massenbilanz und leitet daraus eine Erhaltungsdosis samt gerampter Korrektur ab. Die Wahl des Abbaumittels folgt dem molaren N:P-Verhältnis — Kohlenstoff senkt beide Werte, Lanthan wirkt gezielt auf Phosphat.
KH-Tester (Web + ESP32-Firmware)
Misst die Karbonathärte automatisch per Säure-Titration — wahlweise dynamisch bis zum Ziel-pH oder als Gran-Titration mit Regression über den Äquivalenzpunkt. Live-Verfolgung der laufenden Messung im Browser, pH-Kalibrierung mit Sonden-Gesundheitscheck, Überwachung von Säurevorrat und Abwasserbehälter. Ein Klick übernimmt das Ergebnis ins Kalkmanagement, das daraufhin seinen Dosierplan neu rechnet.
Kalkmanagement (Web + ESP32-Firmware)
Komplette Steuerung für eine selbstgebaute 4-Pumpen-Dosier-Anlage (Calcium, Magnesium, KH-Tag, KH-Nacht). Web-Interface plant die Dosierung, ESP32 führt sie aus.
Web-Funktionen:
- Quick-Inputs für KH/Ca direkt auf der Übersicht + Live-Kanister-Balken
- Restlaufzeit je Kanister: Schnittpunkt des geplanten Verbrauchs (Ausgleich, Erhaltung, KH Tag/Nacht — wie der ESP dosiert) mit „leer“, ohne Auto-Dosierung aus den letzten 14 Tagen. Gerechnet auf dem Server (
pb_hooks/kanister_lib.js,GET /api/kanister) — Anzeige und Warnmail haben dieselben Zahlen - Dosier-Plan-Berechnung (KH + Ca/Mg) mit wählbarer Frequenz (2–12 pro Tag) — ohne Messwert als reine Erhaltungsdosierung aus der eingetragenen Verbrauchsrate
- Verbrauch als Bilanz über die letzten N Messungen (dosiert minus Wertänderung, geteilt durch die Tage) — nur aus einer Messquelle (von Hand oder KH-Tester), ohne ICP-Werte; ein Versatz zwischen zwei Geräten erscheint so nicht als Verbrauch
- Plan-Visualisierung als Tabelle + Charts
- Pumpen-Kalibrierung (Live-Lauf über das Web)
- pH-Sensor-Kalibrierung (2-Punkt mit pH-4 + pH-7)
- Container-Füllstand-Tracking
- Historie (Messungen, Dosierungen) mit Charts
- OTA-Firmware-Update mit einem Klick
ESP32-Firmware:
- Plan-Cache lokal (NVS) → läuft offline beliebig lange weiter (Anpassungs-Doses anhand absoluter Timestamps, danach unbegrenzte Erhaltungs-Dose)
- DS3231-RTC-Sync → Dosier-Plan läuft auch nach Stromausfall ohne Internet weiter
- Auto-Dosierung (per Schalter im Web aktivierbar)
- Anti-Drip-Sequenz (Prime → Dose → Retract) für sauberes Stop-Verhalten
- KH-Tag/Nacht-Umschaltung anhand pH-Wert oder Uhrzeit
- pH-Wächter (optional): eine Sonde, deren Wert 6 h lang steht, gilt als eingefroren → Tag-Pumpe statt Nacht-Lösung, Störung im Gerät-Tab; dazu serverseitig eine E-Mail, wenn der pH ein einstellbares Fenster verlässt oder der ESP die eingefrorene Sonde meldet
- WS2812-Status-LED zeigt System-Zustand
- Ausfall-Benachrichtigung per E-Mail — ein serverseitiger Watchdog (PocketBase-Cron) überwacht den Heartbeat und meldet, wenn der ESP länger als 5 Min ausfällt (pro Nutzer im Gerät-Tab an/aus)
- OTA-Update aus den Releases des eigenen Git-Servers (git.reeftank.pro) — CI baut das .bin automatisch bei jedem Version-Tag
Hosting & Daten
Statische HTML-Seiten, ausgeliefert direkt von PocketBase (pb_public/). Alles läuft im Browser.
Ohne Login (C&R, Spuren): Daten werden ausschließlich lokal im Browser gespeichert (localStorage). Nichts wird übertragen.
Mit Login (E-Mail/Passwort): Daten werden zusätzlich auf einem privaten PocketBase-Server (Deutschland, Übertragung per HTTPS verschlüsselt) abgelegt, damit du sie auf jedem Gerät verfügbar hast. Jeder Nutzer kann nur seine eigenen Daten lesen/schreiben (PocketBase-API-Regeln pro Nutzer). Kein Tracking, keine Weitergabe.
Kalkmanagement, Nährstoffmanagement und KH-Tester erfordern einen Account, weil Web und ESP über PocketBase synchronisieren.
Sicherung je Aquarium: unter „Meine Aquarien“ lädt „Sichern“ alles, was zu einem Aquarium gehört (Einstellungen aller Rechner, Zielwerte, Messwerte, Dosierungen, Pläne, Kalibrierungen, Labor-Proben), als JSON-Datei herunter; „Aquarium hinzufügen → Aus JSON-Sicherung“ legt daraus ein neues Aquarium an. Was dazugehört, fragt der Server bei jedem Aufruf die Datenbank selbst (jede Collection mit Relation auf aquariums, pb_hooks/sicherung_lib.js) — neue Daten sind ohne Änderung mitgesichert. Geprüft mit tools/test-sicherung.py gegen eine lokale PocketBase.
ESP-Firmware bauen
Im Ordner esp-firmware/aquarium-rechner-esp/.
- Board: ESP32-S3 N16R8 (16 MB Flash, 8 MB OPI PSRAM)
- IDE: Arduino 2.x mit „ESP32 by Espressif Systems" Boards
- Partition:
16M Flash (3MB APP/9.9MB FATFS) - Libraries: FastAccelStepper, ArduinoJson (v7), RTClib, Adafruit NeoPixel (kein extra Backend-Client nötig — Anbindung an PocketBase per HTTPS-REST)
Eine Firmware für alle Geräte. Welche Aufgabe ein ESP übernimmt, entscheidet
seine Rolle (kalk, nutrient, khtest), die im Web-Interface pro Gerät
zugewiesen wird — nicht ein eigener Build. Alle drei laufen auf derselben
Platine; was die Rolle unterscheidet (Pumpenzahl und -namen, Rührer-PWM beim
Tester, pH-Fenster), wird beim Boot anhand der Rolle gesetzt; siehe
RoleConfig in config.h.
Neue Releases baut die CI (Forgejo Actions) automatisch: Version-Tag v* pushen →
kompilierte .bin erscheint als Release-Asset auf https://git.reeftank.pro —
der ESP holt sie sich per OTA. Details in FIRMWARE.md.
Werkzeuge
Alles unter tools/ — wird nicht ins Web gespiegelt (siehe deploy.list).
Seiten vor dem Deploy prüfen. Die Rechner sind je eine HTML-Datei mit einem
grossen <script type="module">. Ein Syntaxcheck reicht dort nicht: eine
undefinierte Variable in einem const-Literal ist syntaktisch tadellos und
zerlegt die Seite trotzdem beim Laden — sichtbar erst, wenn jemand sie aufmacht.
python3 tools/check-inline.py nutrient/index.html
Das Skript löst die Importe heraus, ersetzt sie durch nachgiebige Stubs samt
DOM-Attrappe und führt den Modulrumpf aus. Es braucht eine JS-Engine
(node oder macOS-jsc) und meldet sichtbar, wenn es keine findet.
tools/deploy.sh ruft es serverseitig vor dem Spiegeln auf: fällt eine Seite
durch, bricht der Deploy ab und pb_public bleibt auf dem vorigen Stand.
Lager-Rechnung prüfen. Bestand, Verbrauch aus allen Quellen, Reichweite und
die Posten, die die Rechner buchen, gegen ein nachgestelltes Becken. Gerechnet
wird nur auf dem Server (GET /api/lager, dieselbe Rechnung wie in der
Tagesmail); Lager-Seite und Startseite zeigen sie an:
/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc -m tools/test-lager.mjs
Kanister-Rechnung prüfen. Verbrauch und Restlaufzeit (pb_hooks/kanister_lib.js):
Verlauf je Pumpe, Plan mit Ausgleich und Tag/Nacht, Raster der Nährstoff-Pumpen
wie in der Firmware, Messplan und Verbrauch je Messung des KH-Testers:
/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc tools/test-kanister.js
Dosen pro Tag: Die Einstellung fließt durch Plan, Kanister-Rechnung, Tagessummen und ESP. tools/test-dosenzahl.mjs hält fest, was bei jeder Zahl und beim Umstellen gleich bleiben muss, und dass jede Dose im Plan in einer Stunde liegt, die der ESP bedient, auch an den Tagen der Zeitumstellung (die Regel steht in assets/dosier-slots.js). Wie der ESP solche Pläne abfährt, prüft der Slot-Test (esp-firmware/test/slots).
TZ=Europe/Berlin /System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc -m tools/test-dosenzahl.mjs
Tagesmail durchspielen. Der Server-Hook pb_hooks/container_alert.pb.js
(Erinnerung „heute messen" + Kanister fast leer / leer + Lager nachbestellen /
anmischen, einmal morgens) läuft nur in der PocketBase-JSVM. Der Selbstcheck
stellt sie nach, dreht die Uhr auf 8:07 und prüft Mails und Merker in gut
zwanzig Fällen:
/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc tools/test-tagesmail.js
Testvorhersage prüfen. „Nächster Test" (assets/next-test.js) rechnet die
Ungenauigkeit des Plans über bis zu vier Messabstände, daraus eine Spanne
(früher/später Termin) und wie stabil die Messwerte sind, und kennt den Zustand
„Wert außerhalb". Im Eingabefeld steht nur der frühe Termin, der Rest im
Fenster beim Darüberfahren. Der Selbstcheck hält Kontrollmessung, Ausreißer,
Lücken im Soll-Verlauf, Spanne/Stabilität und die Fälle ohne Dosierung fest:
/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc -m tools/test-vorhersage.mjs
Lokal ansehen. Die Seiten laden ihre Module über absolute Pfade
(/assets/...), die ein file://-Aufruf nicht auflöst — ohne Server sieht man
deshalb keine Laufzeitfehler, sondern gar nichts.
python3 tools/devserver.py 8788
Danach http://localhost:8788/nutrient/ im Browser. (Bewusst nicht
python3 -m http.server: dessen __main__ ruft os.getcwd() auf, was in
manchen Sandboxes scheitert.)
Mit Login testen. Der Devserver hat kein PocketBase dahinter — Kalk, Nährstoff, KH-Tester und alles mit Cloud-Sync brauchen eine lokale Instanz:
tools/pb-local.sh
Dieselbe PocketBase-Version wie der Server, die Migrationen und Hooks aus dem
Repo, die Seiten direkt aus dem Repo — aber eine eigene, leere Datenbank unter
~/.pb-aquarium/. Beim ersten Start legt das Skript einen Admin und einen
verifizierten Testnutzer an (Zugangsdaten in ~/.pb-aquarium/zugang.txt) und
leitet Mails ins Leere. Danach http://127.0.0.1:8090/kalk/; mit
tools/pb-local.sh reset fängt man von vorn an. Nichts davon erreicht einen
echten ESP.
Server-Logik ausrollen. tools/deploy-server.sh prüft vorher die Hooks
(tools/check-hooks.js) und spielt alle Migrationen auf einer leeren
Datenbank durch; fällt etwas durch, bleibt der Server unangetastet.
Quellcode & Mitmachen
Der Quellcode liegt auf dem eigenen Git-Server: https://git.reeftank.pro (öffentlich lesbar/klonbar).
Lizenz
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
Du darfst das Material teilen und bearbeiten, sofern du:
- Namensnennung vornimmst (Markus / markus629)
- es nicht für kommerzielle Zwecke nutzt
- abgeleitete Werke unter der gleichen Lizenz weitergibst
Vollständiger Lizenztext: LICENSE