@owenb79 @DuivertNL
Hi Marc and Owen, Thanks for the help.
I’ve decided to limit my ESS charge and discharge power via the AC Input Current Limit.
I will share my flow below for the community. I’m open to suggestions for improvement, and if anyone wants to use this for their own system, feel free to do so!
In short: the flow monitors the DC current to determine whether the battery is charging, discharging, or in an idle state.
- Idle: The limit is set to 10 amps.
- Charging: The flow ensures the phase load does not exceed 23 amps by setting the input current limit to 23 minus the AC load current on that phase.
- Discharging: To prevent backfeeding more than 15 amps into the phase, the PV generation on that phase is subtracted from the discharge current.
The final value is capped at a maximum of 16 (16 * 230 = 3680 watts) and a minimum of 2 (2 * 230 = 460 watts).
The calculation is made every 5 seconds.
Inputs:
- Venus System AC Consumption L1 (W)
- Grid Meter L1 Voltage (V) (for calculation AC Consumption amps W/V=A)
- VE Bus Battery current (A)
- PV System L1 Current (A)
Output:
- VE Bus Active input current limit (A)
The inject node is for simulation purpose.
[
{
"id": "58d39409c2a6a6ca",
"type": "tab",
"label": "Dynamic AC Current Limit",
"disabled": false,
"info": "",
"env": []
},
{
"id": "60d587c92f4da21b",
"type": "victron-input-vebus",
"z": "58d39409c2a6a6ca",
"service": "com.victronenergy.vebus/275",
"path": "/Dc/0/Current",
"serviceObj": {
"service": "com.victronenergy.vebus/275",
"name": "Omvormer"
},
"pathObj": {
"path": "/Dc/0/Current",
"type": "float",
"name": "Battery current (A)"
},
"name": "",
"onlyChanges": false,
"roundValues": "1",
"x": 150,
"y": 120,
"wires": [
[
"37b84e68de93f20c"
]
]
},
{
"id": "c81532203f154cc1",
"type": "victron-input-pvinverter",
"z": "58d39409c2a6a6ca",
"service": "com.victronenergy.pvinverter/40",
"path": "/Ac/L1/Current",
"serviceObj": {
"service": "com.victronenergy.pvinverter/40",
"name": "PV meter"
},
"pathObj": {
"path": "/Ac/L1/Current",
"type": "float",
"name": "L1 Current (A)"
},
"name": "",
"onlyChanges": false,
"roundValues": "0",
"x": 130,
"y": 180,
"wires": [
[
"37b84e68de93f20c"
]
]
},
{
"id": "6ac9493f2ba19699",
"type": "victron-input-gridmeter",
"z": "58d39409c2a6a6ca",
"service": "com.victronenergy.grid/41",
"path": "/Ac/L1/Voltage",
"serviceObj": {
"service": "com.victronenergy.grid/41",
"name": "Grid meter"
},
"pathObj": {
"path": "/Ac/L1/Voltage",
"type": "float",
"name": "L1 Voltage (V)"
},
"name": "",
"onlyChanges": false,
"roundValues": "0",
"x": 130,
"y": 240,
"wires": [
[
"37b84e68de93f20c"
]
]
},
{
"id": "6550d2fa210262a7",
"type": "victron-input-system",
"z": "58d39409c2a6a6ca",
"service": "com.victronenergy.system/0",
"path": "/Ac/Consumption/L1/Power",
"serviceObj": {
"service": "com.victronenergy.system/0",
"name": "Venus system"
},
"pathObj": {
"path": "/Ac/Consumption/L1/Power",
"type": "float",
"name": "AC Consumption L1 (W)"
},
"name": "",
"onlyChanges": false,
"x": 170,
"y": 60,
"wires": [
[
"37b84e68de93f20c"
]
]
},
{
"id": "37b84e68de93f20c",
"type": "join",
"z": "58d39409c2a6a6ca",
"name": "",
"mode": "custom",
"build": "object",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": true,
"timeout": "",
"count": "4",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "num",
"reduceFixup": "",
"x": 430,
"y": 60,
"wires": [
[
"cafb7e1810614f21"
]
]
},
{
"id": "cafb7e1810614f21",
"type": "delay",
"z": "58d39409c2a6a6ca",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "5",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"allowrate": false,
"outputs": 1,
"x": 600,
"y": 60,
"wires": [
[
"f7d8d8fc9052fb8b",
"4c282319399309d4"
]
]
},
{
"id": "f7d8d8fc9052fb8b",
"type": "debug",
"z": "58d39409c2a6a6ca",
"name": "debug data",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 810,
"y": 60,
"wires": []
},
{
"id": "80486658c1238500",
"type": "victron-output-vebus",
"z": "58d39409c2a6a6ca",
"service": "com.victronenergy.vebus/275",
"path": "/Ac/ActiveIn/CurrentLimit",
"serviceObj": {
"service": "com.victronenergy.vebus/275",
"name": "Omvormer"
},
"pathObj": {
"path": "/Ac/ActiveIn/CurrentLimit",
"type": "float",
"name": "Active input current limit (A)",
"mode": "both"
},
"name": "",
"onlyChanges": false,
"x": 820,
"y": 160,
"wires": []
},
{
"id": "4c282319399309d4",
"type": "function",
"z": "58d39409c2a6a6ca",
"name": "function 2",
"func": "// 1. Waarden ophalen\nconst pvCurrent = msg.payload[\"PV meter - L1 Current (A)\"] || 0;\nconst acConsumptionW = msg.payload[\"Venus system - AC Consumption L1 (W)\"] || 0;\nconst gridVoltage = msg.payload[\"Grid meter - L1 Voltage (V)\"] || 235;\nconst batteryCurrent = msg.payload[\"Omvormer - Battery current (A)\"] || 0;\n\n// Onthoud de vorige status in het geheugen van de node\nlet lastStatus = context.get('lastStatus') || \"rust\"; \nlet currentStatus = lastStatus;\n\n// 2. Hysteresis logica voor statusbepaling\nif (batteryCurrent < -0.5) {\n currentStatus = \"ontladen\";\n} else if (batteryCurrent > 0.5) {\n currentStatus = \"laden\";\n} else if (batteryCurrent >= -0.3 && batteryCurrent <= 0.3) {\n // Keer pas echt terug naar rust als hij heel dicht bij 0 is\n currentStatus = \"rust\";\n}\n\ncontext.set('lastStatus', currentStatus);\n\n// 3. Berekening op basis van de vastgestelde status\nconst L1LoadsAmpere = acConsumptionW / gridVoltage;\nlet result;\n\nif (currentStatus === \"ontladen\") {\n result = 15 - pvCurrent + L1LoadsAmpere;\n} else if (currentStatus === \"laden\") {\n result = 23 - L1LoadsAmpere;\n} else {\n // Rust status\n result = 10;\n}\n\n// 4. Begrenzen en afronden\nif (result > 16) result = 16;\nif (result < 2) result = 2;\n\nmsg.payload = Number(result.toFixed(1));\n\n// Extra: voeg status toe aan msg voor debuggen\nmsg.status_debug = currentStatus;\n\nreturn msg;",
"outputs": 1,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 560,
"y": 160,
"wires": [
[
"9ab3f85a79e84ba6",
"80486658c1238500"
]
]
},
{
"id": "9ab3f85a79e84ba6",
"type": "debug",
"z": "58d39409c2a6a6ca",
"name": "debug output",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 810,
"y": 100,
"wires": []
},
{
"id": "b7da306fc992d212",
"type": "inject",
"z": "58d39409c2a6a6ca",
"name": "Inject data",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "{\"Venus system - AC Consumption L1 (W)\":200,\"Grid meter - L1 Voltage (V)\":240,\"PV meter - L1 Current (A)\":10,\"Omvormer - Battery current (A)\":100}",
"payloadType": "json",
"x": 400,
"y": 160,
"wires": [
[
"4c282319399309d4"
]
]
}
]