[DESS HACK] Unexpected Bat2Grid and Solar-Feedin. (Green Mode)

DESS in Green-Mode sometimes shows 3 unexpected behaviours:

  • Charging, when there is enough solar available later the day (I1)
  • Discharging to grid, even if the battery is not fully charged (I2)
  • Not charging/discharging, but idling and sending solar-overhead to the grid, even if the battery is not fully charged (I3)

I’ve therefore designed a (let’s call it) hack to address Issue I2 and I3. For I1, I understand that occassional charge from grid is the easiest way to handle a soc-schedule throughout the day, so I didn’t mess with that.

I’ve now been running this changes for about 2 weeks now, and it seems like the system behaves as I would expect it, beside the unchanged I1 happening very rarely.

DISCLAIMER:
Applying this hack requires the modification of victrons original file. The changes outlined bellow have been created and tested with a certain version as outlined. Any older / newer versions may need different changes. Keep in mind that a system up- or downgrade will always undo these changes as well.

APPLYING THIS CHANGES HAPPENS 100% ON YOUR OWN RISK

So, what does this hack do?

The original DESS-delegate basically makes decisions based on the data VRM computed and send to the gx-device as a schedule.
The gx device now performs one out of 4 “reactions” possible to the schedule:

  • If the VRM-Strategy is set to SELFCONSUME, DESS just behaves like a regular ESS. (R1)
  • If the VRM-Strategy is set to TARGETSOC, there are 3 options available:
  • The current soc is BELLOW the hourly schedule → charging battery (not necessarily from grid) is required (R2)
  • The current soc is EQUAL to the hourly schedule → battery goes idle, excess PV is feed-in instead (R3)
  • The current soc is ABOVE the hourly schedule → battery is discharged to grid (R4)

R1 and R2 are totally fine - but R3 is somewhat mew, and R4 is “&%$!ยง&” :wink:

So, i’ve modified the part of code responsible for R3 and R4 and after all, the actual strategy will be overridden by the following behaviour:

1.)
VRM-Strategy: SELFCONSUME
Conditions: Any
Final-Strategy: SCHEDULED_SELFCONSUME
Means: The system will behave like in regular ESS Mode, as desired by the vrm schedule.
No changes

2.)
VRM-Strategy: TARGETSOC
Conditions: SOC < TARGETSOC
Final-Strategy: SCHEDULED_CHARGE
Means: VRM has scheduled a battery charge for this window. We just pass that on to the regular DESS-Delegate, allowing it to do, whatever it needs to do, to reach target-soc.
No changes

3.)
VRM-Strategy: TARGETSOC
Conditions: SOC >= TARGETSOC and pvpower > consumption
Final-Strategy: OVERRIDE_SELFCONSUME_ACCEPT_CHARGE
Means: Usually the system would now go into idle, feeding in excess PV or even discharge the battery to grid. This is not desired, so we enter SELFCONSUME with the idea to absorb the excess pv power as well. Doing so may bring the actual soc above the target-soc and ahead of plan.

4.)
VRM-Strategy: TARGETSOC
Conditions: SOC > TARGETSOC and pvpower <= consumption
Final-Strategy: OVERRIDE_SELFCONSUME_ACCEPT_DISCHARGE
Means: We have more SOC than the schedule expected. Thus, we will stay in selfconsume mode and compensate PV-shortages from the battery. We are ahead of plan.

5.)
VRM-Strategy: TARGETSOC
Conditions: SOC == TARGETSOC and pvpower <= consumption
Final-Strategy: OVERRIDE_IDLE_MAINTAIN_TARGET_SOC
Means: SOC level is exactly as expected by the schedule, but we have a pv-shortage. Thus, we are entering battery idle mode with the target to maintain the SOC-level to stay on schedule.
Usually this happens, when VRM is scheduling multiple consecutive hours of the same target-soc with the idea to consume from grid instead due to cheap prices.
So, we just follow that idea.


Installation:

Note the changes are only suitable for Green-Mode as battery discharge (to grid) is completely suppressed.

See this post for installation:

That’s it.

As Victron is still working on DESS, this file is subject to changes after a system upgrade.
So, when you upgrade your system, only apply code-changes that are designed for the exact version.

cheers,
dognose

11 Likes

Way to go and thanks for sharing ! :+1:
Wish there were more who study the VOS internals and add their input… :wink:

Top work!

Would be nice if Victron would incorporate that…!

Thanks Dognose,

I did the hack with WinSCP. I only don’t understand how to verify. Can you help me with that?

Cheers

easiest way would be to ssh into the device (when you are using winscp, you got ssh enabled)

so, for example with powershell in windows:

ssh ipOfCerbo -lroot

then, type dbus-spy (enter), search the service com.victronenergy.system, select it with up/down arrows and finally press the RIGHT arrow.

This expands all keys of that service - scroll down again, until you can find DynamicESS/FinalStrategy

If that key is there, the changes are applied and it’s working.

2 Likes

thanks.
So, how to change FinalStrategy.
Mine is now unchanged.

That’s all happening automatically.

Currently you are in VRM_SELFCONSUME, that means the schedule from DESS is SELFCONSUME, and there’s no need to override that based on current values.

The script just “intercepts” irrational decissions that lead to solar feed-in and/or undesired battery discharge, because DESS is trying to hard to stick to the schedule.

thanks again :+1:

1 Like

