143 Commits
Author SHA1 Message Date
retr0andClaude Sonnet 5 cd5f8cb7af ShineBridge v1.12.3 — Fix: NameError SUN_THRESHOLD in /api/weather-forecast
SUN_THRESHOLD war nur lokal in adjusted_timeout_h() definiert, summary()
(genutzt vom Settings-Preview UND vom neuen Dashboard-Diagramm) griff aber
auch drauf zu -> 500-Fehler bei jedem Aufruf, Diagramm blieb leer. Als
Modul-Konstante hochgezogen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.12.3
2026-08-27 13:35:43 +02:00
retr0andClaude Sonnet 5 8be3a7eb47 ShineBridge v1.12.2 — Feature: Solarprognose-Diagramm im Energie-Dashboard
Neues 24h-Balkendiagramm direkt unter dem EPEX-Spot-Chart im Energie-Tab,
nach demselben Muster (renderSpotChart als Vorbild) — stündliche Solar-
strahlung (GHI), aktueller Wert hervorgehoben, Balken über der Sonnenschwelle
gelb statt grau. Nur sichtbar, wenn ein Standort gesetzt ist.

/api/weather-forecast liefert jetzt zusätzlich die rohe 24h-Stundenreihe
(hourly: [{ts, ghi}]) fürs Diagramm, nicht nur die Zusammenfassung fürs
Einstellungen-Tab.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.12.2
2026-08-27 13:19:45 +02:00
retr0andClaude Sonnet 5 1ce98df596 ShineBridge v1.12.1 — Feature: Wetterprognose-Vorschau im Einstellungen-Tab
v1.12.0 hat die Prognose nur intern verrechnet, nirgends sichtbar gemacht.
Neuer Endpunkt GET /api/weather-forecast (weather_forecast.summary()) liefert
aktuelle Solarstrahlung (naechste 3h/12h Maximum) + ein Beispiel, wie sich der
Zwangslade-Timeout dadurch gerade veraendern wuerde (Basis: erster konfigurierter
Kathrein-Timeout, sonst 2h-Default). Wird direkt unter den Standort-Feldern
angezeigt, aktualisiert sich nach dem Speichern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.12.1
2026-08-26 16:28:34 +02:00
retr0andClaude Sonnet 5 8f5106e3a0 ShineBridge v1.12.0 — Feature: Prognosebasierter Zwangslade-Timeout (Open-Meteo)
Neuer Standort-Bereich im Einstellungen-Tab (Breitengrad/Längengrad, optional,
site-weit statt pro Gerät). Neues Modul weather_forecast.py fragt Open-Meteos
kostenlose stündliche Solarstrahlungs-Prognose (shortwave_radiation, 48h
voraus, timezone=auto) ab, gecacht alle 3h.

adjusted_timeout_h() passt den Zwangslade-Timeout adaptiv an:
- bald nennenswerte Sonne zu erwarten (naechste 3h) -> Timeout verlaengern
  (x1.75, gedeckelt auf Basiswert+4h)
- auch im 12h-Fenster keine nennenswerte Sonne zu erwarten -> Timeout
  verkuerzen (x0.5, min. 0.5h) statt sinnlos den vollen Timeout abzuwarten
- ohne Standort (lat/lon leer): unveraendertes Verhalten, Feature ist Opt-in

EmsController.update() bekommt einen neuen optionalen timeout_override_h-
Parameter statt selbst Standortdaten zu kennen — Wetter-Logik bleibt im
Poll-Loop, EmsController fokussiert auf die eigentliche Lade-Steuerung.

Auf Sonnenstand-Berechnung bewusst verzichtet — die stuendliche Strahlungs-
prognose bildet Tag/Nacht-Verlauf implizit schon ab, eigene Ephemeriden-
Berechnung waere doppelte Arbeit ohne Mehrwert.

Teil 2 von 2 des 'Prognosebasiertes Laden'-Roadmap-Punkts, damit komplett.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.12.0
2026-08-26 15:57:04 +02:00
retr0andClaude Sonnet 5 202759cc84 ShineBridge v1.11.2 — Feature: PV-Überschuss batteriebewusst berechnen
_get_pv_surplus() zieht jetzt die aktuelle Batterie-Entladeleistung vom
Netzexport ab, bevor er als PV-Überschuss fürs Auto verwendet wird. Verhindert,
dass PV-Überschussladen bei bewölktem Wetter versehentlich den Hausspeicher
anzapft, wenn der Export eigentlich aus der Batterie statt frischer PV-Produktion
kommt. Betrifft nur PV-Überschussladen — Zwangsladen bleibt bewusst unverändert
netzbasiert. Anlagen ohne Batterie (bat_discharge_power fehlt) verhalten sich
unverändert wie zuvor.

