forked from fritob/Camper-Monitor
Kühlbox: Stellbefehl in der Länge, die die Box erwartet
Diesmal gegen die Referenzimplementierung geprüft statt geraten. Rahmen, Längenbyte, Prüfsumme, Anmelde- und Abfragepaket stimmen dort byteweise mit unseren überein. Ein Unterschied blieb: die Länge des Einstellungs- blocks. Ich hatte sie an die Zonenerkennung gehängt. Sendet eine Box den langen Datensatz, füllt den zweiten Block aber mit Nullen, galt sie als einzonig und bekam den kurzen Befehl - während sie den langen erwartet. Die Box verwirft ihn dann wortlos, und Ein- und Ausschalten blieb wirkungslos. Die Referenz hängt die Länge an die Antwort der Box, nicht an eine Deutung davon. Jetzt auch hier. Für die Anzeige bleibt die Erkennung unverändert: ein leerer zweiter Block wird weiterhin nicht als zweite Zone gezeigt. Zweitens die Anmeldung. Abfragen beantwortet die Box teils auch unangemeldet, Stellbefehle nicht. Ob die Anmeldung je bestätigt wurde, wurde bisher nicht verfolgt. Jetzt schon: fehlt die Bestätigung, wird vor dem Stellbefehl noch einmal angemeldet. In der Diagnose steht der Stand als eigene Zeile. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -91,6 +91,10 @@ final class BMSSession: NSObject {
|
||||
}
|
||||
/// Ob die Kühlbox in dieser Sitzung schon angemeldet wurde.
|
||||
private var didBind = false
|
||||
/// Ob die Box die Anmeldung auch beantwortet hat. Abfragen nimmt sie
|
||||
/// teils auch unangemeldet an, Stellbefehle nicht – deshalb wird vor
|
||||
/// einem Befehl notfalls noch einmal angemeldet.
|
||||
private(set) var bindAcknowledged = false
|
||||
private var buffer: [UInt8] = []
|
||||
private var pollTimer: DispatchSourceTimer?
|
||||
private var lastResponse: Data?
|
||||
@@ -234,6 +238,7 @@ final class BMSSession: NSObject {
|
||||
isNotifyActive = false
|
||||
didUnlock = false
|
||||
didBind = false
|
||||
bindAcknowledged = false
|
||||
buffer.removeAll()
|
||||
activationToken += 1
|
||||
let token = activationToken
|
||||
@@ -438,6 +443,21 @@ final class BMSSession: NSObject {
|
||||
return
|
||||
}
|
||||
|
||||
// Hat die Box die Anmeldung nie beantwortet, wird sie hier nachgeholt.
|
||||
// Ein Stellbefehl an eine unangemeldete Box wird sonst verworfen.
|
||||
guard bindAcknowledged else {
|
||||
send(AlpicoolProtocol.packet(.bind))
|
||||
queue.asyncAfter(deadline: .now() + 0.4) { [weak self] in
|
||||
guard let self else { return }
|
||||
self.send(packet)
|
||||
self.queue.asyncAfter(deadline: .now() + 1.0) { [weak self] in
|
||||
guard let self, self.dialect == .alpicool else { return }
|
||||
self.send(AlpicoolProtocol.packet(.query))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
send(packet)
|
||||
// Genug Abstand, damit ein aufgeteiltes Paket vollständig draußen ist.
|
||||
queue.asyncAfter(deadline: .now() + 1.0) { [weak self] in
|
||||
@@ -495,6 +515,9 @@ final class BMSSession: NSObject {
|
||||
guard !frames.isEmpty else { return false }
|
||||
buffer = remainder
|
||||
adopt(.alpicool)
|
||||
if frames.contains(where: { $0.command == AlpicoolProtocol.Command.bind.rawValue }) {
|
||||
bindAcknowledged = true
|
||||
}
|
||||
for frame in frames { alpicoolState.apply(frame) }
|
||||
alpicoolState.zoneMode = fridgeZoneMode
|
||||
onFridgeState?(alpicoolState)
|
||||
@@ -574,6 +597,7 @@ final class BMSSession: NSObject {
|
||||
serviceUUID: currentEndpoint?.write.service?.uuid.uuidString,
|
||||
isConnected: peripheral.state == .connected,
|
||||
isNotifyActive: isNotifyActive,
|
||||
isBound: dialect == .alpicool ? bindAcknowledged : nil,
|
||||
gattSummary: gattSummary,
|
||||
sentFrames: sentFrameCount,
|
||||
receivedBytes: receivedByteCount,
|
||||
|
||||
Reference in New Issue
Block a user