User Tools

Site Tools


Table of Contents

Dynamic ESS - manual

What is Dynamic ESS?

Dynamic ESS is an algorithm that aims to minimise the costs made on the grid and battery:

  • By scheduling charge/discharge cycles of the battery,
  • While taking grid limitations, battery specifications and day ahead energy prices into account,
  • When it can, it also considers the consumption and solar yield forecasts when scheduling.

Also check these community posts for remarks and further troubleshooting:

Can I use it? | Eligibility Criteria

Dynamic ESS is only eligible for the installations which fits the following criteria:

  • Be an ESS;
  • Not use Generator connection outside of power outages;
  • Run Venus OS v3.30 (or newer)

For best results:

  • Have a variable or dynamic energy contract.
  • Use a supported energy meter (especially if your system setup has heavy loads (EV charger, heat pumps) in front of the Victron system). See here for more information on this.


  • Only the dynamic energy contracts of the following countries are supported for day ahead prices: Austria, Belgium, Bulgaria, Croatia, Czech Republic, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Italy, Latvia, Lithuania, Luxembourg, Montenegro, Netherlands, North Macedonia, Norway, Poland, Portugal, Romania, Serbia, Slovakia, Slovenia, Spain, Sweden, Switzerland and Ukraine.
  • If you have fixed prices (which may differ weekends/weekdays/daytime/nighttime), you can also use it outside these named countries.

How can I get started? | Configuration

To get started, you need to provide VRM with the necessary configuration Dynamic ESS requires. To do this, you can navigate to Settings → Dynamic ESS and follow the instructions on the page. This should take 15 minutes of your time.

From the page, you can configure the settings in 5 steps. All filled out values can always be adjusted later.

Also make sure that you have set the location of your device (so we can do the correct solar forecast) and have “Two-way communication enabled” on VRM. This is needed for injecting the Target SOC schedules on to the device.

Step 1: System

First thing we need to know is whether or not you can sell back to the grid or not. If you can, you get additional questions on the power limits when selling back. This is the lowest one of either your grid connection or what your system is capable of. So if your grid connection can do 4 kWh and your system 2.5 kWh, fill out 2.5 kWh.

Note that this is part is setting the capabilities, not actually setting limits for the system to use. See here for info on setting limits for the system.

Then you need to set the operating mode:

  • Green mode:
    • Only sell surplus solar back to the grid after consumption and battery charging
    • Energy in battery is reserved for consumption
    • Charge battery when prices are low
  • Trade mode:
    • Always sells surplus solar back to the grid
    • Energy in battery is used to trade
    • Charge battery when it is beneficial for trading

You can always adjust this mode at a later stage, so pick the one that best suits your needs.

Step 2: Battery

Then we need to know information on your battery:

  • Battery Energy Capacity - In order to calculate how much 1% of SOC of the battery is, we need to know how much capacity the battery has.
  • Maximum charge and discharge power - This is used for determining the maximum amount we can (dis)charge the battery in an hour
  • Battery costs - Battery costs indicate how expensive it is to use it for charging and discharging, expressed in €/kWh. A typical calculation for this is:
  costs for buying the battery in € / (charging cycles * battery capacity in kWh)

One battery charge cycle equals full battery charged to 100% and fully used to 0%. If you only use half of the battery power, then recharge it and repeat it the following day — it will also count as one charge cycle instead of two. The number of charging cycles is a number that differs per brand. The battery costs is usually somewhere between € 0.02 and € 0.06 /kWh. Some feedback of users is that they don’t care about the battery costs, as they already paid for it, so technically there’s no additional costs to charge it. In that case we still advise to put a small amount in as battery costs. E.g. 0.01 €/kWh.

In order to make the calculation for you, you can also fill out the invoiced battery cost and the estimated amount of cycles the battery can do. Together with the filled out battery capacity this will calculate the price for you.

  • Configure Dynamic ESS SoC - The Minimum Dynamic ESS SOC determines when Dynamic ESS will stop selling to the grid to leave enough energy for self-consumption. By not setting the Minimum Dynamic ESS SOC separately, Dynamic ESS will use the Minimum SOC instead.

If you set the min soc using the slider, then save the form, it will not have been logged to lastLogData yet. Thus the old value will be used in the schedule. Installation will handle this, and the next hour the correct value will be used.

Step 3 and 4: Buy and sell prices

For buying and selling you can either have dynamic (day ahead) prices or fixed prices (which can differ at different times / weekend vs weekdays). So first you need to fill out if you have fixed or dynamic pricing.

Dynamic prices

Each country and provider uses their own formula for pricing. As the system grows, we will have more and more pre-filled out formula's to select from, but you may need to adjust or fill out your own formula.

Unfortunately getting the buy and sell formulas right isn't always straightforward. As all calculations, on when to buy and sell from the grid, are based on the formulas, getting it right is important. Most of the details of your formulas are located somewhere in the contract you signed with your provider. Quite often these contracts are not the most clear documents to read and dissect. We can give you some general rules and show you what other users have filled out as their formula. With these instructions, you should be able to approximate the actual price you are paying and receiving for your energy.

Generalised over countries and providers a formula typically something like: (p+0.02+0.13)*1.21. It this example it breaks down to:

  • p - the dynamic price / kWh
  • € 0.02 - energy provider profit share
  • € 0.13 - DSO working price + contributions/levy/transportation fees
  • 21% - tax

The sell price formula looks often identical and in common cases looks something like (p-0.02+0.13)*1.21. So the energy provider profit share works the other way around.

If the provider takes a 15 % percentage of the day ahead buy price and the taxes are 6%, the formula becomes: ( p * 1.15 ) * 1.06. This is a bit weird, because in case of negative buy prices, the provider is going to pay you extra for all of the energy. Knowing providers, this is quite unlikely. So the more plausible formula becomes: (p + abs(p * 0.15)) * 1.06, which makes sure that the provider takes its share, even when the prices are negative. Also note that, if you don't use euro's, you can set the sites currency in the general settings for your site.

You can also get some ideas from this issue.

Fixed prices

If you have a fixed prices contract, you can still have different prices at different moments of the day. In some cases you can have different prices between weekdays and weekends. So that is the first question to answer.

Then, you can fill out the price per hour (more granularity is currently not possible).

Step 5: Confirmation

In the final step you see the filled out values summarised. If you need to make adjustments, you can do so. Otherwise you can submit the form.

Now navigate to the installation’s Dashboard and click the button shown below to open the Controls menu. Under the ESS section, you will find Dynamic ESS controls.

What's next? | After configuration

As the configuration flow points out, you can navigate to the Installation ControlsESS settings to see the running state of Dynamic ESS. The switch is green when Dynamic ESS is on and red when it is switched off.

The Auto (green) mode is the usual mode in which Dynamic ESS should operate. If you want to disable Dynamic ESS, toggle the switch to Off (red).

The state of Dynamic ESS will also show on the dashboard, just after the title. As a side note: If you run the Node-RED implementation of Dynamic ESS, here it will show “Node-RED”.


Data Visualisations

Once operational, you can find Dynamic ESS visualisations that appear below the installation data charts on the Dashboard page. There you can find a graph showing the current forecast:

On the left side of the vertical line, you see the recorded values. On the right side of the line it shows the solar forecast, the consumption forecast and also the target SOC that will be followed (as scheduled during the last calculation for the site).

By clicking on the legend, you can enable or disable shown data sets in the graph.

Below you first find a summary on the totals for the day and then there are three tabs which visualise:

  • Costs and earnings made as a result of Dynamic ESS usage;
  • Schedule of battery and grid usage;
  • All energy factors which are taken into account when scheduling

Costs and earnings

This tab begins with a summary that compares the system using Dynamic ESS with the system using regular ESS.


The prices graph is available on both this tab and the Energy tab. It shows the buy and sell prices per hour.

The usage graph shows the energy usage of the grid and of the battery in kWh.


The prices and graph is the same one as on the Schedule tab. It shows the buy and sell prices per hour.

Then there is the energy graph, which summaries everything the system has done and is planning for.

Warm-up period

Dynamic ESS uses consumption and solar yield forecasts to schedule ahead, when the forecasts are available. Depending on the historical data available prior, the accuracy of these forecasts can vary. As it stands now, optimal consumption forecasts need 28 days of past consumption data and optimal solar yield forecasts need 28 days of past solar data. Thus, if there is not enough data the forecasts might be suboptimal which makes the performance of Dynamic ESS suboptimal. However, despite lower accuracy in forecasts, turning Dynamic ESS on in this period is still more cost-efficient and it gets better every day until it reaches its optimal state after 28 days of warm-up period.

Unexpected behaviour?

It is possible that you deem the behavior of Dynamic ESS to be unexpected or suboptimal. Depending on when it happens, there are two possible causes:

  • If the suboptimal scheduling is in the future plan, it is probably due to the configurations set by the user. For instance, battery costs being high leads to limited usage of the battery.
  • If the suboptimal scheduling is in the past, then it is mostly due to the inaccuracies that come from consumption or solar yield forecasts. It is important to note forecasting will always come with its inaccuracies and even with these inaccuracies at distinct hours, Dynamic ESS minimizes costs compared to Default ESS mode in the longer run.
  • Make sure you have the formula's right. The system uses these to determine the price per hour and, if they are not correct, the system will make the wrong decisions.

You might also want to read the chapter on determining the target SOC, to get some more idea on how the algorithm determines the optimal (dis)charging path.

If you feel like the behavior that you are observing is not explained by above points and you cannot find the answer in the FAQ below, you are encouraged to visit the community thread dedicated to this. If needed, please also report your issue here, containing the VRM tag.


This part of the documentation is about how the system works on a technical level, as it might help troubleshooting for the more advanced users. The system works by taking all of the available data (day ahead pricing/fixed prices, solar forecast, consumption forecast, current SOC and minimum SOC) into account and calculating the optimal planning for the next hours. It looks as far ahead as it has information on the pricing. In case of day ahead prices until the end of the known prices (midnight when the prices are not in yet, tomorrow midnight once the prices get available). In case of fixed prices, the system always plans 48 hours ahead.

The planning is being converted into a target state of charge for the batteries per hour and whether or not the system can feed in to the grid during that hour. If the target SOC is lower than the current SOC, the batteries discharge (either to consumption or the grid; if feed-in is allowed), if the target SOC is higher than the current SOC the batteries get charged (either from solar or from grid). The upcoming four hours schedules are put into the GX device via the two-way VRM communication channel. On the dbus these schedules can be found under `com.victronenergy.settings`, path `/Settings/DynamicEss/Schedule/[0-3]`. Each schedule has a unix timestamp as starting time, a duration (typically 1 hour, 3600 seconds), a target SOC and a boolean value for if feed-in is possible.

Every few seconds the GX device will compare the target SOC with the current SOC and determine the power to use to reach that target before reaching the timestamp + duration. So it takes the full hour to reach the target SOC.

In all cases, when the target SOC changes, it will calculate the charge current required to get there, and then distribute that over all the chargers, with the solar chargers getting priority. If it needs more current to get there than solar provides, it will charge from the grid for the rest, but only if the price of the grid is not too high.

Determining the target SOC

Several people want to know how the algorithm determines the target SOC. This is done by taking 4 steps for each site running Dynamic ESS on each re-calculation of the schedule. This is typically done each hour.

  1. Obtain data;
  2. Set boundary conditions (battery, grid and the consumption/pv yield boundaries);
  3. Find the most optimal charging cycle according to the data at hand and the battery/grid costs;
  4. Attempt to reach the target SOC for the current hour by the end of this hour

We've ran a lot of simulations to check if we needed to increase the frequency of re-calculation, but that does not help much. In hindsight it is easy to conclude when the algorithm was off in its prediction. But usually it matches it quite well.

We keep the battery stable and not the grid: in our internal testing keeping the battery usage stable (basically the same as the plan) has been a lot more cost-effective than otherwise, because of the battery costs that pile up.

Also keep in mind that, when doing a consumption forecast, the system does not known when during the hour that consumption will be done. If the forecast does not match the reality, Dynamic ESS does keep the planned battery usage stable while punishing the forecast inaccuracies on the grid (selling the excess to grid, buy the additional need from the grid). This can be less ideal, but it is an issue of the forecasts being inaccurate, nothing that the Dynamic ESS decided.

The Node-RED implementation

There exists also a Node-RED implementation of Dynamic ESS.

The Node-RED flow uses the VRM API to get the calculation for the site and inserts the hourly schedules into the GX device. If you have specific needs, the Node-RED implementation gives you a lot more options than the current VRM implementation.

You should only be running one implementation at the same time. If you want to run the VRM version, disable the Node-RED flow. You can read on how to do that here.

Country / provider specific

It turns out that some countries have specific pricing rules and regulations. Most of these quirks that affect dynamic ESS have been added below.

Czech Republic

In the Czech Republic there are dynamic transport charges work the same as Denmark, working with peak-tariff and off-peak tariff transport fees.


In Denmark there are dynamic transport charges, depending on the time of day. At the moment there is no support for this in our system, but we will plan to add it later on.


German regulation does not allow feeding in from the battery into the grid (even if the power came from solar). From Venus OS version 3.20~17 it is possible to set certain restrictions.


At least one provider in Portugal only allows feeding in solar to the grid during daytime. This looks a lot like the German regulation. For the near future, won't link the battery to grid feed-in to specific times, but disabling battery-to-grid completely will be the first alternative (which is the function that will be implemented soon).


We are aware that the provider Octopus offers day ahead pricing, but as these are not offered via the ENTSO-E API, we are unable to process those. Eventually we will probably support these prices, but will take some time.

Also in the UK, (fixed) prices are known to change at the half hour instead of the whole hour (where our system works with). The work-a-round is to add the average price of in the overlapping hour. So if the price changes from 40 cents to 20 pence at 16.30, fill out a price of 30 pence from 16.00 - 17.00.

Adding better support for this will eventually be done, but as this also affects graphs and the scheduling, it might take a while.


Missing a question? Please ask them in the community forum with a remark that it should be added to the documentation and/or FAQ.

Q: Why can't I find dynamic ESS on VRM?

Right now (early March) Dynamic ESS is still in beta and only available via the beta VRM site. We expect to have Dynamic ESS ready for the officially launch in March 2024, after which it will no longer be needed to use VRM beta.

For those of you who aren’t familiar with beta VRM, you can log in through this link with your normal credentials.

Q: Why can't I find dynamic ESS on Beta VRM?

There are some pre-conditions a site must fulfill in order to get the “Dynamic ESS” menu option. Make sure that the sites system type is set to ESS or Hub-4. If it is not set to this, you need a different ESS assistant, which can be configured through VE.Configure. When in doubt on how to do that, please ask your installer for help.

Q: Which energy meters are supported?

In order to function properly and knowing how much energy is flowing a supported energy meter is needed. Basically any energy meter that is supported on the GX device will suffice. See the energy selection guide for supported meters.

Things like the Dutch P1 meter are not sampling fast enough and not supported right now.

Q: What is the default behaviour if the VRM connection is lost longer then 12 hours?

The system will run out of its schedule after 12 hours and revert to standard ESS operation. Once the connection is reestablished, new schedules will get added again and the Dynamic ESS will commence its operation.

As the system is partly depending on third-party services (e.g. for retrieving the day ahead price information). If we are somehow unable to fetch new pricing information, the calculations can no longer be done and the system will run out of schedule too. We have monitoring in place to check for this.

Q: Can the system handle charging my EV or other heavy loads?

The short answer is no. The longer answer is that we are working on this, but as it is not that straight forward to come up with a solution that is user friendly and works for everyone, it can take a while before support for this will appear.

See here for information on the options of limiting power.

Q: Is there an API available?

Yes, there is. The Node-RED implementation uses that as well. See here for more information. Do note that you will need to use an access token for that. Instructions on how to generate one can be found here.

Also the VRM-API node supports the Dynamic ESS API.

Q: Why does the system exceed the configured power?

During the configuration of the system, you are setting the capacity of the system, not the actual limits of the system. These capacities are used by the system to make its calculations, so it used as an average power the system can do in an hour.

If you need to limit the import configured power, you can configure import and export AC current limits via the Settings → ESS menu in the GX. This is possible since the v3.30~10 release.

How does it work?

As you’d expect, it monitors the current and when needed engages to keep that within the configured limits:

  • to prevent overcurrent during export, system limits solar production and battery discharge.
  • to prevent overcurrent during import, system limits battery charging.
  • to prevent overcurrent during import because of loads, system will assist using battery power. (As long as battery permits of course).
  • In case SOC is dropped more than 5% below configured ESS minimum SOC, the battery will be recharged from the grid as soon as loads drop.

Requirements and other details:

  1. The feature is part of ESS; and applies to MultiPlus, Quattro, MultiPlus-II and so forth. The Multi RS will come with the same feature when we release Energy Meter and ESS support for that, but thats a different project and implementation.
  2. NOTE: The function properly, the inverter/charges require an updated ESS Assistant, which you need VEConfigure for. The required version of the ESS Assistant is 018C.
  3. About the existing “Limit system feed-in” option in the ESS menu, in watts: if you have both set, the lower of the two is followed for feeding in DC-coupled PV.
  4. The GX does not limit PV-inverters in relation to the new export current limit. To illustrate: in case of major solar production, plus high tariff on selling energy to the utility, the new mechanism will limit feed in of power from the battery to 0. So, as long as the installed PV Inverter system is done such that it can’t by itself blow the fuse then its fine.
  5. Works with all ESS supported energy meters.

Q: Does it also take into account changing provider fees during the day?

Not right now, at the moment only the `p` is the variable piece of data of the formula. But as the system grows, new features will be added. It helps us a lot if we get more feedback on how your local provider makes his calculation. Please add to this GitHub issue on where we ask you for your providers formulas.

Q: Does the system work in the UK (or any other non-EU country)?

If your provider has “fixed” tariffs which are steady, but differ on hourly intervals, then yes. You can set the system to use a fixed contract. If your provider has hourly changing tariffs that are not covered by the ENTSO-E API, then you are out of luck for now. But if there is a public API and you let us know where we can fetch the information, we will gladly add it.

Q: My contract does not allow discharging the battery into the grid

In Germany it is forbidden to import electricity into a battery and then later export it out of the battery again, as the feed-in tariff is fixed, this would allow greenwashing.

In order to comply to this rule, the dynamic ESS system has a configurable option to prevent exporting from the battery at all. This can be set under the Settings → Dynamic ESS → Battery menu.

Q: My country is not using the Euro, how do I switch currency?

Under the Settings → General part of your site, you can set your currency.

Q: My providers changes price at the half hour instead of the full hour

Some (UK) providers offer fixed prices that change on the half hour instead of at the full hour. Unfortunately the 30 minute interval has some more implications than just allowing it to be entered into the fields.

The calculations and forecasts are currently done on the whole hour, so that needs to be accounted for as well. And the same goes for the graphs. All not impossible to solve, but not trivial either and needs a fair bit of testing.

