BiasFandClaude Opus 5 767fe4e798 Ausrichtungs-Assistent fürs Rangieren
Begleitet das Einparken: verfolgt die Neigung über die Zeit, meldet ob es
besser oder schlechter wird, und erinnert an den flachsten Punkt - "vor 4
Sekunden stand das Fahrzeug 0,8 Grad flacher". Bei Erreichen der Toleranz
gibt es eine Vibration, das Display bleibt währenddessen wach.

Bewusst ohne Positionsbestimmung. Aus einem MEMS-Sensor lässt sich keine
brauchbare Strecke ableiten: der Fehler wächst beim zweifachen Integrieren
quadratisch mit der Zeit, und im Schritttempo gehen die tatsächlichen
Beschleunigungen im Rauschen unter. Gebraucht wird sie auch nicht - beim
Einparken lautet die Frage nie "wo stehe ich", sondern "wird es besser".
Das steckt vollständig im zeitlichen Verlauf der Neigung, ohne jede
Annahme über das Gelände. Die vorhandene Verlaufsaufzeichnung war mit
einem Punkt alle fünf Sekunden zu grob; der Assistent führt einen eigenen
Ringpuffer, der nur läuft solange die Ansicht offen ist.

Sind Spurweite und Radstand hinterlegt, kommt die nötige Höhe der
Auffahrkeile dazu. Das ist reine Geometrie und damit exakt. Die Masse
stehen im Fahrzeugprofil.

Dabei fiel auf, dass sich vorhandene Fahrzeuge praktisch nicht bearbeiten
liessen: das ging nur über eine Wischgeste, die niemand findet - erst
recht nicht, wenn dort jetzt die Masse einzutragen sind. Die Zeile hat nun
einen sichtbaren Knopf dafür, wie bei den WLAN-Einstellungen: antippen
wählt aus, das Zeichen daneben öffnet die Bearbeitung.

Ausserdem übernimmt der Assistent den anliegenden Messwert beim Öffnen.
Sonst stand dort bis zur nächsten Messung "Warte auf Messwerte", obwohl
längst welche vorlagen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 15:52:57 +02:00
2026-08-30 10:36:52 +02:00
2026-08-30 14:21:28 +02:00
2026-08-30 14:21:28 +02:00

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)
Batterie-BMS (Bulltron/Daly, WattCycle) GATT-Verbindung, alle 5 s abgefragt SoC, Spannung, Strom, Restkapazität, alle Einzelzellspannungen, Zelldifferenz, Temperaturen, Zyklen, MOSFET-Status
Kompressor-Kühlbox (Alpicool und Baugleiche) GATT-Verbindung, lesen und stellen Ist- und Solltemperatur je Zone, Betriebsart, Kompressorstatus, Bordspannung, Batterieanzeige
Neigungsmesser (VanAlign Pro) GATT-Verbindung Längs- und Querneigung als Libelle, Kalibrierung aus der App

Ein Victron SmartShunt/BMV wird ebenfalls unterstützt, falls später einer dazukommt.

Die Firmware des Neigungsmessers liegt mit im Projekt, siehe firmware/vanalign.

Bauen und installieren

open /Users/fritob/GIT/Camper-Management/CamperMonitor.xcodeproj

Dann in Xcode:

  1. Target CamperMonitorSigning & 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.

Batterie / BMS

Kein Schlüssel nötig. Auswählen, Art auf Batterie / BMS stellen, Sichern. Bulltron-Akkus melden sich meist als DL-…, WattCycle je nach Charge unter eigenem Namen findest du nichts, in der Geräteliste auf Alle umschalten.

Die App probiert drei Protokolle durch und übernimmt, was antwortet:

Dialekt Verbreitung
Daly klassisch (A5) Bulltron und viele Daly-BMS
Daly Modbus (D2) neuere Daly-Firmware
JBD / Xiaoxiang (DD A5) viele LiFePO4-Akkus mit eigener App
WattCycle (1E/7E) WattCycle-Bluetooth-Serie

