WattCycle-Akkus unterstützen

WattCycle spricht weder Daly noch JBD, sondern ein eigenes Modbus-artiges
Protokoll – und verlangt vor der ersten Abfrage eine Freischaltung: der
Text "HiLink" muss auf die Charakteristik FFFA geschrieben werden, sonst
bleibt der Akku auf alles stumm. Genau daran scheiterte die Erkennung;
die Charakteristik war im GATT-Baum sichtbar, wurde aber nur als weiterer
Schreibkandidat behandelt.

Neu ist WattCycleProtocol mit Rahmenbau (1E … 0D für Anfragen, 7E … 0D für
Antworten), Prüfsummen und der Auswertung des Messwert-Datensatzes
0x008C. Der ist selbstbeschreibend: Zellenanzahl, Zellspannungen,
Fühleranzahl, MOSFET- und Platinentemperatur, Zellfühler, dann Strom,
Spannung, Kapazitäten, Zyklen und Ladezustand. Der Strom hat ein eigenes
Format, bei dem Bit 15 das Vorzeichen und Bit 14 die Nachkommastelle
angibt. Aus Datenpunkt 0x0092 kommen Modell, Hersteller und Seriennummer,
die einmalig gelesen und in der Detailansicht gezeigt werden.

BMSSession kennt die Freischaltung jetzt als Teil eines Kandidaten: liegt
im selben Dienst eine FFFA-Charakteristik, wird nach dem bestätigten Abo
kurz gewartet, freigeschaltet, nochmal gewartet und dann erst abgefragt.
Für die anderen Protokolle ist das unschädlich.

Protokoll und Feldbelegung stammen aus frabnet/esphome-wattcycle-ble. Die
dortige Tabellen-Prüfsumme ist gegen den klassischen Modbus-CRC
nachgerechnet (identisch über 3063 Testfälle), sodass die vorhandene
CRC-Funktion genügt und die 512 Byte Tabellen entfallen. Die
Anfragerahmen sind byteweise abgesichert, die Auswertung an einem
vollständigen Datensatz – 107 Prüfungen laufen durch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
BiasF
2026-08-30 13:00:16 +02:00
co-authored by Claude Opus 5
parent fc73f730a7
commit 091243a1d8
7 changed files with 482 additions and 14 deletions
+21 -7
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) |
| Batterie-BMS (Bulltron/Daly, WattCycle/JBD) | GATT-Verbindung, alle 5 s abgefragt | SoC, Spannung, Strom, Restkapazität, alle Einzelzellspannungen, Zelldifferenz, Temperaturen, Zyklen, MOSFET-Status |
| Batterie-BMS (Bulltron/Daly, WattCycle) | 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.
@@ -75,7 +75,20 @@ Die App probiert drei Protokolle durch und übernimmt, was antwortet:
|---|---|
| Daly klassisch (`A5`) | Bulltron und viele Daly-BMS |
| Daly Modbus (`D2`) | neuere Daly-Firmware |
| JBD / Xiaoxiang (`DD A5`) | WattCycle und viele andere LiFePO4-Akkus |
| 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
@@ -126,7 +139,8 @@ CamperMonitor/
│ ├── 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 (WattCycle), Rahmen und Auswertung
│ ├── JBDProtocol.swift JBD/Xiaoxiang, Rahmen und Auswertung
│ ├── WattCycleProtocol.swift WattCycle, Freischaltung und Auswertung
│ └── BMSSession.swift GATT-Verbindung, Protokollerkennung, Abfrage
├── Store/
│ ├── DeviceStore.swift Geräteliste, Persistenz
@@ -149,10 +163,10 @@ CamperMonitor/
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 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.