I need help creating a Helper
(or something better) which will output a true or false statement, based on a lot of factors, but the most important being the price per kWh calculated 24 hours ahead. I don’t know if it’s even possible, but I thought I’d ask at least.
My alternative is to just put a regular schedule when the price tends to be low, but that’s boring, and in worst case I will use more energy during a peak than I really have to.
The reason?
I have two electric cars + one home battery that I want to charge all at the same time when the price is at it’s lowest. Our electricity price changes every hours according to Nordpool and I want to start and stop based on the price. Math is not my top subject (I admit) so I don’t know how it would work really, but I’ve seen that the integration for my smart car charging are spotting the price perfectly every time - preferably I would like my home battery to charge at the same time, but I don’t know how to reuse that function.
Sorry for lengthy post, but I want to get into the details. Here we go…
Total available power to the house
Ampere: 20A (3 phase)
kW: 4.8 X 3 = 14.4 kW
Note: Car charging are controlled by an (Easee) “Equalizer” which limits the power to the car depending on what the house needs. This is to ensure no fuses blow.
Base house load
Around 1 kW
Scenarios
In all scenarios below I want to charge the home battery (BYD 11 kWh) if the difference in price in low peak and high peak is more than 50 cents.
- Both cars needs charging + the price of electricity is low + there’s a big peak in price in the morning, or during the day
- One cars needs charging + the price of electricity is low + there’s a big peak in price in the morning, or during the day
- No cars needs charging + the price of electricity is low + there’s a big peak in price in the morning, or during the day
Conditions / Factors
Condition: There must be enough power for the cars to be ready in time, usually before 6AM.
Action: Set the home battery to force CHARGE at 50% rate (~2.4 kW)
Condition: When cars are charging I don’t want to take any power from the home battery to fill the cars battery, just unnecessary cycles…
Action: Set the home battery to force CHARGE at 50% rate (~2.4 kW) to disallow discharge. Another option here is just to HOLD the home battery, no charge or discharge.
Condition: If no cars are charging then we can use the full power to the home battery
Action: Set the home battery to force CHARGE at 100% rate (~4.8 kW)
Condition:: Every hour there’s a new price for electricity, and the car-charging are scheduled to the cheapest hours by the integration above. To my knowledge there’s no entity for the time start and time stop, otherwise I could use that to decide when to start and stop the home battery charging.
Action Complicated, and the reason for this thread start since it depends on so many factors.
Condition:: If it’s a cold night then the heat pump will kick in and take another minimum 3-4 kW. The Equalizer will even out the load if cars are charging but not if they’re not charging, as it only controls the car charging. The risk that fuse is blown is medium high since if:
- I force charge the home battery it’s 4.8 kW
- Heat pump peaks at its max setting 6.5 kW
- Base load in the house is around 1.5 kW
The total power will be at the limit for what the total house power can handle.
Action The action here should be to limit the home battery charge, or hold it if it reaches the limit. Like the Equalizer does, but in “software” with a Helper
in HAOS or something.
Final words
So I think you get the picture now. What do you think would be the best strategy for this?
I have Node-RED in place, and with some help from this thread, I’ve set up Modbus to talk to the battery. I’m just in the debuggning phase so far, but I have created a few battery strategies that work at least.
Now the question is how to stitch it together since I want the home battery to stop charging / hold / or force charge art either 50% or 100% based on the house load.
[{"id":"effce8e2e8a9f43c","type":"tab","label":"Flow 1","disabled":false,"info":"","env":[]},{"id":"d4ddcb9085ea730f","type":"group","z":"effce8e2e8a9f43c","name":"Write changes!","style":{"label":true},"nodes":["180989e6b6be69e1","beceba7f58b3cb02","8257c587efbab683"],"x":1574,"y":399,"w":512,"h":122},{"id":"9d13313687e3f017","type":"group","z":"effce8e2e8a9f43c","name":"Normal state","style":{"label":true},"nodes":["2468d8245a765d21"],"x":854,"y":379,"w":232,"h":82},{"id":"ceea0bd0f56e5cbe","type":"group","z":"effce8e2e8a9f43c","name":"100% CHARGE","style":{"label":true},"nodes":["8bf3fd6bab97b524","0548b4b7a9faec3d","f79b4f746a482239","ab188204ffe303ef"],"x":854,"y":279,"w":292,"h":82},{"id":"32f8524788c52a9d","type":"group","z":"effce8e2e8a9f43c","name":"50-75% CHARGE","style":{"label":true},"nodes":["f941ac38c439226e"],"x":854,"y":479,"w":292,"h":82},{"id":"f84e3a88a392756e","type":"group","z":"effce8e2e8a9f43c","name":"HOLD (No charge or discharge) - NOT TESTED","style":{"label":true},"nodes":["4be156af80f1d0d2"],"x":854,"y":579,"w":312,"h":82},{"id":"7ba45c1373d6db9c","type":"group","z":"effce8e2e8a9f43c","name":"Check current price/kWh","style":{"label":true},"nodes":["d5351cdc453ee22e","3b6d2b1103a7ee5c","dd104017de06fd0b"],"x":234,"y":259,"w":432,"h":162},{"id":"9164e2cf469fbb1a","type":"group","z":"effce8e2e8a9f43c","name":"Payload","style":{"label":true},"nodes":["4a3bc7d5caa41672"],"x":1254,"y":419,"w":292,"h":82},{"id":"a2d0a27e96764e53","type":"group","z":"effce8e2e8a9f43c","name":"Check if car is charging","style":{"label":true},"nodes":["0f7bddac0d6e47e9","34930c36e0d50c0c","afd38d704e49105d"],"x":234,"y":459,"w":432,"h":142},{"id":"0548b4b7a9faec3d","type":"junction","z":"effce8e2e8a9f43c","g":"ceea0bd0f56e5cbe","x":880,"y":320,"wires":[[]]},{"id":"f79b4f746a482239","type":"junction","z":"effce8e2e8a9f43c","g":"ceea0bd0f56e5cbe","x":880,"y":320,"wires":[[]]},{"id":"ab188204ffe303ef","type":"junction","z":"effce8e2e8a9f43c","g":"ceea0bd0f56e5cbe","x":880,"y":320,"wires":[[]]},{"id":"180989e6b6be69e1","type":"modbus-response","z":"effce8e2e8a9f43c","g":"d4ddcb9085ea730f","name":"","registerShowMax":20,"x":1870,"y":480,"wires":[]},{"id":"beceba7f58b3cb02","type":"modbus-flex-write","z":"effce8e2e8a9f43c","g":"d4ddcb9085ea730f","name":"Fronius Storage","showStatusActivities":true,"showErrors":true,"showWarnings":true,"server":"ecd41b68db8d4254","emptyMsgOnFail":true,"keepMsgProperties":true,"delayOnStart":false,"startDelayTime":"10","x":1680,"y":460,"wires":[["180989e6b6be69e1","8257c587efbab683"],[]]},{"id":"8257c587efbab683","type":"debug","z":"effce8e2e8a9f43c","g":"d4ddcb9085ea730f","name":"Inverter MODBUS Response","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1910,"y":440,"wires":[]},{"id":"8bf3fd6bab97b524","type":"function","z":"effce8e2e8a9f43c","g":"ceea0bd0f56e5cbe","name":"4800W FORCED CHARGE","func":"msg.StorCtl_Mod = \"2\"\n// 0%\nmsg.OutWRte = \"65535\"\n\nmsg.newstate = \"forcechargeonly\"\n\nreturn msg","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1000,"y":320,"wires":[["4a3bc7d5caa41672"]],"info":"Example 1: Only permit energy storage charging\nThis behavior can be achieved by limiting the maximum discharge capacity to 0%\n=> results in window [-3300 W, 0 W]\n- OutWRte = 0% (set discharge limit of WchaMax to 0%)\n- StorCtl_Mod = 2 (activates discharge limit, bit pattern: 10)\n- InWRte is not relevant in this case"},{"id":"f941ac38c439226e","type":"function","z":"effce8e2e8a9f43c","g":"32f8524788c52a9d","name":"[1650 W, 2475 W] CHARGE","func":"\nmsg.StorCtl_Mod = \"3\"\n// - 50%\nmsg.OutWRte = 65485\n// 75%\nmsg.InWRte = \"7500\"\n\nmsg.newstate = \"charge_1650_2475\"\n\nreturn msg","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1000,"y":520,"wires":[["4a3bc7d5caa41672"]],"info":"Example 5: Charging in the range of 50% to 75% of the nominal power\nThis behavior can be achieved by limiting the maximum charge capacity to 75%\nand the maximum discharge capacity to -50%\n=> results in window [1650 W, 2475 W]\n- InWRte = 75% (set charge limit of WchaMax to 75%)\n- OutWRte = -50% (set discharge limit of WchaMax to -50%)\n- StorCtl_Mod = 3 (activate both limit values, bit pattern: 11)\n- Battery status in Fronius Solar.web will change to Forced Recharge"},{"id":"2468d8245a765d21","type":"function","z":"effce8e2e8a9f43c","g":"9d13313687e3f017","name":"Normal Operation","func":"\nmsg.StorCtl_Mod = \"0\"\nmsg.OutWRte = 10000\nmsg.InWRte = 10000\n\nmsg.newstate = \"normal\"\n\nreturn msg","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":970,"y":420,"wires":[["4a3bc7d5caa41672"]],"info":"This puts the battery in normal operation.\nMeaningn that it will both charge and discharge to\nits set limits at 100%,\n"},{"id":"d5351cdc453ee22e","type":"api-current-state","z":"effce8e2e8a9f43c","g":"7ba45c1373d6db9c","name":"Spotpris","server":"afa7e6c.89d5e18","version":3,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.energi_data_service","state_type":"num","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":340,"y":380,"wires":[["3b6d2b1103a7ee5c"]]},{"id":"3b6d2b1103a7ee5c","type":"switch","z":"effce8e2e8a9f43c","g":"7ba45c1373d6db9c","name":"> 50 öre or < 50 öre","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"0.5","vt":"num"},{"t":"lt","v":"0.5","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":540,"y":380,"wires":[[],[]]},{"id":"dd104017de06fd0b","type":"cronplus","z":"effce8e2e8a9f43c","g":"7ba45c1373d6db9c","name":"Every hour","outputField":"payload","timeZone":"","storeName":"","commandResponseMsgOutput":"output1","defaultLocation":"","defaultLocationType":"default","outputs":1,"options":[{"name":"schedule1","topic":"topic1","payloadType":"default","payload":"","expressionType":"cron","expression":"0 0 * * * * *","location":"","offset":"0","solarType":"all","solarEvents":"sunrise,sunset"}],"x":350,"y":300,"wires":[["d5351cdc453ee22e"]]},{"id":"4be156af80f1d0d2","type":"function","z":"effce8e2e8a9f43c","g":"f84e3a88a392756e","name":"HOLD (no charge or discharge)","func":"\nmsg.StorCtl_Mod = \"0\"\nmsg.OutWRte = 65535\nmsg.InWRte = 65535\n\nmsg.newstate = \"HOLD state\"\n\nreturn msg","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1010,"y":620,"wires":[["4a3bc7d5caa41672"]],"info":"Example 3: Do not permit charging or discharging\nThis behavior can be achieved by limiting the maximum charge capacity to 0%\nand the maximum discharge capacity to 0%\n=> results in window [0 W, 0 W]\n- InWRte = 0% (set charge limit of WchaMax to 0%)\n- OutWRte = 0% (set discharge limit of WchaMax to 0%)\n- StorCtl_Mod = 3 (activate both limit values, bit pattern: 11)"},{"id":"0f7bddac0d6e47e9","type":"poll-state","z":"effce8e2e8a9f43c","g":"a2d0a27e96764e53","name":"Volkswagen status","server":"afa7e6c.89d5e18","version":3,"exposeAsEntityConfig":"","updateInterval":"60","updateIntervalType":"num","updateIntervalUnits":"seconds","outputInitially":false,"outputOnChanged":false,"entityId":"sensor.ev_smart_charging_volkswagen_charging","stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputs":1,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":350,"y":500,"wires":[["afd38d704e49105d"]]},{"id":"34930c36e0d50c0c","type":"poll-state","z":"effce8e2e8a9f43c","g":"a2d0a27e96764e53","name":"Tesla status","server":"afa7e6c.89d5e18","version":3,"exposeAsEntityConfig":"","updateInterval":"60","updateIntervalType":"num","updateIntervalUnits":"seconds","outputInitially":false,"outputOnChanged":false,"entityId":"sensor.ev_smart_charging_charging","stateType":"str","ifState":"","ifStateType":"str","ifStateOperator":"is","outputs":1,"outputProperties":[{"property":"payload","propertyType":"msg","value":"","valueType":"entityState"},{"property":"data","propertyType":"msg","value":"","valueType":"entity"},{"property":"topic","propertyType":"msg","value":"","valueType":"triggerId"}],"x":330,"y":560,"wires":[["afd38d704e49105d"]]},{"id":"afd38d704e49105d","type":"switch","z":"effce8e2e8a9f43c","g":"a2d0a27e96764e53","name":"Charging or not?","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"off","vt":"num"},{"t":"lt","v":"running","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":550,"y":540,"wires":[[],[]]},{"id":"4a3bc7d5caa41672","type":"function","z":"effce8e2e8a9f43c","g":"9164e2cf469fbb1a","name":"Modbus Payload Template","func":"var values = [msg.StorCtl_Mod, (65535), (700), (10000), (65535), (65535), (5), (msg.OutWRte), (msg.InWRte)]\n\nmsg.payload = {\n 'value': values,\n 'fc': 16,\n 'unitid': 1,\n // INT+SF = -10\n 'address': 40348,\n 'quantity': 9\n}\n\nreturn msg","outputs":1,"timeout":"","noerr":0,"initialize":"","finalize":"","libs":[],"x":1400,"y":460,"wires":[["beceba7f58b3cb02"]]},{"id":"0f54a40946a31d13","type":"cronplus","z":"effce8e2e8a9f43c","name":"Every minute","outputField":"payload","timeZone":"","storeName":"","commandResponseMsgOutput":"output1","defaultLocation":"","defaultLocationType":"default","outputs":1,"options":[{"name":"schedule1","topic":"topic1","payloadType":"default","payload":"","expressionType":"cron","expression":"* * * * * * *","location":"","offset":"0","solarType":"all","solarEvents":"sunrise,sunset"}],"x":150,"y":900,"wires":[[]]},{"id":"ecd41b68db8d4254","type":"modbus-client","name":"Fronius Gen24","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":true,"queueLogEnabled":false,"failureLogEnabled":true,"tcpHost":"10.10.10.4","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"0x3A","unit_id":1,"commandDelay":1,"clientTimeout":1000,"reconnectOnTimeout":true,"reconnectTimeout":2000,"parallelUnitIdsAllowed":true,"showWarnings":true,"showLogs":true},{"id":"afa7e6c.89d5e18","type":"server","name":"Home Assistant","addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"","connectionDelay":false,"cacheJson":false,"heartbeat":true,"heartbeatInterval":"30","statusSeparator":"","enableGlobalContextStore":false}]