Kühlbox: weniger Piepen, Diagnose zum Weitergeben

Dein Befund grenzt es ein: die Solltemperatur lässt sich stellen, also
kommen Schreibvorgänge an. Es scheitert nur am Einstellungsblock.

Das mehrfache Piepen war meine Schuld. Beantwortet die Box die Anmeldung
nicht, habe ich sie vor jedem Stellbefehl erneut angemeldet - und die Box
quittiert jede Anmeldung mit einem Ton. Jetzt geschieht das höchstens
einmal je Verbindung.

Weiter komme ich nicht ohne die Antwort deiner Box. Ihre Länge entscheidet
darüber, wie lang der Stellbefehl sein muss, und sie steht jetzt als
"Statusdaten der Box" in der Diagnose. Dazu ein Knopf, der alles zusammen
in die Zwischenablage legt - Merkmalsbaum, Weg, Schreibart, letzten Befehl
und letzte Antwort. Das abzutippen wäre zuviel verlangt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
BiasF
2026-08-31 09:08:43 +02:00
co-authored by Claude Opus 5
parent 8b1e2ac39d
commit 8f8edb137b
3 changed files with 60 additions and 3 deletions
@@ -11,6 +11,7 @@ struct DeviceDetailView: View {
@State private var editedName = ""
@State private var keyInput = ""
@State private var showDeleteConfirmation = false
@State private var didCopyReport = false
@AppStorage(AppSettings.showDiagnosticsKey) private var showDiagnostics = false
/// Ob die technischen Angaben eingeblendet werden.
@@ -272,6 +273,33 @@ struct DeviceDetailView: View {
return String(format: "0x%02X", byte)
}
/// Alles auf einmal, zum Weitergeben. Einzeln abzutippen ist zuviel
/// verlangt, und gerade der Merkmalsbaum ist zu lang dafür.
private func report(_ info: BMSDiagnostics) -> String {
var lines = [
"Gerät: \(currentDevice.name) (\(currentDevice.role.title))",
"Protokoll: \(info.dialect)",
"Verbunden: \(info.isConnected ? "ja" : "nein")",
"Empfang abonniert: \(info.isNotifyActive ? "ja" : "nein")",
]
if let position = info.endpointPosition {
lines.append("Weg: \(position.index) von \(position.total)")
}
if let endpoint = info.endpointLabel { lines.append("Merkmal: \(endpoint)") }
if let isBound = info.isBound { lines.append("Angemeldet: \(isBound ? "ja" : "nein")") }
lines.append("Gesendet: \(info.sentFrames) · empfangen: \(info.receivedBytes) Byte"
+ " · bestätigt: \(info.confirmedWrites)")
if let writeError = info.lastWriteError { lines.append("Schreibfehler: \(writeError)") }
if let command = info.lastCommandHex { lines.append("Letzter Stellbefehl: \(command)") }
if let hex = info.lastResponseHex { lines.append("Letzte Antwort: \(hex)") }
if let payload = info.fridgePayloadHex { lines.append("Statusdaten: \(payload)") }
if !info.gattSummary.isEmpty {
lines.append("Merkmale:")
lines.append(contentsOf: info.gattSummary)
}
return lines.joined(separator: "\n")
}
/// Welches Protokoll das BMS spricht und was zuletzt ankam.
@ViewBuilder
private var bmsDiagnosticsSection: some View {
@@ -350,6 +378,22 @@ struct DeviceDetailView: View {
.textSelection(.enabled)
}
}
if let payload = info.fridgePayloadHex {
VStack(alignment: .leading, spacing: 4) {
Text("Statusdaten der Box (\(payload.split(separator: " ").count) Byte)")
Text(payload)
.font(.caption.monospaced())
.foregroundStyle(.secondary)
.textSelection(.enabled)
}
}
Button {
UIPasteboard.general.string = report(info)
didCopyReport = true
} label: {
Label(didCopyReport ? "Diagnose kopiert" : "Diagnose kopieren",
systemImage: didCopyReport ? "checkmark" : "doc.on.doc")
}
} header: {
Text("Diagnose")
} footer: {