1/3 Phasen Umschaltung Victron und Loxone

habe mal mit der Ki zusammen ein Script für die 1/3 Phasen Umschaltung der Wallboxen gebastelt.

Wallbox Phasenumschaltung

🎛️ Belegung der Ein- und Ausgänge am Script-Baustein
Eingänge (Inputs):
* AI1 (In1): Soll-Leistung in Watt (vom PV-Energiemanager / Überschuss).
* AI2 (In2): Schwelle 3-Phasen in Watt (z. B. 4150).
* AI3 (In3): Schwelle 1-Phase in Watt (z. B. 3500).
* AI4 (In4): EV-Status vom Phoenix (Modbus Register 100).
* AI5 (In5): Spannung L1 vom Phoenix (Modbus Register 104).
* AI6 (In6): Mindestlaufzeit in Minuten (z. B. 10 oder 15).
* AI7 (In7): Freigabe Wallbox Manager (Vom Loxone Baustein, z. B. Ausgang Cp oder Ladestart-Logik).
* AI8 (In8): Gemessene Ist-Leistung (L1) vom Phoenix in Watt (vom Modbus-Zähler).
* AI9 (In9): Zählertyp (0 = 1-phasiger Zähler, 1 = 3-phasiger Zähler).

Ausgänge (Outputs):
* AQ1: Schütz 1-Phase (Digital-Ausgang an Loxone Relais).
* AQ2: Schütz 3-Phasen (Digital-Ausgang an Loxone Relais).
* AQ3: Modbus-Enable für Phoenix Controller (Holding Register 400 / 100).
* AQ4: Modbus-Ladestrom in Ampere (Holding Register 300).
* AQ5: Errechnete Ist-Leistung in Watt (Direkt für den Loxone Wallbox Manager Eingang Pe / Wirkleistung).
* AQ6: Fehlerausgang (Digital-Ausgang: 0 = Alles OK, 1 = Fehler Status E oder F aktiv).
* AQ7: Fahrzeug lädt (Digital-Ausgang: 1 = Lädt aktiv, 0 = Standby/Pause/Warten).
* AQ8: Fahrzeug angesteckt (Digital-Ausgang: 1 = Status B, C oder D).

und hier das Script

// Loxone PicoC Script mit ZOE-Anlaufverzögerung, Status-Auswertungen und Steck-Erkennung (AQ8)
int aktuellePhase = 1; 
int umschaltPhase = 0; 
float zielStrom = 0.0;
int phasenZeitZaehler = 0; 
int ladeAnlaufZaehler = 0; 

