diff --git a/VanControl.xcodeproj/project.pbxproj b/VanControl.xcodeproj/project.pbxproj index fb791fb..701f30a 100644 --- a/VanControl.xcodeproj/project.pbxproj +++ b/VanControl.xcodeproj/project.pbxproj @@ -507,6 +507,7 @@ INFOPLIST_FILE = "Config/VanControl-Info.plist"; INFOPLIST_KEY_CFBundleDisplayName = "VanControl Pro"; INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "Zum Auslesen von Victron-Geraeten und dem Daly BMS per Bluetooth."; + INFOPLIST_KEY_NSSupportsLiveActivities = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; @@ -538,6 +539,7 @@ INFOPLIST_FILE = "Config/VanControl-Info.plist"; INFOPLIST_KEY_CFBundleDisplayName = "VanControl Pro"; INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "Zum Auslesen von Victron-Geraeten und dem Daly BMS per Bluetooth."; + INFOPLIST_KEY_NSSupportsLiveActivities = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; diff --git a/VanControl/Bluetooth/BluetoothManager.swift b/VanControl/Bluetooth/BluetoothManager.swift index 4915543..c7a4e9a 100644 --- a/VanControl/Bluetooth/BluetoothManager.swift +++ b/VanControl/Bluetooth/BluetoothManager.swift @@ -394,6 +394,10 @@ final class BluetoothManager: NSObject { // MARK: - Kühlbox steuern (vom Hauptthread aufgerufen) func updateFridgeZoneMode(for device: ConfiguredDevice) { + guard !isDemo else { + applyDemoFridgeChange(for: device.id) { $0.zoneMode = device.fridgeZoneMode } + return + } let deviceID = device.id, mode = device.fridgeZoneMode queue.async { guard let session = self.session(for: deviceID) else { return } @@ -404,21 +408,51 @@ final class BluetoothManager: NSObject { } func setFridgeTarget(_ celsius: Int, zone: AlpicoolState.Zone, for deviceID: UUID) { + guard !isDemo else { + applyDemoFridgeChange(for: deviceID) { state in + switch zone { + case .left: state.leftTarget = celsius + case .right: state.rightTarget = celsius + } + } + return + } sendFridgeSettings(for: deviceID) { _ in AlpicoolState.setTarget(zone: zone, to: celsius) } } func setFridgePower(_ on: Bool, for deviceID: UUID) { + guard !isDemo else { + applyDemoFridgeChange(for: deviceID) { $0.isPoweredOn = on } + return + } sendFridgeSettings(for: deviceID) { $0.settingsCommand(poweredOn: on) } } func setFridgeEco(_ eco: Bool, for deviceID: UUID) { + guard !isDemo else { + applyDemoFridgeChange(for: deviceID) { $0.runMode = eco ? 1 : 0 } + return + } sendFridgeSettings(for: deviceID) { $0.settingsCommand(eco: eco) } } func setFridgeLock(_ locked: Bool, for deviceID: UUID) { + guard !isDemo else { + applyDemoFridgeChange(for: deviceID) { $0.isLocked = locked } + return + } sendFridgeSettings(for: deviceID) { $0.settingsCommand(locked: locked) } } + /// Im Demo-Modus gibt es keine Box, die einen Stellbefehl bestätigt – die + /// Änderung wird direkt im angezeigten Zustand nachgezogen, auf dem + /// Hauptthread, wo `fridgeStates` lebt. + private func applyDemoFridgeChange(for deviceID: UUID, _ change: (inout AlpicoolState) -> Void) { + var state = fridgeStates[deviceID] ?? DemoData.fridgeState + change(&state) + fridgeStates[deviceID] = state + } + /// Der Einstellungsblock wird aus dem zuletzt empfangenen Zustand gebaut – /// und zwar auf der Funk-Queue, wo dieser Zustand lebt. /// diff --git a/VanControl/Store/DeviceStore.swift b/VanControl/Store/DeviceStore.swift index a0a0cb2..7fbcf81 100644 --- a/VanControl/Store/DeviceStore.swift +++ b/VanControl/Store/DeviceStore.swift @@ -244,7 +244,12 @@ final class DeviceStore { } } + /// Im Demo-Modus wird nichts geschrieben – sonst überlebten die erfundenen + /// Fahrzeuge und Geräte das Ausschalten des Demo-Modus, weil z.B. das + /// Ändern der Fahrzeuggrafik oder der Einbaulage ganz normal `save()` + /// aufruft. private func save() { + guard !DemoData.isEnabled else { return } let defaults = UserDefaults.standard if let data = try? JSONEncoder().encode(devices) { defaults.set(data, forKey: Self.devicesKey)