DESS: Trade mode not smart in cloudy days, while green mode charges to early on sunny days

I have DESS running in Trade mode, with normal sunny days this works fine, but when there are cloudy days and the solar prediction is low DESS in Trade Mode doesn’t charge the solar in the morning because the target soc is at minimum at the end of the day. When the prices of the next day arrive DESS sees it needs more energy for the next day but it allready missed the solar energy in the morning.

The result is that in the morning solar power is sold to grid but the next day, before solar power is sufficient, it has to be bought from grid but at a higher price.

Green mode prevents this, because it always tries to charge the battery to maximum, but it starts also charging when the sell price is high and enough excess solar energy is predicted.

So with cloudy days Green mode works best, but with sunny days Trade mode works best.

Maybe it is possible to create a mode when solar prediction is low, solar is charged to battery in the morning like green mode does, and when solar prediction is high solar is charged on the cheapest moment like in trade mode?

I can create a flow in nodered that checks the solar prediction of the current day in the early morning and switches to green mode at low solar prediction and to trade mode at high solar prediction, but maybe a Hybrid option can be added to Green and Trade mode so other users can also use this benefit?

I’ve noticed the same behavior. While I usually don’t like to see the system sitting idle - especially after the very active summer so far - I can kind of understand DESS’ choices on days like today for my own system once I include RTE and battery cost in the picture.

That said, I don’t have such a high delta between buy-sell price as you do. I agree it might not be sensible to sell solar to the grid right now..

For now I created this nodered flow, if the solarforcast is less than 120% of the consumption forecast the system switches to green mode, otherwise it switches to trade mode.

[
    {
        "id": "885e4c42eae7c14a",
        "type": "group",
        "z": "493a25f4f755fa08",
        "name": "Determine Green or Trade Mode",
        "style": {
            "label": true
        },
        "nodes": [
            "e37be342ee2595f8",
            "3f1854380b800af6",
            "50a2bfc023e0902e",
            "dacdb599bf17917d",
            "34f3a9850e3ca6c4",
            "3c7f6b56f7f38bb9",
            "c2b24127f73b15ae",
            "c226425011f448e0"
        ],
        "x": 74,
        "y": 59,
        "w": 1032,
        "h": 242
    },
    {
        "id": "e37be342ee2595f8",
        "type": "vrm-api",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "vrm": "19a6b69d787cf208",
        "name": "Get Solar  yield forecast",
        "api_type": "installations",
        "idUser": "",
        "usersQuery": "me",
        "idSite": "111111",
        "installations": "stats",
        "attribute": "solar_yield_forecast",
        "stats_interval": "years",
        "show_instance": false,
        "stats_start": "",
        "stats_end": "",
        "use_utc": false,
        "gps_start": "",
        "gps_end": "",
        "widgets": "",
        "instance": "",
        "store_in_global_context": false,
        "verbose": false,
        "transform_price_schedule": false,
        "outputs": 1,
        "x": 430,
        "y": 100,
        "wires": [
            [
                "3f1854380b800af6",
                "50a2bfc023e0902e"
            ]
        ]
    },
    {
        "id": "3f1854380b800af6",
        "type": "change",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "solarforecast",
                "pt": "global",
                "to": "payload.totals.solar_yield_forecast",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 730,
        "y": 100,
        "wires": [
            []
        ]
    },
    {
        "id": "50a2bfc023e0902e",
        "type": "vrm-api",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "vrm": "19a6b69d787cf208",
        "name": "Get Solar  yield forecast",
        "api_type": "installations",
        "idUser": "",
        "usersQuery": "me",
        "idSite": "111111",
        "installations": "stats",
        "attribute": "vrm_consumption_fc",
        "stats_interval": "years",
        "show_instance": false,
        "stats_start": "",
        "stats_end": "",
        "use_utc": false,
        "gps_start": "",
        "gps_end": "",
        "widgets": "",
        "instance": "",
        "store_in_global_context": false,
        "verbose": false,
        "transform_price_schedule": false,
        "outputs": 1,
        "x": 430,
        "y": 180,
        "wires": [
            [
                "dacdb599bf17917d",
                "3c7f6b56f7f38bb9"
            ]
        ]
    },
    {
        "id": "dacdb599bf17917d",
        "type": "change",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "consumptionforecast",
                "pt": "global",
                "to": "payload.totals.vrm_consumption_fc",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 750,
        "y": 180,
        "wires": [
            []
        ]
    },
    {
        "id": "34f3a9850e3ca6c4",
        "type": "function",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "Determine Green or Trade",
        "func": "let solarforecast = global.get(\"solarforecast\");\nlet consumptionforecast = global.get(\"consumptionforecast\");\n\nif (solarforecast < consumptionforecast * 1.2) msg.payload = 1;\nelse msg.payload = 0;\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 530,
        "y": 260,
        "wires": [
            [
                "c2b24127f73b15ae"
            ]
        ]
    },
    {
        "id": "3c7f6b56f7f38bb9",
        "type": "delay",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 320,
        "y": 260,
        "wires": [
            [
                "34f3a9850e3ca6c4"
            ]
        ]
    },
    {
        "id": "c2b24127f73b15ae",
        "type": "victron-output-dess",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "service": "com.victronenergy.settings",
        "path": "/Settings/DynamicEss/OperatingMode",
        "serviceObj": {
            "service": "com.victronenergy.settings",
            "name": "Venus settings",
            "communityTag": "dess"
        },
        "pathObj": {
            "path": "/Settings/DynamicEss/OperatingMode",
            "type": "enum",
            "name": "Dynamic ESS operating mode",
            "enum": {
                "0": "Trade mode",
                "1": "Green mode"
            },
            "mode": "both"
        },
        "name": "",
        "onlyChanges": false,
        "roundValues": "no",
        "rateLimit": 0,
        "outputs": 0,
        "conditionalMode": false,
        "condition1Operator": ">",
        "condition2Enabled": false,
        "condition2Service": "",
        "condition2Path": "",
        "condition2Operator": ">",
        "logicOperator": "AND",
        "outputTrue": "true",
        "outputFalse": "false",
        "outputOnChange": false,
        "debounce": 2000,
        "x": 900,
        "y": 260,
        "wires": []
    },
    {
        "id": "c226425011f448e0",
        "type": "cronplus",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "",
        "outputField": "payload",
        "timeZone": "",
        "storeName": "",
        "commandResponseMsgOutput": "output1",
        "defaultLocation": "",
        "defaultLocationType": "default",
        "outputs": 1,
        "options": [
            {
                "name": "schedule1",
                "topic": "topic1",
                "payloadType": "default",
                "payload": "",
                "expressionType": "cron",
                "expression": "0 0 6,18 * * * *",
                "location": "",
                "offset": "0",
                "solarType": "all",
                "solarEvents": "sunrise,sunset"
            }
        ],
        "x": 180,
        "y": 100,
        "wires": [
            [
                "e37be342ee2595f8"
            ]
        ]
    },
    {
        "id": "19a6b69d787cf208",
        "type": "config-vrm-api",
        "name": "",
        "forceIpv4": false
    },
    {
        "id": "290802918da3cc89",
        "type": "global-config",
        "env": [],
        "modules": {
            "victron-vrm-api": "0.3.11",
            "@victronenergy/node-red-contrib-victron": "1.6.64",
            "node-red-contrib-cron-plus": "2.2.4"
        }
    }
]

