Kühlbox: fehlenden zweiten Fühler erkennen
Deine Diagnose hat es gezeigt. Die Box sendet 30 Byte Nutzlast, also den langen Datensatz - hat aber nur einen Fühler. Für den fehlenden zweiten meldet sie -128, den üblichen Platzhalter, und die Einstellungen der rechten Zone stehen auf lauter Nullen. Meine Erkennung hat diesen Platzhalter für einen Messwert gehalten und die Box deshalb für zweizonig gehalten. Damit ging der lange Stellbefehl raus, 31 Byte statt 20 - und den verwirft sie wortlos. Die Solltemperatur ging weiter, weil sie ein eigenes, kurzes Kommando hat und von der Zonenfrage nicht berührt wird. Genau dieses Bild stand im Bericht. Als zweite Zone gilt jetzt nur noch, wo der zweite Fühler auch wirklich misst. Für diese Box heisst das: 20 Byte, ein Schreibvorgang. Nebenbei fiel auf, dass die Anzeige eine rechte Zone mit -128 Grad geführt hat. Auch das ist damit weg. Die echte Antwort der Box steht als Prüfung im Testlauf, mitsamt der Möglichkeit, die Erkennung in den Geräteeinstellungen zu übersteuern. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -92,6 +92,9 @@ enum AlpicoolProtocol {
|
||||
|
||||
static func signed(_ byte: UInt8) -> Int { Int(Int8(bitPattern: byte)) }
|
||||
|
||||
/// Womit diese Boxen einen nicht vorhandenen Fühler melden.
|
||||
static let missingSensorReading = -128
|
||||
|
||||
/// Pause zwischen den Teilstücken eines aufgeteilten Pakets, damit das
|
||||
/// Gerät sie wieder zusammensetzen kann.
|
||||
static let chunkDelay: TimeInterval = 0.15
|
||||
@@ -154,16 +157,24 @@ struct AlpicoolState: Equatable {
|
||||
/// Übersteuerung aus den Geräteeinstellungen.
|
||||
var zoneMode: FridgeZoneMode = .automatic
|
||||
|
||||
/// Rohe Bytes der rechten Zone, für die Erkennung und die Diagnose.
|
||||
/// Die Einstellungsbytes der rechten Zone, für die Erkennung und die
|
||||
/// Diagnose. Ohne den Messwert – der wird getrennt beurteilt.
|
||||
var rightZoneBytes: [UInt8] = []
|
||||
|
||||
/// Ob die Box wirklich eine zweite Zone hat.
|
||||
///
|
||||
/// Die Nutzlastlänge allein taugt nicht: Einzonen-Boxen senden den langen
|
||||
/// Datensatz teils mit, füllen den zweiten Block aber mit Nullen. Als
|
||||
/// zweizonig gilt deshalb nur, wo dieser Block überhaupt etwas enthält.
|
||||
/// Datensatz teils mit und füllen den zweiten Block auf. Zwei Anzeichen
|
||||
/// verraten das. Erstens meldet die Box für den fehlenden zweiten Fühler
|
||||
/// -128, den üblichen Platzhalter. Zweitens stehen die Einstellungen der
|
||||
/// rechten Zone dann auf lauter Nullen oder lauter 0xFF.
|
||||
///
|
||||
/// Das ist keine Frage der Anzeige allein: der Stellbefehl fällt für eine
|
||||
/// Box mit zwei Zonen länger aus, und die falsche Länge wird verworfen.
|
||||
var detectedDualZone: Bool {
|
||||
guard rightCurrent != nil, !rightZoneBytes.isEmpty else { return false }
|
||||
guard let current = rightCurrent,
|
||||
current != AlpicoolProtocol.missingSensorReading else { return false }
|
||||
guard !rightZoneBytes.isEmpty else { return false }
|
||||
return rightZoneBytes.contains { $0 != 0x00 } && rightZoneBytes.contains { $0 != 0xFF }
|
||||
}
|
||||
|
||||
@@ -213,7 +224,7 @@ struct AlpicoolState: Equatable {
|
||||
rightTarget = AlpicoolProtocol.signed(p[18])
|
||||
rightCurrent = AlpicoolProtocol.signed(p[26])
|
||||
runningStatus = Int(p[27])
|
||||
rightZoneBytes = Array(p[18...26])
|
||||
rightZoneBytes = Array(p[18...25])
|
||||
} else {
|
||||
rightTarget = nil
|
||||
rightCurrent = nil
|
||||
@@ -263,12 +274,12 @@ struct AlpicoolState: Equatable {
|
||||
p[10], p[11], p[12], p[13], // Kompressordrehzahlen
|
||||
]
|
||||
|
||||
// Der zweite Block gehört an den Befehl, sobald die Box ihn auch
|
||||
// gemeldet hat – unabhängig davon, ob die Anzeige eine zweite Zone
|
||||
// zeigt. Die Box erwartet den Befehl in der Länge, in der sie selbst
|
||||
// antwortet; ein kürzerer wird verworfen, auch wenn der zweite Block
|
||||
// nur Nullen enthält.
|
||||
if p.count >= 28 {
|
||||
// Der zweite Block gehört nur an den Befehl, wenn die Box wirklich
|
||||
// zwei Zonen hat. Eine Einzonen-Box sendet den langen Datensatz teils
|
||||
// trotzdem – nimmt aber nur den kurzen Befehl an. Stimmt die Erkennung
|
||||
// im Einzelfall nicht, lässt sie sich in den Geräteeinstellungen von
|
||||
// Hand festlegen.
|
||||
if isDualZone, p.count >= 28 {
|
||||
data += [
|
||||
p[18], // Sollwert rechts
|
||||
0, 0,
|
||||
|
||||
Reference in New Issue
Block a user