Can I email the flow to this address then ? victron@av-e.nl
I have a paid version supergrok, its still rubbish haha
Yes, best is to zip it with a password let say ānoderedā
Or via X account assuming you have one. Does chat, talk and files I saw mentioned this week. @kevdav100
Iām past that initial learning curve, would much appreciate to be granted a look at some example code, no expectations of direct use ability, just for learning. @BartChampagne
Just sent the email, have fun, and let us know if any good for your needs, will obviously need some major reworks for your market.
Thanks, I have put mine above: Phasing out the Node-RED Dynamic ESS implementation - #8 by UpCycleElectric
Same password
ā¦
Hybrid ākeep batteries chargedā just activated, added screenshots above.
You like spaghetti a lot @kevdav100 ?
No worries, Iāll figure it out. The provided adaptation steps seem common sense and readily available. I replied to your E-mail, pls confirm receipt.
Gemini likes spaghetti :).. I will get it to reorganise the flows at some point to tidy them up, my main goal now is to migrate the system onto the PI ..
Yes recieved your replies, will look at them later when I have more time
Cheers
Donāt put too much expectations on my code
Currently Iām swamped with my construction project and telecom work (a big network overhaul thatās turning out to be a LOT more complex than I anticipated) and with the release of Venus OS 3.60 around the corner Iād like to clean up some of my kludgy code.
Since the DESS code and functions have heavily changed from v3.55 to v3.60 Iāll need to completely rethink & redo some of my logic.
And on top of all thereās something else brewing that I canāt disclose yet, simply because I havenāt the foggiest idea about how it might turn out.
I either need 36 hour days or a couple months off to catch up with my backlog.
(The latter didnāt really work in 2020 so damnit)
Make that 48
@dfaber I think the API way of feeding DESS still requires a lot of attention. One, there is undocumented way of updating the schedule, and sent via API schedule is working bad ā [BUG] DESS - VRM is displaying wrong values after API update
Any news about this? I created a work around but things get complicated quickly, see also here: UpCycle Hybrid DESS Trade
No news on that yet. Been a bit busy with other priorities the last couple of days.
I think by now Iāve tried everything I could imagine to āemulateā this in VRM DESS (using Node-RED) and came up with a reasonably working solution. But it is a dearly missed option that makes VRM DESS pretty much dysfunctional for a DESS Trade only system.
And the preparation seems there in VRM-API:
By the way, there is a strange bug in your āsum inputsā subflow, sometimes it is off by exactly +1.0
I ended up using a simplified function based on it.
The news is that we will phase the b_goal_soc
and b_goal_hour
parameters completely.
I hope you mean āphase inā not āphase outā with that. For a practical example of the use case see also this topic with data from today: Another Strange DESS behaviour - #13 by UpCycleElectric
If not, I would be very interested in an evaluation of my workaround and some guidance on how Victron would propose to solve the āissueā that it represents. (or re-evaluate the decision not to bring this feature to VRM DESS).
Maybe you plan to enable the scheduled charge levels to work in combination with DESS? And Iād love to learn more about (or even participate in) the efforts to incorporate āpredictive pricingā beyond the āknown pricesā into the schedule forecast data. A pricing forecast window longer than the current 24 to 48 hours, even if less accurate beyond the actual known pricing window, could also solve a lot of the missed trading opportunity issues as it could prevent the rather stubborn behaviour to target minimum SoC at end of the same day (or next day after new prices roll in). Awell, many ways to skin a cat I guess, looking forward to the new developments, it is still very early in the DESS development space.
I also hope the b_goal_soc
and b_goal_hour
will stay. I would work great to implement my goal to make sure to have a full battery after sunset.
This is probably a drop-in-replacement for the Node-RED implementation of Dynamic ess using the VRM-API node and the āoriginal flowā.
I used some code from dynamic-ess/src/nodes/victron-dynamic-ess.js at main Ā· victronenergy/dynamic-ess Ā· GitHub for this.
It is probably not yet 15-minutes compatible but I think this will be easy to add in the near future using the dess.is_half_hour_schedule
variable (or similar).
[
{
"id": "ddb754a848a5437c",
"type": "group",
"z": "d457e88372dcd44a",
"name": "Dynamic ESS",
"style": {
"label": true
},
"nodes": [
"1857e6dc9a194fec",
"7049b7140944117e",
"76a5b63506d3a697",
"8533359282a12955",
"756103b9698a27ff",
"d81811500e0ae9f8",
"484523849a6134a7",
"780ff00a1393a6fe",
"70fcd76ccd733faf"
],
"x": 974,
"y": 264,
"w": 432,
"h": 317
},
{
"id": "1857e6dc9a194fec",
"type": "link out",
"z": "d457e88372dcd44a",
"g": "ddb754a848a5437c",
"name": "schedule 0 - current hour",
"mode": "link",
"links": [
"da28729197a836c4",
"36f3c65014ac2767"
],
"x": 1305,
"y": 420,
"wires": []
},
{
"id": "7049b7140944117e",
"type": "link out",
"z": "d457e88372dcd44a",
"g": "ddb754a848a5437c",
"name": "schedule 1 - current hour +1",
"mode": "link",
"links": [
"9072b4ed90c3d650"
],
"x": 1305,
"y": 460,
"wires": []
},
{
"id": "76a5b63506d3a697",
"type": "link out",
"z": "d457e88372dcd44a",
"g": "ddb754a848a5437c",
"name": "schedule 2 - current hour +2",
"mode": "link",
"links": [
"7677870734c617e4"
],
"x": 1305,
"y": 500,
"wires": []
},
{
"id": "8533359282a12955",
"type": "link out",
"z": "d457e88372dcd44a",
"g": "ddb754a848a5437c",
"name": "schedule 3 - current hour +3",
"mode": "link",
"links": [
"163da36509915168"
],
"x": 1305,
"y": 540,
"wires": []
},
{
"id": "756103b9698a27ff",
"type": "inject",
"z": "d457e88372dcd44a",
"g": "ddb754a848a5437c",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "300",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 1090,
"y": 320,
"wires": [
[
"70fcd76ccd733faf"
]
]
},
{
"id": "d81811500e0ae9f8",
"type": "function",
"z": "d457e88372dcd44a",
"g": "ddb754a848a5437c",
"name": "VRM DESS compatibility",
"func": "let dess = msg.payload\n\n/**\nconst currentDateTime = new Date()\ncurrentDateTime.setMinutes(0, 0, 0)\n\nconst unixTimestamp = Math.floor(currentDateTime.getTime() / 1000)\n\n\nlet currentHour = currentDateTime.getHours()\nif (currentHour > Object.keys(dess.schedule).length) {\n currentHour -= 24\n}\n**/\nconst output = []\nif (dess.output) {\n const currentDateTime = new Date()\n currentDateTime.setMinutes(0, 0, 0)\n const unixTimestamp = Math.floor(currentDateTime.getTime() / 1000)\n const currentHour = currentDateTime.getHours()\n for (let schedule = 0; schedule <= 3; schedule++) {\n let schedulePick = currentHour + schedule\n if (dess.is_half_hour_schedule) {\n schedulePick = (currentHour * 2) + schedule\n if (schedulePick > Object.keys(dess.output.SOC).length) {\n schedulePick -= 48\n }\n if (currentHour === 0 && Object.keys(dess.output.SOC).length > 48) {\n schedulePick += 48\n }\n } else {\n if (schedulePick > Object.keys(dess.output.SOC).length) {\n schedulePick -= 24\n }\n if (currentHour === 0 && Object.keys(dess.output.SOC).length > 24) {\n schedulePick += 24\n }\n }\n output.push({\n topic: `Schedule ${schedule}`,\n soc: Number((dess.output.SOC[schedulePick])),\n feed_in: dess.options.feed_in_possible ? 1 : 0,\n duration: dess.is_half_hour_schedule ? 1800 : 3600,\n start: unixTimestamp + (schedule * (dess.is_half_hour_schedule ? 1800 : 3600)),\n restrictions: Number((dess.output.restrictions[schedulePick] || 0)),\n strategy: dess.output.coping_strategy[schedulePick]\n })\n }\n}\n\nreturn output\n\n/**\nreturn [\n {\n soc: dess.output.SOC[currentHour],\n feed_in: dess.output.feed_in[currentHour],\n start: unixTimestamp,\n duration: 3600,\n restrictions: dess.output.restrictions[currentHour],\n strategy: dess.output.coping_strategy[currentHour],\n },\n {\n soc: dess.output.SOC[currentHour+1],\n feed_in: dess.output.feed_in[currentHour+1],\n start: new Date(dess.output.timestamps[currentHour+1]),\n duration: 3600,\n restrictions: dess.output.restrictions[currentHour+1],\n strategy: dess.output.coping_strategy[currentHour+1],\n },\n {\n soc: dess.output.SOC[currentHour+2],\n feed_in: dess.output.feed_in[currentHour+2],\n start: new Date(dess.output.timestamps[currentHour+2]),\n duration: 3600,\n restrictions: dess.output.restrictions[currentHour+2],\n strategy: dess.output.coping_strategy[currentHour+2],\n },\n {\n soc: dess.output.SOC[currentHour+3],\n feed_in: dess.output.feed_in[currentHour+3],\n start: new Date(dess.output.timestamps[currentHour+3]),\n duration: 3600,\n restrictions: dess.output.restrictions[currentHour+3],\n strategy: dess.output.coping_strategy[currentHour+3],\n }\n];\n**/",
"outputs": 4,
"timeout": 0,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1110,
"y": 520,
"wires": [
[
"1857e6dc9a194fec"
],
[
"7049b7140944117e"
],
[
"76a5b63506d3a697"
],
[
"8533359282a12955"
]
]
},
{
"id": "484523849a6134a7",
"type": "change",
"z": "d457e88372dcd44a",
"g": "ddb754a848a5437c",
"name": "",
"rules": [
{
"t": "set",
"p": "dess",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1070,
"y": 460,
"wires": [
[
"d81811500e0ae9f8"
]
]
},
{
"id": "780ff00a1393a6fe",
"type": "victron-dynamic-ess",
"z": "d457e88372dcd44a",
"g": "ddb754a848a5437c",
"name": "DEPRECATED",
"vrm_id": "",
"vrmtoken": "",
"country": "",
"contract_buy": "",
"contract_sell": "",
"b_max": 10,
"fb_max": 1.1,
"tb_max": 1.2,
"fg_max": 1,
"tg_max": 1,
"b_cycle_cost": 0,
"buy_price_formula": "p",
"sell_price_formula": "p",
"green_mode_on": true,
"b_goal_hour": 0,
"b_goal_SOC": 0,
"feed_in_possible": true,
"feed_in_control_on": true,
"verbose": false,
"x": 1300,
"y": 320,
"wires": [
[
"1857e6dc9a194fec"
],
[
"7049b7140944117e"
],
[
"76a5b63506d3a697"
],
[
"8533359282a12955"
]
]
},
{
"id": "70fcd76ccd733faf",
"type": "vrm-api",
"z": "d457e88372dcd44a",
"g": "ddb754a848a5437c",
"vrm": "",
"name": "",
"api_type": "dynamic-ess",
"idUser": "",
"users": "",
"idSite": "",
"installations": "",
"attribute": "",
"stats_interval": "",
"show_instance": false,
"stats_start": "",
"stats_end": "",
"use_utc": false,
"gps_start": "",
"gps_end": "",
"widgets": "",
"instance": "",
"vrm_id": "",
"country": "",
"b_max": "",
"tb_max": "",
"fb_max": "",
"tg_max": "",
"fg_max": "",
"b_cycle_cost": "",
"buy_price_formula": "",
"sell_price_formula": "",
"green_mode_on": "",
"feed_in_possible": "",
"feed_in_control_on": "",
"b_goal_hour": "",
"b_goal_SOC": "",
"store_in_global_context": false,
"verbose": false,
"x": 1080,
"y": 400,
"wires": [
[
"484523849a6134a7"
]
]
}
]
That is very interesting, thanks for sharing.
I have a singular question:
Does this provide a port of Node-RED DESSās ability to set b_goal_SOC @ b_goal_hour?
Not having this ability (to force the DESS scheduler to target a preset SOC at a preset time) ported to the VRM-API DESS implementation is the only roadblock for us to switch over.
Yes, the VRM API node has the same options and look-and-feel as the one that is being planned for Deprecation. It contains a subset of the āold oneā (retreive the data from VRM) but does not set flow.dess nor outputs the next 4 hour schedules. Thatās why I added those 2 nodes in the flow.
Second difference is it is now managed by Victron / venus-OS updates instead of being a custom integration.
Screenshot of the last options of the VRM API node with the Dynamic ESS api-type: