Emergency setup by a three-phase generator

I’d like to prepare an emergency setup where my three Victron MultiPlus-II units can be supplied by a three-phase generator.

For this, I want to use Node-RED to reliably implement the following:

A) Limit the current drawn from the generator
I want to configure a current limit so that the system draws no more than 6.5 A per phase from the generator, to avoid overloading it.

B) Prevent any backfeed into the generator
It must be ensured that no power is fed back into the generator under any circumstances. Backfeeding could damage or even destroy the generator.

My intended procedure during a grid outage is:

  1. In case of a grid failure, I start the generator manually.

  2. Then I disconnect the Victron system from the public grid using a mechanical 1–0–2 changeover switch.

  3. After that, I switch from “0” to the generator position — but only once the settings mentioned above (current limiting and backfeed prevention) have been applied.

Additional important requirements:

  • If, for example, the sun is shining and the battery is full, there must still be no reverse power flow into the generator. In that scenario, excess PV power must not be exported to the generator, because it could destroy it.

  • Also, while running on the generator, there must be no phase balancing via the grid / AC input. Any normal phase-balancing or load-sharing behavior across phases that would involve the AC input should be avoided in this operating mode.

My question:
Can these parameters and protections be controlled via Node-RED on the Cerbo GX, either directly through Node-RED or via MQTT (e.g., by setting the relevant values/parameters)?

I’m assuming you are running ESS on your Multis and that you have is set to export to grid when appropriate.

The AC input current limit can be set from the GX device assuming you have programmed Overruled by remote in the Multi’s configuration.

Would switching the AC input type from grid to generator accomplish this?

Hi
I do not understand the generator Settings and >I do not have a AC2 In.
That’s my first attempt for Node-RED.
I recognise that the power has failed when my smart meter is inactive; in such an instance, I activate generator mode within Node-RED.

CurrentLimit (AC-Input) → Restricts the maximum current drawn from the generator, thereby safeguarding it against overload.
→ Implemented via Victron veBus output: /Ac/In/<index>/CurrentLimit (A).

DisableFeedIn (ESS) → The ESS regulates the system to suppress grid feed-in (feed-in disabled).
→ Implemented via Victron veBus output: /Hub4/DisableFeedIn = 1 (disable).

