Files
Camper-Monitor/CamperMonitorWatch/WatchDemo.swift
T
BiasFandClaude Opus 5 5fec4a55dd Kühlbox nur verbinden, während man sie ansieht
Jede Verbindung meldet sich am Display der Box an – sie piept, und wer
gerade davorsteht, wird gestört. Dauerhaft verbunden zu sein ist dort
also nicht unsichtbar wie beim BMS, sondern lästig.

Die Kühlbox wird deshalb nur noch verbunden, solange ihre Ansicht offen
ist: am iPhone über die Detailansicht, an der Uhr über einen eigenen
Befehl, den sie beim Öffnen und Schliessen schickt. Ein Stellbefehl geht
weiterhin immer durch – ist die Box nicht verbunden, wird er gemerkt und
löst den Verbindungsaufbau aus.

Abgeriegelt sind alle drei Wege, über die bisher verbunden wurde: beim
Start, im Takt des Wiederverbindens, und – das war das eigentliche Loch –
sobald das Gerät in den Werbedaten auftaucht. Da die App dauerhaft
scannt, hätte allein dieser Weg die Box weiter angefunkt. Dass sie in
Reichweite ist, ist kein Grund, sie anzufassen.

Auf der Übersicht steht dafür der zuletzt gestellte Stand statt der
Messwerte: Sollwert, Ein/Aus, Eco oder Max, dazu wann er gestellt wurde.
Das bleibt richtig, auch wenn es von gestern ist – ein Sollwert ändert
sich nur, wenn jemand ihn ändert. Eine Innentemperatur von gestern sähe
dagegen aus wie eine von jetzt, und man würde ihr glauben. Genau das
sichern die neuen Prüfungen ab: Hauptwert ist der Sollwert, gemessene
Temperatur und Bordspannung kommen nicht vor.

Der Stand liegt in den Einstellungen (FridgeSettings) mit einem
Zeitstempel, der „zuletzt geändert" bedeutet und nicht „zuletzt gesehen" –
sonst behauptete die Kachel Frische, wo sich nichts getan hat. Die Uhr
bekommt dasselbe Bild: WatchFridge trägt jetzt ein Kennzeichen isLive.

BMS und Neigungsmesser bleiben dauerhaft verbunden. Sie stören nicht, und
ihre Werte will man laufend sehen.

Nicht nachgezogen ist die Android-App – dort verbindet der
BluetoothManager weiterhin dauerhaft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 22:00:10 +02:00

85 lines
4.3 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Foundation
/// Erfundene Werte für den Simulator, damit sich die Ansichten ohne iPhone und
/// ohne Fahrzeug prüfen lassen. Eingeschaltet über `CAMPER_DEMO=1`:
///
/// xcrun simctl launch --terminate-running-process booted \
/// de.fritob.CamperMonitor.watchkitapp
/// # mit SIMCTL_CHILD_CAMPER_DEMO=1 davor
///
/// Im normalen Betrieb wird hiervon nichts ausgeführt.
enum WatchDemo {
private static let profile = Profile(name: "Kastenwagen", symbol: "box.truck",
trackWidth: 1.85, wheelbase: 3.50)
private static let solarID = UUID(uuidString: "00000000-0000-0000-0000-000000000050")!
private static let batteryID = UUID(uuidString: "00000000-0000-0000-0000-0000000000A0")!
private static let fridgeID = UUID(uuidString: "00000000-0000-0000-0000-0000000000F0")!
private static let levelID = UUID(uuidString: "00000000-0000-0000-0000-0000000000E0")!
/// `seconds` läuft weiter, damit sich die Neigung bewegt sonst zeigt der
/// Ausrichtungs-Assistent nie einen Trend.
static func payload(at seconds: Double) -> WatchPayload {
let now = Date()
let swing = sin(seconds / 8)
var level = LevelState()
level.pitch = 1.4 * swing + 0.3
level.roll = -0.9 * cos(seconds / 11)
level.pitchOffset = 0.4
level.rollOffset = -0.2
var solar = DeviceSnapshot(deviceID: solarID, timestamp: now, rssi: -58)
solar.state = "Konstantspannung (Absorption)"
solar.metrics = [
Metric("pv_power", "PV-Leistung", 284 + 40 * swing, unit: "W", precision: 0, primary: true),
Metric("battery_voltage", "Batteriespannung", 14.12, unit: "V", precision: 2),
Metric("battery_current", "Ladestrom", 18.6, unit: "A", precision: 1),
]
var battery = DeviceSnapshot(deviceID: batteryID, timestamp: now, rssi: -64)
battery.state = "Lädt"
battery.metrics = [
Metric("soc", "Ladezustand", 78.4, unit: "%", precision: 1, primary: true),
Metric("voltage", "Spannung", 13.66, unit: "V", precision: 2),
Metric("current", "Strom", 18.6, unit: "A", precision: 1),
Metric("capacity", "Restkapazität", 156.8, unit: "Ah", precision: 1),
]
var fridge = DeviceSnapshot(deviceID: fridgeID, timestamp: now, rssi: -66)
fridge.state = "Kompressor läuft"
fridge.metrics = [
Metric("temperature", "Innentemperatur", 6, unit: "°C", precision: 0, primary: true),
Metric("target", "Solltemperatur", 4, unit: "°C", precision: 0),
Metric("battery_voltage", "Bordspannung", 12.7, unit: "V", precision: 1),
]
return WatchPayload(
generatedAt: now,
profile: profile,
isRadioReady: true,
radioStatus: "Demo-Modus",
devices: [
WatchDevice(id: levelID, name: "Nivellierung", role: .leveling,
link: .live, snapshot: level.snapshot(deviceID: levelID, rssi: -70),
level: level, orientation: .identity, fridge: nil),
WatchDevice(id: batteryID, name: "Bulltron 200 Ah", role: .bms,
link: .live, snapshot: battery, level: nil,
orientation: nil, fridge: nil),
WatchDevice(id: solarID, name: "Solar Dach", role: .solarCharger,
link: .live, snapshot: solar, level: nil,
orientation: nil, fridge: nil),
WatchDevice(id: fridgeID, name: "Kühlbox", role: .fridge,
link: .live, snapshot: fridge, level: nil, orientation: nil,
fridge: WatchFridge(isLive: true, updated: now,
isPoweredOn: true, isEco: true, isLocked: false,
isDualZone: false, unitSymbol: "°C",
leftTarget: 4, leftCurrent: 6,
rightTarget: nil, rightCurrent: nil,
minTarget: -20, maxTarget: 20,
batteryVolts: 12.7)),
])
}
}