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:
@@ -240,11 +240,20 @@ struct DeviceDetailView: View {
|
||||
if let info = bluetooth.bmsDiagnostics[device.id] {
|
||||
Section {
|
||||
LabeledContent("Erkanntes Protokoll", value: info.dialect)
|
||||
if let service = info.serviceUUID {
|
||||
LabeledContent("Dienst") {
|
||||
Text(service).font(.caption.monospaced()).foregroundStyle(.secondary)
|
||||
if let position = info.endpointPosition {
|
||||
LabeledContent("Verbindungsweg",
|
||||
value: "\(position.index) von \(position.total)")
|
||||
}
|
||||
if let endpoint = info.endpointLabel {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("Aktueller Weg")
|
||||
Text(endpoint)
|
||||
.font(.caption.monospaced())
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
LabeledContent("Gesendet / empfangen",
|
||||
value: "\(info.sentFrames) Anfragen / \(info.receivedBytes) Byte")
|
||||
if let hex = info.lastResponseHex {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text("Letzte Antwort")
|
||||
@@ -257,9 +266,21 @@ struct DeviceDetailView: View {
|
||||
} header: {
|
||||
Text("Diagnose")
|
||||
} footer: {
|
||||
Text("Die App probiert Daly (klassisch und Modbus) sowie JBD/Xiaoxiang "
|
||||
+ "durch und übernimmt, was antwortet. Bleibt es bei „wird ermittelt“, "
|
||||
+ "spricht das BMS ein anderes Protokoll – dann hilft die Rohantwort weiter.")
|
||||
Text("Die App probiert alle Schreib-/Empfangs-Kombinationen des Geräts "
|
||||
+ "durch und fragt auf jeder Daly (klassisch und Modbus) sowie "
|
||||
+ "JBD/Xiaoxiang an. Bleibt „empfangen“ bei 0 Byte, nimmt das BMS "
|
||||
+ "die Kommandos nicht an.")
|
||||
}
|
||||
|
||||
if !info.gattSummary.isEmpty {
|
||||
Section {
|
||||
Text(info.gattSummary.joined(separator: "\n"))
|
||||
.font(.caption2.monospaced())
|
||||
.foregroundStyle(.secondary)
|
||||
.textSelection(.enabled)
|
||||
} header: {
|
||||
Text("Bluetooth-Merkmale des Geräts")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user