Blockzitat
[
{
“id”: “fcabfa2270aca509”,
“type”: “tab”,
“label”: “Flow 1”,
“disabled”: false,
“info”: “”,
“env”:
},
{
“id”: “503d0a58ee96d68c”,
“type”: “victron-input-gridmeter”,
“z”: “fcabfa2270aca509”,
“service”: “com.victronenergy.grid/30”,
“path”: “/Ac/Power”,
“serviceObj”: {
“service”: “com.victronenergy.grid/30”,
“name”: “Grid meter”
},
“pathObj”: {
“path”: “/Ac/Power”,
“type”: “float”,
“name”: “Power (W)”
},
“name”: “Netz-Leistung (Direkt EM24)”,
“onlyChanges”: false,
“roundValues”: “2”,
“rateLimit”: 0,
“outputs”: 1,
“x”: 160,
“y”: 160,
“wires”: [
[
“e1d9f41c3b276828”,
“e900dcaff77313a3”
]
]
},
{
“id”: “cb48f540f6620c61”,
“type”: “function”,
“z”: “fcabfa2270aca509”,
“name”: " Kopplung",
“func”: “const MAX_HM600 = 600;\nconst MAX_HM800 = 800;\nconst MAX_TOTAL = MAX_HM600 + MAX_HM800; // 1400W\nconst TARGET_GRID = 20; \n\n// 1. Das aktuelle Limit aus dem internen Gedächtnis holen (oder mit Maximum starten)\nlet currentLimitWatt = context.get(‘currentLimitWatt’);\nif (currentLimitWatt === undefined || currentLimitWatt === null || isNaN(currentLimitWatt)) {\n currentLimitWatt = MAX_TOTAL;\n}\n\n// Zeitstempel für die 5-Sekunden-Bremse abfragen\nlet lastSendTime = context.get(‘lastSendTime’) || 0;\nlet currentTime = Date.now();\n\n// 2. Den Netzwert DIREKT aus dem Kabel lesen\nlet gridPower = Number(msg.payload);\n\n// Sicherheitsnetz: Falls kein gültiges Signal im Kabel liegt, die Berechnung stoppen\nif (isNaN(gridPower)) {\n return null; \n}\n\n// 3. Regelabweichung berechnen\nlet error = gridPower - TARGET_GRID;\n\nif (gridPower < 0) {\n // A: EINSPEISUNG (z.B. -400W) → PV-Leistung SOFORT und aggressiv reduzieren\n currentLimitWatt += (error * 0.95);\n} else if (gridPower > 40) {\n // B: NETZBEZUG (z.B. 140W) → PV-Leistung schrittweise erhöhen\n currentLimitWatt += (error * 0.70);\n}\n\n// 4. Grenzen knallhart absichern\nif (currentLimitWatt > MAX_TOTAL) currentLimitWatt = MAX_TOTAL;\nif (currentLimitWatt < 140) currentLimitWatt = 140; // 10% Mindestleistung\n\n// Wert für das nächste Kabel-Signal im Gedächtnis speichern\ncontext.set(‘currentLimitWatt’, currentLimitWatt);\n\n// 5. Zeitprüfung: Sind bereits 5 Sekunden (5000 Millisekunden) vergangen?\nif (currentTime - lastSendTime >= 5000) {\n \n // Proportionale Verteilung berechnen\n let shareHM600 = (currentLimitWatt / MAX_TOTAL) * MAX_HM600;\n let shareHM800 = (currentLimitWatt / MAX_TOTAL) * MAX_HM800;\n\n let pctHM600 = Math.round((shareHM600 / MAX_HM600) * 100);\n let pctHM800 = Math.round((shareHM800 / MAX_HM800) * 100);\n\n if (pctHM600 < 10) pctHM600 = 10;\n if (pctHM600 > 100) pctHM600 = 100;\n if (pctHM800 < 10) pctHM800 = 10;\n if (pctHM800 > 100) pctHM800 = 100;\n\n // Aktuellen Zeitstempel für den nächsten Durchlauf merken\n context.set(‘lastSendTime’, currentTime);\n\n // Ausgaben an die MQTT-Nodes und Dashboard-Texte senden\n return [ { payload: pctHM600 }, { payload: pctHM800 } ];\n}\n\n// Falls keine 5 Sekunden vergangen sind, wird absolut nichts weitergeleitet\nreturn null;\n”,
“outputs”: 2,
“timeout”: “”,
“noerr”: 0,
“initialize”: “”,
“finalize”: “”,
“libs”: ,
“x”: 680,
“y”: 160,
“wires”: [
[
“2019e8a7051ce831”,
“e646aa8b46bac0c1”
],
[
“14fd5b5e970bb703”
]
]
},
{
“id”: “e1d9f41c3b276828”,
“type”: “ui_chart”,
“z”: “fcabfa2270aca509”,
“name”: “Netzverlauf”,
“group”: “battery_ctrl_group”,
“order”: 8,
“width”: 0,
“height”: 0,
“label”: “Netzverlauf (letzte Stunde)”,
“chartType”: “line”,
“legend”: “false”,
“xformat”: “HH:mm:ss”,
“interpolate”: “linear”,
“removeOlder”: 1,
“removeOlderUnit”: “3600”,
“colors”: [
“#1f77b4”,
“#aec7e8”,
“#ff7f0e”,
“#ffbb78”,
“#2ca02c”,
“#98df8a”,
“#d62728”,
“#ff9896”,
“#9467bd”
],
“outputs”: 1,
“x”: 370,
“y”: 100,
“wires”: [
]
},
{
“id”: “e900dcaff77313a3”,
“type”: “delay”,
“z”: “fcabfa2270aca509”,
“name”: “Zeitverzögerung 1Sec”,
“pauseType”: “rate”,
“timeout”: “5”,
“timeoutUnits”: “seconds”,
“rate”: “1”,
“nbRateUnits”: “5”,
“rateUnits”: “second”,
“randomFirst”: “1”,
“randomLast”: “5”,
“randomUnits”: “s”,
“drop”: true,
“allowrate”: false,
“outputs”: 1,
“x”: 460,
“y”: 160,
“wires”: [
[
“cb48f540f6620c61”
]
]
},
{
“id”: “e646aa8b46bac0c1”,
“type”: “mqtt out”,
“z”: “fcabfa2270aca509”,
“name”: “MQTT HM600 Limit”,
“topic”: “solar/1141810xxxxxx/cmd/limit_nonpersistent_relative”,
“qos”: “”,
“retain”: “”,
“respTopic”: “”,
“contentType”: “”,
“userProps”: “”,
“correl”: “”,
“expiry”: “”,
“broker”: “e6f6ef6a378da38e”,
“x”: 890,
“y”: 120,
“wires”:
},
{
“id”: “14fd5b5e970bb703”,
“type”: “delay”,
“z”: “fcabfa2270aca509”,
“name”: “1s Versatz”,
“pauseType”: “delay”,
“timeout”: “1”,
“timeoutUnits”: “seconds”,
“rate”: “1”,
“rateUnits”: “second”,
“randomFirst”: “1”,
“randomLast”: “5”,
“randomUnits”: “seconds”,
“drop”: false,
“allowrate”: false,
“outputs”: 1,
“x”: 870,
“y”: 200,
“wires”: [
[
“d944192787ca9945”,
“4566995916c5688e”
]
]
},
{
“id”: “d944192787ca9945”,
“type”: “mqtt out”,
“z”: “fcabfa2270aca509”,
“name”: “MQTT HM800 Limit”,
“topic”: “solar/114190xxxxxx/cmd/limit_nonpersistent_relative”,
“qos”: “”,
“retain”: “”,
“respTopic”: “”,
“contentType”: “”,
“userProps”: “”,
“correl”: “”,
“expiry”: “”,
“broker”: “e6f6ef6a378da38e”,
“x”: 1070,
“y”: 200,
“wires”:
},
{
“id”: “2019e8a7051ce831”,
“type”: “ui_text”,
“z”: “fcabfa2270aca509”,
“group”: “battery_ctrl_group”,
“order”: 10,
“width”: “3”,
“height”: “2”,
“name”: “Anzeige HM600”,
“label”: “Limit HM600:”,
“format”: “{{msg.payload}} %”,
“layout”: “row-spread”,
“x”: 880,
“y”: 80,
“wires”:
},
{
“id”: “4566995916c5688e”,
“type”: “ui_text”,
“z”: “fcabfa2270aca509”,
“group”: “battery_ctrl_group”,
“order”: 12,
“width”: “3”,
“height”: “2”,
“name”: “Anzeige HM800”,
“label”: “Limit HM800:”,
“format”: “{{msg.payload}} %”,
“layout”: “row-spread”,
“x”: 1060,
“y”: 260,
“wires”:
},
{
“id”: “battery_ctrl_group”,
“type”: “ui_group”,
“name”: “Batterieladung Regelung”,
“tab”: “battery_ctrl_tab”,
“order”: 1,
“disp”: true,
“width”: “16”,
“collapse”: false,
“className”: “”
},
{
“id”: “e6f6ef6a378da38e”,
“type”: “mqtt-broker”,
“name”: “”,
“broker”: “localhost”,
“port”: 1883,
“clientid”: “”,
“autoConnect”: true,
“usetls”: false,
“protocolVersion”: 4,
“keepalive”: 60,
“cleansession”: true,
“autoUnsubscribe”: true,
“birthTopic”: “”,
“birthQos”: “0”,
“birthRetain”: “false”,
“birthPayload”: “”,
“birthMsg”: {},
“closeTopic”: “”,
“closeQos”: “0”,
“closeRetain”: “false”,
“closePayload”: “”,
“closeMsg”: {},
“willTopic”: “”,
“willQos”: “0”,
“willRetain”: “false”,
“willPayload”: “”,
“willMsg”: {},
“userProps”: “”,
“sessionExpiry”: “”
},
{
“id”: “battery_ctrl_tab”,
“type”: “ui_tab”,
“name”: “Solar & Batterie”,
“icon”: “dashboard”,
“order”: 1,
“disabled”: false,
“hidden”: false
},
{
“id”: “db4befefa83a3fc9”,
“type”: “global-config”,
“env”: ,
“modules”: {
“@victronenergy/node-red-contrib-victron”: “1.6.64”,
“node-red-dashboard”: “3.6.6”
}
}
]