GX Opportunity Loads and Node-RED

The 3.80 release of Venus brings us Opportunity Loads. Which is an awesome way to make maximum use of the PV power (by activating extra loads, ev charging, etc). Now the initial release within Venus “only” supports our battery, EV charger and Shelly devices. Node-RED users of course want more, and preferably in an easy and user friendly way. In this post I am going to explain a bit on how to accomplish just that.

It is good to know that under the hood, Opportunity Loads, communicates with the resources over the S2 protocol. S2 is a communication standard for energy flexibility in homes and buildings, developed by TNO in the Netherlands and becoming an international standard. If you are interested in diving into that rabbit hole, I can certainly recommend starting on https://s2standard.org/ and reading the white-paper there at some point.

Luckily we can hop over that hole for now and focus on getting an extra load working. All we need to know is that Opportunity Loads works with Operation Mode Based Control types and that each extra defined load needs its own Resource Manager. An operation mode can be as simple as “on” or “off”, but also a bit more advanced as steering anything between 0 and 100% power. And will need some way to attach energy consumption to the state. Which is enough intro to get started with getting a third party load as opportunity load into Node-RED.

First we need to install the palette: node-red-contrib-s2 into Node-RED. At some future moment we’ll pre-install that into Venus, but as the package is still being actively changed regularly I like the benefit of being able to update it outside of a Venus release for now.

The most simple example is just a simple load to a wifi plug (TuYa, Ikea, Tapo, Acara and countless others) and a load of say 500 Watts when switched on, 0 Watts when switched off. So we start by pulling the simplest node: s2-resource onto the canvas and configure that.

Configuration has a few tabs, lets go through them in order:

Starting with the Connection tab. The Transport is the way the load will communicate to the GX device. S2 supports multiple transport options and so does this node. For the GX connection, the Built-in - D-Bus (Victron Energy) is the best choice.

Under the hood, the s2-resource will create a virtual device, just like the regular virtual devices, on the dbus and it will need some extra information to be able to do that. If you click the + for the Virtual Device, you’ll get the following options:

Connection can be left to Auto, Device Type can be either AC load or heatpump. Likely you’ll just connect a single phase device on a certain phase and position. Power measurements are there to be able to tell opportunity loads the amount of energy the device is using. Measurements report in instantaneous power (W).

Setting the checkbox for showing the raw S2 messages in debug sidebar will help check what S2 communication is going on between the Resource Manager and the CEM (Opportunity Loads).

Then on to the next tab, which is the Resource Manager (or RM). There is no need to fill out anything here, as it mostly is used for identification purposes. Only note that, because the AC load is consuming energy, the “Consumer” checkbox needs to be checked.

The last tab consists of configuring the modes the device can be in.

As mentioned before, the used control type for opportunity loads is Operation Mode Based. For most Resource Mangers, the S2 standard also adds “Not controllable” as control type. Meaning that, if that is the active control type, the device cannot be controlled. E.g. when it is plugged out or for some other reason.

Then the “Friendly” panel gives a list, by default with just one item, to specify all of the modes the AC load can be in. For a 2 state device, you should add a second item, describing the used power when on. The minimum time for the mode is a per-mode minimum-duration timer (e.g. don’t cycle a compressor faster than every N minutes).

Lastly there is a dropdown for setting the default mode (or none) on deploy of the flow. And the option to automatically confirm mode switches (default unchecked). This should be checked if you don’t have a way to actually tell in what state the device is, instead of manually telling the resource manager in what state the device is. For the wifi plugs wire the plug’s real on/off feedback into the s2-resource input as a ModeConfirmation instead.

I hope this is enough to get you started with configuring resource managers for Opportunity loads within Node-RED. Also note that there are importable examples for the nodes too.

If you’re having issues building flows, kindly post them into new or existing, similar topics. Thanks.

Hi @dfaber and @nickdb

thanks a lot for introducing Opportunity Loads in Node-RED!

You already show a simple example flow, but perhaps a similar example using a Shelly could be a useful addition, as this might be a fairly common use case in practice: Resource → Virtual Switch → Shelly

It also shows the required message translations and connections between the nodes and could give users another practical starting point.

Perhaps you have some ideas for improvements or suggestions on how this could best be integrated into the documentation?

Just an idea — I thought it might be useful for people getting started with Opportunity Loads. :blush:

Best,
Axel


Power measurement:

msg.payload = {
  "Ac/L1/Power": msg.payload
};

return msg;

Mode confirmation:

var state = msg.payload ;

if (state === 1) {
  msg.topic = "ModeConfirmation";
  msg.payload = {
  label: "On"
  };
return msg;
}

if (state === 0) {
  msg.topic = "ModeConfirmation";
  msg.payload = {
  label: "Off"
  };
return msg;
}

return null;

Mode Instrucion:

var label = msg.payload && msg.payload.label;

if (label === "On") {
  msg.payload = {
  "SwitchableOutput/output_1/State": 1
  };
return msg;
}

if (label === "Off") {
  msg.payload = {
  "SwitchableOutput/output_1/State": 0
  };
return msg;
}

