|
[ |
|
{ |
|
"id": "3c3fdfe5fe463bcd", |
|
"type": "tab", |
|
"label": "EVCS Single", |
|
"disabled": false, |
|
"info": "", |
|
"env": [] |
|
}, |
|
{ |
|
"id": "204b5ab04a5c68a6", |
|
"type": "group", |
|
"z": "3c3fdfe5fe463bcd", |
|
"style": { |
|
"stroke": "#999999", |
|
"stroke-opacity": "1", |
|
"fill": "none", |
|
"fill-opacity": "1", |
|
"label": true, |
|
"label-position": "nw", |
|
"color": "#a4a4a4" |
|
}, |
|
"nodes": [ |
|
"2c83c38d02e45fe2", |
|
"146b85e59378a322", |
|
"0f12e7377fc6da89", |
|
"466f174791be3953", |
|
"f748732cc9ccf243", |
|
"bfa768f60df4cd3b", |
|
"a8f00b2b93894a05" |
|
], |
|
"x": 34, |
|
"y": 119, |
|
"w": 892, |
|
"h": 202 |
|
}, |
|
{ |
|
"id": "fe70ccdaa24adb74", |
|
"type": "group", |
|
"z": "3c3fdfe5fe463bcd", |
|
"style": { |
|
"stroke": "#999999", |
|
"stroke-opacity": "1", |
|
"fill": "none", |
|
"fill-opacity": "1", |
|
"label": true, |
|
"label-position": "nw", |
|
"color": "#a4a4a4" |
|
}, |
|
"nodes": [ |
|
"d273d10f00129227", |
|
"9616899d5414c944", |
|
"b5e87479400223e4", |
|
"f38ff2ef8a48ec89", |
|
"8ca5477daf69bf83", |
|
"e2c66430a911c4dd", |
|
"c77d5c3f0d1e1561", |
|
"836a1d6c5f7870d0", |
|
"17f1c6f173a27ae5", |
|
"b75669b4d606f9bd", |
|
"44e45a473d268e16", |
|
"ffedd774985bf0d5", |
|
"419b5d4fb4044dd9", |
|
"39b13f574857393f" |
|
], |
|
"x": 34, |
|
"y": 359, |
|
"w": 1192, |
|
"h": 362 |
|
}, |
|
{ |
|
"id": "d273d10f00129227", |
|
"type": "join", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"name": "InputMerger", |
|
"mode": "custom", |
|
"build": "object", |
|
"property": "payload", |
|
"propertyType": "msg", |
|
"key": "topic", |
|
"joiner": "\\n", |
|
"joinerType": "str", |
|
"accumulate": false, |
|
"timeout": "", |
|
"count": "5", |
|
"reduceRight": false, |
|
"reduceExp": "", |
|
"reduceInit": "", |
|
"reduceInitType": "", |
|
"reduceFixup": "", |
|
"x": 480, |
|
"y": 500, |
|
"wires": [ |
|
[ |
|
"b5e87479400223e4", |
|
"f38ff2ef8a48ec89" |
|
] |
|
], |
|
"info": "Merge charger information and the current of the phase that has the most load into a single new msg." |
|
}, |
|
{ |
|
"id": "9616899d5414c944", |
|
"type": "debug", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"name": "debug 41", |
|
"active": false, |
|
"tosidebar": true, |
|
"console": false, |
|
"tostatus": false, |
|
"complete": "payload", |
|
"targetType": "msg", |
|
"statusVal": "", |
|
"statusType": "auto", |
|
"x": 920, |
|
"y": 400, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "b5e87479400223e4", |
|
"type": "function", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"name": "Loadsharing", |
|
"func": "// Declare context and flow variables\nvar didwestop = context.get('didwestop')||0;\nvar time = context.get('time')||0;\nvar startstop = msg.payload.EVCS_StartStop;\n\nconst connectorstatus = msg.payload.EVCS_Status;\nconst chargemode = msg.payload.EVCS_Mode;\nconst chargecurrent = msg.payload.EVCS_ChargeCurrent;\nconst maxGrid = msg.payload.MaxAmpsGrid;\n\n\nif (chargemode == 0 && connectorstatus !== 3 && typeof startstop !== 'undefined') {\n // Get out if we're not involved OR start signal after overload did not read back yet\n if (didwestop == 0 && startstop == 0) {\n return null;\n }\n \n // Define variables\n maxAll = 20; // Max grid current before we start throttling\n maxValue = 16; // Max charge current of this charger\n newValue = 0;\n \n // Take external factors into account and ensure statements are sorted high to low\n // Beware of grid lost alarm\n if (global.get('victronenergy.vebus._276.Alarms.GridLost') == 2 || typeof global.get('victronenergy.vebus._276.Alarms.GridLost') == 'undefined') {\n maxValue = 6;\n }\n // Beware of overload alarm\n if (global.get('victronenergy.vebus._276.Alarms.Overload') >= 1 || typeof global.get('victronenergy.vebus._276.Alarms.Overload') == 'undefined') {\n maxValue = 0;\n }\n \n // Do the math and set new value\n newValue = maxAll - maxGrid + chargecurrent;\n // newValue = Math.floor(newValue / 2) * 2;\n if (newValue >= maxValue) {\n newValue = maxValue;\n }\n \n // stop and start charging if value out of range\n switch (didwestop) {\n case 0:\n if (newValue < 6) {\n newValue = 6;\n startstop = 0;\n didwestop = 1;\n // create and store a fresh timestamp + 10mins\n var d = new Date();\n time = d.getTime();\n time = time + (300*1000);\n }\n break;\n case 1:\n if ((maxAll - maxGrid) < 6) {\n newValue = 6;\n break;\n }\n // Retrieve the timestamp and compare to @now\n var nd = new Date();\n var ntime = nd.getTime();\n\n if (ntime >= time) {\n startstop = 1;\n didwestop = 0;\n break;\n }\n break;\n default:\n break;\n }\n \n context.set('didwestop',didwestop);\n context.set('time',time);\n \n // Constructing the message\n var msg1 = { topic: \"payload\", payload: newValue };\n var msg2 = { topic: \"payload\", payload: startstop };\n \n \n return [msg1,msg2];\n}", |
|
"outputs": 2, |
|
"timeout": "", |
|
"noerr": 0, |
|
"initialize": "", |
|
"finalize": "", |
|
"libs": [], |
|
"x": 670, |
|
"y": 500, |
|
"wires": [ |
|
[ |
|
"e2c66430a911c4dd", |
|
"9616899d5414c944" |
|
], |
|
[ |
|
"8ca5477daf69bf83", |
|
"c77d5c3f0d1e1561" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "f38ff2ef8a48ec89", |
|
"type": "debug", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"name": "debug 42", |
|
"active": false, |
|
"tosidebar": true, |
|
"console": false, |
|
"tostatus": false, |
|
"complete": "payload", |
|
"targetType": "msg", |
|
"statusVal": "", |
|
"statusType": "auto", |
|
"x": 440, |
|
"y": 420, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "8ca5477daf69bf83", |
|
"type": "rbe", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"name": "", |
|
"func": "rbe", |
|
"gap": "", |
|
"start": "", |
|
"inout": "out", |
|
"septopics": true, |
|
"property": "payload", |
|
"topi": "topic", |
|
"x": 910, |
|
"y": 520, |
|
"wires": [ |
|
[ |
|
"b75669b4d606f9bd" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "e2c66430a911c4dd", |
|
"type": "rbe", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"name": "", |
|
"func": "rbe", |
|
"gap": "", |
|
"start": "", |
|
"inout": "out", |
|
"septopics": true, |
|
"property": "payload", |
|
"topi": "topic", |
|
"x": 910, |
|
"y": 440, |
|
"wires": [ |
|
[ |
|
"17f1c6f173a27ae5" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "c77d5c3f0d1e1561", |
|
"type": "debug", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"name": "debug 43", |
|
"active": false, |
|
"tosidebar": true, |
|
"console": false, |
|
"tostatus": false, |
|
"complete": "payload", |
|
"targetType": "msg", |
|
"statusVal": "", |
|
"statusType": "auto", |
|
"x": 920, |
|
"y": 560, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "836a1d6c5f7870d0", |
|
"type": "link in", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"name": "MaxAmpsGrid In", |
|
"links": [ |
|
"bfa768f60df4cd3b" |
|
], |
|
"x": 245, |
|
"y": 440, |
|
"wires": [ |
|
[ |
|
"d273d10f00129227" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "17f1c6f173a27ae5", |
|
"type": "victron-output-evcharger", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"service": "com.victronenergy.evcharger/40", |
|
"path": "/SetCurrent", |
|
"serviceObj": { |
|
"service": "com.victronenergy.evcharger/40", |
|
"name": "EVCS-NS-01" |
|
}, |
|
"pathObj": { |
|
"path": "/SetCurrent", |
|
"type": "float", |
|
"name": "Set charge current (manual mode) (A)", |
|
"writable": true |
|
}, |
|
"initial": "", |
|
"name": "Charging Current", |
|
"onlyChanges": false, |
|
"x": 1110, |
|
"y": 440, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "b75669b4d606f9bd", |
|
"type": "victron-output-evcharger", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"service": "com.victronenergy.evcharger/40", |
|
"path": "/StartStop", |
|
"serviceObj": { |
|
"service": "com.victronenergy.evcharger/40", |
|
"name": "EVCS-NS-01" |
|
}, |
|
"pathObj": { |
|
"path": "/StartStop", |
|
"type": "enum", |
|
"name": "Start/stop charging (manual mode)", |
|
"enum": { |
|
"0": "Stop", |
|
"1": "Start" |
|
}, |
|
"writable": true |
|
}, |
|
"initial": "", |
|
"name": "Start/Stop", |
|
"onlyChanges": false, |
|
"x": 1090, |
|
"y": 520, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "31d1b7236e7aee8d", |
|
"type": "victron-input-vebus", |
|
"z": "3c3fdfe5fe463bcd", |
|
"service": "com.victronenergy.vebus/276", |
|
"path": "/Alarms/GridLost", |
|
"serviceObj": { |
|
"service": "com.victronenergy.vebus/276", |
|
"name": "MultiPlus-II 48/3000/35-32" |
|
}, |
|
"pathObj": { |
|
"path": "/Alarms/GridLost", |
|
"type": "enum", |
|
"name": "Grid lost alarm", |
|
"enum": { |
|
"0": "Ok", |
|
"2": "Alarm" |
|
} |
|
}, |
|
"initial": "", |
|
"name": "MultiPlus_GridAlarm", |
|
"onlyChanges": false, |
|
"x": 150, |
|
"y": 60, |
|
"wires": [ |
|
[] |
|
] |
|
}, |
|
{ |
|
"id": "44e45a473d268e16", |
|
"type": "victron-input-evcharger", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"service": "com.victronenergy.evcharger/40", |
|
"path": "/Current", |
|
"serviceObj": { |
|
"service": "com.victronenergy.evcharger/40", |
|
"name": "EVCS-NS-01" |
|
}, |
|
"pathObj": { |
|
"path": "/Current", |
|
"type": "float", |
|
"name": "Charge current (A)" |
|
}, |
|
"name": "EVCS_ChargeCurrent", |
|
"onlyChanges": false, |
|
"x": 160, |
|
"y": 500, |
|
"wires": [ |
|
[ |
|
"d273d10f00129227" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "ffedd774985bf0d5", |
|
"type": "victron-input-evcharger", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"service": "com.victronenergy.evcharger/40", |
|
"path": "/Status", |
|
"serviceObj": { |
|
"service": "com.victronenergy.evcharger/40", |
|
"name": "EVCS-NS-01" |
|
}, |
|
"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 fault", |
|
"9": "Welded contacts", |
|
"10": "CP Input shorted", |
|
"11": "Residual current detected", |
|
"12": "Under voltage detected", |
|
"13": "Overvoltage detected", |
|
"14": "Overheating detected" |
|
} |
|
}, |
|
"initial": "", |
|
"name": "EVCS_Status", |
|
"onlyChanges": false, |
|
"x": 130, |
|
"y": 560, |
|
"wires": [ |
|
[ |
|
"d273d10f00129227" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "419b5d4fb4044dd9", |
|
"type": "victron-input-evcharger", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"service": "com.victronenergy.evcharger/40", |
|
"path": "/Mode", |
|
"serviceObj": { |
|
"service": "com.victronenergy.evcharger/40", |
|
"name": "EVCS-NS-01" |
|
}, |
|
"pathObj": { |
|
"path": "/Mode", |
|
"type": "enum", |
|
"name": "Mode", |
|
"enum": { |
|
"0": "Manual", |
|
"1": "Auto", |
|
"2": "Schedule" |
|
} |
|
}, |
|
"initial": "", |
|
"name": "EVCS_Mode", |
|
"onlyChanges": false, |
|
"x": 130, |
|
"y": 620, |
|
"wires": [ |
|
[ |
|
"d273d10f00129227" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "39b13f574857393f", |
|
"type": "victron-input-evcharger", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "fe70ccdaa24adb74", |
|
"service": "com.victronenergy.evcharger/40", |
|
"path": "/StartStop", |
|
"serviceObj": { |
|
"service": "com.victronenergy.evcharger/40", |
|
"name": "EVCS-NS-01" |
|
}, |
|
"pathObj": { |
|
"path": "/StartStop", |
|
"type": "enum", |
|
"name": "Start/stop charging (manual mode)", |
|
"enum": { |
|
"0": "Stop", |
|
"1": "Start" |
|
} |
|
}, |
|
"initial": "", |
|
"name": "EVCS_StartStop", |
|
"onlyChanges": false, |
|
"x": 140, |
|
"y": 680, |
|
"wires": [ |
|
[ |
|
"d273d10f00129227" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "4525d26663b1ad18", |
|
"type": "victron-input-vebus", |
|
"z": "3c3fdfe5fe463bcd", |
|
"service": "com.victronenergy.vebus/276", |
|
"path": "/Alarms/Overload", |
|
"serviceObj": { |
|
"service": "com.victronenergy.vebus/276", |
|
"name": "MultiPlus-II 48/3000/35-32" |
|
}, |
|
"pathObj": { |
|
"path": "/Alarms/Overload", |
|
"type": "enum", |
|
"name": "Overload", |
|
"enum": { |
|
"0": "Ok", |
|
"1": "Warning", |
|
"2": "Alarm" |
|
} |
|
}, |
|
"initial": "", |
|
"name": "MultiPlus_Overload", |
|
"onlyChanges": false, |
|
"x": 350, |
|
"y": 60, |
|
"wires": [ |
|
[] |
|
] |
|
}, |
|
{ |
|
"id": "2c83c38d02e45fe2", |
|
"type": "victron-input-gridmeter", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "204b5ab04a5c68a6", |
|
"service": "com.victronenergy.grid/50", |
|
"path": "/Ac/L1/Current", |
|
"serviceObj": { |
|
"service": "com.victronenergy.grid/50", |
|
"name": "Shelly Pro3EM" |
|
}, |
|
"pathObj": { |
|
"path": "/Ac/L1/Current", |
|
"type": "float", |
|
"name": "L1 Current (A)" |
|
}, |
|
"name": "Grid L1 Current", |
|
"onlyChanges": false, |
|
"roundValues": "0", |
|
"x": 140, |
|
"y": 160, |
|
"wires": [ |
|
[ |
|
"f748732cc9ccf243" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "146b85e59378a322", |
|
"type": "victron-input-gridmeter", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "204b5ab04a5c68a6", |
|
"service": "com.victronenergy.grid/50", |
|
"path": "/Ac/L3/Current", |
|
"serviceObj": { |
|
"service": "com.victronenergy.grid/50", |
|
"name": "Shelly Pro3EM" |
|
}, |
|
"pathObj": { |
|
"path": "/Ac/L3/Current", |
|
"type": "float", |
|
"name": "L3 Current (A)" |
|
}, |
|
"name": "Grid L3 Current", |
|
"onlyChanges": false, |
|
"roundValues": "0", |
|
"x": 140, |
|
"y": 280, |
|
"wires": [ |
|
[ |
|
"f748732cc9ccf243" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "0f12e7377fc6da89", |
|
"type": "victron-input-gridmeter", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "204b5ab04a5c68a6", |
|
"service": "com.victronenergy.grid/50", |
|
"path": "/Ac/L2/Current", |
|
"serviceObj": { |
|
"service": "com.victronenergy.grid/50", |
|
"name": "Shelly Pro3EM" |
|
}, |
|
"pathObj": { |
|
"path": "/Ac/L2/Current", |
|
"type": "float", |
|
"name": "L2 Current (A)" |
|
}, |
|
"name": "Grid L2 Current", |
|
"onlyChanges": false, |
|
"roundValues": "0", |
|
"x": 140, |
|
"y": 220, |
|
"wires": [ |
|
[ |
|
"f748732cc9ccf243" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "466f174791be3953", |
|
"type": "function", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "204b5ab04a5c68a6", |
|
"name": "MaxAmpsGrid", |
|
"func": "// Variables to hold max value \nlet maxValue = 0;\n\n//converting the object in the payload to an array\nconst values = Object.values(msg.payload);\n\n//Using the .map() method to loop the array, find maximum value\nvalues.map((entry) => {\n //getting the value from each object and \n //comparing to existing value\n maxValue = Math.max(maxValue, entry);\n});\n\nmsg.topic = \"MaxAmpsGrid\";\nmsg.payload = maxValue;\nreturn msg;", |
|
"outputs": 1, |
|
"timeout": "", |
|
"noerr": 0, |
|
"initialize": "", |
|
"finalize": "", |
|
"libs": [], |
|
"x": 680, |
|
"y": 200, |
|
"wires": [ |
|
[ |
|
"bfa768f60df4cd3b" |
|
] |
|
], |
|
"info": "Determine which of the phases has the biggest load and return that number for future calculations." |
|
}, |
|
{ |
|
"id": "f748732cc9ccf243", |
|
"type": "join", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "204b5ab04a5c68a6", |
|
"name": "Grid Current", |
|
"mode": "custom", |
|
"build": "object", |
|
"property": "payload", |
|
"propertyType": "msg", |
|
"key": "topic", |
|
"joiner": "\\n", |
|
"joinerType": "str", |
|
"accumulate": false, |
|
"timeout": "", |
|
"count": "3", |
|
"reduceRight": false, |
|
"reduceExp": "", |
|
"reduceInit": "", |
|
"reduceInitType": "", |
|
"reduceFixup": "", |
|
"x": 420, |
|
"y": 200, |
|
"wires": [ |
|
[ |
|
"466f174791be3953" |
|
] |
|
], |
|
"info": "Merge the load of all phases into a single new msg." |
|
}, |
|
{ |
|
"id": "bfa768f60df4cd3b", |
|
"type": "link out", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "204b5ab04a5c68a6", |
|
"name": "MaxAmpsGrid Out", |
|
"mode": "link", |
|
"links": [ |
|
"836a1d6c5f7870d0" |
|
], |
|
"x": 875, |
|
"y": 200, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "a8f00b2b93894a05", |
|
"type": "comment", |
|
"z": "3c3fdfe5fe463bcd", |
|
"g": "204b5ab04a5c68a6", |
|
"name": "Link node", |
|
"info": "Decided not to use a sub-flow to ensure the MaxAmps value is not requested and calculated at different points in time for the two individual chargers.", |
|
"x": 840, |
|
"y": 280, |
|
"wires": [] |
|
} |
|
] |