Teil 1 von 2 des 'Prognosebasiertes Laden'-Roadmap-Punkts — Teil 2
(Wetterprognose + Sonnenstand) folgt als eigener Schritt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.11.2
2026-08-26 15:41:41 +02:00
retr0andClaude Sonnet 5 0f564a561f ROADMAP: endgültige Root Cause des 6,5-Minuten-Zyklus — Schütz in der Wallbox zog nicht an
Reines Hardware-Problem (Leistungskontakt), Steuerungs-/Kommunikationsebene der
Wallbox lief einwandfrei. ShineBridge zu 100% als Ursache ausgeschlossen.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 15:10:06 +02:00
retr0andClaude Sonnet 5 c524a0189a ROADMAP: 6,5-Minuten-Zyklus live diagnostiziert — kein ShineBridge-Bug
Live-Test 2026-08-26: Wallbox gibt korrekt und stabil 16A/11kW frei, tatsächlicher
Strom/Leistung blieb bei 0 auf allen drei Phasen. Nutzer bestätigt Auto hing in
einem Lade-Loop. ShineBridge/EMS damit endgültig als Ursache ausgeschlossen —
Verhandlungs-/Kompatibilitätsproblem zwischen Kathrein-Wallbox und Fahrzeug.
Discord-Alerts-Punkt damit auch nicht mehr blockiert.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 14:31:27 +02:00
retr0andClaude Sonnet 5 4ff91a2674 ROADMAP: Discord-Alerts bewusst hinter Zyklus-Bug-Fix zurückgestellt
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 12:50:35 +02:00
retr0andClaude Sonnet 5 117a2d2beb ROADMAP: Backup-Verwaltung als erledigt markiert
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 12:27:23 +02:00
retr0andClaude Sonnet 5 b7dc008cd7 ShineBridge v1.11.1 — Feature: Backup-Verwaltung im Einstellungen-Tab
Neue Sektion 'Automatische Backups':
- Aufbewahrung (Tage) konfigurierbar statt hartcodierter 14 Tage
  (config_backup_retention_days, Teil der normalen Config-Persistenz)
- Liste aller vorhandenen Backups (Datum, Größe), neueste zuerst
- Download-Button pro Backup
- Wiederherstellen-Button pro Backup (mit Bestätigungsdialog, da überschreibend)

Backend: Validierung+Anwendung aus /api/import-config in _apply_import_data()
extrahiert, von Datei-Upload und neuem Backup-Restore-Endpunkt gemeinsam
genutzt. Neue Endpunkte GET /api/config-backups, GET .../download,
POST .../restore — mit Path-Traversal-Schutz (_safe_backup_filename, nur
Dateinamen aus dem Backup-Ordner selbst).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.11.1
2026-08-26 12:27:00 +02:00
retr0andClaude Sonnet 5 3318d1344d ShineBridge v1.11.0 — Feature: automatisches tägliches Config-Backup nach /share
Neuer Daemon-Thread (gleiches Muster wie der History-Cleanup-Thread) schreibt
täglich einen Config-Export nach /share/shinebridge-backups/ — bewusst nicht
nach /data, da genau dieser Ordner bei Add-on-Uninstall+Reinstall gelöscht
wird (siehe Vorfall 2026-08-25). Export sofort beim Start plus alle 24h,
14 Tage Aufbewahrung mit automatischem Cleanup alter Dateien.