while(1) {
    float sollLeistung = getinput(0);
    float schwelle3p = getinput(1);
    float schwelle1p = getinput(2);
    float evStatus = getinput(3);
    float netzSpannung = getinput(4);
    int mindestLaufzeitMin = (int)getinput(5); 
    int managerFreigabe = (int)getinput(6);    
    float istLeistungModbus = getinput(7);     
    int zaehlerTyp = (int)getinput(8);         
    
    // Sicherheits-Fallback für Netzspannung
    if (netzSpannung < 180.0 || netzSpannung > 260.0) {
        netzSpannung = 230.0; 
    }
    
    // Sekundenzähler für die aktuelle Phase hochzählen 30 Sekunden
    if (phasenZeitZaehler < 30000) {
        phasenZeitZaehler++;
    }
    
    // Ermittlung der gewünschten Zielphase basierend auf der Leistung
    int zielPhase = aktuellePhase;
    if (sollLeistung >= schwelle3p) {
        zielPhase = 3;
    } else if (sollLeistung < schwelle1p) {
        zielPhase = 1;
    }
    
    int mindestLaufzeitSek = mindestLaufzeitMin * 60;
    
    // --- FEHLERPRÜFUNG (Status E = 69 oder Status F = 70) ---
    if (evStatus == 69 || evStatus == 70) {
        setoutput(2, 0);    // Modbus Enable AUS
        setoutput(3, 0.0);  // Ladestrom auf 0A
        setoutput(0, 0);    // 1p Schütz AUS
        setoutput(1, 0);    // 3p Schütz AUS
        setoutput(4, 0.0);  // Ist-Leistung auf 0W
        
        setoutput(5, 1);    // Fehlerausgang AQ6 auf 1
        setoutput(6, 0);    // Lade-Indikator AQ7 auf 0
        setoutput(7, 0);    // Angesteckt-Indikator AQ8 auf 0 bei Fehler
        
        sleep(1000);
        continue; 
    } else {
        setoutput(5, 0);    // Kein Fehler aktiv
    }
    
    // Umschaltung triggern unter Einhaltung der ZOE-Sicherheitszeiten & Mindestlaufzeit
    if (zielPhase != aktuellePhase && umschaltPhase == 0 && evStatus > 65 && evStatus < 69 && phasenZeitZaehler >= mindestLaufzeitSek) {
        umschaltPhase = 1;
        
        setoutput(3, 0.0);  
        setoutput(2, 0);    
        setoutput(0, 0);    
        setoutput(1, 0);    
        setoutput(4, 0.0);
        setoutput(6, 0);    
        // AQ8 bleibt während der Umschaltung auf 1, da das Auto physisch angesteckt bleibt
        setoutput(7, 1);    
        
        sleep(10000); // Beruhigungszeit für die ZOE  10Sekunden
        
        aktuellePhase = zielPhase;
        if (aktuellePhase == 1) {
            setoutput(0, 1); 
        } else {
            setoutput(1, 1); 
        }
        
        sleep(3000); // Schützkontakte stabilisieren 3Sekunden
        
        phasenZeitZaehler = 0;
        ladeAnlaufZaehler = 0; 
        umschaltPhase = 0;
    }
    
    // Regelbetrieb und Leistungsberechnung
    if (umschaltPhase == 0) {
        
        // --- 1. LADESTEUERUNG ---
        if (managerFreigabe == 1 && evStatus > 65 && evStatus < 69) {
            if (aktuellePhase == 1) {
                zielStrom = sollLeistung / netzSpannung;
            } else {
                zielStrom = sollLeistung / (netzSpannung * 3.0);
            }
            
            if (zielStrom < 6.0) {
                setoutput(2, 0); 
                setoutput(3, 0.0);
                ladeAnlaufZaehler = 0; 
            } else {
                if (zielStrom > 32.0) zielStrom = 32.0; 
                setoutput(3, zielStrom); 
                setoutput(2, 1); 
                
                if (ladeAnlaufZaehler < 100) {
                    ladeAnlaufZaehler++;
                }
            }
        } else {
            setoutput(2, 0);   
            setoutput(3, 0.0); 
            ladeAnlaufZaehler = 0;
            
            if (evStatus <= 65) {
                setoutput(0, 0);
                setoutput(1, 0);
            }
        }
        
        // --- 2. IST-LEISTUNGSBERECHNUNG & DYNAMISCHE AUSGÄNGE ---
        float gesamteIstLeistung = 0.0;
        int istAmLaden = 0;
        int istAngesteckt = 0;
        
        // AQ8 Steuerung: Angesteckt bei Zustand B (66), C (67) oder D (68)
        if (evStatus >= 66 && evStatus <= 68) {
            istAngesteckt = 1;
        }
        
        if (evStatus == 67 || evStatus == 68) { 
            if (istLeistungModbus > 10.0 || ladeAnlaufZaehler < 20) {
                if (istLeistungModbus > 10.0) {
                    istAmLaden = 1;
                }
                
                if (zaehlerTyp == 1) {
                    gesamteIstLeistung = istLeistungModbus;
                } else {
                    if (aktuellePhase == 1) {
                        gesamteIstLeistung = istLeistungModbus;
                    } else {
                        gesamteIstLeistung = istLeistungModbus * 3.0;
                    }
                }
            }
        }
        
        setoutput(4, gesamteIstLeistung); // Gesamtleistung an AQ5
        setoutput(6, istAmLaden);          // Lade-Indikator an AQ7
        setoutput(7, istAngesteckt);       // Angesteckt-Indikator an AQ8 (HIER NEU)
    }
    
    sleep(1000); 
}

ich bin gespannt ob das funktioniert :innocent:

1 „Gefällt mir“