[
    {
        "id": "f1a2b3c4d5e6f7a8",
        "type": "mqtt in",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "Generatorbetrieb (MQTT)",
        "topic": "N/Generatorbetrieb",
        "qos": "0",
        "datatype": "auto",
        "broker": "b1c2d3e4f5a6b7c8",
        "nl": false,
        "rap": true,
        "rh": 0,
        "inputs": 0,
        "x": 200,
        "y": 120,
        "wires": [
            [
                "a2b3c4d5e6f7a8b9"
            ]
        ]
    },
    {
        "id": "a2b3c4d5e6f7a8b9",
        "type": "json",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "JSON parse",
        "property": "payload",
        "action": "",
        "pretty": false,
        "x": 410,
        "y": 120,
        "wires": [
            [
                "b3c4d5e6f7a8b9c0"
            ]
        ]
    },
    {
        "id": "b3c4d5e6f7a8b9c0",
        "type": "function",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "payload.value -> Zahl",
        "func": "let v = msg.payload;\n// akzeptiert {value:0/1} ODER \"0\"/\"1\" ODER 0/1\nif (typeof v === 'object' && v !== null && v.value !== undefined) v = v.value;\nv = Number(v);\nif (Number.isNaN(v)) return null;\nmsg.payload = v;\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 610,
        "y": 120,
        "wires": [
            [
                "c4d5e6f7a8b9c0d1"
            ]
        ]
    },
    {
        "id": "c4d5e6f7a8b9c0d1",
        "type": "rbe",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "nur Änderungen",
        "func": "rbe",
        "gap": "",
        "start": "",
        "inout": "out",
        "septopics": false,
        "property": "payload",
        "x": 820,
        "y": 120,
        "wires": [
            [
                "d5e6f7a8b9c0d1e2"
            ]
        ]
    },
    {
        "id": "d5e6f7a8b9c0d1e2",
        "type": "switch",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "Generator an/aus",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "1",
                "vt": "num"
            },
            {
                "t": "eq",
                "v": "0",
                "vt": "num"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 1020,
        "y": 120,
        "wires": [
            [
                "b9c0d1e2f3a4b5c6"
            ],
            [
                "c0d1e2f3a4b5c6d7"
            ]
        ]
    },
    {
        "id": "e6f7a8b9c0d1e2f3",
        "type": "victron-input-vebus",
        "z": "c3a1b2c3d4e5f6a7",
        "service": "com.victronenergy.vebus/276",
        "path": "/Ac/In/1/CurrentLimit",
        "serviceObj": {
            "service": "com.victronenergy.vebus/276",
            "name": "VE.Bus 276"
        },
        "pathObj": {
            "path": "/Ac/In/1/CurrentLimit",
            "type": "float",
            "name": "Input 1 current limit (A)"
        },
        "initial": "",
        "name": "Live: CurrentLimit (A)",
        "onlyChanges": false,
        "x": 180,
        "y": 220,
        "wires": [
            [
                "f7a8b9c0d1e2f3a4"
            ]
        ]
    },
    {
        "id": "f7a8b9c0d1e2f3a4",
        "type": "change",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "store last_current_limit",
        "rules": [
            {
                "t": "set",
                "p": "last_current_limit",
                "pt": "flow",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 420,
        "y": 220,
        "wires": [
            []
        ]
    },
    {
        "id": "a8b9c0d1e2f3a4b5",
        "type": "victron-input-vebus",
        "z": "c3a1b2c3d4e5f6a7",
        "service": "com.victronenergy.vebus/276",
        "path": "/Hub4/DisableFeedIn",
        "serviceObj": {
            "service": "com.victronenergy.vebus/276",
            "name": "VE.Bus 276"
        },
        "pathObj": {
            "path": "/Hub4/DisableFeedIn",
            "type": "enum",
            "name": "ESS Disable feed-in",
            "enum": {
                "0": "Feed-in allowed",
                "1": "Feed-in disabled"
            }
        },
        "initial": "",
        "name": "Live: DisableFeedIn",
        "onlyChanges": false,
        "x": 170,
        "y": 280,
        "wires": [
            [
                "d0e1f2a3b4c5d6e7"
            ]
        ]
    },
    {
        "id": "d0e1f2a3b4c5d6e7",
        "type": "change",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "store last_disable_feed_in",
        "rules": [
            {
                "t": "set",
                "p": "last_disable_feed_in",
                "pt": "flow",
                "to": "payload",
                "tot": "msg"
            }
        ],
        "x": 430,
        "y": 280,
        "wires": [
            []
        ]
    },
    {
        "id": "b9c0d1e2f3a4b5c6",
        "type": "function",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "Generator=1 -> Limit + No Feed-in",
        "func": "// Capture current (pre-generator) values once\nconst lastCL = flow.get('last_current_limit');\nconst lastDF = flow.get('last_disable_feed_in');\n\nif (lastCL !== undefined) flow.set('orig_current_limit', lastCL);\nif (lastDF !== undefined) flow.set('orig_disable_feed_in', lastDF);\nflow.set('generator_mode', true);\n\n// Setpoints for generator mode\nconst setCurrentLimitA = { payload: 6.5 }; // ~4.5kW total @3ph/230V\nconst disableFeedIn    = { payload: 1 };\n\nreturn [setCurrentLimitA, disableFeedIn];\n",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1280,
        "y": 90,
        "wires": [
            [
                "d1e2f3a4b5c6d7e8",
                "f0f0f0f0f0f0f0f1"
            ],
            [
                "e2f3a4b5c6d7e8f9",
                "f0f0f0f0f0f0f0f1"
            ]
        ]
    },
    {
        "id": "c0d1e2f3a4b5c6d7",
        "type": "function",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "Generator=0 -> Restore",
        "func": "flow.set('generator_mode', false);\n\nconst origCL = flow.get('orig_current_limit');\nconst origDF = flow.get('orig_disable_feed_in');\n\nconst m1 = (origCL !== undefined) ? { payload: origCL } : null;\n// Wenn wir nichts gespeichert haben: Feed-in sicherheitshalber wieder erlauben (0)\nconst m2 = (origDF !== undefined) ? { payload: origDF } : { payload: 0 };\n\nreturn [m1, m2];\n",
        "outputs": 2,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 1250,
        "y": 150,
        "wires": [
            [
                "d1e2f3a4b5c6d7e8",
                "f0f0f0f0f0f0f0f2"
            ],
            [
                "e2f3a4b5c6d7e8f9",
                "f0f0f0f0f0f0f0f2"
            ]
        ]
    },
    {
        "id": "d1e2f3a4b5c6d7e8",
        "type": "victron-output-vebus",
        "z": "c3a1b2c3d4e5f6a7",
        "service": "com.victronenergy.vebus/276",
        "path": "/Ac/In/1/CurrentLimit",
        "serviceObj": {
            "service": "com.victronenergy.vebus/276",
            "name": "MultiPlus-II"
        },
        "pathObj": {
            "path": "/Ac/In/1/CurrentLimit",
            "type": "float",
            "name": "Input 1 current limit (A)",
            "mode": "both"
        },
        "name": "SET: CurrentLimit (A)",
        "onlyChanges": true,
        "x": 1560,
        "y": 120,
        "wires": []
    },
    {
        "id": "e2f3a4b5c6d7e8f9",
        "type": "victron-output-vebus",
        "z": "c3a1b2c3d4e5f6a7",
        "service": "com.victronenergy.vebus/276",
        "path": "/Hub4/DisableFeedIn",
        "serviceObj": {
            "service": "com.victronenergy.vebus/276",
            "name": "MultiPlus-II"
        },
        "pathObj": {
            "path": "/Hub4/DisableFeedIn",
            "type": "enum",
            "name": "ESS disable feedback flag phase",
            "enum": {
                "0": "Feed in allowed",
                "1": "Feed in disabled"
            },
            "mode": "both"
        },
        "name": "SET: DisableFeedIn",
        "onlyChanges": true,
        "x": 1560,
        "y": 180,
        "wires": []
    },
    {
        "id": "f0f0f0f0f0f0f0f1",
        "type": "debug",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "GEN ON actions",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 1540,
        "y": 60,
        "wires": []
    },
    {
        "id": "f0f0f0f0f0f0f0f2",
        "type": "debug",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "GEN OFF restore",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 1550,
        "y": 240,
        "wires": []
    },
    {
        "id": "be8a3e7d3f26dd99",
        "type": "inject",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "generatorbetrieb 1",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "N/Generatorbetrieb",
        "payload": "1",
        "payloadType": "str",
        "x": 210,
        "y": 440,
        "wires": [
            [
                "63ab5142243c514c"
            ]
        ]
    },
    {
        "id": "281bda5dd670baaf",
        "type": "inject",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "generatorbetrieb 0",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "N/Generatorbetrieb",
        "payload": "0",
        "payloadType": "str",
        "x": 210,
        "y": 480,
        "wires": [
            [
                "63ab5142243c514c"
            ]
        ]
    },
    {
        "id": "63ab5142243c514c",
        "type": "mqtt out",
        "z": "c3a1b2c3d4e5f6a7",
        "name": "",
        "topic": "",
        "qos": "1",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "fe412fd957247504",
        "x": 490,
        "y": 460,
        "wires": []
    },
    {
        "id": "b1c2d3e4f5a6b7c8",
        "type": "mqtt-broker",
        "name": "Venus MQTT",
        "broker": "127.0.0.1",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "sessionExpiry": ""
    },
    {
        "id": "fe412fd957247504",
        "type": "mqtt-broker",
        "name": "",
        "broker": "10.11.12.149",
        "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": "58d82c055f9c8bbb",
        "type": "global-config",
        "env": [],
        "modules": {
            "@victronenergy/node-red-contrib-victron": "1.6.55"
        }
    }
]

What I have recently read and intend to incorporate:

Import Setpoint (Fine-tuning, “+50 W per Phase”) — Total Setpoint Instead of Per-Phase, a Practical Approach

  • While some installations permit the setting of per-phase setpoints, in practice, a small positive total setpoint (e.g., +150 W, equating to +50 W per phase) via AcPowerSetPoint (CGwacs setting) proves sufficient.

  • This configuration ensures the energy storage system (ESS) consistently draws a slight amount of power, thereby physically preventing any reverse power flow.

Synergy: The CurrentLimit safeguards the generator during load peaks, DisableFeedIn instructs the ESS not to feed power back into the grid, and the Import Setpoint (+150 W) further prevents even short-term negative power output—particularly during PV peaks or control delays.

What are your thoughts on this? Have I overlooked anything?

An MP2 with ESS is not designed for generator.

The MP2 AC1 is
either configured for grid/ESS with grid code
or for off grid and generator without grid code.

The Quattro can have different configurations a the two different inputs (ACin 1+2).

To change the grid code, you need to reprogram the MP2 with VeConfigure and in case of your 3p system with QuickConfigure.

With some grid codes, the rate of change is limited. E.g. in Germany the MP2 can adapt to power changes at a rate of 400W/s. This might not be sufficient for generator operation and fast changing loads, e.g. switching electric stove.

Furthermore with grid code the loss of mains (LOM) detection will permanently try to change frequency to test if grid was lost.

PV generation is controlled by frequency shifting during off-grid operation. With grid code and generator on AC_in, this will not work.

I assume easiest way to recharge a 3p MP2 system with a generator is adding a 3p DC-charger with only the generator attached. Maybe a used fork lift battery charger.

Others use a single MP2 or a TelKo server PSU like Eltek FlatPack 2 or Huawei with a 1p generator.

Hmm, thank you for your response, Björn.
I have not yet fully grasped the matter and would interpret it thus:

The MP2 anti-islanding tests (LOM), commences active testing—introducing slight frequency variations, minimal phase shifts, and power impulses. The MP2 detects the absence of a grid, as the public grid would resist and counteract such disturbances; however, the generator either adapts or drifts away.

Consequently, the MP2 interprets this as “grid unstable or absent.”

Result:
AC input is disconnected once more; the generator runs idle.
After a brief interval, a new attempt is initiated—resulting in an endless loop.

Have I understood this correctly?

THX EDSTOBI

Hi Marc,

I do not exactly the procedure how MP2 does lost of mains detected, but in general I assume you interpretation is correct.
If the grid - you generator - is not rock stable like grid, the MP2 will detect lost of mains and disconnect.

The LOM detection can be switched off with grid code “none” which is for off-grid operation and generator on AC1. But this incompatible with grid ties operation. And reconfiguration is done vie VeConfigure. Though no option for frequent grid failures. For those scenarios the Quattro is the right choice.

Thank you. My challenge is that the generator has been idle since the Victron PV system was commissioned. However, following the recent incidents in Berlin, where there were prolonged power outages, we have become concerned, as we would risk losing our animals in such a scenario. Consequently,

I will prepare an emergency plan outlining the reconfiguration and all other necessary steps. We initially assumed an extremely stable grid and, for cost reasons at the time, opted not to install a Quadro. Thank you for your insight, which has prompted me to delve deeper into the system’s technical functionality. This is one of the great advantages of Victron—its systems are not black boxes.
Have a nice day

@EDSTOBI

Cheap Alternative:
Connect your 3p generator to 3x 1p EltecFlatpack 2 PSU.
You get than at 150-200 EUR at eBay. Than you can recharge any time at 3x2000W. MP2s will also use the energy from DC bus PSUs and battery.
No reconfiguration needed. If you have an electric starter for your generator, you can fully automate the process with Victron build in options.

Maybe a 3p forklift charger might work as well.

If you are from Germany, you can reach out via mail bk-ve@gmx.de Might be easier than chatting via forum.

Cheers
Björn