# Camper Monitor iOS-App, die per Bluetooth LE die Energieanlage im Wohnmobil ausliest: | Gerät | Weg | Was ankommt | |---|---|---| | Victron Ladebooster (Orion-TR Smart / Orion XS) | Instant Readout im Advertisement | Ein-/Ausgangsspannung, beim XS auch Ströme und Ladeleistung, Zustand, Abschaltgrund | | Victron Solarladeregler (SmartSolar MPPT) | Instant Readout im Advertisement | PV-Leistung, Batteriespannung, Ladestrom, Tagesertrag, Laststrom, Ladezustand (Bulk/Absorption/Float) | | Daly BMS (Bulltron) | GATT-Verbindung, alle 5 s abgefragt | SoC, Spannung, Strom, Restkapazität, alle Einzelzellspannungen, Zelldifferenz, Temperaturen, Zyklen, MOSFET-Status | Ein Victron SmartShunt/BMV wird ebenfalls unterstützt, falls später einer dazukommt. ## Bauen und installieren ```bash open /Users/fritob/GIT/Camper-Management/CamperMonitor.xcodeproj ``` Dann in Xcode: 1. Target `CamperMonitor` → **Signing & Capabilities** → dein Apple-Team auswählen. Die Bundle-ID `de.fritob.CamperMonitor` ggf. anpassen, falls sie schon vergeben ist. 2. iPhone per Kabel anschließen, oben als Ziel wählen, ⌘R. Wichtig: **Der Simulator hat kein Bluetooth.** Die App startet dort, findet aber nie ein Gerät. Zum Testen muss sie auf ein echtes iPhone. Mit einem kostenlosen Apple-Account läuft die App 7 Tage und muss dann neu installiert werden; mit einem bezahlten Developer-Account ein Jahr. ## Einrichtung in der App ### Victron-Geräte Victron-Geräte senden ihre Messwerte etwa im Sekundentakt verschlüsselt im BLE-Advertisement. Es wird nichts verbunden und nichts gestört – VictronConnect kann parallel laufen. Dafür brauchst du pro Gerät einmalig den Schlüssel: 1. VictronConnect öffnen, Gerät anwählen 2. Zahnrad (Einstellungen) → ⋮ oben rechts → **Produkt-Info** 3. **Instant Readout** einschalten 4. **Verschlüsselungsdaten anzeigen** → der Schlüssel sind 32 Hex-Zeichen In der App: **+** → Gerät aus der Liste wählen (Victron-Geräte werden erkannt und die Art vorausgefüllt) → Schlüssel einfügen → Sichern. Der Schlüssel liegt in der iOS-Keychain, nicht in den UserDefaults. #### Wenn „Schlüssel passt nicht" erscheint Victron sendet das erste Byte des Schlüssels unverschlüsselt mit, damit sich ein falscher Schlüssel sofort erkennen lässt. Die Detailansicht des Geräts hat dafür den Abschnitt **Diagnose**: * *Gerät sendet als erstes Schlüsselbyte* – was das Gerät erwartet * *Eingetragener Schlüssel beginnt mit* – was in der App steht Stimmen die beiden nicht überein, gehört der Schlüssel zu einem anderen Gerät. Bei mehreren Victron-Geräten ist das die mit Abstand häufigste Ursache: In VictronConnect prüfen, dass wirklich dieses Gerät geöffnet war, als der Schlüssel angezeigt wurde. Die Diagnose zeigt außerdem Produkt-ID, Datensatztyp und die Rohdaten des Advertisements – letztere lassen sich durch langes Antippen kopieren. ### Daly BMS Kein Schlüssel nötig. In der Liste erscheint das BLE-Modul meist als `DL-…`. Auswählen, Art auf **Batterie / BMS** stellen, Sichern. Die App erkennt selbst, ob das BMS das klassische `A5`-Protokoll oder das neuere Modbus-Protokoll (`D2`) spricht, und sucht die passenden GATT- Charakteristiken automatisch – die BLE-Module unterscheiden sich zwischen Fertigungschargen. Nur **eine** App gleichzeitig kann mit dem BMS verbunden sein. Wenn die Bulltron-/Daly-App offen ist, bekommt Camper Monitor keine Verbindung. ## Ohne Fahrzeug ansehen Ein Demo-Modus füllt die App mit erfundenen Werten, damit sich die Ansichten ohne Bluetooth prüfen lassen. In Xcode unter *Product → Scheme → Edit Scheme → Run → Arguments* die Umgebungsvariable `CAMPER_DEMO` auf `1` setzen. Er greift nur in Debug-Builds. ## Protokolle prüfen ```bash ./run-tests.sh ``` Prüft die Entschlüsselung und die Rahmenverarbeitung ohne Hardware und ohne Simulator – unter anderem AES-CTR gegen den Referenzvektor aus NIST SP 800-38A und die Prüfsummen beider Daly-Dialekte. ## Aufbau ``` CamperMonitor/ ├── Models/ │ ├── ConfiguredDevice.swift Eingerichtetes Gerät, Rolle, Transportart │ ├── DeviceSnapshot.swift Messwerte in Anzeigeform │ └── VictronCodes.swift Klartexte für Zustands-/Fehlercodes ├── Bluetooth/ │ ├── BluetoothManager.swift Zentraler Scan, Verbindungen, Verlauf │ ├── VictronAdvertisement.swift Advertisement entschlüsseln und auswerten │ ├── AESCounterMode.swift AES-128-CTR (CommonCrypto) │ ├── BitReader.swift Bitweises Lesen der gepackten Felder │ ├── DalyProtocol.swift Rahmenbau und Prüfsummen beider Dialekte │ ├── DalyState.swift Sammelt Antworten zu einem Gesamtbild │ └── DalySession.swift GATT-Verbindung und Abfragezyklus ├── Store/ │ ├── DeviceStore.swift Geräteliste, Persistenz │ └── KeychainStore.swift Victron-Schlüssel └── Views/ ├── DashboardView.swift Kachelübersicht ├── DeviceCard.swift Eine Kachel ├── DeviceDetailView.swift Alle Werte, Verlauf, Zellspannungen └── AddDeviceView.swift Scannen und Einrichten ``` ## Bekannte Grenzen * **Kein Hintergrundbetrieb.** iOS erlaubt das ungefilterte Scannen nach Advertisements nur im Vordergrund. Die App pausiert, sobald sie in den Hintergrund geht, und nimmt beim Zurückkommen wieder auf. * **Das Modbus-Registerlayout des neuen Daly-Protokolls variiert zwischen Firmwareständen.** Das klassische `A5`-Protokoll ist gut dokumentiert und sicher; falls dein BMS Modbus spricht und Werte unplausibel aussehen, muss das Mapping in `DalyState.apply(registers:)` am realen Gerät nachgezogen werden. * Die Feldbelegungen der Victron-Datensätze stammen aus Victrons „Extra Manufacturer Data“-Beschreibung. Solarladeregler und DC/DC-Wandler sind die am besten belegten Typen. * Die Bluetooth-Kennung eines Geräts ist pro iPhone eindeutig. Auf einem zweiten Gerät müssen die Geräte neu eingerichtet werden.