ESS runtime parameters to work with other consumers of excess PV power

Hello all,

I recently installed a MP-II GX I’m currently reworking some automation I had (part python services, part home assistant), to node-red and integrate it properly around the ESS.
First of all, the rerouting of excess PV power to my water heater.

My goal is for excess power to be consumed in priority by the water heater, since it’s basically a battery that doesn’t wear I cycle everyday anyway for my hot water needs.
Then, when it’s charged, I allow ESS to charge the battery.

I can’t use the grid meter in my water heater control loop because it is already in the ESS control, so using it for another load without feeding anything back to ESS would basically create a nice randomly oscillating system.
Looking at node-red victron nodes I’m quite sure there is currently no way to insert a consumer in the ESS control loop. There seems to be third party mods for Venus to have a power broker system that would allow this (a good concept indeed, hope Victron will consider this for future features), but I’d rather stick to stock firmware.

I have settled for setting the water heater power at PV production, minus MP-II output and a fixed power setting reserved for loads between grid and the MP-II (I lack another metering device to report this, and since my PV is AC-tied there, this is an unsolvable equation).

This works, but while the water heater charges, ESS also tries to hit its grid setpoint, as it’s way more reactive than my flow it ends up charging at little power that I’d rather see into the heater, and that I suspect will reset batterylife and prevent raising active soc during low PV yield times.

So, I also need a way to tell ESS “stop charging” that
1/ Is not a setting that may be written into a flash or eeprom of a microcontroller and cause wearout
2/ Does not mess with ESS native features, like batterylife

For now, I use the ESS Control Node to prevent battery charge while the water heater is preempting excess PV power :
image
It is satisfying, but I don’t know if it answers the criteria I mentioned just before.

I set it based on a function that prevents excessive flapping

var disable_charge = (
    allowed_time &&.  // static 08:00 - 18:00 time range
    heater_needs_power &&. // flag set when the heater thermostat is closed
    pv_power_sufficient. // threshold when I consider I start/stop producing (100W for 2700Wp)
) ? 1 : 0;

To give an overview of the flow

There are other flows it depends upon, that collect PV data from OpenDTU via MQTT, among others.

I’ll happily share any details, I’d just rather not dump the whole thing right away without discussion context.

Read you later

I might have misunderstood something – but what you’re trying is basically what my EV charging setup with evcc does: suck up all available solar energy dynamically, optimally leaving the battery and grid at 0 watts, right?
What evcc does is simply look at the battery charge power plus the grid meter value, and then “steal” that amount of power for the car – without needing to set anything on the victron side, as the ESS simply reacts to the additional load.
You might even be able to use evcc to run your water heater, I think it has support for that.

Yes it seems the same : to have an external load preempt PV excess power that ESS will otherwise use to maintain its grid setpoint until the battery reaches 100% SoC.
With added bonus that if that power being “stolen” under ESS’s nose makes it eventually trigger its batterylife algorithm the same way it would if PV production was merely lacking, it’s all the better.

The thing I can’t figure out is, how can you do that using a grid meter, while ESS is also watching that measurement and reacting quite fast to keep it at setpoint.

If I use the grid meter to control the heater in a feedback loop, like it did before the MP-II, then each system (ESS and my own) will be influencing grid power without each other’s loop being aware of the other, it can’t be stable.

It is why I rather take the solar power reported by the inverters, substract the known/estimated loads and use that value for the heater.

Thinking about how you describe the EVCC mode of operation, I’ve quickly thrown together a flow that implements something like that :

On the top, the sum of grid meter and sign-reversed battery power represents what would be drawn from grid (negative meaning exporting) if the battery wasn’t charging.

It is fed into a PID controller node (node-red-contrib-pid (node) - Node-RED) with a setpoint at 50 (same as ESS grid setpoint, if this is stable I may let the flow fetch that setting directly from the Multiplus settings rather than leave it hardcoded).
Right now I’ve not tweaked the PID parameters. Could be either oscillating wildly or slow to react.

The Postprocess function merely turns the PID 0-1 output to 0-100 (not sure the range node works on a float input) and sets the topic.

The remainder handles the heater control modes (my HASS setup has a control to force mode between automatic, on and off) and wether it is actually ready to use power, to enable/disable PID and/or send a fixed power directive when relevant.

Of course the minute I switch from the former flow to this one, my water heater is charged :smiley:

This is inconclusive, but the fault is in the PID settings.

I am trying to follow the tuning guide given in the node-red-contrib-pid node doc but I probably don’t get it right, I either have it oscillating wildly, or being roughly stable 500 watts above setpoint.

I could cheat and move the setpoint, but that’s a bit crass.

Edit : I gave up on the “start with proportional gain at 0 to measure overshoot” PID tuning methods; I gather the nodered dashboard charts I’m using to observe are not accurate/reactive enough. Instead I focused on what the node-red-contrib-pid doc says about Proportional band : the value (in the units of input and setpoint, here watts) that a corresponds to the output full power, so the power of my heater’s resistance at 100%.
With that, and integral/derivative out of the play, for some time it stayed some 300W above setpoint but I left it alone and it slowly homed on it. The sky is clear, so the PV yield is pretty stable. It would be different with passing clouds.
The sign I must now adjust with integral and derivative settings, I think.

For now I think I’ll leave it run a few days and look at when the ESS battery starts charging, should be when the heater is done, and there should be little or no transient charging before that.

If I can get it working it’s a good way to avoid the question of interacting with ESS parameters altogether.

