forked from fritob/Camper-Monitor
solar-integration (aus dem separaten VanAligneiOS-Repo) und dev_watch haben unabhängige Git-Historien, decken aber überlappende und sich ergänzende Funktionen ab. Übernommen aus solar-integration: Votronic- Solar-ESP-Anbindung samt Geräterolle, die Live-Activity/Widget-Extension fürs Sperrbildschirm/Dynamic-Island/CarPlay, das Querformat-Layout für Libelle/Fahrzeug-Ansicht und Ausrichtungs-Assistent, sowie die mehreren Fahrzeuggrafik-Stile (Vanster/California). Beibehalten aus dev_watch: alle zusätzlichen Geräteprotokolle (Daly-/JBD-BMS, Alpicool- Kühlbox, WattCycle, Victron), die dort zwischenzeitlich entstanden. Die Xcode-Projektdatei wurde von Hand um die neue Widget-Extension samt SharedActivity-Gruppe erweitert (Datei-synchronisierte Gruppen, kein App-Group-Entitlement nötig). Build für App, Watch und Widget-Extension geprüft (Debug und Release). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
57 lines
2.3 KiB
Swift
57 lines
2.3 KiB
Swift
import SwiftUI
|
||
|
||
@main
|
||
struct CamperMonitorApp: App {
|
||
@State private var store: DeviceStore
|
||
@State private var bluetooth: BluetoothManager
|
||
@State private var watch: PhoneWatchLink
|
||
@State private var levelActivity: LevelActivityManager
|
||
@Environment(\.scenePhase) private var scenePhase
|
||
|
||
init() {
|
||
let store = DeviceStore()
|
||
let bluetooth = BluetoothManager(store: store)
|
||
let levelActivity = LevelActivityManager()
|
||
bluetooth.activityManager = levelActivity
|
||
_store = State(initialValue: store)
|
||
_bluetooth = State(initialValue: bluetooth)
|
||
_watch = State(initialValue: PhoneWatchLink(store: store, bluetooth: bluetooth))
|
||
_levelActivity = State(initialValue: levelActivity)
|
||
}
|
||
|
||
var body: some Scene {
|
||
WindowGroup {
|
||
DashboardView()
|
||
.environment(store)
|
||
.environment(bluetooth)
|
||
.environment(watch)
|
||
.environment(levelActivity)
|
||
.task { watch.activate() }
|
||
}
|
||
.onChange(of: scenePhase) { _, phase in
|
||
// Im Hintergrund darf ohne Service-Filter ohnehin nicht gescannt
|
||
// werden, also Funk sparen und beim Zurückkommen neu starten.
|
||
//
|
||
// Ausnahme: Solange jemand auf die Uhr schaut, läuft es weiter. Beim
|
||
// Rangieren liegt das iPhone in der Halterung mit dunklem Bildschirm
|
||
// – hörte das Funkgerät dann auf, wäre die Anzeige am Handgelenk
|
||
// genau dann tot, wenn sie gebraucht wird. Die verbundenen Geräte
|
||
// (Neigungsmesser, BMS, Kühlbox) liefern im Hintergrund weiter; die
|
||
// Victron-Werbedaten nicht, dafür müsste ohne Filter gesucht werden.
|
||
watch.isAppInBackground = phase != .active
|
||
switch phase {
|
||
case .active:
|
||
bluetooth.start()
|
||
case .background:
|
||
// Läuft gerade eine Live Activity, muss der Neigungsmesser
|
||
// auch mit dunklem Bildschirm weiter Werte liefern – sonst
|
||
// friert die Anzeige auf Sperrbildschirm und CarPlay beim
|
||
// ersten Wegdrücken der App ein.
|
||
if !watch.wantsLiveUpdates && !levelActivity.isActive { bluetooth.stop() }
|
||
default:
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|