Export-Datenaufbau aus /api/export-config in _build_export_data() extrahiert,
von Endpoint und Scheduler gemeinsam genutzt. Neue Berechtigung map: share:rw
in config.yaml.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.11.0
2026-08-26 10:52:52 +02:00
retr0andClaude Sonnet 5 c924955be9 ROADMAP: Wallbox-Duplikat-Fund dokumentiert, Punkt 6 zurückgestellt, Auto-Cleanup als neuer Punkt
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 10:47:42 +02:00
retr0andClaude Sonnet 5 89250e16bf ROADMAP: auf v1.9.0+-Stand aktualisiert, neue Roadmap für Energiemanagement-Features
Hardware-/Firmware-Roadmap ist mit dem growatt-diagnose-tool-Split raus. Neue
priorisierte Liste: Wallbox-Duplikat klären, automatischer Config-Export,
Discord-Alerts, Fahrzeug-Sessions, Peak Shaving, Multi-Wallbox-Verteilung,
Prognosebasiertes Laden, Chart-Feintuning.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 10:43:28 +02:00
retr0andClaude Sonnet 5 789e25967a ShineBridge v1.10.3 — Fix: HA-Entity-Anbindung auf Long-Lived Token umgestellt (host_network verhindert SUPERVISOR_TOKEN)
homeassistant_api: true funktioniert nicht, solange host_network: true gesetzt
ist — der Container ist dann nicht im internen Supervisor-Netzwerk und bekommt
keinen SUPERVISOR_TOKEN injiziert (bestätigt per Diagnose-Log: keine TOKEN/
SUPERVISOR/HASSIO-Env-Var im Container vorhanden).

Statt host_network anzufassen (Risiko für Modbus/Goodwe-UDP): HAEntityReader
nutzt jetzt ein normales, manuell in HA erstelltes Long-Lived Access Token
gegen http://localhost:8123/api — funktioniert dank host_network direkt ohne
Umweg über den Supervisor-Proxy. homeassistant_api wieder aus config.yaml
entfernt (unnötig).

Neue Felder im Geräte-Dialog: 'Home Assistant URL' (Default localhost:8123)
und 'Long-Lived Access Token'.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.10.3
2026-08-25 16:26:57 +02:00
retr0andClaude Sonnet 5 1c787349e3 ShineBridge v1.10.2 — Diagnose: Env-Var-Dump wenn SUPERVISOR_TOKEN fehlt
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.10.2
2026-08-25 16:22:34 +02:00
retr0andClaude Sonnet 5 1b78857b3d ShineBridge v1.10.1 — Fix: Config-Import scheiterte an Geräten ohne modbus_ip (ha_entity-Typ)
/api/import-config verlangte bisher zwingend modbus_ip fuer jedes Geraet in der
importierten Config — der neue GROWATT_WIFI_X-Typ (ha_entity) hat aber keins,
nutzt stattdessen ha_entity_prefix. Import schlug dadurch mit 400 fehl, sobald
so ein Geraet enthalten war. Validierung jetzt protokollabhaengig.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.10.1
2026-08-25 16:11:13 +02:00
retr0andClaude Sonnet 5 6f30fe6b1c ShineBridge v1.10.0 — Neuer Geräte-Typ: Growatt ShineWifi-X über bestehende HA-Entity (ESPHome)
Statt selbst per Modbus/UDP zu pollen, kann ShineBridge jetzt einen Wechselrichter
einbinden, der bereits per ESPHome nativ in Home Assistant läuft — nützlich für
die ShineWifi-X-Variante, die keine eigene Modbus-TCP-Schnittstelle hat.

