DeviceRole-Fälle für Victron- und Votronic-Solar eindeutig benennen

.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>
This commit is contained in:
fototeddy
2026-09-06 21:08:28 +02:00
co-authored by Claude Sonnet 5
parent e9b9c5bcd5
commit 83ea85f3b8
7 changed files with 61 additions and 49 deletions
@@ -891,7 +891,7 @@ extension BluetoothManager: CBCentralManagerDelegate {
return
}
if device.role == .solar {
if device.role == .votronicSolar {
// Bewusst kein Draht zu `activityManager`: Der Solarertrag soll
// nicht in der Live Activity/CarPlay auftauchen, die ist dem
// Neigungsmesser vorbehalten.
+11 -11
View File
@@ -34,9 +34,9 @@ enum DemoData {
name: "Ladebooster", role: .chargeBooster, profileID: Profile.defaultID,
peripheralID: UUID(uuidString: "00000000-0000-0000-0000-0000000000B1")!)
static let solar = ConfiguredDevice(
static let victronSolar = ConfiguredDevice(
id: UUID(uuidString: "00000000-0000-0000-0000-000000000050")!,
name: "Solar Dach", role: .solarCharger, profileID: Profile.defaultID,
name: "Solar Dach", role: .victronSolarCharger, profileID: Profile.defaultID,
peripheralID: UUID(uuidString: "00000000-0000-0000-0000-000000000051")!)
static let battery = ConfiguredDevice(
@@ -44,9 +44,9 @@ enum DemoData {
name: "Bulltron 200 Ah", role: .bms, profileID: Profile.defaultID,
peripheralID: UUID(uuidString: "00000000-0000-0000-0000-0000000000A1")!)
static let caravanSolar = ConfiguredDevice(
static let caravanVictronSolar = ConfiguredDevice(
id: UUID(uuidString: "00000000-0000-0000-0000-0000000000C3")!,
name: "Solar Wohnwagen", role: .solarCharger, profileID: secondProfile.id,
name: "Solar Wohnwagen", role: .victronSolarCharger, profileID: secondProfile.id,
peripheralID: UUID(uuidString: "00000000-0000-0000-0000-0000000000C4")!)
static let fridge = ConfiguredDevice(
@@ -61,11 +61,11 @@ enum DemoData {
static let votronicSolar = ConfiguredDevice(
id: UUID(uuidString: "00000000-0000-0000-0000-0000000000D0")!,
name: "VotronicSolarESP", role: .solar, profileID: Profile.defaultID,
name: "VotronicSolarESP", role: .votronicSolar, profileID: Profile.defaultID,
peripheralID: UUID(uuidString: "00000000-0000-0000-0000-0000000000D1")!)
static var devices: [ConfiguredDevice] {
[solar, booster, battery, fridge, level, votronicSolar, caravanSolar]
[victronSolar, booster, battery, fridge, level, votronicSolar, caravanVictronSolar]
}
/// Leicht schräg stehend, damit die Libelle etwas zu zeigen hat.
@@ -103,9 +103,9 @@ enum DemoData {
}
static func snapshots() -> [DeviceSnapshot] {
var solarSnapshot = DeviceSnapshot(deviceID: solar.id, timestamp: Date(), rssi: -58)
solarSnapshot.state = "Konstantspannung (Absorption)"
solarSnapshot.metrics = [
var victronSolarSnapshot = DeviceSnapshot(deviceID: victronSolar.id, timestamp: Date(), rssi: -58)
victronSolarSnapshot.state = "Konstantspannung (Absorption)"
victronSolarSnapshot.metrics = [
Metric("pv_power", "PV-Leistung", 284, unit: "W", precision: 0, primary: true),
Metric("battery_power", "Ladeleistung", 262, unit: "W", precision: 0),
Metric("battery_voltage", "Batteriespannung", 14.12, unit: "V", precision: 2),
@@ -139,7 +139,7 @@ enum DemoData {
Metric("cycles", "Ladezyklen", 143, unit: "", precision: 0),
]
var caravanSnapshot = DeviceSnapshot(deviceID: caravanSolar.id, timestamp: Date(), rssi: -77)
var caravanSnapshot = DeviceSnapshot(deviceID: caravanVictronSolar.id, timestamp: Date(), rssi: -77)
caravanSnapshot.state = "Erhaltung (Float)"
caravanSnapshot.metrics = [
Metric("pv_power", "PV-Leistung", 62, unit: "W", precision: 0, primary: true),
@@ -147,7 +147,7 @@ enum DemoData {
Metric("battery_current", "Ladestrom", 4.4, unit: "A", precision: 1),
]
return [solarSnapshot, boosterSnapshot, batterySnapshot,
return [victronSolarSnapshot, boosterSnapshot, batterySnapshot,
fridgeState.snapshot(deviceID: fridge.id, rssi: -66),
levelState.snapshot(deviceID: level.id, rssi: -70),
votronicSolarESPState.snapshot(deviceID: votronicSolar.id, rssi: -58),
+4 -4
View File
@@ -127,7 +127,7 @@ private struct ConfigureDeviceView: View {
@Environment(\.dismiss) private var dismiss
@State private var name: String = ""
@State private var role: DeviceRole = .solarCharger
@State private var role: DeviceRole = .victronSolarCharger
@State private var key: String = ""
private var needsKey: Bool { role.transport == .advertisement }
@@ -188,15 +188,15 @@ private struct ConfigureDeviceView: View {
private func prefill() {
if let recordType = discovery.victronRecordType {
switch VictronAdvertisement.RecordType(rawValue: recordType) {
case .solarCharger: role = .solarCharger
case .solarCharger: role = .victronSolarCharger
case .dcdcConverter, .orionXS: role = .chargeBooster
case .batteryMonitor: role = .batteryMonitor
default: role = .solarCharger
default: role = .victronSolarCharger
}
} else if discovery.isLevelSensor {
role = .leveling
} else if discovery.isVotronicSolarESPSensor {
role = .solar
role = .votronicSolar
} else if let name = discovery.name?.lowercased(),
["alpicool", "icecube", "ice cube", "fridge", "cool"].contains(where: name.contains) {
role = .fridge