Files

119 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Gemini-Delegator Memory
## Bug-Patterns
### State-Initialisierung bei Scan-Start
**Problem identifiziert:** In BleScanner wurde `PositionCalculator` nur beim `startScanning()` initialisiert. Config-Änderungen während eines laufenden Scans wurden nicht übernommen.
**Lösung:** Extrahiere Initialisierungs-Logik in separate Methode (`initializePositionCalculator()`), biete öffentliche `reloadConfig()` Methode an. UI ruft diese nach Config-Änderung auf.
**Pattern:** Bei Langlebigen Objekten (Scanner) die State von kurzlebiger Config abhängt → Reload-Mechanismus vorsehen.
### KeyboardType für negative Zahlen
**Problem:** `KeyboardType.Decimal` und `KeyboardType.Number` erlauben in Android Compose **kein Minuszeichen**.
**Lösung:** `KeyboardType.Text` für Felder verwenden, die negative Werte akzeptieren müssen (Koordinaten, RSSI). Validierung via `toDoubleOrNull()` bleibt bestehen.
**Betroffene Felder:** Beacon-Koordinaten (X/Y), Raum-Positionen (X/Y), RSSI-Werte (immer negativ).
## Hardware-Debugging
### BLE-Unsichtbarkeit (ESP32 + Android)
**Problem:** Ein spezifischer ESP32-C3 wird auf einem spezifischen Android-Handy NICHT gefunden (auch nicht mit nRF Connect), auf anderen Handys aber schon. Andere ESP32s funktionieren auf dem problematischen Handy.
**Ursache (wahrscheinlich):** MAC-Adress-Kollision oder Android BLE-Controller-Blacklisting auf Hardware-Level.
**Diagnose-Schritte:**
1. Original BLE-MAC auslesen (`esp_bt_dev_get_address()` nach `BLEDevice::init()`)
2. Mit MAC auf funktionierendem Handy (nRF Connect) vergleichen
3. Custom-MAC setzen via `esp_base_mac_addr_set()` **VOR** `BLEDevice::init()`
**Lösung:** Custom-MAC flashen mit locally administered Address (Byte 0 = `0x02`), eindeutige Werte wählen.
**Code-Pattern (ESP32):**
```cpp
#include "esp_bt_device.h" // Für MAC-Ausgabe
#include "esp_mac.h" // Für MAC-Setzen
uint8_t custom_mac[6] = {0x02, 0xAA, 0xBB, 0xCC, 0xDD, 0x05};
esp_base_mac_addr_set(custom_mac); // VOR BLEDevice::init()
BLEDevice::init("Name");
const uint8_t* ble_mac = esp_bt_dev_get_address(); // Ausgeben
```
**Quellen:** [Random Nerd Tutorials](https://randomnerdtutorials.com/get-change-esp32-esp8266-mac-address-arduino/), [Nordic DevZone BLE Invisibility](https://devzone.nordicsemi.com/f/nordic-q-a/77366/nrf-ble-android---my-blescannercompat-doesn-t-detect-a-device-but-nrf-connect-does)
## Projekt-Spezifisches
### BLE Indoor Positioning App
- **Aktive Version:** `/App v2/` (vorher `/App v1_2/`)
- **Config-Persistierung:** SharedPreferences via `ConfigRepository`
- **Datenfluss:** ConfigRepository → BleScanner → PositionCalculator → UI
- **Keine DI:** Direkte Instanziierung, StateFlow für Reaktivität
- **Sprache:** Kotlin, Compose UI, Kommentare auf Deutsch
- **Koordinaten:** Beliebige Werte möglich (auch negativ) – Bounding Box wird aus Räumen + Beacons berechnet
### Kritische Klassen
- `BleScanner`: Zentrale BLE-Logik, verwaltet Scanner, Filter, Calculator, Smoother
- `PositionCalculator`: Trilateration (IDW + Gauss-Newton + Blending)
- `ConfigRepository`: Lädt/Speichert AppConfig (Raumgröße + Beacon-Positionen)
- `BeaconFilterManager`: Verwaltet RSSI-Filter pro Beacon (Kalman/EMA/MA)
### Häufige Fehlerquellen
- Config-Änderungen während laufender Operationen
- Initialisierung nur bei Start ohne Reload-Mechanismus
- Fehlende Synchronisation zwischen UI-State und Scanner-State
### Config-Modell Pattern (erweitert)
**Gelernt bei:** Individuelle pathLossExponent + rssiAtOneMeter pro Beacon
- `@Serializable data class` mit Default-Werten → Abwärtskompatibilität (alte Configs ohne neue Felder laden mit Defaults)
- Neue Felder in **beiden** Dialogen:
- **AddBeaconDialog:** Neue Beacons (Default-Werte vorbelegen: `mutableStateOf("5.5")`)
- **EditBeaconDialog:** Bearbeitung (beacon.field.toString() initialisieren)
- Config-Anzeige: LazyColumn erweitern (neue Felder anzeigen)
- Beacon-Liste klickbar: `.clickable { showEditBeaconDialog = beacon }`
- Berechnungs-Methoden: Per-Beacon-Lookup mit Fallback → `beacons.find { it.minor == beaconMinor }?.field ?: globalDefault`
## Gemini-Interaktion
### Rate Limits
Gemini: 429 RESOURCE_EXHAUSTED möglich, liefert oft trotzdem Ergebnisse nach Retries (am Ende der Ausgabe).
### Gemini Prompt Best Practices
- Kontext vollständig angeben (relevante Code-Ausschnitte mit Line-Nummern)
- Aufgabe strukturiert (nummeriert), Dateipfade explizit
- Output-Format: "OUTPUT ONLY unified diff, no explanations"
### Wann selbst fixen vs. Gemini
- **Selbst:** Klare Anforderung, minimale Änderung (z.B. KeyboardType-Wechsel)
- **Gemini:** Große Refactorings, komplexe Algorithmen
- **Nach Gemini:** IMMER fachlich prüfen (Typ, Logik, Patterns)
### Gemini Fehler-Pattern
**Problem:** Gemini generiert Diffs mit falschen Annahmen über Datenstrukturen
- **Beispiel (2026-02-10):** Negative Koordinaten – Gemini verwendete `.corners` (nicht existent) statt `.x/.y/.width/.height`
- **Lösung:** Bei strukturellen Änderungen (Datenmodell, API) relevante Klassen vollständig in Prompt inkludieren
- **Warnung:** Gemini erfindet manchmal Pfade (`com.example` statt `com.erik`) → Diff-Pfade immer prüfen
### Color-Parameter in @Composable mit Canvas (2026-02-10)
**Problem:** Gemini versuchte `beaconColor: Color = MaterialTheme.colorScheme.primary` als Default-Parameter in Funktionssignatur zu setzen – funktioniert NICHT, da kein @Composable-Context in Parameter-Defaults verfügbar ist.
**Lösung:** Color-Parameter MIT Defaults direkt in der @Composable-Funktion deklarieren (wo MaterialTheme verfügbar ist). Bei Helper-Funktionen (z.B. drawRooms) Parameter ohne Defaults durchreichen.
**Korrektur:** Nach Gemini-Output selbst gefixt – Color-Parameter in FloorplanView mit MaterialTheme-Defaults versehen, drawRooms()-Signatur manuell erweitert.
### Material Icons Verfügbarkeit (2026-02-10)
**Problem:** Gemini generiert oft nicht-existierende Material Icons (z.B. `DarkMode`, `LightMode`, `Brightness4`, `Brightness7`, `Nightlight`, `WbSunny`).
**Lösung:** Nach Gemini-Output IMMER Icon-Verfügbarkeit prüfen:
- Nur Icons aus `Icons.Default.*` verwenden, die in bestehenden Dateien bereits verwendet werden (z.B. `Settings`, `Place`, `Info`)
- Falls spezielle Icons benötigt werden: Im Projekt nach verwendeten Icons greppen (`Icons\.Default\.`)
- Fallback: Generische Icons wie `Info`, `Check`, `Star` verwenden
**Warnung:** `Icons.Outlined`/`Icons.Filled` sind oft nicht vollständig in älteren Material Icons Versionen verfügbar.
### remember() außerhalb @Composable (2026-02-10)
**Problem:** Gemini verwendete `var isDarkMode by remember { mutableStateOf(...) }` in `MainActivity.onCreate()` – `remember` funktioniert NICHT außerhalb von `@Composable` Funktionen.
**Lösung:** Direkt `mutableStateOf()` als Property verwenden (`private var isDarkMode by mutableStateOf(false)`) oder `rememberSaveable` INNERHALB `setContent { }` Block nutzen.