ESS setting - Self-consumption on Battery

Hello guys, please when you implement possibility to write (and read) setting for Self-consumption on Battery. I need to create Node-RED flow to not drain my battery when EVCS is on manual mode :smiley: Thanks in advance.

1 Like

Is there not way to create a feedback loop that just freezes/sets the min soc to what ever it is at that time?

I think it is possible, but it is much more complivated than use proposed feature.

Custom Input or Custom Control Node with Custom Input = com.victronenergy.settings and Measurement = /Settings/CGwacs/BatteryUse seems to be the right Option Number = 0 is for All system loads, 1 is for only critical loads.

Unfortunately, this register does not yet exist in the official “Modbus register List”…

I’m currently considering this solution for winter operation.

yes, exactelly - this solution for winter time and for EVCS is something I want to program.

Seems it already works :slight_smile:

pourrait on avoir le detail sur ces nodes

merci

For which one are you looking for?

j’ai le meme probleme, mode manuel sur EV chargeur, vide la batterie.

pouvais vous partager le json?

merci

Here it is:

[
{
“id”: “de5c019c228bbd55”,
“type”: “tab”,
“label”: “EVCS battery drain protector”,
“disabled”: false,
“info”: “”,
“env”:
},
{
“id”: “30d7c50cf35d48f7”,
“type”: “victron-output-custom”,
“z”: “de5c019c228bbd55”,
“service”: “com.victronenergy.settings”,
“path”: “/Settings/CGwacs/BatteryUse”,
“serviceObj”: {
“service”: “com.victronenergy.settings”,
“name”: “com.victronenergy.settings”
},
“pathObj”: {
“path”: “/Settings/CGwacs/BatteryUse”,
“name”: “/Settings/CGwacs/BatteryUse”,
“type”: “number”,
“value”: 1
},
“name”: “ESS setting - Self-consumption on Battery”,
“onlyChanges”: false,
“x”: 1200,
“y”: 160,
“wires”:
},
{
“id”: “583ad65a6ae6eb5a”,
“type”: “ui_text”,
“z”: “de5c019c228bbd55”,
“group”: “0087557d1ad61a95”,
“order”: 6,
“width”: “0”,
“height”: “0”,
“name”: “”,
“label”: “EVCS state”,
“format”: “{{msg.payload}}”,
“layout”: “row-spread”,
“className”: “”,
“style”: false,
“font”: “”,
“fontSize”: “”,
“color”: “#000000”,
“x”: 1110,
“y”: 80,
“wires”:
},
{
“id”: “505e2c99d5c6cc56”,
“type”: “function”,
“z”: “de5c019c228bbd55”,
“name”: “logic EVCS_state”,
“func”: “var EVCS_state = flow.get(“EVCS_state”);\n\n\n\nvar result = false ;\n\nif (EVCS_state == 0 || EVCS_state == 1 || EVCS_state == 3 || EVCS_state == 4 || EVCS_state == 5 || EVCS_state == 6 || EVCS_state == 7) { \n result = true;\n}\n\nflow.set(“EVCS_state”, result);\n\nnode.status({ text: result });\n\nmsg.payload = result;\n\nreturn msg;”,
“outputs”: 1,
“timeout”: “”,
“noerr”: 0,
“initialize”: “”,
“finalize”: “”,
“libs”: ,
“x”: 470,
“y”: 80,
“wires”: [
[
“65f693074f8211a2”
]
]
},
{
“id”: “fe436200be2f1a20”,
“type”: “change”,
“z”: “de5c019c228bbd55”,
“name”: “EVCS state”,
“rules”: [
{
“t”: “set”,
“p”: “EVCS_state”,
“pt”: “flow”,
“to”: “payload”,
“tot”: “msg”
}
],
“action”: “”,
“property”: “”,
“from”: “”,
“to”: “”,
“reg”: false,
“x”: 270,
“y”: 80,
“wires”: [
[
“505e2c99d5c6cc56”
]
]
},
{
“id”: “ea665164b1fd7f8b”,
“type”: “victron-input-evcharger”,
“z”: “de5c019c228bbd55”,
“service”: “com.victronenergy.evcharger/40”,
“path”: “/Status”,
“serviceObj”: {
“service”: “com.victronenergy.evcharger/40”,
“name”: “EVCS”
},
“pathObj”: {
“path”: “/Status”,
“type”: “enum”,
“name”: “Status”,
“enum”: {
“0”: “Disconnected”,
“1”: “Connected”,
“2”: “Charging”,
“3”: “Charged”,
“4”: “Waiting for sun”,
“5”: “Waiting for RFID”,
“6”: “Waiting for start”,
“7”: “Low SOC”,
“8”: “Ground test error”,
“9”: “Welded contacts test error”,
“10”: “CP input test error (shorted)”,
“11”: “Residual current detected”,
“12”: “Undervoltage detected”,
“13”: “Overvoltage detected”,
“14”: “Overheating detected”,
“15”: “Reserved”,
“16”: “Reserved”,
“17”: “Reserved”,
“18”: “Reserved”,
“19”: “Reserved”,
“20”: “Charging limit”,
“21”: “Start charging”,
“22”: “Switching to 3 phase”,
“23”: “Switching to 1 phase”,
“24”: “Stop charging”
}
},
“initial”: “”,
“name”: “”,
“onlyChanges”: false,
“x”: 110,
“y”: 80,
“wires”: [
[
“fe436200be2f1a20”
]
]
},
{
“id”: “8cc8de92f20673f6”,
“type”: “ui_text”,
“z”: “de5c019c228bbd55”,
“group”: “0087557d1ad61a95”,
“order”: 2,
“width”: 0,
“height”: 0,
“name”: “”,
“label”: “Self-consumption on Battery”,
“format”: “{{msg.payload}}”,
“layout”: “row-spread”,
“className”: “”,
“style”: false,
“font”: “”,
“fontSize”: 16,
“color”: “#000000”,
“x”: 1160,
“y”: 340,
“wires”:
},
{
“id”: “ab78ee1017978dea”,
“type”: “function”,
“z”: “de5c019c228bbd55”,
“name”: “logic Self-consumption_on_battery”,
“func”: “let EVCS_switch = flow.get(“EVCS_switch”); // This is expected to be a boolean (true/false)\nlet winter_switch_string = flow.get(“winter_switch”); // This is the string value (e.g., “true” or “false”)\n\n// — CONVERSION STEP —\nlet winter_switch_boolean = \n (typeof winter_switch_string === ‘string’ && winter_switch_string.toLowerCase() === ‘true’);\n// The variable winter_switch_boolean will now be a proper boolean (true or false).\n\n// — START DEBUGGING LINES —\n//node.warn("EVCS_switch value: " + EVCS_switch + ", type: " + typeof EVCS_switch);\n//node.warn("winter_switch_string value: " + winter_switch_string + ", type: " + typeof winter_switch_string);\n//node.warn("winter_switch_boolean value: " + winter_switch_boolean + ", type: " + typeof winter_switch_boolean);\n// — END DEBUGGING LINES —\n\nlet result;\n\n// Result = 0 only when EVCS_switch is true AND winter_switch is false\nif (EVCS_switch === true && winter_switch_boolean === false) {\n result = 0;\n} else {\n result = 1;\n}\n\nmsg.payload = result;\n\n// Update the node status for easy debugging\nnode.status({ text: "Payload: " + result });\n\nreturn msg;”,
“outputs”: 1,
“timeout”: “”,
“noerr”: 0,
“initialize”: “”,
“finalize”: “”,
“libs”: ,
“x”: 840,
“y”: 160,
“wires”: [
[
“30d7c50cf35d48f7”
]
]
},
{
“id”: “200945ca0e47a08d”,
“type”: “function”,
“z”: “de5c019c228bbd55”,
“name”: “UI logic self-consumption_on_battery”,
“func”: “var input_value = msg.payload;\nvar result;\n\n// Check if the input value is a number and is either 0 or 1\nif (typeof input_value === ‘number’) {\n if (input_value === 1) {\n result = “Critical loads only”;\n } else if (input_value === 0) {\n result = “All system loads”;\n } else {\n // Handle case where input is a number but not 1 or 0\n result = “Error: Input out of range (not 0 or 1)”;\n }\n} else if (typeof input_value === ‘string’ && (input_value === ‘1’ || input_value === ‘0’)) {\n // Optional: Handle case where input is a string “0” or “1” (common in Node-RED)\n var num_value = parseInt(input_value);\n if (num_value === 1) {\n result = “Critical loads only”;\n } else {\n result = “All system loads”;\n }\n} else {\n // Handle case where input is neither a number 0/1 nor string “0”/“1”\n result = “Error: Invalid input type or value”;\n}\n\nnode.status({ text: result });\nmsg.payload = result;\n\nreturn msg;”,
“outputs”: 1,
“timeout”: “”,
“noerr”: 0,
“initialize”: “”,
“finalize”: “”,
“libs”: ,
“x”: 830,
“y”: 340,
“wires”: [
[
“8cc8de92f20673f6”
]
]
},
{
“id”: “de309d7884850895”,
“type”: “victron-input-custom”,
“z”: “de5c019c228bbd55”,
“service”: “com.victronenergy.settings”,
“path”: “/Settings/CGwacs/BatteryUse”,
“serviceObj”: {
“service”: “com.victronenergy.settings”,
“name”: “com.victronenergy.settings”
},
“pathObj”: {
“path”: “/Settings/CGwacs/BatteryUse”,
“name”: “/Settings/CGwacs/BatteryUse”,
“type”: “number”,
“value”: 1
},
“name”: “ESS setting - Self-consumption on Battery”,
“onlyChanges”: false,
“x”: 200,
“y”: 340,
“wires”: [
[
“88a0e072a515809d”
]
]
},
{
“id”: “e55543ab09117c0c”,
“type”: “change”,
“z”: “de5c019c228bbd55”,
“name”: “winter switch”,
“rules”: [
{
“t”: “set”,
“p”: “winter_switch”,
“pt”: “flow”,
“to”: “payload”,
“tot”: “msg”
}
],
“action”: “”,
“property”: “”,
“from”: “”,
“to”: “”,
“reg”: false,
“x”: 510,
“y”: 160,
“wires”: [
[
“ab78ee1017978dea”,
“5480852de8c8e38e”
]
]
},
{
“id”: “a2655bf7e1fb7a91”,
“type”: “function”,
“z”: “de5c019c228bbd55”,
“name”: “EVCS status txt”,
“func”: “var EVCS_switch = flow.get(“EVCS_switch”);\n\nvar result;\n\nif (EVCS_switch == true) {\n result = “not in use”;\n} else if (EVCS_switch == false) {\n result = “in use”;\n} else {\n // Optional: Handle case where battery_logic is neither 1 nor 0\n result = “Error: Invalid logic value”;\n}\n\nnode.status({ text: result });\n\nmsg.payload = result;\n\nreturn msg;”,
“outputs”: 1,
“timeout”: “”,
“noerr”: 0,
“initialize”: “”,
“finalize”: “”,
“libs”: ,
“x”: 900,
“y”: 80,
“wires”: [
[
“583ad65a6ae6eb5a”
]
]
},
{
“id”: “0afcba55204219aa”,
“type”: “inject”,
“z”: “de5c019c228bbd55”,
“name”: “”,
“props”: [
{
“p”: “payload”
},
{
“p”: “topic”,
“vt”: “str”
}
],
“repeat”: “”,
“crontab”: “59 23 * * *”,
“once”: false,
“onceDelay”: 0.1,
“topic”: “”,
“payload”: “”,
“payloadType”: “date”,
“x”: 110,
“y”: 160,
“wires”: [
[
“23a7ff8cdbbc6cc0”
]
]
},
{
“id”: “23a7ff8cdbbc6cc0”,
“type”: “function”,
“z”: “de5c019c228bbd55”,
“name”: “date range function”,
“func”: “// Get the current date and time\nconst now = new Date();\n\n// Get the current month (0 = January, 11 = December) and day of the month\nconst currentMonth = now.getMonth();\nconst currentDay = now.getDate();\n\n// Define the start and end of the date range\n// Start: September 25 (Month 8, Day 25)\nconst startMonth = 8; // September\nconst startDay = 25;\n\n// End: March 25 (Month 2, Day 25)\nconst endMonth = 2; // March\nconst endDay = 25;\n\nlet inRange = false;\n\n// The period spans across the year end (e.g., Winter)\n// The condition is: (Current date is after or on Sep 25) OR (Current date is before or on Mar 25)\n\nif (currentMonth > startMonth || (currentMonth === startMonth && currentDay >= startDay)) {\n // This handles dates from Sep 25 up to and including Dec 31\n inRange = true;\n} else if (currentMonth < endMonth || (currentMonth === endMonth && currentDay <= endDay)) {\n // This handles dates from Jan 1 up to and including Mar 25\n inRange = true;\n}\n\n// Set the output payload\nmsg.payload = inRange ? “true” : “false”; // Outputs “true” or “false” string\n\n// Return the message to the next node in the flow\nreturn msg;”,
“outputs”: 1,
“timeout”: 0,
“noerr”: 0,
“initialize”: “”,
“finalize”: “”,
“libs”: ,
“x”: 310,
“y”: 160,
“wires”: [
[
“e55543ab09117c0c”
]
]
},
{
“id”: “88a0e072a515809d”,
“type”: “change”,
“z”: “de5c019c228bbd55”,
“name”: “self-consumption on batery”,
“rules”: [
{
“t”: “set”,
“p”: “batery.logic”,
“pt”: “flow”,
“to”: “payload”,
“tot”: “msg”
}
],
“action”: “”,
“property”: “”,
“from”: “”,
“to”: “”,
“reg”: false,
“x”: 520,
“y”: 340,
“wires”: [
[
“200945ca0e47a08d”
]
]
},
{
“id”: “daa891d639a88fde”,
“type”: “ui_text”,
“z”: “de5c019c228bbd55”,
“group”: “0087557d1ad61a95”,
“order”: 2,
“width”: 0,
“height”: 0,
“name”: “”,
“label”: “Winter time”,
“format”: “{{msg.payload}}”,
“layout”: “row-spread”,
“className”: “”,
“style”: false,
“font”: “”,
“fontSize”: 16,
“color”: “#000000”,
“x”: 1210,
“y”: 240,
“wires”:
},
{
“id”: “5480852de8c8e38e”,
“type”: “function”,
“z”: “de5c019c228bbd55”,
“name”: “winter time activation function”,
“func”: “// The incoming payload is a string like “true” or “false”\nlet inputString = msg.payload;\n\n// Convert the string to a boolean format and check its value\nif (inputString === “true”) {\n // If it’s “true”, set the payload to “active”\n msg.payload = “active”;\n} else {\n // Otherwise (if it’s “false” or anything else), set it to “non-active”\n msg.payload = “non-active”;\n}\n\n// Return the modified message\nreturn msg;”,
“outputs”: 1,
“timeout”: 0,
“noerr”: 0,
“initialize”: “”,
“finalize”: “”,
“libs”: ,
“x”: 790,
“y”: 240,
“wires”: [
[
“bf50bbbf0538b0fb”
]
]
},
{
“id”: “65f693074f8211a2”,
“type”: “change”,
“z”: “de5c019c228bbd55”,
“name”: “EVCS switch”,
“rules”: [
{
“t”: “set”,
“p”: “EVCS_switch”,
“pt”: “flow”,
“to”: “payload”,
“tot”: “msg”
}
],
“action”: “”,
“property”: “”,
“from”: “”,
“to”: “”,
“reg”: false,
“x”: 690,
“y”: 80,
“wires”: [
[
“a2655bf7e1fb7a91”,
“ab78ee1017978dea”
]
]
},
{
“id”: “bf50bbbf0538b0fb”,
“type”: “change”,
“z”: “de5c019c228bbd55”,
“name”: “Save”,
“rules”: [
{
“t”: “set”,
“p”: “current_status”,
“pt”: “flow”,
“to”: “payload”,
“tot”: “msg”
}
],
“action”: “”,
“property”: “”,
“from”: “”,
“to”: “”,
“reg”: false,
“x”: 1030,
“y”: 240,
“wires”: [
[
“daa891d639a88fde”
]
]
},
{
“id”: “550af2534a8abdd9”,
“type”: “inject”,
“z”: “de5c019c228bbd55”,
“name”: “”,
“props”: [
{
“p”: “payload”
},
{
“p”: “topic”,
“vt”: “str”
}
],
“repeat”: “”,
“crontab”: “”,
“once”: true,
“onceDelay”: “5”,
“topic”: “”,
“payload”: “”,
“payloadType”: “date”,
“x”: 850,
“y”: 280,
“wires”: [
[
“89f881fe7d6f4b65”
]
]
},
{
“id”: “89f881fe7d6f4b65”,
“type”: “change”,
“z”: “de5c019c228bbd55”,
“name”: “Load”,
“rules”: [
{
“t”: “set”,
“p”: “payload”,
“pt”: “msg”,
“to”: “current_status”,
“tot”: “flow”
}
],
“action”: “”,
“property”: “”,
“from”: “”,
“to”: “”,
“reg”: false,
“x”: 1030,
“y”: 280,
“wires”: [
[
“daa891d639a88fde”
]
]
},
{
“id”: “0087557d1ad61a95”,
“type”: “ui_group”,
“name”: “SELF-CONSUMPTION ON BATTERY”,
“tab”: “0ff001bcecf46f00”,
“order”: 12,
“disp”: true,
“width”: “6”,
“collapse”: false,
“className”: “”
},
{
“id”: “0ff001bcecf46f00”,
“type”: “ui_tab”,
“name”: “Home”,
“icon”: “dashboard”,
“disabled”: false,
“hidden”: false
}
]

Bonjour à tous,

Je partage avec vous un flux **Node-RED** que j’ai développé pour gérer intelligemment la décharge de la batterie lors de l’utilisation d’un chargeur EVCS Victron.

**:bullseye: Le problème résolu :**

Quand le chargeur EVCS est en mode normal et que le véhicule charge, la batterie peut se décharger pour alimenter la charge, ce qui n’est pas toujours souhaitable (surtout la nuit ou en l’absence de production solaire).

**:white_check_mark: La solution :**

Un flux Node-RED qui permet d’activer un “mode protection” via un simple bouton sur le dashboard. Quand actif :

- La batterie continue d’alimenter la **maison uniquement**

- L’EVCS utilise le **réseau électrique** (ou le solaire si disponible)

- Un contrôle précis via ESS MaxDischargePower

**:bar_chart: Fonctionnalités :**

- Switch ON/OFF sur le dashboard

- Monitoring en temps réel (consommation maison, puissance EVCS, SOC batterie)

- Utilise les **nœuds Victron officiels** (configuration automatique)

- Visualisation avec jauges paramétrables

- Version alternative MQTT également disponible

**:link: GitHub :** GitHub - couse1/victron-evcs-nodered: Node-RED flows for Victron EVCS battery protection - Smart discharge control

N’hésitez pas si vous avez des questions ou suggestions d’amélioration ! :rocket: