Hi i know nothing about coding but with help, I have created a Node-RED flow but it does not seem to be working as expected. Anyone out there that can help fix this? The key issues are:
- The event does not trigger at the correct times/at All
- The SOC conditions for discharging and charging are not being properly checked.
- The manual start and stop functions are not working. Is there anyone that knows coding that can fix this please as ive been bashing my head for days!
[
{
"id": "1a63f41645ba5e52",
"type": "tab",
"label": "Power Up Session Alpha",
"disabled": false,
"info": "",
"env": []
},
{
"id": "84b2246d471931f0",
"type": "change",
"z": "1a63f41645ba5e52",
"name": "",
"rules": [
{
"t": "set",
"p": "soc",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 410,
"y": 40,
"wires": [
[]
]
},
{
"id": "dd912d151a1569b6",
"type": "change",
"z": "1a63f41645ba5e52",
"name": "",
"rules": [
{
"t": "set",
"p": "setpoint",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 400,
"y": 100,
"wires": [
[]
]
},
{
"id": "4e1516ce53b0a0f2",
"type": "victron-input-battery",
"z": "1a63f41645ba5e52",
"service": "com.victronenergy.battery/512",
"path": "/Soc",
"serviceObj": {
"service": "com.victronenergy.battery/512",
"name": "Pylontech battery"
},
"pathObj": {
"path": "/Soc",
"type": "float",
"name": "State of charge (%)"
},
"name": "",
"onlyChanges": true,
"x": 170,
"y": 20,
"wires": [
[
"84b2246d471931f0"
]
]
},
{
"id": "d67ca93879292897",
"type": "victron-input-ess",
"z": "1a63f41645ba5e52",
"service": "com.victronenergy.settings",
"path": "/Settings/CGwacs/AcPowerSetPoint",
"serviceObj": {
"service": "com.victronenergy.settings",
"name": "Venus settings"
},
"pathObj": {
"path": "/Settings/CGwacs/AcPowerSetPoint",
"type": "integer",
"name": "Grid set-point (W)"
},
"name": "",
"onlyChanges": true,
"x": 160,
"y": 80,
"wires": [
[
"dd912d151a1569b6"
]
]
},
{
"id": "5da65ef8f136a94c",
"type": "inject",
"z": "1a63f41645ba5e52",
"name": "Manual Start",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": "",
"topic": "",
"payload": "manual_start",
"payloadType": "str",
"x": 110,
"y": 140,
"wires": [
[
"d95c8cdf200c096c"
]
]
},
{
"id": "2bad45313e6ac5ff",
"type": "inject",
"z": "1a63f41645ba5e52",
"name": "Manual Stop",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": "",
"topic": "",
"payload": "manual_stop",
"payloadType": "str",
"x": 110,
"y": 260,
"wires": [
[
"a67bb775a23251a6"
]
]
},
{
"id": "d95c8cdf200c096c",
"type": "function",
"z": "1a63f41645ba5e52",
"name": "Set Event Date",
"func": "const now = new Date();\nconst startTime = new Date(now);\nconst stopTime = new Date(now);\n\n// Define event times\nstartTime.setHours(12, 0, 0);\nstopTime.setHours(14, 0, 0);\n\n// If current time is past the stop time, schedule for the next day\nif (now >= stopTime) {\n startTime.setDate(startTime.getDate() + 1);\n stopTime.setDate(stopTime.getDate() + 1);\n}\n\nflow.set('event_date', startTime);\nflow.set('event_stop_time', stopTime);\nflow.set('event_running', true);\nflow.set('soc', 70); // Initial SOC for testing\nreturn msg;",
"outputs": 1,
"x": 230,
"y": 160,
"wires": [
[
"235c3185b210d918"
]
]
},
{
"id": "a67bb775a23251a6",
"type": "function",
"z": "1a63f41645ba5e52",
"name": "Stop Event",
"func": "flow.set('event_running', false);\nflow.set('grid_set_point_sent', false);\nflow.set('dvcc_sent', false);\nreturn [{ payload: -50 }, { payload: -1 }];",
"outputs": 2,
"x": 230,
"y": 220,
"wires": [
[
"eae850e5c87f816f"
],
[
"a7d49d7c5d95063f"
]
]
},
{
"id": "235c3185b210d918",
"type": "function",
"z": "1a63f41645ba5e52",
"name": "Event Control",
"func": "const now = new Date();\nconst eventDate = flow.get('event_date');\nconst stopTime = flow.get('event_stop_time');\nconst eventRunning = flow.get('event_running') || false;\nconst soc = flow.get('soc') || 70; // Dynamic SOC\n\nif (now >= eventDate && now <= stopTime && eventRunning) {\n const currentHour = now.getHours();\n const currentMinute = now.getMinutes();\n\n if (currentHour === 12 && currentMinute >= 0 && currentMinute < 60 && soc > 68) {\n return { payload: 'max_discharge' };\n } else if (currentHour === 13 && currentMinute >= 0 && currentMinute < 60 && soc > 30) {\n return { payload: 'max_charge' };\n } else if (now > stopTime) {\n flow.set('event_running', false);\n return { payload: 'stop_event' };\n } else {\n return null;\n }\n} else {\n return null;\n}\n",
"outputs": 1,
"x": 400,
"y": 160,
"wires": [
[
"63a2a378e670c2af"
]
]
},
{
"id": "63a2a378e670c2af",
"type": "switch",
"z": "1a63f41645ba5e52",
"name": "Handle Event",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "max_discharge",
"vt": "str"
},
{
"t": "eq",
"v": "max_charge",
"vt": "str"
},
{
"t": "eq",
"v": "stop_event",
"vt": "str"
}
],
"outputs": 3,
"x": 570,
"y": 160,
"wires": [
[
"315c1b925c255e97"
],
[
"b98e28ce14682b74"
],
[
"d9acc5ebd0964677"
]
]
},
{
"id": "315c1b925c255e97",
"type": "function",
"z": "1a63f41645ba5e52",
"name": "Check SOC for Discharge",
"func": "const soc = flow.get('soc') || 70;\nif (soc >= 65) {\n return { payload: -6700 };\n} else {\n return [{ payload: -50 }, { payload: -1 }];\n}\n",
"outputs": 2,
"x": 670,
"y": 100,
"wires": [
[
"eae850e5c87f816f"
],
[
"a7d49d7c5d95063f"
]
]
},
{
"id": "b98e28ce14682b74",
"type": "function",
"z": "1a63f41645ba5e52",
"name": "Check SOC for Charge",
"func": "const soc = flow.get('soc') || 70;\nif (soc >= 30) {\n return { payload: 8000 };\n} else {\n return [{ payload: -50 }, { payload: -1 }];\n}\n",
"outputs": 2,
"x": 590,
"y": 280,
"wires": [
[
"eae850e5c87f816f"
],
[
"a7d49d7c5d95063f"
]
]
},
{
"id": "eae850e5c87f816f",
"type": "function",
"z": "1a63f41645ba5e52",
"name": "Grid Set Point",
"func": "const action = msg.payload;\nconst currentGridSetPointSent = flow.get('grid_set_point_sent');\n\nif (action === -6700 || action === 8000) {\n flow.set('grid_set_point_sent', action === -50);\n return { payload: action };\n} else if (action === 'stop_event') {\n if (!currentGridSetPointSent) {\n flow.set('grid_set_point_sent', true);\n return { payload: -50 };\n } else {\n return null;\n }\n} else {\n return null;\n}\n",
"outputs": 1,
"x": 900,
"y": 80,
"wires": [
[
"ca3448310c69e4c3"
]
]
},
{
"id": "a7d49d7c5d95063f",
"type": "function",
"z": "1a63f41645ba5e52",
"name": "DVCC Output",
"func": "const action = msg.payload;\nconst dvccSent = flow.get('dvcc_sent');\n\nif (action === -1) {\n flow.set('dvcc_sent', true);\n return { payload: -1 };\n} else if (action === 'stop_event') {\n if (!dvccSent) {\n flow.set('dvcc_sent', true);\n return { payload: -1 };\n } else {\n return null;\n }\n} else {\n return null;\n}\n",
"outputs": 1,
"x": 860,
"y": 360,
"wires": [
[
"ca3448310c69e4c3"
]
]
},
{
"id": "d9acc5ebd0964677",
"type": "function",
"z": "1a63f41645ba5e52",
"name": "Session End",
"func": "flow.set('event_running', false);\nflow.set('grid_set_point_sent', false);\nflow.set('dvcc_sent', false);\nreturn [{ payload: -50 }, { payload: -1 }];",
"outputs": 2,
"x": 740,
"y": 200,
"wires": [
[
"eae850e5c87f816f"
],
[
"a7d49d7c5d95063f"
]
]
},
{
"id": "ca3448310c69e4c3",
"type": "debug",
"z": "1a63f41645ba5e52",
"name": "Debug Output",
"active": true,
"tosidebar": true,
"x": 920,
"y": 280,
"wires": []
}
]