BMS: alle Schreib-/Empfangs-Kombinationen durchprobieren

Die WattCycle-Batterie meldete sich am FFF0-Dienst, nahm aber keine
Kommandos an. Grund: dort ist FFF1 die erste beschreibbare
Charakteristik, sie sieht schreibbar aus und bleibt trotzdem stumm –
Kommandos gehören auf FFF2.

Statt die richtige Charakteristik zu raten, stellt BMSSession jetzt alle
Paare aus schreibbarer und benachrichtigender Charakteristik zusammen,
jeweils mit und ohne Schreibbestätigung, und arbeitet sie ab, bis eines
antwortet. Bekannte Paare (FFF2/FFF1, FF02/FF01, Nordic UART) kommen
zuerst dran; ein Kandidat, der sich nicht abonnieren lässt, wird sofort
übersprungen. Auf jedem Weg werden weiterhin Daly klassisch, Daly Modbus
und JBD angefragt.

Die Diagnose zeigt dazu den vollständigen GATT-Baum des Geräts, den
gerade versuchten Weg samt Position in der Kandidatenliste sowie Zähler
für gesendete Anfragen und empfangene Bytes. Damit lässt sich
unterscheiden, ob das BMS die Kommandos gar nicht annimmt oder ein
unbekanntes Protokoll spricht.

Nebenbei: "caravan" existiert nicht als SF-Symbol und ließ SwiftUI
stillschweigend auf Text zurückfallen – in den Demodaten ersetzt.
README auf Profile und WattCycle/JBD nachgezogen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
BiasF
2026-08-30 11:31:16 +02:00
co-authored by Claude Opus 5
parent fdcc644828
commit b0e7f057b6
5 changed files with 300 additions and 124 deletions
+41 -17
View File
@@ -6,7 +6,7 @@ iOS-App, die per Bluetooth LE die Energieanlage im Wohnmobil ausliest:
|---|---|---|
| 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 |
| Batterie-BMS (Bulltron/Daly, WattCycle/JBD) | 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.
@@ -63,18 +63,35 @@ 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
### Batterie / BMS
Kein Schlüssel nötig. In der Liste erscheint das BLE-Modul meist als `DL-…`.
Auswählen, Art auf **Batterie / BMS** stellen, Sichern.
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 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.
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`) | WattCycle und viele andere LiFePO4-Akkus |
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
Bulltron-/Daly-App offen ist, bekommt Camper Monitor keine Verbindung.
Hersteller-App offen ist, bekommt Camper Monitor keine Verbindung.
## 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
@@ -98,6 +115,7 @@ und die Prüfsummen beider Daly-Dialekte.
```
CamperMonitor/
├── Models/
│ ├── Profile.swift Fahrzeug
│ ├── ConfiguredDevice.swift Eingerichtetes Gerät, Rolle, Transportart
│ ├── DeviceSnapshot.swift Messwerte in Anzeigeform
│ └── VictronCodes.swift Klartexte für Zustands-/Fehlercodes
@@ -106,16 +124,18 @@ CamperMonitor/
│ ├── 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
│ ├── DalyProtocol.swift Daly-Rahmen und Prüfsummen
│ ├── DalyState.swift Sammelt Daly-Antworten zu einem Gesamtbild
── JBDProtocol.swift JBD/Xiaoxiang (WattCycle), Rahmen und Auswertung
│ └── 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
├── DeviceDetailView.swift Alle Werte, Verlauf, Zellspannungen, Diagnose
├── ProfilesView.swift Fahrzeuge anlegen und verwalten
└── AddDeviceView.swift Scannen und Einrichten
```
@@ -125,10 +145,14 @@ CamperMonitor/
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.
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.
* **Welches BMS in einem WattCycle-Akku steckt, ist nicht garantiert.** Die
Unterstützung ist auf JBD/Xiaoxiang ausgelegt, das dort üblich ist. Meldet
die Diagnose dauerhaft „wird ermittelt“, spricht der Akku etwas anderes
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.