return null;

Auto

if (msg.payload === 1) {
  msg.payload = {
  command: "SetAvailableControlTypes",
    availableControlTypes: ["OPERATION_MODE_BASED_CONTROL"]
  };
return msg;
}

if (msg.payload === 0) {
  msg.payload = {
  command: "SetAvailableControlTypes",
  availableControlTypes: [ "NOT_CONTROLABLE" ]
  };
return msg;
}

return null;

node-red-contrib-s2 version 0.9.7 is out.

Thanks to everyone who tried the first versions and reported back here. Most of what changed comes straight from this thread and the ones split off from it. Super thanks to @nickdb for picking up the first response to all of those posts. And to @AxelR and @Roberto for reporting the main issues.

Update via Manage palette in Node-RED, then restart Node-RED (or set it to Disabled and back to Enabled in the GX menu).

What’s new and fixed:

  • Copied resources no longer get mixed up. A copy-pasted s2-resource (or a flow or example imported twice) kept the original’s resource ID, and Opportunity Loads saw two loads as one: one showing up twice, the other missing. Copies now get their own ID automatically. A cut-and-paste keeps its ID, so Opportunity Loads keeps its settings for that load.
  • The node status now shows both the connection and the mode, e.g. “CEM connected (opportunity_loads) - NC,OMBC | Confirmed: Off”. Before, “Confirmed: Off” could hide that no CEM was connected.
  • A ModeRequest now explains itself. Instead of an empty (null) payload, it says that no mode is known yet and lists the modes you can confirm, and the node shows “waiting for ModeConfirmation” until you do. Existing nodes keep the old behaviour; open the node and press “Update to latest” on the Control tab to switch.
  • Subflows: put an s2-resource in a subflow and set its Resource ID to ${NAME}, with a different NAME per subflow instance, so each instance is its own load.
  • “Control type: None” no longer gives a “not properly configured” warning on every deploy.
  • The edit dialogs now follow dark Node-RED themes.

Please check after updating:

If two of your nodes share a resource ID (for example an s2-resource you copy-pasted with an earlier version), the second one now refuses to start and shows a red “duplicate resource ID” status, instead of silently confusing Opportunity Loads. To fix it: copy and paste that node (the copy gets a new ID), delete the original, and deploy. The same goes for an empty or invalid resource ID (“resource ID missing” / “invalid resource ID”): open the node, press Done and deploy.

If something doesn’t work as expected, please post your flow (exported JSON) in a new topic, so we can see what’s going on.

What is next

If no new issues surface, I’ll tag version 1.0.0 next and add that to the default Venus installation (the 3.90 beta’s), so it no longer needs to be installed manually.

As a practical example, I’d like to show my Node-RED flows for controlling the three heating stages and the heating-circuit pump.

The division of responsibilities is clear: Victron Opportunity Loads decides whether energy is available. Node-RED determines the heat demand, takes the safety conditions into account, and handles relay control and pump automation.

While debugging, I was missing an independent display of the current OPL instruction. The power shown under “AC loads” does not answer whether Victron still wants a consumer switched on, or whether the connected controller is mistakenly retaining an earlier ON state. That led to my suggestion for a dedicated OPL status screen.

I’d be happy to hear your questions, experiences and suggestions for improvement. Feel free to contact me in German, Dutch, French or English.

The heating elements flow

Der Pumpensteuerungs Flow (Heizungs Kreislauf Pumpe)

Die Ansicht der Bedienoberfläche im browserbasierten flowfuse/node-red-dashboard

  • Heating day => On/Off for the Opportunity Loads heating elements. If the outdoor temperature is below 15 degrees at 03:30, the system activates automatically
  • Desired temperature at the bottom: adjustable target temperature in the 500-litre buffer tank, with 1-degree hysteresis
  • Heating stages: switch each individual 1 kW heating element off or on, with its current status
  • Heating-circuit pump: automatic operation (on at 70 degrees / off at 65 degrees) or timer operation for 1–5 hours
  • System status: Victron OPLoads energy decision: red means no permission, grey means communication is unavailable, green means permission from the OPLoads perspective

My change request / suggestion: a dedicated OPL status screen

The following information would be helpful:

· Overall status: OPL is actively regulating, paused or disabled, or has handed over control.

· For each consumer: current OPL instruction: ON, OFF or no active control.

· Reason for the decision: for example, insufficient surplus, battery charging priority, phase/inverter limit or minimum run time.

· Time of the last instruction.

· Separately alongside this: reported consumer state and power, ideally with an indication of any persistent discrepancy.

Example:

Heating element L1
OPL instruction: OFF – insufficient surplus
Reported state: ON / 1,000 W
Note: The instruction and reported state do not match.

The key point is that the displayed instruction should come directly from the OPL coordinator and be independent of the consumer’s feedback.

That would make it possible to distinguish clearly during troubleshooting: Is Victron still requesting the load, or is the problem with the connected controller?

Is this diagnostic option already available elsewhere? If not, I’d welcome such a status screen in the GX interface and the Remote Console.

I’ll add pictures later.

Kind regards,
Philip