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>
Die Suche nach dem richtigen Verbindungsweg blieb auf dem ersten
Kandidaten stehen: gesendet wurde erst, nachdem iOS das Abonnieren der
Notify-Charakteristik bestätigt hat. Bestätigt ein Modul das nie – bei
der WattCycle-Batterie auf FFF1 der Fall –, wurde weder je eine Anfrage
geschickt noch zum nächsten Kandidaten gewechselt. Die Diagnose zeigte
dauerhaft "1 von 16" und "0 Anfragen / 0 Byte".
Die Aktivierung eines Kandidaten hat jetzt ein Zeitlimit von vier
Sekunden. Läuft es ab, geht es zum nächsten; ist es der einzige Weg,
wird trotzdem gesendet – manche Module antworten auch ohne bestätigtes
Abonnement. Ein Token verhindert, dass verspätete Rückmeldungen eines
bereits verworfenen Kandidaten den aktuellen durcheinanderbringen.
Damit sich Fortschritt überhaupt beobachten lässt, wird die Diagnose
jetzt bei jeder gesendeten Anfrage aktualisiert statt nur am Ende einer
Runde, und zeigt zusätzlich Verbindungszustand, ob der Empfang abonniert
ist, und wann zuletzt gesendet wurde. Die Suche ist enger getaktet, damit
alle Wege in gut zwei Minuten durch sind.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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>