WattCycle-Akkus verlangen eine Besonderheit: vor der ersten Abfrage muss der Text HiLink auf eine eigene Freischalt-Charakteristik (FFFA) geschrieben werden, sonst bleiben sie auf jede Anfrage stumm. Die App macht das automatisch, sobald ein Gerät diese Charakteristik anbietet. Modell, Hersteller und Seriennummer liest sie einmalig mit aus und zeigt sie in der Detailansicht unter Gerät.

Protokoll und Feldbelegung stammen aus frabnet/esphome-wattcycle-ble; die Prüfsummen-Variante von dort ist gegen den klassischen Modbus-CRC nachgerechnet, die Anfragerahmen sind byteweise in run-tests.sh abgesichert.

Auch die GATT-Charakteristiken werden gesucht statt vorausgesetzt, weil sich die BLE-Module zwischen Herstellern und Chargen unterscheiden. Welches Protokoll erkannt wurde, steht in der Detailansicht unter Diagnose zusammen mit der letzten Rohantwort.

Nur eine App gleichzeitig kann mit dem BMS verbunden sein. Wenn die Hersteller-App offen ist, bekommt Camper Monitor keine Verbindung.

Kühlbox

Die IceCube-Boxen von Plug-in Festivals sind umgelabelte Alpicool-Boxen erkennbar daran, dass der Hersteller die App „Alpicool T-Series“ nennt. Dasselbe Protokoll sprechen auch BrassMonkey und Ocean Comfort.

Beim Einrichten Art auf Kühlbox stellen. Die App meldet sich beim Verbinden selbst an; steht APP im Display der Box, verlangt sie dabei einen Tastendruck am Gerät.

Neben den Messwerten gibt es hier als einzigem Gerät auch Bedienelemente: Ein/Aus, Eco oder Max, Solltemperatur je Zone und die Bedienfeldsperre. Alle Schalter zeigen den Stand, den die Box zurückmeldet nach jedem Stellbefehl wird ihr Zustand neu abgefragt, statt die Eingabe anzunehmen. Das Ausschalten fragt einmal nach, weil dabei die Kühlung stoppt.

Interessant für die Energieübersicht: Die Box misst die Bordspannung und meldet sie mit, was einen Quervergleich zu Batterie und Solarregler erlaubt.

Protokoll und Feldbelegung stammen aus Gruni22/alpicool_ha_ble.

Nivellierung

Der Neigungsmesser VanAlign Pro ist ein ESP32 mit MPU6050, der Längs- und Querneigung über Bluetooth bereitstellt. Er bewirbt seinen Dienst, wird beim Einrichten also sicher erkannt und die Art vorbelegt.

Die Detailansicht zeigt eine Libelle: die Blase wandert dorthin, wo das Fahrzeug höher steht, wie bei einer echten Wasserwaage. Grün heißt eben (bis 0,5°), orange bis zwei Grad, darüber rot. Dazu steht in Worten, welche Seite höher steht.

Vor der ersten Nutzung kalibrieren: Fahrzeug eben stellen, dann Auf aktuelle Lage kalibrieren. Ohne das zeigt die Anzeige die Lage des Sensors, nicht die des Fahrzeugs je nachdem, wie schief er eingebaut ist.

Die Werte werden zweimal je Sekunde abgefragt. Bietet ein Gerät notify an, werden sie stattdessen abonniert die mitgelieferte Firmware tut das allerdings nicht, siehe deren README.

Ob bereits kalibriert wurde, meldet nicht jede Firmware zurück. Fehlt die Angabe, gilt sie als unbekannt und die App warnt nicht eine Warnung, die sich nie abstellen lässt, wäre schlimmer als keine. Kalibrieren aus der App braucht Firmware 1.0.2.

Ausrichtungs-Assistent

