first commit
This commit is contained in:
@@ -0,0 +1,494 @@
|
||||
# VanControl Pro
|
||||
|
||||
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.
|
||||
|
||||
Dazu gehört eine **Apple-Watch-App**: Übersicht, Nivellierung samt
|
||||
Ausrichtungs-Assistent mit Vibration und die Steuerung der Kühlbox am
|
||||
Handgelenk. Den Neigungsmesser funkt die Uhr selbst an, alles Übrige kommt
|
||||
über das iPhone – warum diese Aufteilung, steht unter
|
||||
[Apple Watch](#apple-watch).
|
||||
|
||||
Die Firmware des Neigungsmessers liegt mit im Projekt, siehe
|
||||
[firmware/vanalign](firmware/vanalign/README.md).
|
||||
|
||||
## 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.
|
||||
Dasselbe beim Target `CamperMonitorWatch`; dessen Bundle-ID muss die des
|
||||
iPhones mit angehängtem `.watchkitapp` bleiben.
|
||||
2. iPhone per Kabel anschließen, oben als Ziel wählen, ⌘R.
|
||||
|
||||
Das Schema `CamperMonitor` baut die Watch-App mit und bettet sie ein. Dafür
|
||||
muss die watchOS-Plattform in Xcode installiert sein – sonst bricht schon das
|
||||
Übersetzen des Symbolkatalogs ab:
|
||||
|
||||
```bash
|
||||
xcodebuild -downloadPlatform watchOS
|
||||
```
|
||||
|
||||
Auf die Uhr kommt die App danach von selbst: Sie steckt in der iPhone-App und
|
||||
taucht in der Watch-App des iPhones unter *Verfügbare Apps* auf.
|
||||
|
||||
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](https://github.com/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 VanControl Pro 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.
|
||||
|
||||
**Verbunden wird nur, während die Kühlbox geöffnet ist.** Jede Verbindung
|
||||
meldet sich an ihrem Display an und stört, wer gerade davorsteht; und ihre Werte
|
||||
ändern sich langsam. Auf der Übersicht steht deshalb nicht die gemessene
|
||||
Innentemperatur, sondern der **zuletzt gestellte Stand** – Sollwert, Ein/Aus,
|
||||
Eco oder Max, dazu wann er gestellt wurde. Der bleibt richtig, auch wenn er von
|
||||
gestern ist: Ein Sollwert ändert sich nur, wenn jemand ihn ändert. Eine
|
||||
Innentemperatur von gestern sähe dagegen aus wie eine von jetzt.
|
||||
|
||||
Sobald du die Box öffnest, verbindet die App sich und zeigt alles live; beim
|
||||
Verlassen der Ansicht trennt sie wieder. Dasselbe gilt für die Uhr: Auch von
|
||||
dort wird die Verbindung nur angefordert, solange die Kühlbox-Ansicht offen ist.
|
||||
Ein Stellbefehl geht ebenfalls immer durch – ist die Box gerade nicht verbunden,
|
||||
wird er gemerkt und geht raus, sobald sie antwortet.
|
||||
|
||||
BMS und Neigungsmesser bleiben dagegen dauerhaft verbunden. Sie stören dabei
|
||||
nicht, und ihre Werte will man laufend sehen.
|
||||
|
||||
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](https://github.com/Gruni22/alpicool_ha_ble).
|
||||
|
||||
### Nivellierung
|
||||
|
||||
Der Neigungsmesser [VanAlign Pro](https://github.com/) 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 bietet zwei Darstellungen, umschaltbar und über Starts
|
||||
hinweg gemerkt:
|
||||
|
||||
* **Libelle** – die Blase wandert dorthin, wo das Fahrzeug höher steht, wie bei
|
||||
einer echten Wasserwaage. Ringe markieren Toleranz und zwei Grad.
|
||||
* **Fahrzeug** – Seitenansicht für längs, Heckansicht für quer, beide gekippt.
|
||||
Die Heckansicht teilt die Blickrichtung des Fahrers, links im Bild ist also
|
||||
links am Fahrzeug. Die Neigung ist dreifach überhöht dargestellt, sonst wäre
|
||||
sie bei zwei Grad kaum zu erkennen; die angezeigten Gradzahlen sind echt.
|
||||
|
||||
In beiden Fällen: grün heißt eben (bis 0,5°), orange bis zwei Grad, darüber
|
||||
rot. Dazu steht in Worten, welche Seite höher steht.
|
||||
|
||||
Die Fahrzeugzeichnungen stammen aus dem Ursprungsprojekt VanAlign Pro. Sie
|
||||
liegen als Schablonen im Asset-Katalog und werden je nach Abweichung
|
||||
eingefärbt; die Helligkeit des Originals wurde dafür in Deckkraft übersetzt,
|
||||
damit Fenster und Konturen beim Einfärben erhalten bleiben.
|
||||
|
||||
**Vor der ersten Nutzung die Einbaulage bestimmen.** Sitzt der Sensor quer,
|
||||
gedreht oder kopfüber, meldet er längs und quer vertauscht oder mit falschem
|
||||
Vorzeichen. Der Assistent unter *Sensor → Einbaulage* klärt das durch zwei
|
||||
Kippbewegungen: einmal die Front nach unten, einmal die linke Seite. Aus der
|
||||
Reaktion ergibt sich die Zuordnung – geraten wird nichts.
|
||||
|
||||
Dabei wird auch eine **Verdrehung um die Hochachse** mitgemessen, also der
|
||||
Fall, dass der Sensor schräg statt längs im Fahrzeug klebt. Ohne diese
|
||||
Korrektur verteilt sich eine reine Querneigung auf beide Achsen: Das Fahrzeug
|
||||
kippt zur Seite, und die Längsanzeige kippt sichtbar mit – bei 20° Verdrehung
|
||||
mit gut einem Drittel des Werts. Der Winkel steht im Ergebnis des Assistenten
|
||||
(„um 20° verdreht") und wird von da an herausgerechnet.
|
||||
|
||||
Beim **Kalibrieren** liesse sich das nicht ermitteln, und zwar grundsätzlich
|
||||
nicht: Es misst eine einzige Lage und zieht sie als Nullpunkt ab. Eine Drehung
|
||||
um die Hochachse steckt darin nicht – eben sieht in jeder Verdrehung gleich
|
||||
aus. Dafür braucht es zwei Kippbewegungen in bekannte Richtungen, und genau die
|
||||
macht der Einbaulage-Assistent.
|
||||
|
||||
### Beides liegt im Sensor, nicht in der App
|
||||
|
||||
Sowohl die **Kalibrierung** als auch die **Einbaulage** speichert der ESP32
|
||||
selbst und gibt sie an jeden aus, der fragt. Das ist der Punkt, sobald mehr als
|
||||
ein Gerät im Spiel ist: iPhone, Apple Watch und Android-App zeigen dasselbe,
|
||||
und bestimmt werden muss beides nur ein einziges Mal, von welchem Gerät aus
|
||||
auch immer.
|
||||
|
||||
| | wo |
|
||||
|---|---|
|
||||
| Nullpunkt der Kalibrierung | im ESP (`pitch_offset`, `roll_offset`), wird dort auch schon abgezogen |
|
||||
| Einbaulage samt Verdrehung | im ESP, Charakteristik `…3428`, lesbar und schreibbar |
|
||||
| Spurweite und Radstand | in der jeweiligen App, im Fahrzeugprofil |
|
||||
|
||||
Beim Verbinden liest jede App die Einbaulage aus dem Gerät und übernimmt sie.
|
||||
Wer sie neu bestimmt, schreibt sie hinauf. Steht dort noch nichts – ältere
|
||||
Firmware oder nie bestimmt –, gilt weiter, was die App örtlich gespeichert hat;
|
||||
kaputtgehen kann dabei nichts.
|
||||
|
||||
Angewandt wird sie trotzdem in den Apps und nicht im Sensor. Der Sensor
|
||||
verwahrt sie nur: Würde er die Winkel schon umgerechnet melden, rechnete jede
|
||||
ältere App die Korrektur ein zweites Mal ein.
|
||||
|
||||
Die acht Byte der Charakteristik sind in `VanAlignProtocol` beschrieben und in
|
||||
`run-tests.sh` byteweise festgenagelt – daran hängen drei Apps und die
|
||||
Firmware.
|
||||
|
||||
**Danach 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 – **je Rad**, als Draufsicht auf
|
||||
das Fahrzeug. Getrennte Angaben für quer und längs wären irreführend: „rechts
|
||||
8 cm" und „vorne 4 cm" beschreiben dasselbe Fahrzeug, und unter beiden liegt
|
||||
teils dasselbe Rad. Es steht auf vier Punkten, also gehören vier Zahlen hin.
|
||||
|
||||
Das ist reine Geometrie und damit exakt: 2,0° Querneigung bei 2,00 m Spurweite
|
||||
ergeben 7,0 cm unter beide Räder der tieferstehenden Seite; kommen 1,5°
|
||||
Längsneigung bei 3,50 m Radstand dazu, braucht die tiefste Ecke 16,1 cm, ihre
|
||||
Nachbarn 9,2 und 7,0 cm, und das höchststehende Rad bleibt liegen. Die Maße
|
||||
stehen im Fahrzeugprofil, erreichbar über das ⓘ in der Fahrzeugliste.
|
||||
|
||||
## Apple Watch
|
||||
|
||||
Die Uhr zeigt dasselbe wie das Dashboard, nur auf das eingedampft, wofür man
|
||||
den Arm hebt:
|
||||
|
||||
* **Übersicht** – je Gerät der Hauptwert und ein Punkt für den Zustand der
|
||||
Verbindung. Ganz unten steht, wie alt der Stand ist.
|
||||
* **Nivellierung** – drei Seiten zum Wischen, weil auf diesem Bildschirm ein
|
||||
Wisch besser zu treffen ist als eine Scrollposition:
|
||||
|
||||
1. *Neigung* – wahlweise als Fahrzeugansicht wie am iPhone (Seiten- und
|
||||
Heckansicht, dreifach überhöht) oder als Libelle; umschaltbar und über
|
||||
Starts hinweg gemerkt. Dazu, was zu tun ist, und woher die Werte kommen.
|
||||
2. *Keile* – die Höhe je Rad als Draufsicht. Fehlen Spurweite und Radstand im
|
||||
Fahrzeugprofil, steht das dort statt einer leeren Seite.
|
||||
3. *Ausrichten* – der Assistent fürs Rangieren.
|
||||
|
||||
Kalibriert wird nur am iPhone: Das gehört einmalig auf ebenen Boden, und ein
|
||||
Knopf dafür an der Uhr wäre vor allem eine Gelegenheit, die Nullage aus
|
||||
Versehen zu verstellen.
|
||||
* **Ausrichten** – derselbe Assistent wie am iPhone: Tendenz, Rat und der
|
||||
Hinweis auf den flachsten Punkt der letzten anderthalb Minuten. **Steht das
|
||||
Fahrzeug in der Toleranz, vibriert die Uhr.** Das ist der eigentliche Gewinn
|
||||
gegenüber dem iPhone – beim Rangieren schaut niemand aufs Display, aber die
|
||||
Vibration am Handgelenk kommt an.
|
||||
* **Kühlbox** – ein/aus, Eco oder Max und die Solltemperatur, über die Krone
|
||||
gestellt. Verbunden wird die Box erst beim Öffnen dieser Ansicht, davor steht
|
||||
dort der zuletzt gestellte Stand.
|
||||
|
||||
### Wer mit wem funkt
|
||||
|
||||
Die Aufteilung folgt dem, was jedes Gerät hergibt.
|
||||
|
||||
**Den Neigungsmesser funkt die Uhr selbst an.** Er bewirbt seinen Dienst, ist
|
||||
also ohne jede Einrichtung auffindbar, und er ist unverschlüsselt – es gibt
|
||||
keinen Schlüssel, der auf der Uhr ein zweites Mal lagern müsste. Damit steht
|
||||
die Nivellierung am Handgelenk **ohne iPhone**: kein geöffnetes Telefon, keine
|
||||
Reichweite dorthin. Genau dafür hebt man beim Rangieren den Arm.
|
||||
|
||||
Die Einbaulage des Sensors reist einmal vom iPhone herüber und bleibt auf der
|
||||
Uhr gespeichert. Ohne sie stünden längs und quer je nach Einbau vertauscht oder
|
||||
mit falschem Vorzeichen – eingestellt wird sie weiterhin nur am iPhone, im
|
||||
Assistenten dort.
|
||||
|
||||
**Alles Übrige kommt über das iPhone.** Zwei Gründe, beide hart:
|
||||
|
||||
* BMS und Kühlbox lassen jeweils nur **eine** Verbindung zu. Eine mitlesende
|
||||
Uhr nähme dem iPhone die Verbindung weg, statt sie zu ergänzen.
|
||||
* Die Victron-Schlüssel liegen in der Keychain des iPhones. Sie auf die Uhr zu
|
||||
kopieren hiesse, sie ein zweites Mal aufzubewahren, ohne dass der zweite Ort
|
||||
irgendetwas brächte.
|
||||
|
||||
Was die Uhr stellt, stellt also in Wahrheit das iPhone – und angezeigt wird
|
||||
auch dort nur, was das Gerät zurückmeldet, nicht der Tastendruck.
|
||||
|
||||
### Was das für den Betrieb heisst
|
||||
|
||||
Für Batterie, Solar und Kühlbox muss VanControl Pro auf dem iPhone laufen.
|
||||
Solange die Uhr meldet, dass jemand hinschaut, hält die App das Funkgerät auch
|
||||
im Hintergrund am Leben; die Victron-Werbedaten stehen dabei still, weil iOS im
|
||||
Hintergrund kein ungefiltertes Suchen erlaubt.
|
||||
|
||||
Für die Nivellierung gilt das alles nicht – die läuft an der Uhr allein.
|
||||
Gefunkt wird dort nur im Vordergrund: watchOS lässt eine App im Hintergrund
|
||||
ohnehin kaum scannen, und beim Ausrichten schaut man auf die Uhr.
|
||||
|
||||
Gesendet wird in zwei Takten: ein halber Sekundentakt, solange die Watch-App im
|
||||
Vordergrund ist, sonst alle zwei Sekunden und nur bei Änderungen. Der schnelle
|
||||
Takt läuft über eine Frist, die die Uhr regelmässig erneuert – schläft sie ein,
|
||||
hört das iPhone von selbst wieder auf.
|
||||
|
||||
Was die Uhr zeigt, ist immer Weitergereichtes. Deshalb steht auf jedem
|
||||
Bildschirm das Alter des Standes: Eine abgerissene Strecke zum iPhone sähe sonst
|
||||
genauso aus wie ein Fahrzeug, an dem sich nichts tut.
|
||||
|
||||
## Diagnose
|
||||
|
||||
Im Alltag zeigt die App nur Messwerte und Bedienelemente. Die technischen
|
||||
Angaben – erkanntes Protokoll, Bluetooth-Merkmale, gesendete Befehle, Rohdaten
|
||||
der letzten Antwort – sind ausgeblendet und lassen sich unter *Einstellungen →
|
||||
Diagnose anzeigen* einschalten. Die Einstellungen sitzen im Fahrzeugmenü oben
|
||||
links im Dashboard.
|
||||
|
||||
Meldet ein Gerät einen Fehler oder fehlt ein Victron-Schlüssel, werden die
|
||||
Angaben unabhängig davon eingeblendet – dann sind sie genau das, was
|
||||
weiterhilft.
|
||||
|
||||
## 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.
|
||||
|
||||
Die Watch-App kennt denselben Schalter und braucht dann kein iPhone: Im Schema
|
||||
`CamperMonitorWatch` dieselbe Variable setzen. Die Neigung wandert dort
|
||||
langsam hin und her, sonst hätte der Ausrichtungs-Assistent nichts zu zeigen.
|
||||
|
||||
## 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
|
||||
|
||||
```
|
||||
firmware/vanalign/ Firmware des Neigungsmessers (ESPHome)
|
||||
├── esp32_ble.yaml Neigungsmessung und Bluetooth-Schnittstelle
|
||||
└── experimente/ Nicht für den Betrieb nötig
|
||||
|
||||
Shared/ In iPhone- und Watch-App übersetzt
|
||||
├── Models/
|
||||
│ ├── Profile.swift Fahrzeug samt Maßen
|
||||
│ ├── AlignmentAssistant.swift Verlauf, Tendenz und Keilhöhe je Rad
|
||||
│ ├── SensorOrientation.swift Einbaulage und ihre Erkennung
|
||||
│ ├── ConfiguredDevice.swift Eingerichtetes Gerät, Rolle, Transportart
|
||||
│ ├── DeviceSnapshot.swift Messwerte in Anzeigeform
|
||||
│ ├── LevelState.swift Neigung, Toleranz und Klartext dazu
|
||||
│ └── VictronCodes.swift Klartexte für Zustands-/Fehlercodes
|
||||
├── Bluetooth/
|
||||
│ ├── VanAlignProtocol.swift Neigungsmesser: Winkel und Kalibrierung
|
||||
│ └── LevelSession.swift Verbindung zum Neigungsmesser (iPhone und Uhr)
|
||||
├── VehicleTilt.swift Überhöhung und Farben der Fahrzeugansicht
|
||||
├── WheelLiftPlan.swift Keilhöhen als Draufsicht auf die vier Räder
|
||||
└── WatchLink/
|
||||
└── WatchLink.swift Datensatz und Befehle zwischen iPhone und Uhr
|
||||
|
||||
CamperMonitor/
|
||||
├── 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
|
||||
│ └── BMSSession.swift GATT-Verbindung, Protokollerkennung, Abfrage
|
||||
├── Store/
|
||||
│ ├── DeviceStore.swift Geräteliste, Persistenz
|
||||
│ └── KeychainStore.swift Victron-Schlüssel
|
||||
├── Watch/
|
||||
│ └── PhoneWatchLink.swift Sendet den Stand, nimmt Befehle der Uhr an
|
||||
└── 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
|
||||
├── VehicleTiltView.swift Neigung am Fahrzeug dargestellt
|
||||
├── SettingsView.swift App-Einstellungen
|
||||
├── SensorSetupView.swift Assistent für die Einbaulage
|
||||
└── AddDeviceView.swift Scannen und Einrichten
|
||||
|
||||
CamperMonitorWatch/ watchOS-App
|
||||
├── CamperWatchApp.swift Einstieg, meldet dem iPhone das Hinschauen
|
||||
├── PhoneLink.swift Gegenstelle zum iPhone
|
||||
├── WatchLevelRadio.swift Eigene Bluetooth-Verbindung zum Neigungsmesser
|
||||
├── WatchDemo.swift Erfundene Werte für den Simulator
|
||||
└── Views/
|
||||
├── WatchRootView.swift Übersicht und Altersangabe
|
||||
├── WatchBubble.swift Libelle für den kleinen Bildschirm
|
||||
├── WatchVehicleView.swift Fahrzeugansicht auf Uhrgrösse
|
||||
├── WatchLevelView.swift Die drei Seiten: Neigung, Keile, Ausrichten
|
||||
├── WatchAlignView.swift Ausrichten mit Vibration
|
||||
├── WatchDeviceDetailView.swift Alle Werte eines Geräts
|
||||
└── WatchFridgeControls.swift Kühlbox stellen
|
||||
|
||||
Config/
|
||||
└── CamperMonitor-Info.plist Nur der Hintergrundbetrieb für die Uhr
|
||||
```
|
||||
|
||||
## Bekannte Grenzen
|
||||
|
||||
* **Im Hintergrund nur die verbundenen Geräte.** iOS erlaubt das ungefilterte
|
||||
Scannen nach Advertisements nur im Vordergrund; die Victron-Werte stehen im
|
||||
Hintergrund also still. Verbundene Geräte – Neigungsmesser, BMS, Kühlbox –
|
||||
laufen weiter, aber nur solange die Uhr meldet, dass jemand hinschaut. Ohne
|
||||
Uhr pausiert die App im Hintergrund vollständig und nimmt beim Zurückkommen
|
||||
wieder auf.
|
||||
* **Die Uhr braucht das iPhone – ausser für die Nivellierung.** Batterie, Solar
|
||||
und Kühlbox zeigt sie nur, was von dort kommt; ist das iPhone ausser
|
||||
Reichweite, steht dort, wie alt der letzte Stand ist. Den Neigungsmesser
|
||||
erreicht sie selbst.
|
||||
* **Neigungsmesser und Uhr:** Der ESP32 nimmt mehrere Verbindungen an, iPhone
|
||||
und Uhr können also gleichzeitig mitlesen. Weist er die zweite ab, hilft es,
|
||||
die iPhone-App zu schliessen – dann gehört der Sensor der Uhr.
|
||||
* **Auf der Uhr muss beim ersten Start Bluetooth erlaubt werden**, sonst bleibt
|
||||
die Nivellierung dort leer.
|
||||
* **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.
|
||||
Reference in New Issue
Block a user