Load sharing for Victron EVCS

The Victron EV Charging station has limited functionality to share a load within your home. If your setup allows, it will provide basic overload protection but in some setups this functionality may not suffice.

This flow is designed for load sharing between a Victron EV Charging Station and your home.

Grid metering: The flow takes a reading from your grid meter and calculates which phase has the heaviest load.

Grid lost and Multi overload alarms: The flow takes grid lost and overload alarms into account by setting the minimum charge current. It does not specifically read if the charger is connected to AC-OUT but simply assumes it will fail otherwise.

Basic load sharing within the house: The flow controls the EV charge current by taking a maximum of 20A grid load. This number was chosen to prevent the new ESS import current limiting feature from kicking in which will simply start inverting the lack of power. If the remaining charge current is less than 6A it will stop the charging process and try to restart it after 5mins.

For now, this is very very much a beta so please use carefully. Any comments or help to improve is much appreciated!

[{"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":[]}]

Flow Info

Created 2 months, 3 weeks ago
Rating: 5 1

Owner

Actions

Rate:

Node Types

Core
  • comment (x1)
  • debug (x3)
  • function (x2)
  • join (x2)
  • link in (x1)
  • link out (x1)
  • rbe (x2)
Other
  • group (x2)
  • tab (x1)
  • victron-input-evcharger (x4)
  • victron-input-gridmeter (x3)
  • victron-input-vebus (x2)
  • victron-output-evcharger (x2)

Tags

  • victron
  • victronenergy
  • evcs
  • EV
  • Charger
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option