Von der Nivellierungs-Ansicht aus erreichbar, gedacht fürs Rangieren. Er verfolgt die Neigung über die Zeit und sagt, ob es gerade besser oder schlechter wird und wo es am besten stand: „Vor 4 Sekunden stand das Fahrzeug 0,8° flacher." Steht der Camper in der Toleranz, meldet das Gerät sich mit einer Vibration; das Display bleibt solange wach.

Bewusst ohne Positionsbestimmung. Aus einem MEMS-Beschleunigungssensor lässt sich keine brauchbare Strecke ableiten, weil der Fehler beim zweifachen Integrieren quadratisch mit der Zeit wächst und die Beschleunigungen im Schritttempo ohnehin im Rauschen untergehen. Gebraucht wird das auch nicht: Beim Einparken lautet die Frage nie „wo stehe ich", sondern „wird es besser". Das steckt vollständig im zeitlichen Verlauf der Neigung ohne jede Annahme über das Gelände.

Sind beim Fahrzeug Spurweite und Radstand hinterlegt, rechnet der Assistent zusätzlich die nötige Höhe der Auffahrkeile aus. Das ist reine Geometrie und damit exakt: 2,0° Querneigung bei 2,00 m Spurweite ergeben 7,0 cm unter die tieferstehende Seite. Die Maße stehen im Fahrzeugprofil, erreichbar über das ⓘ in der Fahrzeugliste.

Mehrere Fahrzeuge

Oben links im Dashboard sitzt der Fahrzeugwechsel. Jedes Profil hat seinen eigenen Gerätesatz; die App scannt und verbindet immer nur für das gewählte Fahrzeug. Über Fahrzeuge verwalten… lassen sich Profile anlegen, umbenennen, mit einem Symbol versehen und löschen. Geräte, die vor der Profilverwaltung eingerichtet wurden, wandern beim Update automatisch ins erste Profil.

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

./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

firmware/vanalign/               Firmware des Neigungsmessers (ESPHome)
├── esp32_ble.yaml               Neigungsmessung und Bluetooth-Schnittstelle
└── experimente/                 Nicht für den Betrieb nötig

CamperMonitor/
├── Models/
│   ├── Profile.swift             Fahrzeug samt Maßen
│   ├── AlignmentAssistant.swift  Verlauf, Tendenz und Keilberechnung
│   ├── 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        Daly-Rahmen und Prüfsummen
│   ├── DalyState.swift           Sammelt Daly-Antworten zu einem Gesamtbild
│   ├── JBDProtocol.swift         JBD/Xiaoxiang, Rahmen und Auswertung
│   ├── WattCycleProtocol.swift   WattCycle, Freischaltung und Auswertung
│   ├── AlpicoolProtocol.swift    Kühlboxen: Auswertung und Stellbefehle
│   ├── VanAlignProtocol.swift    Neigungsmesser: Winkel und Kalibrierung
│   ├── LevelSession.swift        Verbindung zum Neigungsmesser
│   └── BMSSession.swift          GATT-Verbindung, Protokollerkennung, Abfrage
├── 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, Diagnose
    ├── ProfilesView.swift        Fahrzeuge anlegen und verwalten
    ├── FridgeControls.swift      Bedienelemente der Kühlbox
    ├── LevelView.swift           Libelle und Kalibrierung
    ├── AlignmentAssistantView.swift  Ausrichtungs-Assistent fürs Rangieren
    └── 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 und das JBD-Protokoll sind gut dokumentiert; falls dein BMS Modbus spricht und Werte unplausibel aussehen, muss das Mapping in DalyState.apply(registers:) am realen Gerät nachgezogen werden.
  • Die Feldbelegung der BMS-Datensätze ist nicht an jedem Modell geprüft. Meldet die Diagnose dauerhaft „wird ermittelt“, spricht der Akku ein Protokoll, das die App nicht kennt die dort angezeigte Rohantwort ist dann der Ansatzpunkt.
  • 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.
S
Description
No description provided
Readme
5.7 MiB
Languages
Kotlin 50.1%
Swift 49.5%
Shell 0.4%