I’ve also been making changes to this file to improve “trade mode” as I mentioned in other thread. Do you have a github account where you could fork victron repo and make changes? This would make it easier for us to evolve improvements between us, and also propose changes to victron via pull request.

My fork is here [1] GitHub - dfeist/dbus-systemcalc-py at dfeist/idle-selfconsume but this currently only has a subset of the changes I’ve made locally. I’m still doing some testing before uploading further changes. If may well be some of the code is common to trade/green modes, so I’ll definitely look at what you’ve done too!

1 Like

I think for trade mode, the battery discharge is a desired feature, as it needs to be invoked to “sell” at desired high prices.

So the only improvement for trademode could be to avoid the “feed-in-because-idle-issue”. But it is also not as clear to be avoidable in Trade mode, because the plan could eventually be “Maintain Target soc, we have enough for self consumption and feed in excess to make money”.

Haven’t seen that and actually would welcome this behaviour when there is plenty of solar forecasted for the next day and consumption forecast could be covered for by actual - below 100% - soc. My DESS unnecessessarly charges the battery to 100%, too early and too often.

I had this quite often.

But I guess the reason is, that I have a bunch of overhead-controlled consumers, they are only enabled when there is plenty of solar.

So DESS generally overestimates consumption during the day and therefore underestimates the Target SOC which made my system “pause” in that idle state quite often.

For the same reason, I see “charge from grid” only rarely I assume. (Cause soc is always equal or ahead schedule)

So, here is a quite nice example of the “OVERRIDE_SELFCONSUME_ACCEPT_CHARGE” - Behaviour:

This morning, the system concluded, that there will be a high consumption and little solar. So, according to the expectation it created a schedule to MAINTAIN the target soc throughout the day, with regards to expensive prices at the evening.

This is a totally fine “roadmap” with regards to the forecast:

However, we just had a “sunny moment”, lasting about 45 minutes. The target-Soc was scheduled for 34%, while there have been peaks upto 10kW solar:

Override

The original implementation would have gone into “battery-idle-mode” because the targetsoc says 34% (or even discharge, when exceeded)!:

Idle

So, the OVERRIDE_SELFCONSUME_ACCEPT_CHARGE modification kicked in, just setting the system into regular ESS mode, causing it to do, what an ESS is supposed to do: Charge the Battery!:

After the 45 minute period, the DESS schedule was still sitting at 34%, while the override managed to push the battery upto 47% and quite ahead of plan:

AheadOfPlan

finally, we absorbed a total of 3.75 kWh (13% SoC) that would have endet up beeing feed-in to the grid with the default behaviour:

image


The original behaviour is - just as I write - causing new posts over here:


The original implemention does not obey current solar and/or consumption values. If the roadmap says “targetSoc” - it sticks to that, wasting (selling) energy that could charge the battery. While this might be usefull for Trade-Mode to keep the soc precisely at the target_soc - I can’t see any benefits justifying this behaviour in Green Mode. :man_shrugging:

3 Likes

@dognose
Thanks for quoting me :slight_smile:
(By the way I was running in trade mode)

didn’t know that causes a “mentioning” :smiley:

btw, updated the “conclusion”, for “Trade-Mode” that behaviour may be more understandable:

The original implemention does not obey current solar and/or consumption values. If the roadmap says “targetSoc” - it sticks to that, wasting (selling) energy that could charge the battery. While this might be usefull for Trade-Mode to keep the soc precisely at the target_soc - I can’t see any benefits justifying this behaviour in Green Mode. :man_shrugging:

@dfaber, is there is a job opening at Victron for dognose? :wink:

From my point of view in Trade-Mode targetSoc shouldn’t be that precisely kept.
If we come from 20% and targetSoc is 25% whats the problem to “continue with the plan” if targetSoc is reached.
So charge or discharge the battery depending of the plan of the next hour.

But let’s stick to GeenMode for now in this topic

1 Like

Nice hack. As @dfeist also mentioned, I also suggest making a fork of the original code for it on github.

At the moment the team isn’t actively adjusting the scheduler for a while, giving us time to focus on working on other improvements.

If your, or anyone else’s, hack works well for a while for a lot of people in different countries, I can assure you that we will look into incorporating it into the regular code.

7 Likes

Thank you - that’s awesome :slight_smile:
I’ve now created a fork, and published the repository here:
https://github.com/realdognose/dbus-systemcalc-py/blob/master/delegates/dynamicess.py

My changes are designed for “Green Mode”, especially the removal of the discharge may “ruin” Trade-Mode. Unfortunately I can’t test Trade-Mode, so can’t really do anything there. So I wanted to add a check for the mode, and if the user is in Trade-Mode, keep the original implementation.

However, the cerbo does not seem to be aware, if the user is in TRADE or GREEN mode.
So, I can’t distinguish the both modes.

I’ve therefore just added a “Pseudo-Check”, which defaults to “GREEN”. Before any eventual merge, that would need to be adressed properly:

line 570:

#FIX: Trade Mode requires different handling of discharge / idle behaviour
#     Couldn't find out how to distinguish between trade / green mode, so adding 
#     the proper test here would allow better separation of concerns. 
userMode = "GREEN"
if (userMode == "TRADE"):
   # original code
elif (userMode == "GREEN"):
   # improved green mode

I will also update the OP with a more user-friendly way to get the delegate overwritten without touching the code directly, emphasising the current commit is not suitable for trade-mode.

3 Likes

Thats great!

1 Like