Skip to content

Latest commit

 

History

History
180 lines (141 loc) · 11.7 KB

File metadata and controls

180 lines (141 loc) · 11.7 KB

Vibe Coding & Projekt-Handoff

Dieses Dokument ist die Übergabe: Es soll jeder KI (oder jedem Menschen) ermöglichen, GROWCTRL von genau diesem Stand aus weiterzuentwickeln – ohne Vorwissen aus früheren Sitzungen. Architektur, Repos, Bau-/Testbefehle, Konventionen, aktueller Stand und Roadmap stehen hier kompakt beisammen.

GROWCTRL ist „Vibe Coding" – iterativ entworfen und gebaut im Dialog zwischen MrDarkvoid und Claude (Anthropic). Statt eines starren Pflichtenhefts entsteht das System Schritt für Schritt: Idee → Vorschau/Beschreibung → Freigabe → Code → Testlauf → nächster Schritt.


1. Arbeitsweise (verbindlich)

  • Design zuerst: erst Vorschau/Beschreibung einer Änderung, dann Code.
  • Maximale Sorgfalt: jeden Schritt kontrollieren, Zustände und Fehlerfälle durchdenken, Sinnhaftigkeit prüfen, Testläufe gehören dazu (Typecheck, Build, pytest, Syntax).
  • Deutsch als Projekt- und Dokumentationssprache. Die Oberfläche zeigt DE/EN je nach Home-Assistant-Sprache (i18n in cards/core/i18n.ts + loglang.ts, Integration via strings.json/translations).
  • Knappe, präzise Antworten; Karten-Render ist nicht sichtbar → Änderungen deterministisch halten.

2. Die drei Repositories

Repo (GitHub) Arbeitsordner Inhalt
MrDarkvoid/growctrl /home/claude/growctrl Integration (Python, HA) + Karten-Quelle unter cards/ + docs/ + Tests + legacy/
MrDarkvoid/growctrl-cards /home/claude/growctrl-cards-repo Karten-Distribution für HACS: gebautes growctrl-cards.js + README/CHANGELOG/LICENSE/hacs.json/Logo
MrDarkvoid/growctrl-esp /home/claude/growctrl-esp-repo ESPHome-Firmware (Sensorik/Aktorik). In der v4-Linie unverändert.

Das Karten-Bundle wird im Integration-Repo gebaut (cards/) und die fertige Datei ins Distributions-Repo kopiert (siehe §4).

3. Architektur

Integration (custom_components/growctrl/, 17 Module):

  • const.py (Domain, Konfig-Schlüssel, STAGES, Klima-Defaults), config_flow.py (Zelt/Station + OptionsFlow), runtime.py (Laufzeit-State je Entry, abgeleitete Werte aus Preset), controller.py (1-min-Loops: Licht inkl. geteiltem Licht/Votes, Pumpe, Heizung, Klima, DLI, Failsafes), logic.py (reine Funktionen: Lichtfenster, Pumpzyklus, Phasen-Empfehlung, effective_climate_phase, Schutzfunktionen), presets.py (17 Pflanzen × System × Phase → pH/EC/DLI + Klima-Ziel je Phase), sensor.py/ binary_sensor.py/switch.py/number.py/select.py/date.py/time.py/button.py/todo.py (Entities; select.py = Phase + Klima-Phase, number.py u.a. die 16 Klima-Sollwerte, button.py = „Keimstart zurücksetzen"), entity.py (Basis + SIGNAL_UPDATE), __init__.py (Setup/Plattformen, lädt growctrl/plants.yaml|json und stellt den Dienst reload_plants bereit).
  • Eine Station = eine Pflanze. Pflanzenart = Select (nur DWC/Erde), Keimdatum = ein Date-Helfer.
  • Datenbus: Der „Letztes-Ereignis"-Sensor trägt Attribute (gc_sensors, gc_ph_bereich, gc_ec_bereich, gc_dli_ziel, gc_phase, verlauf, schweregrad) – die Karten lesen daraus.
  • Zelt-Gate: „Zelt aktiv" aus → alle Stationen schalten ab. Heizungs-Zwangssperre bei Gate aus / Automatik aus / Wartung / Phase Aus. Geteiltes Licht via ODER-Votes.

Karten (cards/, TypeScript + lit, gebündelt mit esbuild über bundle.ts):

  • core/ – Fundament: id.ts (deterministische Entity-IDs), registry.ts/resolver.ts (robuste Auflösung über growctrl_*-Attribute), data.ts (fetchHistory/sparkline), base-card.ts, editor-base.ts (SEL.*, styleSection, Paletten), theme.ts (CSS-Vars, cardVars, PALETTES/paletteVars, STAGE_COLORS), format.ts/i18n.ts/chart.ts.
  • Karten: station/, checkup/, controls/, tent/, hero/, status/, sensors/, history/, metric/, tank/ (je card.ts + editor.ts).
  • Entity-IDs: <domain>.growctrl_<slug(zelt)>_<slug(station)>_<name-slug>; Zelt-Entities <domain>.growctrl_zelt_<slug(zelt)>_<name-slug>. Abweichungen per YAML overrides:.

4. Bauen & Testen

# Karten: Typecheck + Bundle, dann ins Distributions-Repo kopieren
cd /home/claude/growctrl/cards
npx tsc --noEmit && npm run build            # -> dist/growctrl-cards.js
cp dist/growctrl-cards.js /home/claude/growctrl-cards-repo/growctrl-cards.js

# Integration: Tests + Syntax
cd /home/claude/growctrl
python3 -m pytest tests/ -q                  # aktuell: 76 passed
python3 -c "import ast,pathlib; [ast.parse(p.read_text()) for p in sorted(pathlib.Path('custom_components/growctrl').glob('*.py'))]"

tests/test_controller.py fährt den Regelzyklus mit einem Fake-Home-Assistant durch 16 Sicherheitsszenarien (beide Licht-Failsafes, Handschaltung, Gate, geteiltes Licht, Phase „Aus", Trockenlauf, Sensor-Stale, Klima-aus→Heizer-aus, Taupunkt, CO2). Ein „defektes Relais" reagiert trotz Schaltbefehl nicht → der Failsafe wird real geprüft. Neue Schutz-/Regel-Logik dort absichern – AST und Import-Smoke-Test fangen keine undefinierten Namen im Laufzeitpfad (so wurde der LIGHT_SWITCH_GRACE_S-Crash gefunden).

tsconfig prüft core/ tent/ station/ controls/ sensors/ status/ checkup/ bundle.ts (strict). esbuild bündelt alles über bundle.ts.

Release-Pakete (nach erfolgreichem Build + Tests + Marker-Prüfung) – <version> einsetzen. Integration und Karten werden versionsgleich gehalten; ändert sich nur eine Seite, wird nur deren Paket neu gebaut, die Versionen aber wieder angeglichen, sobald die andere Seite das nächste Mal anfasst.

cd /home/claude
zip -rq /mnt/user-data/outputs/growctrl-<version>.zip growctrl \
  -x "growctrl/cards/node_modules/*" -x "growctrl/cards/package-lock.json" \
  -x "*__pycache__*" -x "*.pytest_cache*" -x "*/.git/*" -x "*.DS_Store"
zip -rq /mnt/user-data/outputs/growctrl-cards-<version>.zip growctrl-cards-repo \
  -x "*/.git/*" -x "*.DS_Store"

Reihenfolge beachten: ein rm growctrl-*.zip trifft auch das Karten-ZIP – daher Integrations-ZIP zuerst (mit dessen rm), dann das Karten-ZIP (rm growctrl-cards-*.zip).

Abnahme-Checkliste vor Auslieferung: tsc fehlerfrei · npm run build ok · Bundle-Marker in erwarteter Anzahl · pytest grün · alle Module per AST parsebar · Doku marker-frei · Versionen einheitlich (manifest.json, package.json, bundle.ts, Modul-Header).

5. Konventionen

  • Versionen synchron halten: manifest.json, cards/package.json, cards/bundle.ts (VERSION) und alle Modul-Header. Lizenz überall GC-SAL 1.0 (auch package.json license).
  • manifest.json-Schlüssel exakt sortieren: domain, name, danach alphabetisch (hassfest besteht darauf).
  • Attribution-Header in jeder Datei: „MrDarkvoid – entwickelt in Zusammenarbeit mit Claude (Anthropic), Vibe Coding".
  • Integritäts-Marker: Im Quellcode (core/chart.ts, core/registry.ts, const.py) und im gebauten Bundle stehen unscheinbare Echtheits-/Lizenz-Marker. Sie dürfen niemals aus dem Code entfernt oder verändert und niemals in Dokumentation/README/LICENSE übernommen werden. Nach jedem Build muss das Bundle die Marker in der erwarteten Anzahl enthalten – das ist Teil der Abnahme (Build-Skript/Review prüfen das).
  • Sicherheit vor Komfort: Trockenlauf-, Übertemperatur-, Sensor-Guard und Heizungs-Sperre haben Vorrang. Das System schaltet Pumpen/Licht/Heizung – die Verantwortung für eine sichere Installation liegt beim Betreiber.

6. Aktueller Stand (Version 4.14.1)

Der Umbau „Station = Pflanze" ist abgeschlossen; darauf wurde seither viel aufgebaut. Kernstand:

Klima pro Phase (zeltweit) – zwei Betriebsarten (Option „Klima automatisch aus Pflanzen" beim Anlegen):

  • Automatik: Sollband je Zyklus aus den Stationen (Pflanze × aktuelle Phase → hinterlegtes Klima-Ziel), über alle aktiven Stationen gleichgewichtet gemittelt (Stationen auf „Aus" zählen nicht). Drei Ziel-Sensoren (Ziel VPD, Ziel RH, bei Heizung Ziel Temp) zeigen das Band; die „Klima-Phase" steht fest auf Auto (ClimatePhaseSelect erzwingt das).
  • Manuell: 16 Sollwert-Zahlen je Zelt (VPD/RH Min/Max für Seedling/Veg/Bloom/Trocknung; Flush erbt Bloom), „Klima-Phase" wählbar (Auto folgt der führenden Station, oder feste Phase).
  • Der VPD-Sensor legt phase_effektiv, sollwerte und klima_auto als Attribute offen.

Pflanzen-Preset + eigene Kulturen: 17 Kulturen × System × Phase → pH/EC/DLI und Klima-Ziel je Phase. Eigene Sorten ohne Code via growctrl/plants.yaml (oder .json, Vorlage examples/plants.example.yaml)

  • Dienst growctrl.reload_plants. So heißt eine Station z.B. „Apple Fritter", die Pflanze bleibt „Cannabis".

Manuelle Übernahme (Handschalter): zwei aufeinanderfolgende Zyklen Ist ≠ Soll erkennen einen manuellen Eingriff; konfigurierbare „Manuelle Übernahme"-Dauer (Standard 60 min, 0 = sofort zurück), danach automatischer Wiederanlauf des Lichtplans. Geteilte Lichter tragen den Handzustand durch die ODER-Votes.

Lux/DLI auf Stationsebene mit phasenabhängiger Prognose aus dem Lichtplan der Station.

Wartungsmodus deckt den früheren „Testmodus" mit ab (Testmodus entfernt).

Karten – integrations-nativ: core/id.ts leitet alle IDs deterministisch aus Zelt-/Stationsnamen ab (overrides: als Ausweg). Station/Tent/Hero/Status/CheckUp sind eigenständige Karten. Aktoren, Sensorwerte, Protokoll und Aufgaben sind klappbare Bereiche (Protokoll standardmäßig zu). Die Stations-Kopfzeile zeigt Titel + Buttons in einer Zeile und darunter „Pflanze · Leistung · Status" über die volle Breite. Trendpfeile reagieren auf ein kurzes jüngstes Zeitfenster; Chart-Zeitachsen skalieren mit der Stundenzahl. Im Klima-Automatik-Modus ist das Phasen-Dropdown der Zelt-Karte gesperrt (zeigt „Automatik" mit Schloss). Hero-Logo/Bild + optionaler Livestream je Station; „Standard an"-Schalter im Editor spiegeln den echten Default.

Robustheit: Zelt-Gate, Heizungs-Zwangssperre, Trockenlauf-/Übertemperatur-/Sensor-Guard, Watchdog-Heartbeat, Leistungs-Plausibilität – Details in informationssystem.md.

Licht-Failsafe zweistufig (seit 4.13.0): zusätzlich zum Über-Beleuchtungs-Not-Aus prüft ein Schaltzeit-Failsafe an jedem geplanten Schaltpunkt, ob das Licht folgt; bleibt es ~2 Zyklen (110 s) hängen → Fehler + erneuter Schaltbefehl, Erholung automatisch. Vorrang: Über-Beleuchtung › Handschaltung › Schaltzeit-Failsafe.

Taupunkt-/Schimmel-Warnung (seit 4.13.0): kühle Blattoberfläche nahe Taupunkt → Warnung (reine Warnung, kein Eingriff); taupunkt/schimmelrisiko als VPD-Attribute.

CO2 (seit 4.14.0): optionaler CO2-Sensor je Zelt (OptionsFlow) + Warnung „CO2 hoch" über Schwelle; co2/co2_status als VPD-Attribute. Bewusst nur Messung + Warnung, keine Dosierung/Steuerung (keine CO2-Hardware).

Szenario-/Sicherheits-Tests (seit 4.14.1): tests/test_controller.py mit Fake-HA-Harness deckt 16 Schutz-Szenarien ab; fand dabei einen Crash-Bug im Verifikations-Pfad. Pflicht: neue Schutz-/Regel-Logik mit einem Szenario-Test absichern.

i18n vollständig (Deutsch ist Quelle, Englisch additiv). hassfest grün; manifest.json korrekt sortiert.

7. Roadmap

Die laufend gepflegte Liste (Erledigt vs. Offen) steht im Roadmap-Abschnitt von informationssystem.md. Bewusst nicht geplant: CO2-Dosierung/-Regelung (keine CO2-Anreicherungshardware – CO2 bleibt reine Messung + Warnung).


GROWCTRL · GC-SAL 1.0 · MrDarkvoid – Vibe Coding mit Claude (Anthropic).