- Neuer ha_entity_client.py: liest Sensor-Werte über die interne Supervisor-API
  (http://supervisor/core/api), braucht dafür 'homeassistant_api: true' in
  config.yaml (neu gesetzt — Add-on muss dafür einmal neu installiert werden)
- Neuer Geräte-Typ 'GROWATT_WIFI_X' in inverters.py, protocol='ha_entity'
- Feste Suffix-Zuordnung (dcpower→pv_power, acpower→ac_power, energytoday→
  energy_today, ...) passend zur esphome-growatt-Komponente aus
  growatt-diagnose-tool/ShineWifi-X — Entity-Id ergibt sich als
  sensor.<prefix>_<suffix>
- Neues Feld 'HA Entity-Prefix' im Geräte-Dialog statt Modbus-IP/Port/Adresse,
  blendet sich abhängig vom gewählten Gerätetyp ein/aus
- Läuft danach durch dieselbe Aggregations-/Dashboard-Logik wie jedes andere
  Gerät (kein Sonderfall in EMS/Finanzen nötig, da Netzbezug bereits über den
  bestehenden Zähler erfasst wird — dieser Wechselrichter liefert nur PV-Werte)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.10.0
2026-08-25 14:28:45 +02:00
retr0andClaude Sonnet 5 9d954d6bd6 ShineBridge v1.9.6 — Beispiel-Diagramm im Leerzustand, Tages-/Wochen-Umschaltung an 14 Wochen geknüpft
- Chart-Logik in buildCostChart() ausgelagert, wiederverwendbar für echte und
  Beispiel-Daten
- Neu: bei Erstinstallation (noch keine echten Daten) zeigt die Finanzen-Seite
  jetzt ein klar als 'BEISPIEL' markiertes, entsättigtes Vorschau-Diagramm mit
  frei erfundenen (deterministischen) Werten statt nur eines Texthinweises —
  keine echt aussehenden Fantasiezahlen, bewusst gedämpfte Farben + Badge
- Umschaltung Tage→Wochen jetzt an 14 Wochen (98 Tage) Historie geknüpft statt
  schon nach 21 Tagen — bis dahin rollierendes Tages-Fenster, danach
  rollierendes Wochen-Fenster (älteste Periode wandert raus sobald neue dazukommt)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.9.6
2026-08-25 14:19:13 +02:00
retr0andClaude Sonnet 5 5b6bed16db ShineBridge v1.9.5 — Finanzen-Chart: Container-Breite gemessen, Periodenanzahl passt sich an statt Balken aufzublasen
Statt die SVG per viewBox unbegrenzt mitwachsen zu lassen (wurde am Desktop
riesig) oder sie bei einer festen max-width zu kappen (ließ rechts Leerraum),
wird jetzt die tatsächliche Container-Breite gemessen und in echten Pixeln
gerendert — Höhe bleibt dabei komplett unabhängig fix.

Zusätzlich: auf breiten Screens werden mehr Wochen gezeigt statt derselben
14 Balken künstlich zu verbreitern (Zielbreite ~24px/Periode, min. 10, max.
28 Perioden) — nutzt den zusätzlichen Platz sinnvoll für mehr Historie statt
für aufgeblähte Einzelbalken.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.9.5
2026-08-25 14:12:45 +02:00
retr0andClaude Sonnet 5 e6422892f3 ShineBridge v1.9.4 — Finanzen-Chart: Obergrenze für Desktop-Breite
width:100% ohne max-width lässt die SVG auf breiten Desktop-Bildschirmen
ungebremst mit dem Container mitwachsen (Text/Balken/Höhe proportional riesig).
max-width:640px begrenzt das, bleibt auf Handy weiterhin voll fluid.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.9.4
2026-08-25 14:07:04 +02:00
retr0andClaude Sonnet 5 608f6bfd42 ShineBridge v1.9.3 — Finanzen-Chart: auf letzte 14 Perioden begrenzt, echt responsiv
- Zeigt nur noch die letzten 14 Balken (statt aller Perioden im Abrechnungsjahr)
  — genug für einen Trend, ohne dass Labels sich gegenseitig überlappen
- SVG jetzt echt responsiv (viewBox + width:100%, Mobile-first dimensioniert)
  statt fester Pixelbreite mit Scrollbalken — passt sich Handy wie Desktop an
- X-Achsen-Labels um -40° gedreht statt horizontal — brauchen dadurch deutlich
  weniger Platz pro Balken, alle 14 bleiben lesbar

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.9.3
2026-08-25 14:02:33 +02:00
retr0andClaude Sonnet 5 722301b1d6 ShineBridge v1.9.2 — Finanzen-Chart modernisiert: Wochen-/2-Wochen-Aggregation, abgerundete Balken, Verlauf
Statt bei langen Abrechnungsjahren jeden einzelnen Tag zu zeigen (bei 112 Tagen
unlesbar), aggregiert der Chart jetzt automatisch:
- ≤21 Tage: täglich (wie bisher)
- 22–180 Tage: wöchentlich (~16 Balken bei einem Jahr)
- >180 Tage: 2-wöchentlich

Zusätzlich: abgerundete Balken mit Farbverlauf statt flacher Füllung, echter
Abstand zwischen Festpreis-/Spot-Balkenpaar statt direkt aneinandergrenzender
Hälften, gestrichelte Gridlines, HTML-Legende mit runden Farbchips statt
SVG-Text-Legende.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.9.2
2026-08-25 13:56:32 +02:00
retr0andClaude Sonnet 5 e9168ee72b ShineBridge v1.9.1 — Fix: Finanzen-Chart bei langen Abrechnungsjahren unlesbar
'Kosten je Tag' quetschte alle Tage in eine feste Breite von 600px — bei 112
Tagen wurden die Balken zu ~1px-Haarlinien. Breite skaliert jetzt mit der
Tagesanzahl (min. 10px Slot/Tag), Chart scrollt bei vielen Tagen horizontal
statt gestaucht zu werden. X-Achsen-Labels richten sich an der tatsächlichen
Balkenbreite aus statt an einer festen Label-Anzahl.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.9.1
2026-08-25 13:52:25 +02:00
retr0andClaude Sonnet 5 e342fff539 README: auf reines Energiemanagement-Repo aktualisiert, Verweis auf growatt-diagnose-tool
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 13:20:57 +02:00
retr0andClaude Sonnet 5 ee404065ce ShineLAN-X, ShineWifi-X und tools/shinediag nach growatt-diagnose-tool verschoben
Konsolidierung aller Hardware-Diagnose/Firmware-Projekte in einem eigenen,
privaten Repo (gitea.bitfire.work/retr0/growatt-diagnose-tool). Dieses Repo
bleibt reines Energiemanagement (ShineBridge).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 13:17:40 +02:00
retr0andClaude Sonnet 5 eb797ed8b7 ShineBridge v1.9.0 — Fokus auf Energiemanagement: Flash/OTA + Setup-Wizard ausgelagert
Repositionierung: ShineBridge macht ab jetzt eine Sache gut (Energiemanagement),
statt alles zu versuchen. Flash/OTA-Firmware-Update fürs ShineLAN-X und der
Ersteinrichtungs-Wizard sind kein Energiemanagement-Feature und wandern ins neue,
eigenständige Projekt 'growatt-diagnose-tool'.

- 4 Flash/OTA-Endpunkte aus main.py entfernt (probe/firmware/update/reboot)
- Flash-Tab, Flash-Panel und zugehöriges CSS/JS aus index.html entfernt
- Setup-Wizard-Overlay entfernt — Geräte werden über '+ Gerät hinzufügen' im
  Geräte-Tab angelegt (Button existierte bereits unabhängig vom Wizard)
- firmware/-Ordner (ShineLAN-X .bin-Dateien) entfernt, liegt jetzt im neuen Repo
- Dockerfile: COPY firmware/ entfernt
- Bugfix dabei gefunden: switchTab() referenzierte noch den entfernten
  'flash'-Tab per Index — hätte die Tab-Reihenfolge durcheinandergebracht

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.9.0
2026-08-25 13:14:12 +02:00
retr0andClaude Sonnet 5 f5ed7c5df6 ShineBridge v1.8.31 — EMS-Fixes: konfigurierbarer Max-Ladestrom, Zwangsladen-Retry, Fault-State-Handling
- ems_max_current_ma konfigurierbar statt hardcoded 32A (Zwangsladen darf jetzt nicht mehr
  mehr fordern als die tatsächliche Wallbox liefern kann, z.B. 16A bei einer 11kW-Wallbox)
- Zwangsladen setzt den Ladestrom bei jedem Poll erneut (statt nur einmal beim Start) —
  ein einzelner fehlgeschlagener Modbus-Write hängt nicht mehr die ganze Nacht
- Unbekannte/Fehler-Ladezustände (z.B. Fahrzeug-Störung) werden nicht mehr wie 'abgesteckt'
  behandelt — Strom wird pausiert, aber der Zwangslade-Timer bleibt erhalten
- Neues Settings-Feld 'Max. Ladestrom (A)' im EMS-Dialog

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
v1.8.31
2026-08-25 12:46:59 +02:00
retr0andClaude Sonnet 4.6 b36b0194f7 ShineBridge v1.8.30 — Ingress-Fix: Flask wieder auf 0.0.0.0
127.0.0.1 brach HAOS Ingress (Proxy kommt von außerhalb localhost).
Sicherheit bleibt gewahrt: kein ports:-Eintrag in config.yaml,
Port 8099 wird nicht ans Host-Netz gemappt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 16:04:15 +02:00
retr0andClaude Sonnet 4.6 04a8fb3125 ShineBridge v1.8.29 — Port 8099 nur auf localhost binden
Flask bindet auf 127.0.0.1 statt 0.0.0.0. Mit host_network: true war Port
8099 direkt vom LAN erreichbar. HAOS-Ingress verbindet sich über localhost,
daher kein Funktionsverlust.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.8.29
2026-05-26 15:23:01 +02:00
retr0andClaude Sonnet 4.6 d9f94d3f28 ShineBridge v1.8.28 — history.py: load_recent Fix + periodisches Cleanup
- load_recent(): Window-Funktion durch pro-Sensor-Indexabfragen ersetzt
  (SELECT ... ORDER BY ts DESC LIMIT N per sensor_id) — nutzt Index optimal,
  kein Full-Table-Scan mehr auf 1M+ Zeilen beim Start
- Periodisches Cleanup: täglich via Daemon-Thread statt nur beim Start —
  DB bleibt dauerhaft auf RETENTION_DAYS beschränkt
- RETENTION_DAYS: 7 → 14 (explizites Maximum per Konfiguration)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.8.28
2026-05-26 13:31:46 +02:00
retr0andClaude Sonnet 4.6 c4047fc804 fix(v1.8.27): Fahrzeugerkennung + Wizard überschreibt Inverterliste
Bug 1 (inverters.py): Kathrein-Register 0x0061-0x0064 existieren nicht —
(0x0060, 10) schlug daher immer mit IllegalAddress fehl, charging_state
wurde nie gelesen → EMS meldete dauerhaft "kein Fahrzeug". Fix: aufgeteilt
in (0x0060, 1) + (0x0065, 6), sodass die Lücke übersprungen wird.

Bug 2 (index.html): wizardStep2Next() postete [neues_gerät] statt
[...invertersList, neues_gerät] → überschrieb die gesamte Inverterliste.
Wenn der Wizard bei einem bestehenden Setup erschien, flogen alle anderen
Geräte raus. Fix: bestehende Geräte werden beibehalten.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 10:58:44 +02:00
retr0andClaude Sonnet 4.6 5564a50c3c fix(ems): Zwangsladen-Countdown läuft ohne angestecktes Auto
Kathrein Reg 0x0060 liefert IllegalAddress wenn kein Fahrzeug angeschlossen.
Default war 1 (STATE_CONNECTED) → EMS nahm Auto als verbunden an → Countdown.

IllegalAddress ist kein sporadischer Lesefehler, sondern das definierte Signal
der Wallbox für "kein Fahrzeug". Default auf 0 (STATE_IDLE) → EMS kehrt sofort
zu "kein Fahrzeug" zurück, _no_pv_since-Timer wird nicht gestartet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 10:12:35 +02:00
retr0andClaude Sonnet 4.6 dc2df891fb fix: TCP-Timeout auf 40% des Poll-Intervalls begrenzt (max. 5s)
Logs zeigen: Bei 10s Poll-Rate + 10s TCP-Timeout läuft ein fehlgeschlagener
Connect exakt so lange wie das Interval. stop.wait() wird 0 → nächster Poll
startet sofort → zweite parallele TCP-Verbindung → Wallbox überfordert → Spirale.

Fix: timeout = min(5.0, interval * 0.4). Bei 15s → 5.0s Timeout; bei 10s → 4.0s.
Ein Fehler belegt max. 40% des Intervalls, der Rest ist Wartezeit vor dem nächsten Versuch.
Gilt für WallboxReader (Kathrein) und ModbusReader (ShineLAN-X / SDM-630).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 10:08:59 +02:00
retr0andClaude Sonnet 4.6 a361c30f1b fix: Offline-Flapping — erst nach 3 aufeinanderfolgenden Lesefehlern offline
Ein einzelner UDP-Paketverlust (Goodwe) oder TCP-Timeout (Modbus) hat sofort
MQTT-Status "offline" getriggert. Bei 10s Poll-Rate reicht ein Ausreißer.

Fix: _fail_count pro Poll-Loop, OFFLINE_THRESHOLD=3. Erst wenn 3 Reads in Folge
scheitern (≥30s bei 10s Interval) wird offline publiziert. Erfolg resettet
den Zähler auf 0 und stellt online sofort wieder her.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 09:58:48 +02:00
retr0andClaude Sonnet 4.6 a9f33c8e9e fix(goodwe): Netzbezug-Periode zeigt 0 kWh — integrierter grid_power-Zähler
e_total_imp vom Goodwe-WR ist ein Lifetime-Zähler seit Inbetriebnahme.
Beim ersten Verbinden speichert save_period_start_if_new() den aktuellen
Wert als Periodenstart → Delta = 0.

Fix: _int_import/_int_export werden je Poll-Zyklus aus grid_power integriert
(W × dt / 3.600.000 → kWh), in der measurements-DB persistiert und
beim Neustart aus der DB wiederhergestellt. AGG_SENSOR_IDS bevorzugt nun
_int_import vor e_total_imp, SDM-630 (import_kwh) bleibt erste Wahl.
Private Keys (Prefix _) werden nicht an MQTT gepublished.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 09:55:24 +02:00
retr0andClaude Sonnet 4.6 512b743b16 Fix: Stromtarif-Einstellungen nach Neustart verloren + Finanzen-Layout (v1.8.22)
State.mqtt_cfg wurde beim Start nur mit 4 MQTT-Keys initialisiert — alle
Tarif/Billing-Keys fehlten, wurden nach Neustart auf Defaults zurückgesetzt.
Fix: alle persistenten Keys aus load_config() in State.mqtt_cfg übernehmen.

Finanzen-Tab: mehr Abstände, größere Karten (22px Wert), Abschnittsüberschriften,
Trennlinie vor dem Chart.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.8.22
2026-05-06 08:26:52 +02:00
retr0andClaude Sonnet 4.6 cb5f23d486 Fix: Finanzen-Tab bleibt bei 'Lade...' hängen (v1.8.21)
fEur/fKwh waren lokale Funktionen in renderEnergy() — loadFinance()
konnte sie nicht aufrufen (ReferenceError außerhalb des Scopes).
Beide Funktionen in den globalen Scope verschoben, lokale Kopien entfernt.
loadFinance() Rendering-Block in try/catch gewrappt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
v1.8.21
2026-05-06 08:18:17 +02:00
retr0andClaude Sonnet 4.6 7904d498b5 v1.8.20: Fix Eigenversorgungskarte + Stromtarif-Einstellungen verloren
Bug 1 — Eigenversorgungskarte verschwindet wenn PV offline:
- savings_kwh wird jetzt gesetzt wenn pv_total vorhanden (grid_exp muss
  nicht mehr explizit vorhanden sein, default 0.0)
- Karte bleibt sichtbar auch wenn Wechselrichter offline geht

Bug 2 — Stromtarif-Einstellungen gehen beim Speichern verloren:
- savePrices(): parseInt mit || 1 Fallback, verhindert NaN → JSON-null
- api_save_config(): None-Checks + try/except für alle numerischen Keys,
  save_config() wird garantiert immer aufgerufen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 07:25:01 +02:00
retr0andClaude Sonnet 4.6 5a00c7b5d3 docs: Roadmap auf v1.8.19 aktualisiert
Alle erledigten Features als [x] markiert, neue Einträge für
Flash-Wizard, NuttX OTA, Setup-Wizard, MQTT rc=5, Port-Sicherheit,
Mobile-Layout. Changelog bis v1.8.19 ergänzt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 21:53:58 +02:00
retr0andClaude Sonnet 4.6 b64bcde203 v1.8.19: Version erhöht
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 21:45:27 +02:00
retr0andClaude Sonnet 4.6 b3f67df967 fix: Mobile-Layout — Tabs scrollen, kein horizontaler Overflow
- html/body: overflow-x: hidden verhindert seitlichen Scroll
- Tabs: overflow-x: auto + white-space: nowrap + flex-shrink: 0
  → horizontal scrollbar-frei auf Handy
- Header: min-width: 0, flex-shrink: 0 für Pill, Text-Overflow
- main: padding 16px statt 20px
- energy-wrap: width: 100%, kwh-card min-width: 0
- @media ≤520px: sensor-grid, settings, header-icon ausgeblendet

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 21:39:59 +02:00
retr0andClaude Sonnet 4.6 e72ad2db19 docs: README auf v1.8.18 aktualisiert
Flash-Wizard, OTA-Abschnitt (Zwei-Phasen), Setup-Wizard, Finanzen-Tab,
Abschlags-Tracker, Port-Sicherheit, Überschuss-Geräte, repo-Struktur.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 21:32:29 +02:00
retr0andClaude Sonnet 4.6 3b3d4055f6 v1.8.18: Version in config.yaml angehoben
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 20:05:07 +02:00
retr0andClaude Sonnet 4.6 15c0ede72e v1.8.18: MQTT rc=5 Fehlerhandling, Port-Absicherung, Flash-Wizard + NuttX OTA
MQTT:
- rc=5 (Not Authorized) stoppt Reconnect-Loop via _auth_failed Flag
- Fehlermeldung im MQTT-Einstellungen-Banner sichtbar

Sicherheit:
- /api/* nur über HAOS-Ingress (X-Ingress-Path) oder Loopback erreichbar

Flash-Wizard (Baustelle B):
- Neuer Tab "Flash" mit IP-Eingabe und OTA-Modus-Erkennung
- OTA: integrierte oder eigene Firmware via POST /api/flash/update auf Stick
- Fortschrittsbalken + Polling bis Stick nach Reset wieder online
- ST-Link-Erstflash-Anleitung (Pinout, st-flash Kommando)
- Firmware-Binaries im Docker-Image unter /firmware/

NuttX OTA (Baustelle A, shinelanx-modbus):
- ota_http.c: Zwei-Phasen OTA für STM32F103 Single-Bank Flash
  Stage 1: Firmware in Staging-Bereich (obere Flashhälfte) schreiben
  Stage 2: .ramfuncs aus SRAM heraus — Staging → App-Bereich kopieren, Reset
- ota_http.h, Makefile und main.c entsprechend erweitert
- ld.script.dfu: .ramfuncs in .data Section → Ausführung aus SRAM

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 19:45:40 +02:00
retr0andClaude Sonnet 4.6 bbfb11fb9c v1.8.17: Atomarer Config-Write + Backup-Fallback
Verhindert Datenverlust wenn HAOS den Container während eines Saves
stoppt. Schreibt erst config.json.tmp, dann atomares os.replace().
Hält config.json.bak als Fallback für den nächsten Start.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 13:40:56 +02:00
retr0andClaude Sonnet 4.6 2456f356b4 v1.8.16: Finanzen-Tab — Festpreis vs. Spot-Vergleich
Täglicher Tarif-Tracking: kWh + EPEX-Ø-Preis werden ab jetzt täglich
gespeichert. Neuer Finanzen-Tab zeigt Balkendiagramm (Festpreis vs.
Spot hypothetisch), Summen-Karten und Empfehlung ob flexibler Tarif
sich lohnen würde.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 13:29:55 +02:00
retr0andClaude Sonnet 4.6 dfb42e6902 v1.8.15: Abschlags-Tracker zeigt ganze Zahlungen statt Bruchmonate
Berechnung auf geleistete Abschlagszahlungen umgestellt:
Anzahl ganzer Monate seit Abrechnungsstart statt Tage/30.4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 13:12:43 +02:00
retr0andClaude Sonnet 4.6 fec49ec4fb v1.8.14: Abschlags-Tracker (monatliche Rate + Grundpreis)
Neues optionales Feature: Abschlags-Übersicht im Energie-Dashboard.
Zeigt Bereits bezahlt, Grundpreis anteilig, Energiekosten sowie
voraussichtliche Nachzahlung oder Guthaben für das laufende Abrechnungsjahr.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 11:45:56 +02:00
retr0andClaude Sonnet 4.6 5ab8ee75fb v1.8.13: Labels + Invertiert-Modus für Überschuss-Geräte
- Beschriftung über jedem Eingabefeld (Name, Z2M Name, Schwellwert, etc.)
- Checkbox "Invertiert": EIN bei Netzbezug, AUS bei Überschuss
- Live-Tab: ↑/↓ Pfeil zeigt normale/invertierte Logik

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1.8.13
2026-05-04 15:12:15 +02:00
retr0andClaude Sonnet 4.6 33ada90df4 v1.8.12: Mindest-Laufzeit pro Überschuss-Gerät
- min_on_minutes pro Gerät: Gerät bleibt mindestens X Minuten an
  auch wenn Überschuss unter Ausschaltschwelle fällt (Boiler-Fix)
- Live-Tab zeigt verbleibende Mindestlaufzeit während Gerät läuft
- get_states() liefert on_minutes für Laufzeit-Tracking

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1.8.12
2026-05-04 12:02:37 +02:00