I also have EVCC running in combination with a Victron system, however: I cannot seem to get it working as you describe @cmock
EVCC only starts charging my car when there is actually power going back to grid. It does not seem to take the power going over the Victron system to my battery into account, no matter the priority settings I make in the Home Battery Window.

Only when I set “start automatically when above”, it works, but that should be for the battery-supported charging.

Am I doing/configuring something wrong? Can you confirm that EVCC starts charging the car when PV power is going to the battery while power to grid is 0 (kept 0 by Victron ESS)?

Also: @pkannoglou : did you manage to get a setup like you wanted?

I am very interested into your experiences/setup…

So far my water heater is working satisfactorily with more or less the flow above based on node-red-contrib-pid. There’s some jitter when the solar input is unstable, and probably someone with actual skill in process regulation could tune the PID better. I merely followed the guides you can find, and poorly so because they would imply to create a simulation environment (or wait for the test conditions to show up and be ready to drop everything then…).

The PID input is the consolidated grid power = grid meter - battery charging power. Setpoint is slightly positive (50W) to keep a no export balance point. Proportional band is the nominal full power of my heater. Integral time 10”, derivative 0, initial integral 0.5. PID node output is 0-1 which drives the heater power accordingly between 0 …100%. I added a limit to 10 msg/s between the PID and actual mqtt emitter to the heater controller, because complex flows aggregating many async messages will trigger each time a message is received on one input and end up very verbose. Rather than latching all inputs, limiting output is simpler.

Besides that, I just added some mechanic in the flow to integrate with HASS and allow automatic and manual operation (like, want to manually trigger a charge from HASS).

It does the job well enough : uses solar excess to charge the heater, then when done the Victron ESS takes over charging its battery. In that time window I trigger other automations like charging e-bikes and such. A pity that laundry and dish washers now have enough electronics to not tolerate being powered on by a contacter, but not enough to receive an actual start order. Ok some makers certainly offer that, but you’ll pay dear for it and probably will have to use the vendor’s cloud services to start your laundry. Not what I want.

And when I end up exporting when the ESS battery is full, I’ve a last flow that senses excessive export and gradually throttles inverter limit down (or back up if drawing power from grid) with 10% steps every 15 seconds. Using OpenDTU here with Hoymiles micro-inverters.

I can share the flows if you need. Ping me then so I get a mail notification.

image

I’ve those flows running whose names should be evocative enough (they run on a separate docker nodered instance, not wanting to clutter the Venus board’s ram usage when I can avoid).

In general, evcc does work as intended for me. It basically takes whatever is “excess” (i.e. exported to the grid and/or sent to the battery) and feeds it to the car.

There’s a gotcha when you use the “victron-energy” meter type for “usage: pv”, because that adds up all the AC + DC PV power, and then limits charging to the “maxacpower” setting.

My evcc.yaml, roughly:

meters:
  - name: grid
    usage: grid
    ...
  - name: wallbox
    usage: charge
    ...
  - pv_production_ac
    usage: pv
    ...
  - pv_production_dc
    usage: pv
    maxacpower: 7200
    power:
      source: modbus
      uri: 192.168.57.171:502
      id: 100
      register:
        address: 850 # DC pv power
        type: input
        decode: uint16
  - name: battery_meter
    type: template
    template: victron-energy
    usage: battery
site:
  title: MySite
  meters:
    grid: grid
    pv:
      - pv_production_ac
      - pv_production_dc
    battery:
      - battery_meter
  residualPower: 20

I think this is the main data. By splitting the PV generation into AC and DC components, only the DC is limited to maxacpower.

Do you have a meter with “usage: battery”? I think that’s what evcc uses to know how much is being charged, and therefore can be diverted to the car.

Hope this helps,

cm.

Great. Thanks for all the input guys. I will be digging into this the coming day’s (if we have enough sun here in Belgium to test :slight_smile: ).

@pkannoglou: I am very interested in the flows. Can you share them here ?

This is a complete export with irrelevant flows cut out. I hope the trimming did not break consistency.

  • OpenDTU Interface does just that, offers PV Inverter exposes consolidated data and inverter actions (limit) to other flows through link nodes
  • Grid Power Consolidated calculates a grid power import (+) / export (-) as if we weren’t charging the battery
  • Water Heater v2 is the actual water heater controller.
    • some elements are examined to enable the PID or not ; no need to have it wobbling when its output is not used, it would just make it unstable
      • pv power from opendtu
      • ecs/mode/requested > a string in “AUTO” | “ON” | “OFF” for operation mode ; from a dashboard dropbox in HASS
      • ecs/powered > 0 | 1 from the physical heater controller ; 1 when its thermosat is trying to enable the heater
      • ess/output/power > output power on victron inverter
    • then depending on the mode, either the PID output or absolute values 100 / 0% are used to drive the heater power
  • Other Batteries will trigger some tasmota plugs to load tool & bike batteries when the heater has finished loading and there’e excess power. Since those loads have an unknown, fixed power draw it is done when ESS battery is charging so that its own regulation can keep grid import/export near 0.
  • PV Power Limit kicks in when the ESS battery is at 100% SoC and there’s still an important excess we can’t route anywhere anymore. My energy provider tolerates export but the limits are not clear and I’m not finding out, so I make sure there’s none or barely.
  • Off-Grid Battery Saver is a gradual shutdown of “critical” loads that will shut down the less important ones when SoC hits certain thresholds.

flows.zip (11,7 Ko)

nice. Thanks!

BTW: I also have Hoymiles micro inverters and OpenDTU to monitor/control them. :slight_smile: