Can you see/analyse/test wheter the output object is/is not taking ‘scheduledsoc’ into account? I am not a coder but from the looks of it all the ‘scheduledSoc’ references to b_goal_SoC and b_goal_hour are now completely removed.
99% sure it will not since it is a GET function only. The options provided in the old node-red implementation permitted sending these options in the request while now they are all input in VRM. (And VRM has no such option.)
It will allow us to make our own logic using VRM data and if I recall, posting your own schedule to VRM might be possible in the future as well.
I am pretty much at the end of my wits on this ‘scheduledSoC’ topic. No room for dialog on the functional merits, no explanations, no alternative in sight, at most a ‘no not planning for it’. I just don’t get what could be the motivation to act this way.
Just tried this option and I couldn’t find the correct prices in the fetched array? All prices were way off to be from this day, maybe they were from a different price zone or applied wrong pruce calculations. Had to reset node-red for now and re-flow my price controlled loads, better than nothing till we get a better solution.
Hi Sarka, I’m sorry you had to reset your node-red.
Uninstalling my “hack” can be done in reverse (remove your nodes, remove it from the palette, restart node-red and re-enable the old vrm-api nodes)
But I think the data is almost right? There is a difference between the API results and VRM though. VRM thinks the prices are 15 minutes later and correspond with what nordpool shows. The api shows the prices 15minutes to early.
The timestamps are unixtime / UTC, so for example this data:
"deGb":[
[
1759329003000,
0.284713
],
[
1759329903000,
0.24532749999999998
],
[
1759330803000,
0.2815912
]
Is:
1759329003000,
0.284713
==
GMT: Wednesday 1 October 2025 14:30:03
Your time zone: woensdag 1 oktober 2025 16:30:03 GMT+02:00 DST
1759329903000,
0.24532749999999998
==
GMT: Wednesday 1 October 2025 14:45:03
Your time zone: woensdag 1 oktober 2025 16:45:03 GMT+02:00 DST
and
1759330803000,
0.2815912
==
GMT: Wednesday 1 October 2025 15:00:03
Your time zone: woensdag 1 oktober 2025 17:00:03 GMT+02:00 DST
This one was expected to be the first result though:
And this is the graph from the nordpool day ahead market, showing 17:00 - 17:15 to be the price-dip and not 16:45-17:00 (according to the API results)
What do you think @dfaber ?
edit
And it seems like the last item returned is ~now instead of the rest of the day:
The last item is [1759446057000,0.24089889999999997]
GMT: Thursday 2 October 2025 23:00:57
Your time zone: vrijdag 3 oktober 2025 01:00:57 GMT+02:00 DST
I think you’re correct, I was expecting it to work the same way as the previous implementation. I have raspi running node-red also, there vrm-api upgrade was easy. Timestamp came out as UTC for me but it seems that last item deGb[95][1] is ~now and every item before that is price history.
Edit:
There is a strange discrepancy in timestamps as you mentioned, 8:00 price was correct in deGb[95][1] but timestamp formatted to my time zone was 7:45.
We are looking into the time offset thing. It looks like that needs to be fixed on the API endpoint side.
Considering setting the interval via the node. I just published (on npm) version 0.3.1 that removes setting it in the node, as it is something that is going to be determined based on the configuration of your contract. If that is set to 15 minutes, you get 15 minute intervals back. And the same for hours.
Lastly for @UpCycleElectric let me give some more context on the state of charge on a certain hour. Before we had added that, there were people complaining that the battery couldn’t cover the needs for the night. The cause for that was that, while the next day prices weren’t in yet, we were only considering the consumption forecast until the “known” pricing period. So until midnight. One way of mitigating that problem was to add that “target soc at a certain hour”. The other option, which we implemented in the VRM scheduler, is to always look at the period until next sunrise for the needed consumption energy. And multiply that by 1.2, to make sure that the user can cover the night. As this turned out to work very well, we didn’t consider moving the SOC at specific hour to the VRM implementation as it would become a rather advanced feature for just a few users.
So first question is why it doesn’t work well for you. Can you give some specific use cases / dates + system where the algorithm failed to reserve enough energy?
Hi @dfaber - I am not totally sure if @UpCycleElectric and I have the same use case, but in our system we’ve had multiple occurrences where the system either hits (a) min SOC too early (causing unintended consumption from grid during peak hours), or (b) hits 100% too early (causing uncompensated export to grid) (e.g., Force DESS to self-consume for some period of time)
A key contributor to (a) in our situation is our system is so large (4x 10k Quattros), that the ~500W current draw just to keep them active is not accounted for; and for (b) the solar forecast often changes in the morning, so there’s not enough time for the system to self-consume “extra” power.
I think having a way to schedule a SOC could allow us to introduce an upper SOC / lower SOC buffer (though I may be totally wrong, and there could be another way to do this). Our DESS prices are fixed.
And yet another thing to add, as it changed slightly more. From 0.3.2 on the fetching will always return the records in 15 minute buckets. If your contract is hourly based, the 4 buckets of the hour will contain the same value.
Also the data will be fetched from the beginning of the day always and to the end of tomorrow - if the prices aren’t in yet, fewer records will be returned.
At the moment there is still a minor thing on the final hour of tomorrow, but that will be fixed.
If you don’t mind please refer to the link below for the use case. And for the dates I can be short: everyday that presents enough price volatility to make trading profitable. If I would have to point to a single key factor, it is the fact that we run a dedicated large capacity DESS Trade only system. No Solar, No other loads, just trading price volatility. As a trading strategy this cannot be executed correctly with only a ‘sell to min SoC’ biased algorithm, that is only half of the solution. There needs to be a ‘buy to max SoC’ biased algorith in place as well to enable trading the other half of the ‘profit making’ strategy.
I believe the reason that this seems to have disappeared of the radar (if it ever has been on there to begin with) lies in the reality that the popularity of Solar installations far precedes the development of adding (large) battery capacity and the developement of ESS and then DESS.
With solar power production (in kWh per day) initially far exceeding battery capacities I can understand that most systems were served reasonably well with only a ‘sell to min SoC’ bias algo. But times have changed, as our system demonstrates, our battery capacity allows almost a full day of contineous selling (not realistic just to illustrate size), our system usually tries to optimize buy and sell strategies runing over multiple days upto a full week to capture the most profitable price differences.
In context thereof, not having any (official) means to introduce a buy bias to the scheduler, without abusing all kinds of other settings that should really be left alone to function as intended, such as minimum SoC itself, is the core of the problem we encouter when developing and optimizing our trade systems.
Hope that explains it a bit better, ask me anything if you need more details. On when it works, when not, what we tried, how we forced it to work with our hybrid systems etcetera.
In summary, without a means to bias the scheduler to buy energy (within the ‘known prices’ time schedule), it will always plan to deplete the battery al the way down to minimum SoC at the end of the known price schedule, and therefore quite predictably miss any and all low price buying opportunities for which it cannot yet see the selling opportunity (because that opportunity lies beyongd the known price schedule). Therefore the system once charged up to what it knows it can sell within the known price schedule, will refuse to charge up further even during ridiculously cheap or even negative price levels. The system as-is has no ability to take into account the very predictable reality that there will be profitable sell opportunities the next day just as well. And then by the time the new dayly price schedule rolls in, early in the afternoon, many many hours of profitable buying opportunities will have been left unused all morning of the current day.
The workaround we used the last half year with substantial succes was to run the Node-RED DESS scheduler in parralel with the (active) VRM DESS scheduler. And by setting the Node-RED DESS scheduler to target full battery at dinnertime, it provided a very usefull alternative target SoC schedule long before the next day pricing came rolling in. From there it only took some clever decision logic (that also looked at absolute price levels as a secondary decision criterium) to enable a charge overide flow (temporarily setting VRM-DESS to ‘balance battery’ that day via VRM-API call) until the next day prices became available, at which point we could disable the ‘battery balance’ again and let VRM-DESS do its own thing again until next morning. Once we had the secondary price criterium tuned in reasonably well, this systems has been performing near perfect right upto this weeks changeover to 15 minute pricing, but that’s an issue we can solve.
Interesting. And also a directt confirmation that VRM-DESS is based on assumptions that put unnessesary (and unexopected) limits on its functionality, such as the presence of ‘self-consumption’ loads and ‘solar production’ and only accounting for a couple of hours of selfconsumption until solar production would start. Especially for a DESS Trade system these assumptions are counterproductive to say the least, especially when not clearly communicated and documented (at all?)
I still believe that, knowing the scheduler already posesses the capability to take scheduled soc levels into account, the most elegant and fitting solution to this issue is to enable the already implemented ESS ‘Scheduled charge levels’. Thus stop silently ignoring those setting when DESS is active, allowing them to function the same way the ‘scheduledSoC’ b_goal_SoC and b_goal_hour setting did/does as an input to the scheduler. This might not completely solve the issue of the primarily minimum SoC biased algorith but it would make it 10 times less complicated to develop tailermade Node-RED flows to fit a whole slew of additional use cases not (yet) foreseen by the Victron and its user base combined. To me this would be close to perfect to finally get the tools to make the DESS scheduler work for us, instead being forced to adapt to DESS to make it behave the way we need it to. Without the need to resort to running Node-RED DESS in parralel as hybrid system so we can finally sunset Node-RED DESS completely.
Fun fact: tomorrow prices are 0ct (before taxes) all day long. With no official VRM-DESS settings to ensure such an opportunity is being seized upon to charge all our batteries to the brim automatically when such an opportunity presents itself.
I wasn’t the only one noticing:
0.3.2 looks better, thank you for the changes. The schedule for tomorrow still looks a bit weird (like the schedule for yesterday) but this might be on the API side? I have not checked the price/time combo yet.
Didn’t have much time today to tweak the conversion to the “old node-red implementation”, but this is what it currently shows:
Oh, and I force charged past hour and it tries to sell at the 2 price peaks today
I’ll just leave DESS (trade-mode) turned off for now ![]()
Current trade mode seems to do what I want > 95% of the time. If making something like this was easy there was a solution that works 100% of the time. But meh… It ain’t easy to program. (I pondered about it, but I will not even dare to try.)
I put some effort today in getting the date/times correct (they are “toLocaleString(“nl-NL”)”).
The VRM issue depends on what timezone you’d like to use? Right now I get data from yesterday 00:00 UTC (02:00 UTC+2 Amsterdam time) till today 21:45 UTC (23:45 UTC+2)
(The jump in SOC is because I added 16kWh storage around 18:00. Also, not all data is correctly mapped yet.)
Not getting the last slots has been fixed now on the API side.
Also notice that I’ve released 0.3.3, which fixes a problem with setting the end time (which affected stats retrieval, not Dynamic ESS schedules).
will this be included in a v3.70 beta soon?
It is scheduled for the next beta. But when that is due is beyond my control.
Thank you for the continued work on the vrm-api-node. I just installed 0.3.3 and it works wonderfully. I still think however, the API side needs some love as well:
From 0.3.2 on the fetching will always return the records in 15 minute buckets. If your contract is hourly based, the 4 buckets of the hour will contain the same value.
It seems when the contract is in 15 minutes, past forecast-data is only returned in the first quarter of the hour (for the full hour), the other 3 quarters are 0.
Not getting the last slots has been fixed now on the API side.
Yes, forecast wise. But the prices are not known yet since (depending on the timezone) the last 2 hours are for the day after tomorrow. The data starts at 02:00 yesterday (since I live in UTC+2). It would be nice if a timezone parameter is added so everybody around the world can get 48 hour data from local midnight yesterday to local midnight tomorrow.
I am not sure if the new API returns the concepts of “strategy” (0 for trademode, 1 for green-mode), AllowGridFeedIn and Restrictions. Maybe they can be inferred?
My work on getting the new api data in the old /dess page will continue ![]()
This is how I now see the VRM data now in the old UI:
(at 02:00 local time I will only see today in this graph)
Cheers and keep up the good work!
Hi guys, lovely to see an updated VRM API in v3.70~44 beta but a loud and clear heads up (in the beta changelog) that this update breaks ‘installation stats’ (and possibly other calls) would have been appreciated.
this update breaks ‘installation stats’ (and possibly other calls)
I must have missed the breaking, apart from having seen a PR for the end of tomorrow, which I still need to review, merge and tag a new release for.
Or is there something else breaking?