So the 30 minute interval will be added eventually, but it will take some more time.

Q: Why does (dis)charging slow down or speed up towards the end of the hour?

The system calculates every few minutes how quickly it should (dis)charge to reach the target SOC at the end of the hour. If it falls behind (because your load is higher), it will speed up a bit, if it gets there too fast, it will slow down. If the battery capacity is overestimated, it will typically slow down towards the end. If the battery capacity is underestimated, it will typically speed up towards the end.

In addition, battery manufacturers are not always exact in the advertised battery capacity. You may have to tweak it a bit.

Q: Can I use scheduled charging in combination with Dynamic ESS?

The short answer is no, as this will interfere with the calculations of the system. If you want to use scheduled charging, then either switch to normal ESS or get creative in Node-RED.

Q: Can I upload the custom prices for my site myself?

At the moment this is not possible. If we decide to add it, it will first be added to the Node-RED implementation first.

Q: I am getting the alarm "Dynamic ESS error code: No matching schedule available"

The cases this alarm can be triggered are:

  • the system does not have a valid schedule for the current time frame
  • the system clock is off

In most cases your systems clock has drifted such that it cannot find a matching schedule. Usually the GX device will synchronize the time with a NTP server, but your network setup might refrain the GX device from reaching a time server. Please check your time setting / manually set it to the correct time. Users running Dynamic ESS on a Raspberry Pi will see this error more frequently because the Raspberry Pi does not have a realtime clock. Which means that it usually takes a while for these to get back on track with the correct time after a boot. The alarm should disappear once the time is correct again.

This alarm can also occur when DESS automatically switches to ESS because the SOC is below the min SOC level.

Q: I am getting the alarm "Dynamic ESS error code: ESS functionality not available"

This probably means that you once activated Dynamic ESS and are no longer using it. In order to fully disable it, you need to set the `com.victronenergy.settings`, path `/Settings/DynamicEss/Mode` to `0`.

This can be done on different ways, most easily using Node-RED and the output-control node.

Q: Why does Dynamic ESS's plan seem to change after the first few minutes of the hour?

Due to the fact that the scheduling starts running when the new hour starts, the new plan for the current hour can be delayed by a few minutes. This slight delay imposes only a negligible difference in the performance of Dynamic ESS.

Q: What about the efficiency losses of the battery?

Dynamic ESS on VRM takes battery losses into account. The system looks at the dbus service com.victronenergy.settings, path Settings/DynamicEss/SystemEfficiency.

Q: What happens if I modify the minimum SOC (State-Of-Charge) of the battery?

Decreasing the minimum SOC does not affect the performance of DESS negatively. However, when the minimum SOC is increased (above the current SOC), it might require the battery to be charged manually since Dynamic ESS is not designed to operate when current SOC is below the minimum.

Q: The energy graph is showing incorrect data

Sometimes the graph shows that energy was taken from the grid. When looking at the installation data graphs, it shows that the energy actually came from PV yield. This is caused by a known misleading assumption with the Energy graph: It assumes if there is more production than consumption, all consumption is met by production and the other way around: if there is more consumption than production, then all the production goes to consumption.

This is quite an assumption but this is how DESS considers it internally, so that’s why the visuals reflect it that way. If we do not have that assumption, the energy graph would be even more complicated. If you want to know the exact source of the energy, you should look at the installation data graphs (grid, solar and consumption).

Q: I can't find the controls button on the dashboard

You probably have Realtime updates switched off. You can switch it on via Settings → General → Realtime updates.

Note that the dashboard should show: Last updated: Realtime

Q: I get the error message "Dynamic ESS error code: Battery capacity unset"

This error can happen when the Dynamic ESS system starts before we were able to communicate the battery capacity from VRM to the GX device. It will go away as soon as you restart Dynamic ESS or the GX device.

drafts/dynamic_ess.txt · Last modified: 2024-05-15 08:38 by dfaber

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki