Hallo,
hier bitte nur Antworten die sich direkt auf diese Lösung beziehen, Nachfragen und andere Vorschläge bitte hier: Victron Multiplus Backup Kit für alte PV Anlage - #24 by cekey
erst mal das Konzept:
1️⃣ Grundarchitektur (final)
┌─────────────────────────┐
│ Cerbo GX │
│ │
│ Node-RED │
│ ├─ Leistungslogik │
│ ├─ Verbraucherlogik │
│ ├─ Netzlogik (später) │
│ │
│ Relais 1 → Netzrelais │ (später)
│ Relais 2 → Verbraucher │
└─────────┬───────────────┘
│ MQTT
┌─────────────┴─────────────┐
│ │
┌───────▼────────┐ ┌────────▼─────────┐
│ Shelly 2PM G3 │ │ Shelly 1 Gen3 │
│ (WR-Leistung) │ │ Verbraucher 2 │
└───────┬────────┘ └────────┬─────────┘
│ │
2× Wechsler-Relais Verbraucher
(EVU Fronius)
[
{
"id": "config_globals",
"type": "function",
"name": "CONFIG – System & Annahmen",
"func": "// ======================================================\n// ZENTRALE SYSTEMKONFIGURATION\n// Alles hier ändern – nirgendwo sonst!\n// ======================================================\n\n// ------------------------------\n// MQTT / SYSTEM-ANNAHMEN\n// ------------------------------\n// MQTT-Broker läuft lokal auf dem Cerbo GX\nflow.set('MQTT_BROKER', '127.0.0.1');\nflow.set('MQTT_PORT', 1883);\n\n// Victron Standard MQTT Topics (Venus OS)\n// Falls Victron ein Update macht oder sich Topics ändern,\n// sind sie hier zentral angepasst\nflow.set('TOPIC_SOC', 'N/+/system/0/Dc/Battery/Soc');\nflow.set('TOPIC_AC_LOAD', 'N/+/system/0/Ac/Consumption/Total/Power');\nflow.set('TOPIC_GRID_POWER', 'N/+/system/0/Ac/Grid/Total/Power');\nflow.set('TOPIC_GRID_CONNECTED', 'N/+/system/0/Ac/ActiveIn/Connected');\n\n// Shelly MQTT Topics (Gen3)\nflow.set('TOPIC_SHELLY_PV_R1', 'shellies/shelly-2pm-gen3/relay/0/command');\nflow.set('TOPIC_SHELLY_PV_R2', 'shellies/shelly-2pm-gen3/relay/1/command');\nflow.set('TOPIC_SHELLY_CONSUMER', 'shellies/shelly-1-gen3/relay/0/command');\n\n// ------------------------------\n// BATTERIE / SOC\n// ------------------------------\n// Unterhalb dieses SOC wird die PV-Leistung komplett gesperrt\nflow.set('SOC_MIN', 20);\n\n// SOC, bei dem der PV-Wechselrichter grundsätzlich gedrosselt werden soll\n// (nahe voll, um Laden/Entladen zu vermeiden)\nflow.set('SOC_STOP_PV', 95);\n\n// Sicherheitsabstand für Verbraucherfreigaben\n// Beispiel: STOP_PV 95 % – 5 % = Freigabe ab 90 %\nflow.set('SOC_RELEASE_OFFSET', 5);\n\n// ------------------------------\n// NETZ\n// ------------------------------\n// Erlaubter Netzbezug in Watt\n// 0 = absolut kein Bezug\n// 50–200 W sinnvoll bei großen Verbrauchern\nflow.set('GRID_IMPORT_LIMIT_W', 50);\n\n// SOC, bei dem später (optional) das Netz wieder zugeschaltet wird\n// (für Sommer-Inselbetrieb, aktuell nur dokumentiert)\nflow.set('GRID_RECONNECT_SOC', 15);\n\n// ------------------------------\n// LASTSCHWELLEN (hausintern)\n// ------------------------------\n// Unterhalb: keine PV-Freigabe\nflow.set('LOAD_LOW_W', 1000);\n\n// Ab hier: erste Leistungsstufe (30 %)\nflow.set('LOAD_MEDIUM_W', 3000);\n\n// Ab hier: zweite Leistungsstufe (60 %)\nflow.set('LOAD_HIGH_W', 5000);\n\n// ------------------------------\n// HYSTERESE / TAKTVERMEIDUNG\n// ------------------------------\n// SOC-Hysterese in Prozentpunkten\nflow.set('SOC_HYST', 2);\n\n// Leistungshysterese in Watt\nflow.set('POWER_HYST', 200);\n\n// Mindestzeit zwischen Schaltvorgängen\nflow.set('MIN_SWITCH_TIME_SEC', 60);\n\n// ------------------------------\n// VERBRAUCHERFREIGABEN\n// ------------------------------\n// Verbraucher 1: GX Relais 2 (näher an Grundlast)\nflow.set('CONSUMER1_SOC', flow.get('SOC_STOP_PV') - 5);\n\n// Verbraucher 2: Shelly 1 (größer / optional)\nflow.set('CONSUMER2_SOC', flow.get('SOC_STOP_PV') - 8);\n\n// ======================================================\n// ENDE DER KONFIGURATION\n// ======================================================\nreturn null;",
"x": 300,
"y": 80,
"wires": []
},
{
"id": "mqtt_soc",
"type": "mqtt in",
"name": "SOC",
"topic": "N/+/system/0/Dc/Battery/Soc",
"broker": "broker",
"x": 140,
"y": 160,
"wires": [["store_soc"]]
},
{
"id": "store_soc",
"type": "function",
"name": "Store SOC",
"func": "flow.set('soc', Number(msg.payload));\nreturn null;",
"x": 320,
"y": 160,
"wires": []
},
{
"id": "mqtt_load",
"type": "mqtt in",
"name": "AC Load",
"topic": "N/+/system/0/Ac/Consumption/Total/Power",
"broker": "broker",
"x": 140,
"y": 220,
"wires": [["store_load"]]
},
{
"id": "store_load",
"type": "function",
"name": "Store Load",
"func": "flow.set('load', Number(msg.payload));\nreturn null;",
"x": 320,
"y": 220,
"wires": []
},
{
"id": "mqtt_grid",
"type": "mqtt in",
"name": "Grid Power",
"topic": "N/+/system/0/Ac/Grid/Total/Power",
"broker": "broker",
"x": 140,
"y": 280,
"wires": [["store_grid"]]
},
{
"id": "store_grid",
"type": "function",
"name": "Store Grid",
"func": "flow.set('grid', Number(msg.payload));\nreturn null;",
"x": 320,
"y": 280,
"wires": []
},
{
"id": "mqtt_grid_state",
"type": "mqtt in",
"name": "Grid Connected",
"topic": "N/+/system/0/Ac/ActiveIn/Connected",
"broker": "broker",
"x": 160,
"y": 340,
"wires": [["store_grid_state"]]
},
{
"id": "store_grid_state",
"type": "function",
"name": "Store Grid State",
"func": "flow.set('grid_connected', msg.payload === 1);\nreturn null;",
"x": 350,
"y": 340,
"wires": []
},
{
"id": "tick_pv",
"type": "inject",
"name": "PV Logic Tick (10s)",
"repeat": "10",
"once": true,
"x": 160,
"y": 420,
"wires": [["pv_logic"]]
},
{
"id": "pv_logic",
"type": "function",
"name": "PV Leistungslogik",
"func": "// Liest nur gespeicherte Werte\nconst soc = flow.get('soc') || 0;\nconst load = flow.get('load') || 0;\nconst gridConnected = flow.get('grid_connected');\n\n// Offline → keine EVU-Regelung (Frequenzregelung übernimmt)\nif (!gridConnected) {\n return [{ payload: 'off' }, { payload: 'off' }];\n}\n\n// Akku schützen\nif (soc < flow.get('SOC_MIN')) {\n return [{ payload: 'off' }, { payload: 'off' }];\n}\n\n// Lastgeführte Leistungsstufen\nif (load >= flow.get('LOAD_HIGH_W')) {\n return [{ payload: 'on' }, { payload: 'off' }]; // 60 %\n}\n\nif (load >= flow.get('LOAD_MEDIUM_W')) {\n return [{ payload: 'off' }, { payload: 'on' }]; // 30 %\n}\n\n// Default: keine PV-Freigabe\nreturn [{ payload: 'off' }, { payload: 'off' }];",
"x": 360,
"y": 420,
"wires": [["shelly_pv_r1"], ["shelly_pv_r2"]]
},
{
"id": "shelly_pv_r1",
"type": "mqtt out",
"name": "Shelly 2PM – Relay 1",
"topic": "shellies/shelly-2pm-gen3/relay/0/command",
"broker": "broker",
"x": 640,
"y": 400,
"wires": []
},
{
"id": "shelly_pv_r2",
"type": "mqtt out",
"name": "Shelly 2PM – Relay 2",
"topic": "shellies/shelly-2pm-gen3/relay/1/command",
"broker": "broker",
"x": 640,
"y": 440,
"wires": []
},
{
"id": "tick_consumer",
"type": "inject",
"name": "Consumer Logic Tick (15s)",
"repeat": "15",
"once": true,
"x": 160,
"y": 520,
"wires": [["consumer_logic"]]
},
{
"id": "consumer_logic",
"type": "function",
"name": "Verbraucherfreigabe Logik",
"func": "const soc = flow.get('soc') || 0;\nconst grid = flow.get('grid') || 0;\n\nconst c1 = (soc >= flow.get('CONSUMER1_SOC') && grid <= flow.get('GRID_IMPORT_LIMIT_W')) ? 1 : 0;\nconst c2 = (soc >= flow.get('CONSUMER2_SOC') && grid <= flow.get('GRID_IMPORT_LIMIT_W')) ? 1 : 0;\n\nreturn [{ payload: c1 }, { payload: c2 }];",
"x": 380,
"y": 520,
"wires": [["gx_relay_2"], ["shelly_consumer"]]
},
{
"id": "gx_relay_2",
"type": "victron-output-relay",
"name": "GX Relais 2 – Verbraucher",
"relay": "2",
"x": 640,
"y": 500,
"wires": []
},
{
"id": "shelly_consumer",
"type": "mqtt out",
"name": "Shelly 1 – Verbraucher",
"topic": "shellies/shelly-1-gen3/relay/0/command",
"broker": "broker",
"x": 640,
"y": 540,
"wires": []
},
{
"id": "broker",
"type": "mqtt-broker",
"name": "Cerbo MQTT",
"broker": "127.0.0.1",
"port": "1883"
}
]
Und der Kontext dazu:
Anlage:
3x Victon Multiplus 5000 mit Cerbo GX und 25Kwh Akku
Geladen wird am AC-Out per Fronius IG Plus 100V-3 mit EVU Karte
Falls die 5000er Victrons sicher in allen Betriebszuständen die Leistung liefern können, bau ich mir ein Netztrennrelais ein. Dann funktioniert die stufenlose Leistungsregelung per Frequenz und ich schone die Akkus. Das wird sich aber erst nach einem Jahr Betrieb ergeben. Für den Winter und Sonderfälle wird aber auf jeden Fall die Variante mit Relais Verwendung finden müssen.
Onlinebetrieb: Fronius wird per Kontakt freigegeben bei Last oder Bedarf am Akku. Keine Rückspeisung ins Netz.
Offlinebetrieb: Fronius wird per Kontakt voll Freigegeben, Abregelung per Frequenz
Fronius
Karte eingebaut für Leistungsstufen, Zwischen-Relais verbaut um Freizugeben statt zu sperren. Ausgang am Shelly aus = Wechselrichter aus.
Frequenz - Leistungsregelung aktiv
Victron-Einstellung
In VEConfigure:
Grid Code / Assistants