SNLO – Spittank.net Ladeorganisation – Konfiguration¶
Die Laufzeitkonfiguration von SNLO – Spittank.net Ladeorganisation erfolgt über .env. Ausgangspunkt ist .env.example; python3 scripts/init-env.py erzeugt daraus eine sichere lokale Konfiguration mit zufälligen Geheimnissen.
Grundkonfiguration¶
| Variable | Bedeutung | Standard/Beispiel |
|---|---|---|
APP_ORIGIN |
öffentliche Basis-URL ohne abschließenden Pfad | https://snlo.de |
APP_TIMEZONE |
Zeitzone für Anzeige und Abrechnung | Europe/Berlin |
APP_CURRENCY |
Währung | EUR |
HTTP_PORT |
veröffentlichter Host-Port | 8080 |
COOKIE_SECURE |
Cookies nur über HTTPS senden | produktiv true |
SESSION_TTL_HOURS |
normale Browser-Sitzung | 24 |
PWA_SESSION_TTL_DAYS |
langlebige installierte PWA-Sitzung; wird beim App-Start erneuert | 3650 |
LOG_LEVEL |
Python-Loglevel | INFO |
Hinter einem Reverse Proxy muss mindestens gelten:
Der Proxy muss X-Forwarded-Proto und X-Forwarded-For korrekt setzen. Die Anwendung akzeptiert Zustandsänderungen nur von der konfigurierten Origin beziehungsweise ihrer effektiv erkannten eigenen Origin.
Datenbank und Geheimnisse¶
| Variable | Bedeutung |
|---|---|
POSTGRES_DB |
Datenbankname |
POSTGRES_USER |
Datenbanknutzer |
POSTGRES_PASSWORD |
Datenbankpasswort |
POSTGRES_VOLUME_NAME |
expliziter Name des persistenten Docker-Volumes |
CREDENTIAL_ENCRYPTION_KEY |
Base64-URL-kodierter Schlüssel mit 32 Byte Nutzdaten |
BOOTSTRAP_ADMIN_EMAIL |
E-Mail des initialen Administrators |
BOOTSTRAP_ADMIN_NAME |
Anzeigename des initialen Administrators |
BOOTSTRAP_ADMIN_PASSWORD |
initiales Passwort |
CREDENTIAL_ENCRYPTION_KEY darf bei Updates nicht geändert werden. Andernfalls können bereits gespeicherte EVCC-, KEBA- und RFID-Geheimnisse nicht mehr entschlüsselt werden.
Vor Updates sollte die Datenbank gesichert werden:
docker compose exec -T db \
pg_dump -U "${POSTGRES_USER:-snlo}" "${POSTGRES_DB:-snlo}" \
> snlo-backup-$(date +%F).sql
Containerquelle¶
Der Compose-Stack kann dasselbe Image lokal bauen oder aus der Forgejo-Registry beziehen:
| Variable | Bedeutung | Lokal |
|---|---|---|
SNLO_IMAGE |
Image für migrate, api und worker |
snlo:local |
SNLO_PULL_POLICY |
Compose-Pull-Policy | build |
Lokaler Build:
Registry-Release:
Anschließend genügt jeweils:
Collector¶
| Variable | Bedeutung | Standard |
|---|---|---|
EVCC_POLL_INTERVAL_SECONDS |
Intervall für Livezustände | 5 |
EVCC_SESSION_SYNC_INTERVAL_SECONDS |
Intervall für abgeschlossene Sitzungen | 60 |
EVCC_REQUEST_TIMEOUT_SECONDS |
HTTP-Timeout je EVCC-Anfrage | 10 |
BATTERY_MAX_SAMPLE_GAP_SECONDS |
größte noch verwertete Messlücke | 15 |
CHARGING_POWER_THRESHOLD_W |
Mindestleistung für tatsächliches Laden | 100 |
Jede EVCC-Instanz wird im Adminbereich dynamisch angelegt. Als URL wird nur die Basis-URL angegeben:
Nicht angeben:
Der EVCC-API-Key ist für die aktuell genutzten Status-, Sitzungs- und Ladepunktfunktionen normalerweise nicht erforderlich. Ist einer hinterlegt, sendet SNLO ihn als Bearer-Token.
Fahrzeuge und zahlende Nutzer¶
Die technische Fahrzeugerkennung ist von der Abrechnung getrennt:
EVCC-Fahrzeug
-> internes Fahrzeug
-> mehrere berechtigte Nutzer
-> genau ein zahlender Nutzer je Zeitraum
Ein internes Fahrzeug kann mit Fahrzeugen aus beliebig vielen EVCC-Instanzen verknüpft werden. Sitzungen werden anhand des EVCC-Fahrzeugnamens oder -titels dem internen Fahrzeug zugeordnet. Der zum Sitzungsbeginn gültige zahlende Nutzer bestimmt die Abrechnung.
Tarife¶
Tarife sind benannte Vorlagen ohne unmittelbare Nutzer- oder Zeitraumzuordnung, beispielsweise:
Im Nutzerbereich der Administration wird danach festgelegt, welcher Tarif in welchem Zeitraum gilt:
Eine nutzerbezogene Zuordnung überschreibt den globalen Standard. Überlappende Zeiträume innerhalb desselben Geltungsbereichs sind nicht erlaubt.
Sitzungsdauer von Browser und PWA¶
Normale Browser-Anmeldungen verwenden SESSION_TTL_HOURS. Eine über den installierten PWA-Start ausgelöste Anmeldung wird als eigene PWA-Sitzung markiert und verwendet PWA_SESSION_TTL_DAYS. Bei jedem erfolgreichen Start der installierten PWA wird diese Laufzeit erneut ab dem aktuellen Zeitpunkt gesetzt. Standardmäßig sind das 3650 Tage, sodass die App auf einem persönlichen Gerät praktisch bis zum aktiven Abmelden angemeldet bleibt. Eine normale Browser-Sitzung wird nicht ohne erneute Anmeldung in eine PWA-Sitzung umgewandelt. Bei Browser und installierter PWA derselben Origin wird der HTTP-Cookie-Speicher je nach Plattform geteilt; nach einer PWA-Anmeldung kann die langlebige Sitzung deshalb auch im normalen Browser derselben Geräte-/Browserumgebung gelten.
Bei OIDC wird das ID-Token weiterhin während des Login-Vorgangs vollständig validiert. Die danach erzeugte langlebige PWA-Sitzung ist eine SNLO-Anwendungssitzung; Gruppen- und Rollenanpassungen beim Identity Provider werden deshalb spätestens bei der nächsten OIDC-Anmeldung synchronisiert. Administrativ deaktivierte SNLO-Konten verlieren den Zugriff dagegen sofort.
KEBA¶
Die optionale KEBA-P30-UDP-Anbindung verwendet je Ladepunkt Host, UDP-Port und Timeout. RFID-UIDs werden je Nutzer und KEBA-Verbindung verschlüsselt gespeichert. Die im KEBA-Webinterface übliche 8-stellige UID wird unverändert an die Wallbox übergeben. Intern ergänzt SNLO – wie die Home-Assistant-KEBA-Integration – den festen RFID-Class-Wert 01010400000000000000; Nutzer müssen keinen Klassifikator verwalten. Alte, durch SNLO 0.5.9 irrtümlich null-erweiterte Werte werden automatisch erkannt und mit der kurzen UID zuerst versucht. Die P30-UDP-Schnittstelle selbst benötigt keinen API-Key; ein optionales geheimes Feld ist nur für spätere Connectoren vorgesehen.
Zum Sperren versucht SNLO immer zuerst den dokumentierten Befehl mit der echten Nutzerkarte und prüft anschließend report 2/Authreq. Bleibt eine noch nicht ladende Wallbox trotz bestätigtem Befehl entsperrt, kann SNLO als gerätespezifischen Fallback eine absichtlich unbekannte RFID über start simulieren. Der Code wird mit KEBA_LOCK_FALLBACK_RFID konfiguriert (Standard 44556677). Der Fallback wird während einer aktiven Ladung nie verwendet und darf nicht als echte aktive RFID in SNLO hinterlegt sein.
SNLO betreibt für KEBA einen persistenten UDP-Listener auf Port 7090 im Dienst keba-gateway. Der Dienst verwendet Linux-Host-Networking, damit bei einem normalen rootful Docker Engine keine Docker-Bridge-NAT-Stufe zwischen dem gebundenen Socket und dem Hostnetz liegt. KEBA_GATEWAY_TOKEN schützt den internen API/Gateway-Kanal; neue Installationen erzeugen ihn mit scripts/init-env.py. Bei Upgrades muss ein mindestens 32 Zeichen langer Zufallswert ergänzt werden. UDP 7090 muss auf dem Docker-Host frei und aus dem Wallbox-Netz erreichbar sein.
KEBA-Netzwerkdiagnose¶
Live-Log:
Ein Test erzeugt mindestens diese Zeilen:
Kommt die Antwort im Gateway an, folgt:
Fehlt KEBA UDP RX, obwohl ein Paketmitschnitt eine Antwort an Port 7090 zeigt, wird das Paket vor dem Gateway verworfen oder in einen anderen Netzwerk-Namespace zugestellt. Prüfe dann insbesondere Rootless-Docker sowie NAT/Firewall zwischen Docker-Host und Wallbox.
Docker-Modus prüfen:
Zum vollständigen Ausschluss von Docker kann der sichere Read-only-Test direkt auf dem Host ausgeführt werden. Vorher den Gateway stoppen, damit UDP 7090 frei ist:
docker compose stop keba-gateway
python3 scripts/keba-udp-probe.py <KEBA-IP>
docker compose start keba-gateway
Der Probe sendet ausschließlich report 1 und zeigt den vom Host-Kernel verwendeten lokalen Socket an.
OpenID Connect¶
Die vollständige Konfiguration steht unter OpenID Connect. Für den produktiven Betrieb sind insbesondere APP_ORIGIN, COOKIE_SECURE, Gruppenclaims und der lokale Notfallzugang zu prüfen.
TrueNAS SCALE¶
Siehe TrueNAS SCALE. Reverse Proxies werden auf die feste TrueNAS-Host-IP und Port 8080 gerichtet, nicht auf die wechselnde interne Docker-IP des API-Containers.