Die drei Libellen widersprachen sich: Die Live Activity liess die Blase bei
positivem Pitch nach unten wandern – mit dem Kommentar "wie bei der echten
Wasserwaage in der App" –, waehrend iPhone und Uhr genau das Gegenteil taten.
Gemeint war immer eine Draufsicht mit Fahrtrichtung oben, in der die Blase zur
hoeheren Seite ausschlaegt: Steht das Heck hoeher, gehoert sie nach hinten,
also nach unten. iPhone und Uhr ziehen jetzt nach.
Die Android-Fassung bleibt vorerst bei der alten Richtung.
Dazu `shortInstructions`: dieselbe Aussage wie `instruction`, aber in kurzen
Zeilen statt einem Satz. Auf schmalen Anzeigen passt "Heck steht hoeher, links
steht hoeher" in keine lesbare Zeile. Beide stehen nebeneinander, damit die
Vorzeichen nicht auseinanderlaufen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Die Vorlage lag auf einer quadratischen 1254×1254-Leinwand, der Van
darin füllte aber nur rund 59% der Höhe – bei deklariertem
sideAspect = 1 (quadratisch) rechnete SwiftUI die Anzeigegrösse für
dieses volle Quadrat, wodurch der Van in der gemeinsamen Bildhülle
deutlich kleiner erschien als Vanster, dessen Vorlage eng auf die
Silhouette zugeschnitten ist.
Bild jetzt auf den Inhalt zugeschnitten (plus kleiner Rand, wie bei
Vanster), sideAspect entsprechend von 1 auf das tatsächliche Verhältnis
der zugeschnittenen Vorlage (1212×790) angepasst. In beiden
Asset-Katalogen ersetzt (iPhone und Watch, siehe vorherigen Commit zur
Watch-Fahrzeuggrafik).
Die Heckansicht war laut Rückmeldung bereits optisch stimmig und blieb
unverändert.
Build (App + Watch) und Tests grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Die Uhr zeigte in der Fahrzeug-Ansicht bislang immer Vanster fest
verdrahtet, unabhängig von der Auswahl am iPhone – das galt schon vor
dieser Session, nicht erst seit dem Solar-Merge.
WatchDevice trägt jetzt vehicleGraphicStyle (nur beim Neigungsmesser
belegt, wie orientation), von PhoneWatchLink beim Aufbau der Nutzlast
gefüllt. WatchVehicleView nimmt den Stil als Parameter statt der fest
verdrahteten Vanster-Bildnamen, WatchLevelView reicht ihn aus dem
zuletzt vom iPhone übertragenen Stand durch. California-Bilder dafür
zusätzlich in den Watch-eigenen Asset-Katalog kopiert (die Uhr hat
einen eigenen, vom iPhone getrennten Katalog).
Ausgewählt wird der Stil weiterhin nur am iPhone (Neigungsmesser
einrichten → Fahrzeuggrafik). Persistenz war dafür schon vorhanden:
vehicleGraphicStyle ist ein normales, codiertes Feld auf
ConfiguredDevice ohne eigene encode(to:)-Überschreibung – wird also
schon beim Speichern mitgeschrieben.
Nebenbei: Xcode hat beim Bearbeiten den Build-Zähler auf 2 gesetzt und
LSApplicationCategoryType (Dienstprogramme) ergänzt – unverändert
übernommen.
Build (App + Watch) und Tests grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
VanControlWatch hat ein eigenes, vom iPhone-Target unabhängiges
AppIcon.appiconset – das zeigte beim Einbinden von App1/App2 noch das
alte Logo. Jetzt dieselbe Vorlage wie das primäre iPhone-Icon
(App1-Testflight), damit iPhone- und Watch-App auf dem Homescreen
zusammengehörig aussehen.
Build (Watch + App) und Tests grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Vier neue AppIcon-Asset-Kataloge angelegt (App1/App2, jeweils Standard-
und TestFlight-Variante), aus den bereitgestellten 1024×1024-Vorlagen
(bereits randlos, ohne Alphakanal – nur noch skaliert).
Verdrahtet für den aktuellen TestFlight-Build:
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon-App1-Testflight (primär)
- ASSETCATALOG_COMPILER_ALTERNATE_APPICON_NAMES = AppIcon-App2-Testflight
- ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES, damit auch die
noch unverdrahteten App1/App2-Sets (für den finalen Store-Build) mit
ins Bundle kommen, statt vom Compiler als ungenutzt verworfen zu werden
Fürs finale Release genügt es, ASSETCATALOG_COMPILER_APPICON_NAME auf
AppIcon-App1 und die Alternate-Liste auf AppIcon-App2 umzustellen – die
TestFlight-Varianten sollen Betatester optisch von der echten Version
unterscheiden.
Nur das Haupt-App-Target ist betroffen; Watch- und Complication-Icon
bleiben unverändert. Build (App + Watch) und Tests grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Seiten- und Heckansicht kamen als weiß gefüllte Vorlage ohne Alphakanal
(Tools/California Side.png, Tools/California Back.png). Dafür ein neues
Werkzeug ergänzt, das den weißen Grund in echte Transparenz übersetzt
(mit weichem statt hartem Schwellwert, um Kanten nicht auszufransen),
danach wie gewohnt durch make-vehicle-art.swift geschickt.
California hatte bisher keine eigene Heckansicht und griff ersatzweise
auf die von Vanster zurück – jetzt eigenes CaliforniaRear-Imageset,
VehicleGraphicStyle.rearImageName entsprechend angepasst. Seiten- und
Heckbild sind quadratisch (1254×1254), passend zu den bestehenden
Seitenverhältnissen (sideAspect/rearAspect = 1) – keine Anpassung dort
nötig.
Build und Tests grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
App Store Connect fragt beim Hochladen nach Verschlüsselung, wenn der
Info.plist-Schlüssel fehlt. Die App entschlüsselt Victron-Advertisements
per AES-128-CTR über CommonCrypto – ein Standardalgorithmus über eine
vom Betriebssystem gestellte Standardbibliothek, nur Nebenzweck der App
und damit nach US-Exportrecht typischerweise ausgenommen. Schlüssel auf
false gesetzt, damit die Abfrage bei künftigen Uploads entfällt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Beim Setzen der Versionsnummer in Xcode ist bei den beiden
VanControlWatch-Konfigurationen "0,1" statt "0.1" hereingerutscht,
vermutlich durch die deutsche Locale beim Zahlen-Eingabefeld. App Store
Connect erwartet ein Punkt-Format; mit dem Komma wäre das beim
Archivieren/Hochladen vermutlich angeeckt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Der Einstellungen-Schalter für den Demo-Modus war in #if DEBUG
eingeschlossen und damit in Archiven (Release-Konfiguration, wie sie
Product → Archive und damit jeder TestFlight-Build verwendet) komplett
herauskompiliert. TestFlight-Tester konnten den Demo-Modus dadurch nicht
nutzen.
DemoData.isEnabled und der Schalter in SettingsView sind jetzt
konfigurationsunabhängig; nur die CAMPER_DEMO-Umgebungsvariable bleibt
auf Debug-Builds beschränkt, da sie ohnehin nur über Xcode/simctl
gesetzt werden kann.
Build (Debug + Release) und Tests grün; per strings(1) im
Release-Binary verifiziert, dass der Demo-Modus-Code tatsächlich
mitkompiliert wird.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* Demo-Modus-Abschnitt an den tatsächlichen Code angeglichen: Schalter in
den Einstellungen (für lokal installierte Builds ohne Xcode) und
Umgebungsvariable, beide dokumentiert.
* Quelle für den Votronic-Solarregler ergänzt (syssi/esphome-votronic),
eigener Abschnitt analog zu Kühlbox/WattCycle.
* Persönlichen Pfad aus der Bauanleitung entfernt (open VanControl.xcodeproj
statt eines lokalen Nutzerpfads); Beispiel-Bundle-ID im Demo-Modus-Befehl
durch Platzhalter ersetzt.
Zusätzlich: Symbolliste für Fahrzeugprofile auf Wunsch exakt auf die aus
solar-integration zurückgesetzt (car, car.side, suv.side, truck.pickup.side,
box.truck, bus), statt sie mit dev_watchs Liste zusammenzuführen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Drei vom Nutzer im Testbuild gefundene Fehler:
* DeviceStore.save() schrieb auch im Demo-Modus in UserDefaults. Jede
Änderung während aktivem Demo-Modus (z.B. Fahrzeuggrafik oder
Einbaulage ändern) persistierte damit die erfundenen Fahrzeuge/Geräte
dauerhaft – sie blieben nach dem Deaktivieren des Demo-Modus stehen.
save() ist jetzt im Demo-Modus ein no-op.
* Die Kühlbox-Schalter (Ein/Aus, Eco/Max, Solltemperatur, Sperre) liefen
über sendFridgeSettings(), das eine echte Bluetooth-Verbindung
voraussetzt (`managed`-Eintrag) – im Demo-Modus gibt es die nie, die
Schalter taten also nichts. Im Demo-Modus wird der angezeigte
AlpicoolState jetzt direkt geändert, ohne den Umweg über einen
Stellbefehl.
* Der Live-Activity-Schalter liess sich nicht einschalten, weil dem
Haupt-App-Target der Info.plist-Schlüssel NSSupportsLiveActivities
fehlte – Activity.request() wirft ohne ihn, wird aber vom Aufrufer
stillschweigend abgefangen, sodass der Schalter beim Antippen einfach
auf Aus zurückspringt.
Build (App + Watch) und Tests grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Drei Dateien aus solar-integration wurden beim Zusammenführen mit
dev_watch übersehen, weil sie fälschlich als "identisch zwischen den
Branches" eingestuft wurden:
* DemoData.isEnabled kannte nur noch den Umgebungsvariablen-Weg
(CAMPER_DEMO=1). Der Schalter in den Einstellungen – der einzige Weg,
Demo-Daten auf einem lokal installierten Build ohne Xcode-Verbindung
einzuschalten – fehlte ganz, SettingsView.swift war nie zusammengeführt
worden.
* LevelSetupView.swift fehlte der komplette Abschnitt "Fahrzeuggrafik" –
die Kachel-Auswahl zwischen den VehicleGraphicStyle-Varianten
(Vanster/California). Das Feld existierte im Modell und wurde beim
Rendern gelesen, war aber nirgends einstellbar.
* DeviceCard.swift zeigte die Nivellierungs-Kachel wie jedes andere
Gerät (Hauptwert + Nebenwerte) statt der grossen Front/Heck- und
Links/Rechts-Anzeige mit Richtungsbuchstaben.
Anlass: Im Testbuild fehlte deshalb sowohl der Demo-Modus als auch die
Fahrzeuggrafik-Auswahl. Als Konsequenz systematisch alle beim Merge als
"bereits identisch" eingestuften Dateien erneut gegengeprüft – keine
weiteren Lücken gefunden.
Build (App + Watch) und Protokoll-Tests grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
LevelActivityManager.update() stiess bei jeder Messung sofort
activity.update() an – der Neigungsmesser liefert per Notify oder
0,5s-Poll deutlich öfter als einmal pro Sekunde. Bei dieser Frequenz
drosselt iOS lokale Live-Activity-Aktualisierungen zunehmend selbst,
was in CarPlay auffiel: Das Dashboard zeigt neue Werte dort spürbar
verzögert an, weil es ohnehin zurückhaltender aktualisiert als
Sperrbildschirm oder Dynamic Island und die Drosselung dadurch sichtbar
wird.
Jetzt wird höchstens einmal pro Sekunde tatsächlich aktualisiert;
Messungen innerhalb der Sperrfrist werden nicht verworfen, sondern der
neueste Stand fürs Fristende vorgemerkt (wie schon beim
Verbindungsabbruch mit `pendingEnd` gehandhabt).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Nach dem Entfernen der Beispiel-Widget/-Control-Dateien enthielt
VanControlWidget(Extension) nur noch die Live Activity – der Name war
damit irreführend. Jetzt VanControlLiveActivity(Extension) durchgängig:
Ordner, Target, Produkt, Bundle-ID-Suffix, Dateien
(VanControlLiveActivity.swift, VanControlLiveActivityBundle.swift) und
Anzeigename ("VanControl Live Activity").
Build (App Debug+Release, Watch) und Protokoll-Tests grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
VanControlWidget.swift, VanControlWidgetControl.swift und AppIntent.swift
waren unverändertes Xcode-Vorlagenmaterial ("Favorite Emoji", "This is
an example widget", ein Timer-Control ohne echte Funktion) – nie an die
App angebunden. Die Extension bleibt bestehen, weil die Live Activity
(VanControlWidgetLiveActivity, echte Neigungswerte) dort hinein muss;
das Bundle enthält jetzt nur noch sie.
Build (Debug + Release) grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CamperMonitor (Haupt-Repo) und VanAligneiOS (aus dem gemergten
solar-integration-Branch) liefen unter zwei verschiedenen internen
Namen, obwohl die App nach aussen längst einheitlich "VanControl Pro"
heisst. Jetzt durchgängig VanControl:
- Ordner: CamperMonitor/, CamperMonitorWatch/, CamperMonitorComplication/,
VanAligneiOSWidget/ → VanControl/, VanControlWatch/,
VanControlComplication/, VanControlWidget/
- Xcode-Projekt: CamperMonitor.xcodeproj → VanControl.xcodeproj, alle
Targets/Schemes/Produktnamen entsprechend umbenannt
- Bundle-Identifier auf Wunsch mitgeändert: de.s0.fototeddy.VanControl*
(App noch nicht veröffentlicht); dabei auch die
WKCompanionAppBundleIdentifier-Werte korrigiert, die noch das alte
de.fritob-Präfix statt des tatsächlichen de.s0.fototeddy-Präfixes
trugen
- Swift-Dateien/Typen: CamperMonitorApp → VanControlApp,
VanAligneiOSWidget* → VanControlWidget*
- Config/*-Info.plist umbenannt, README.md/Tools/README.md/run-tests.sh
auf die neuen Pfade angepasst
Bewusst unverändert: firmware/vanalign und alle Bezüge auf "VanAlign"
als Namen der Neigungsmesser-Hardware (eigenständiges Produkt, kein
App-Name) sowie der komplette Android/-Ordner.
Build (App, Watch, Debug) und Protokoll-Testlauf grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
.solarCharger und .solar sahen im Code zu ähnlich aus, um auf einen
Blick zu erkennen, welches der Victron-Solarladeregler (passives
BLE-Advertisement) und welches der Votronic-Solarladeregler (aktive
GATT-Verbindung über die ESP32-Bridge) ist. Jetzt .victronSolarCharger
und .votronicSolar, samt allen abgeleiteten Bezeichnern in DemoData,
WatchDemo und Tests. Die rawValues bleiben "solarCharger"/"solar", damit
bereits gespeicherte Geräte beim Decodieren nicht auf einen unbekannten
Rollen-Wert treffen.
VictronAdvertisement.RecordType.solarCharger (das rohe Protokollfeld)
bleibt unverändert – schon durch den Typnamen eindeutig, und passend
zur offiziellen Victron-Bezeichnung des Datensatztyps.
run-tests.sh fehlten VehicleGraphicStyle.swift und VehicleTilt.swift,
seit ConfiguredDevice sie referenziert – ergänzt, Testlauf grün.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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>