import Foundation /// Klartexte für die Zustands- und Fehlercodes aus den Victron-Werbedaten. enum VictronCodes { /// VE.Reg 0x0201 – Betriebszustand des Laders. static func deviceState(_ code: UInt32?) -> String? { guard let code else { return nil } switch code { case 0: return "Aus" case 1: return "Stromsparmodus" case 2: return "Störung" case 3: return "Konstantstrom (Bulk)" case 4: return "Konstantspannung (Absorption)" case 5: return "Erhaltung (Float)" case 6: return "Lagerung" case 7: return "Ausgleichsladung" case 9: return "Wechselrichten" case 11: return "Netzteilbetrieb" case 245: return "Startet" case 246: return "Wiederholte Absorption" case 247: return "Auto-Ausgleich" case 248: return "Battery Safe" case 252: return "Externe Steuerung" default: return "Zustand \(code)" } } /// VE.Reg 0xEDDA – Ladefehler. 0 bedeutet "kein Fehler". static func chargerError(_ code: UInt32?) -> String? { guard let code, code != 0 else { return nil } switch code { case 1: return "Batterietemperatur zu hoch" case 2: return "Batteriespannung zu hoch" case 3: return "Temperatursensor defekt" case 4: return "Temperatursensor Kurzschluss" case 5: return "Temperatursensor unplausibel" case 6: return "Spannungsmessung defekt" case 7: return "Spannungsmessung Kurzschluss" case 8: return "Spannungsmessung unplausibel" case 11: return "Zu hohe Restwelligkeit" case 14: return "Batterietemperatur zu niedrig" case 17: return "Lader überhitzt" case 18: return "Lader Überstrom" case 19: return "Stromrichtung verkehrt" case 20: return "Bulk-Zeit überschritten" case 21: return "Stromsensor defekt" case 22: return "Interner Temperatursensor defekt" case 26: return "Anschlussklemme überhitzt" case 27: return "Kurzschluss im Lader" case 28: return "Endstufenfehler" case 29: return "Überladeschutz" case 33: return "Eingangsspannung zu hoch (PV)" case 34: return "Eingangsstrom zu hoch (PV)" case 38: return "Eingang abgeschaltet (Batteriespannung)" case 39: return "Eingang abgeschaltet (Stromfluss)" case 65: return "Kommunikation verloren" case 66: return "Konfiguration synchronisierter Lader fehlerhaft" case 67: return "BMS-Verbindung verloren" case 68: return "Netzwerk fehlkonfiguriert" case 116: return "Kalibrierdaten verloren" case 117: return "Inkompatible Firmware" case 119: return "Einstellungen ungültig" default: return "Fehler \(code)" } } /// VE.Reg 0x0207 – Bitmaske, warum das Gerät gerade nicht arbeitet. static func offReasons(_ mask: UInt32?) -> [String] { guard let mask, mask != 0 else { return [] } let table: [(UInt32, String)] = [ (0x0000_0001, "Keine Eingangsspannung"), (0x0000_0002, "Per Schalter ausgeschaltet"), (0x0000_0004, "Per Einstellung ausgeschaltet"), (0x0000_0008, "Remote-Eingang"), (0x0000_0010, "Schutzfunktion aktiv"), (0x0000_0020, "Paygo"), (0x0000_0040, "BMS"), (0x0000_0080, "Motor-Abschalterkennung"), (0x0000_0100, "Eingangsspannung wird geprüft"), ] return table.filter { mask & $0.0 != 0 }.map(\.1) } /// VE.Reg 0xEEB8 – Alarmgründe des Batteriewächters. static func alarmReasons(_ mask: UInt32?) -> [String] { guard let mask, mask != 0 else { return [] } let table: [(UInt32, String)] = [ (0x0001, "Unterspannung"), (0x0002, "Überspannung"), (0x0004, "Niedriger Ladezustand"), (0x0008, "Starterbatterie Unterspannung"), (0x0010, "Starterbatterie Überspannung"), (0x0020, "Temperatur zu niedrig"), (0x0040, "Temperatur zu hoch"), (0x0080, "Mittenspannung"), (0x0100, "Ladung überfällig"), ] return table.filter { mask & $0.0 != 0 }.map(\.1) } }