import SwiftUI /// Bedienelemente einer Alpicool-Kühlbox. /// /// Alle Schalter folgen dem Gerät, nicht der Vermutung: nach jedem Stellbefehl /// fragt die Sitzung den Zustand neu ab, und die Ansicht zeigt, was zurückkam. struct FridgeControls: View { let device: ConfiguredDevice let state: AlpicoolState @Environment(BluetoothManager.self) private var bluetooth var body: some View { Section { // Ohne Rückfrage: ein Bestätigungsdialog an einer Section wird von // SwiftUI nicht zuverlässig angezeigt, und der Schalter blieb dann // wirkungslos. Der Weg ist jetzt für Ein und Aus derselbe. Toggle("Eingeschaltet", isOn: Binding( get: { state.isPoweredOn }, set: { bluetooth.setFridgePower($0, for: device.id) } )) Picker("Betriebsart", selection: Binding( get: { state.isEco }, set: { bluetooth.setFridgeEco($0, for: device.id) } )) { Text("Max").tag(false) Text("Eco").tag(true) } .pickerStyle(.segmented) .disabled(!state.isPoweredOn) targetStepper(zone: .left, title: state.isDualZone ? "Soll links" : "Solltemperatur", value: state.leftTarget) if state.isDualZone { targetStepper(zone: .right, title: "Soll rechts", value: state.rightTarget) } Toggle("Bedienfeld gesperrt", isOn: Binding( get: { state.isLocked }, set: { bluetooth.setFridgeLock($0, for: device.id) } )) } header: { Text("Steuerung") } footer: { Text("Änderungen gehen direkt an die Box. Der angezeigte Stand kommt " + "aus ihrer Antwort, nicht aus der Eingabe.") } } private func targetStepper(zone: AlpicoolState.Zone, title: String, value: Int?) -> some View { let range = state.targetRange return Stepper(value: Binding( get: { value ?? range.lowerBound }, set: { bluetooth.setFridgeTarget($0, zone: zone, for: device.id) } ), in: range) { LabeledContent(title) { Text(value.map { "\($0) \(state.unitSymbol)" } ?? "–") .monospacedDigit() } } .disabled(!state.isPoweredOn || value == nil) } }