If I interpret your flow correctly, it looks ahead pretty far (your yield/consumption forecast is set to the whole year?).

Also, just to play the devil’s advocate a little bit here; let’s say it’s a very windy day with extremely low prices during the day but not a lot of sun (<120%). Your system would switch to green mode in this case, which wouldn’t be the most sensible choice probably :slight_smile:

Forecast is for maximum of 2 days afaik (I don’t see more data returning).

And yes indeed it’s driven by the sun not wind or low prices. But with vat and tax not returning on sold electricity (end of ‘saldering’ in 2027) the price has to have extreme highs and lows before purchasing and selling back will be profitable.

So it’s not perfect and a hybride mode instead of green and trade would still be preferred.

For most of the time it will be probably more profitable than buying from grid during days with less solar energy.

Indeed I did something wrong with de range requested. I corrected this.

[
    {
        "id": "885e4c42eae7c14a",
        "type": "group",
        "z": "493a25f4f755fa08",
        "name": "Determine Green or Trade Mode",
        "style": {
            "label": true
        },
        "nodes": [
            "e37be342ee2595f8",
            "3f1854380b800af6",
            "50a2bfc023e0902e",
            "dacdb599bf17917d",
            "34f3a9850e3ca6c4",
            "3c7f6b56f7f38bb9",
            "c2b24127f73b15ae",
            "c226425011f448e0",
            "d415af13d939da17"
        ],
        "x": 74,
        "y": 39,
        "w": 1032,
        "h": 262
    },
    {
        "id": "e37be342ee2595f8",
        "type": "vrm-api",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "vrm": "19a6b69d787cf208",
        "name": "Get Solar  yield forecast",
        "api_type": "installations",
        "idUser": "",
        "usersQuery": "me",
        "idSite": "111111",
        "installations": "stats",
        "attribute": "solar_yield_forecast",
        "stats_interval": "days",
        "show_instance": false,
        "stats_start": "0",
        "stats_end": "86400",
        "use_utc": false,
        "gps_start": "",
        "gps_end": "",
        "widgets": "",
        "instance": "",
        "store_in_global_context": false,
        "verbose": false,
        "transform_price_schedule": false,
        "outputs": 1,
        "x": 430,
        "y": 100,
        "wires": [
            [
                "3f1854380b800af6",
                "50a2bfc023e0902e",
                "d415af13d939da17"
            ]
        ]
    },
    {
        "id": "3f1854380b800af6",
        "type": "change",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "solarforecast",
                "pt": "global",
                "to": "payload.totals.solar_yield_forecast",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 730,
        "y": 100,
        "wires": [
            []
        ]
    },
    {
        "id": "50a2bfc023e0902e",
        "type": "vrm-api",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "vrm": "19a6b69d787cf208",
        "name": "Get Consumption forecast",
        "api_type": "installations",
        "idUser": "",
        "usersQuery": "me",
        "idSite": "111111",
        "installations": "stats",
        "attribute": "vrm_consumption_fc",
        "stats_interval": "days",
        "show_instance": false,
        "stats_start": "0",
        "stats_end": "86400",
        "use_utc": false,
        "gps_start": "",
        "gps_end": "",
        "widgets": "",
        "instance": "",
        "store_in_global_context": false,
        "verbose": false,
        "transform_price_schedule": false,
        "outputs": 1,
        "x": 430,
        "y": 180,
        "wires": [
            [
                "dacdb599bf17917d",
                "3c7f6b56f7f38bb9",
                "d415af13d939da17"
            ]
        ]
    },
    {
        "id": "dacdb599bf17917d",
        "type": "change",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "consumptionforecast",
                "pt": "global",
                "to": "payload.totals.vrm_consumption_fc",
                "tot": "msg"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 750,
        "y": 180,
        "wires": [
            []
        ]
    },
    {
        "id": "34f3a9850e3ca6c4",
        "type": "function",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "Determine Green or Trade",
        "func": "let solarforecast = global.get(\"solarforecast\");\nlet consumptionforecast = global.get(\"consumptionforecast\");\n\nif (solarforecast < consumptionforecast * 1.2) msg.payload = 1;\nelse msg.payload = 0;\n\nreturn msg;",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 530,
        "y": 260,
        "wires": [
            [
                "c2b24127f73b15ae"
            ]
        ]
    },
    {
        "id": "3c7f6b56f7f38bb9",
        "type": "delay",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "",
        "pauseType": "delay",
        "timeout": "1",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 320,
        "y": 260,
        "wires": [
            [
                "34f3a9850e3ca6c4"
            ]
        ]
    },
    {
        "id": "c2b24127f73b15ae",
        "type": "victron-output-dess",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "service": "com.victronenergy.settings",
        "path": "/Settings/DynamicEss/OperatingMode",
        "serviceObj": {
            "service": "com.victronenergy.settings",
            "name": "Venus settings",
            "communityTag": "dess"
        },
        "pathObj": {
            "path": "/Settings/DynamicEss/OperatingMode",
            "type": "enum",
            "name": "Dynamic ESS operating mode",
            "enum": {
                "0": "Trade mode",
                "1": "Green mode"
            },
            "mode": "both"
        },
        "name": "",
        "onlyChanges": false,
        "roundValues": "no",
        "rateLimit": 0,
        "outputs": 0,
        "conditionalMode": false,
        "condition1Operator": ">",
        "condition2Enabled": false,
        "condition2Service": "",
        "condition2Path": "",
        "condition2Operator": ">",
        "logicOperator": "AND",
        "outputTrue": "true",
        "outputFalse": "false",
        "outputOnChange": false,
        "debounce": 2000,
        "x": 900,
        "y": 260,
        "wires": []
    },
    {
        "id": "c226425011f448e0",
        "type": "cronplus",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "",
        "outputField": "payload",
        "timeZone": "",
        "storeName": "",
        "commandResponseMsgOutput": "output1",
        "defaultLocation": "",
        "defaultLocationType": "default",
        "outputs": 1,
        "options": [
            {
                "name": "schedule1",
                "topic": "topic1",
                "payloadType": "date",
                "payload": "",
                "expressionType": "cron",
                "expression": "0 0 6,18 * * * *",
                "location": "",
                "offset": "0",
                "solarType": "all",
                "solarEvents": "sunrise,sunset"
            }
        ],
        "x": 180,
        "y": 100,
        "wires": [
            [
                "e37be342ee2595f8"
            ]
        ]
    },
    {
        "id": "d415af13d939da17",
        "type": "debug",
        "z": "493a25f4f755fa08",
        "g": "885e4c42eae7c14a",
        "name": "debug 1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 940,
        "y": 80,
        "wires": []
    },
    {
        "id": "19a6b69d787cf208",
        "type": "config-vrm-api",
        "name": "",
        "forceIpv4": false
    },
    {
        "id": "4be6c58910dc7b68",
        "type": "global-config",
        "env": [],
        "modules": {
            "victron-vrm-api": "0.3.11",
            "@victronenergy/node-red-contrib-victron": "1.6.64",
            "node-red-contrib-cron-plus": "2.2.4"
        }
    }
]