EV charging scheduling solution with solar power and a home battery

A lot of questions you have here:

Battery liftime: Number of cycles is a nice commercial way to show battery lifetime, but when you look at the warranty terms and conditions you’ll see most of the brands use thoughput, so I made two sensors to track it. The numbers come from the BYD warranty conditions, they warrant at least 60% capacity after 68,310MWh thoughput:

 template:
    - sensor:
       - name: "battery_lifetime"
          unit_of_measurement: "%"
          state: >
            {% set current_charge = states('sensor.total_battery_discharge') | float %}
            {{ ((1 - (current_charge / 68310)) * 100) | float(100) | round(2)}}
        - name: "battery_minimum_charge_left"
          unit_of_measurement: "kWh"
          state: >
            {% set lifetime = states('sensor.battery_lifetime') | float %}
            {% set degradation = 0.4 | float %}
            {% set maximum_charge = 22.08 | float %}
            {{ (((1 - degradation) + (degradation * (lifetime / 100))) * maximum_charge) | float | round(2)}}

Battery use: It would be easy to track the costs, but I don’t take it into account in an automation. I decided not to use peak shaving or to load/unload from/to grid using the battery. For me, the costs just don’t add up.
In winter I can charge at night when the costs are low. During the other months the solar production should be sufficient and I can charge from battery.

Hour control: I use the GitHub - jpulakka/nordpool_diff: Transforms electricity spot price into thermostat control signal. Home Assistant custom component. integration of which I use the interval sensor. For example:

sensor:
  - platform: nordpool_diff
    entsoe_entity: sensor.injectie_current_electricity_market_price
    nordpool_entity: sensor.nordpool_kwh_be_eur_5_10_0
    filter_length: 3
    filter_type: interval
    unit: ''
    normalize: 'no'

It just looks forward and compares the current price the the price for the next xx hours and sets the price difference (not the absolute value) on a scale from -1 to +1, so the >0 option in the automation means the current price is in the cheapest half for the next xx hours. It’s explained in more detail in the automations readme.
Since the prices usually rise towards the morning peak the car usually is able to charge for 3 to 5 hours each night.

Using node red appears to be more conveniet for me since it’s a visual too.

3 Likes

@Bel_RV How did you integrate the BYD batteries into HA?

I am still looking for the “best” batteries that can be integrated in HA.
AlphaESS has nice battery solutions and they presumably can be managed via modbus.

@bartland I don’t communicate with the batteries directly but through a goodwe ET inverter. The standard goodwe integration exposes 149 entities to HA, a lot of which are of the battery. There is also a custom integration with even more options.

Very nice project! thanks for sharing. I am not sure if I fully understand the solution yet.
my main question for now is how/what kind of actions do you send to the inverter to (for example) start charging the battery? is this within the node red code you shared?
Is that a matter of installing the goodWe integration into HA and then be able to send actions to the device through automations or node red? just wondering how that code looks like

@Joost5000 The idea is that Goodwe handles the power distribution just fine according to the operation mode of the inverter: General, Backup, Off grid or Eco mode. Recently Goodwe also added a peak shaving mode which is available in HA using the custom Goodwe inegration: GitHub - mletenay/home-assistant-goodwe-inverter: Experimental version of Home Assistant integration for Goodwe solar inverters

So, sinceGoodwe handles the battery operation, you just take care of you power management based on parameters you find important for your situation.

The charging logic matured a bit, so I have slightly different options and a modified logic flow from what you see above, but the idea remains the same.

This is how it looks like at the moment:

FYI, last month I saved >€500 of my electricity bill by using this solution. December was less profitable due to a very high peak in the electricity prices and ended up slightly above €100 savings.

1 Like

So atm you’re not controlling the charging of the BYD batteries behind your inverter themselves, I’m guessing?

@Thibaultmol No I don’t. When there is excess power available they will charge untill they are full.
Goodwe doesn’t have the option to control the betteries directly. I can’t really think of a good reason why I should be able to?

Dynamic tarrif I guess?
being able to stop charging the battery right before prices go negative so put as much as possible to the grid and finish charging from the grid/pv when prices are negative? I dunno

These gains are marginal. When prices go negative you still need to pay distribution costs which often makes them positive again. So far this year only a few hours have been negative including distribution costs.
At times when prices are negative, your battery is almost always full since the prices are that low because there is an excess of solar power.

1 Like

I keep a detailed recored of what I actually pay for my electricity and what I would pay if I would use a normal contract without automation. Current savings for this year are >€2000 for the first 7 months of 2023.

Hi,

Where do you get you sensor.INJECTIE sensor from ??? can’t find it in the entsoe integration?

Thx in advance !

Kr,

Bart

Thats the name het uses. You can replace it with your entso-e sensor (probably the one with current in the name)

The entso-e sensors don’t have an injection sensor within the integration. That’s why I’m asking

Who sets /determines the injection prices? If these are EPEX then just setup a second entso-e which gives you the prices subject to different rules (eg excluding vat or other taxes).

I’m very interested in your approach and especially the use of nordpool_diff looks like it could solve a use case I have around scheduling my HVAC to anticipate rising prices.

I’m not located in the EU but my energy prices change every 5 minutes so I would need to translate the nordpool_diff concept to my provider Amber Electric.

I’m doing similar scheduling and optimisation for my EV, home battery, HVAC hot water and other household loads using EMHASS add-on: An energy management optimization add-on for Home Assistant OS and supervised

The results have been amazing and like you I am saving thousands of dollars per year against the base case.

2 Likes

What kind of program is it (logic)? How do you use it (Script?)?

Very nice!

I’ve been trying to do something similar for close to two years but haven’t gotten anywhere near as far as you. Main reason is my inability to understand programming logic.

I’ve done what I can using the UI tools and automations and currently I can control discharge by setting discharge allowed intervals manually. One thing I haven’t figured out how to do is to control the home battery charging. I solved it by setting my inverter to charge between specific hours during the night when it’s most likely to be low electricity price but it’s very coarse. How did you configure home assistant to tell inverter to charge battery? I can’t find any entity that can be set to do that. Changing operation mode doesn’t work either as the charging times doesn’t activate unless you set them through solar go app.

Would highly appreciate if you could share more details on the controlling entities in HA.

Cheers
Anders

You’ll need some basic understanding of a logic in order to automate things. With node red you can visualise a lot of things, which makes it more easy.
As an alternative you can use a custom integration using HACS, for example: GitHub - jonasbkarlsson/ev_smart_charging: Electric vehicle smart charging for Home Assistant.

I do not control the battery directly. The inverter controls the battery. I use the battery level (SOC%) to trigger an automation, for example. If the battery soc% is >40% it is ok to charge, stop if it is below 20%.
It is the charger and/or car which determins if it is actally charging.
To carify: I have a number of conditions which could trigger a flag (= a toggle entity helper) which tells if it ok to start charging or not. These conditions could be: home battery level, electricity price, solar power, …
But it’s the charger and the car which decides if the charging actually starts based on their individual settings

Your EV charging solutions is very interesting and exactly what I’m looking for.
My situation is very similar, GoodWe inverter with BYD battery, and EV which I want to charge according the Belpex hour tariffs and solar production.
I just started HA one week ago, so everything is still “chinees voor mij”, but I’m really jealous about your screenshots from your user interface because that’s exactly what I have in mind.

This is what I use to get everything running:

  • HACS
  • DSMR Slimme meter
  • ENTSO-e Transparency platform
  • GoodWe Inverter
  • Node-Red companion
  • Node-Red Add on
  • Nord Pool
  • Wallbox
  • nordpool_diff (= the core of the automation)

I’ve had a few tweeks the past year and this is how it looks like at the moment:

My main strategy:

  • During winter I run in Automatic mode, mainly switching off the 6 hour interval during the weekend.
  • From April to October just turn on “charge from battery only”
  • During high summer I often turn on “only charge when the battery is full”

The main automation sequence in node-red looks like this:

code:

[{"id":"3e69cdaf73117960","type":"tab","label":"Charge on logic","disabled":false,"info":"","env":[]},{"id":"640730e15ac8308f","type":"api-current-state","z":"3e69cdaf73117960","name":"","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.charge_at_night_schedule","state_type":"str","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":310,"y":420,"wires":[["d5e983d821b83bad"],["37fe8108339c41c4","8adb93a631a3cbe8","31ce5a6452e8a6a6"]]},{"id":"d5e983d821b83bad","type":"time-range-switch","z":"3e69cdaf73117960","name":"19:00-07:00","lat":"51.16054","lon":"4.6485","startTime":"19:01","endTime":"07:01","startOffset":0,"endOffset":0,"x":690,"y":420,"wires":[["37fe8108339c41c4","8adb93a631a3cbe8","31ce5a6452e8a6a6"],["84266b72acf4a5db"]]},{"id":"31ce5a6452e8a6a6","type":"api-current-state","z":"3e69cdaf73117960","name":"","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.only_charge_with_full_battery","state_type":"str","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":300,"y":740,"wires":[["9b24b931347d780c"],[]]},{"id":"9b24b931347d780c","type":"api-current-state","z":"3e69cdaf73117960","name":"Battery >=96%","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"96","halt_if_type":"num","halt_if_compare":"gte","entity_id":"sensor.average_battery_state_of_charge","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"on","valueType":"str"},{"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":680,"y":720,"wires":[["c53bebd0c6bc9449"],[]]},{"id":"2be8becef398085f","type":"api-call-service","z":"3e69cdaf73117960","name":"Charge on","server":"f610b696.ce7818","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_on","areaId":[],"deviceId":[],"entityId":["input_boolean.charge"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1190,"y":780,"wires":[["c0b5d5d30dfbbd83"]]},{"id":"615e4fcebe049208","type":"api-current-state","z":"3e69cdaf73117960","name":"","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.charge_when_connected","state_type":"str","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":320,"y":180,"wires":[["a34d2937afd18c16"],["1fe065c1dc9850df"]]},{"id":"a34d2937afd18c16","type":"api-current-state","z":"3e69cdaf73117960","name":"Wallbox Unavailable?","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"Unavailable","halt_if_type":"str","halt_if_compare":"is","entity_id":"switch.wallbox_portal_pause_resume","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"on","valueType":"str"},{"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":680,"y":180,"wires":[[],["40fb6d6ab472f564"]]},{"id":"40fb6d6ab472f564","type":"api-call-service","z":"3e69cdaf73117960","name":"Charge on","server":"f610b696.ce7818","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_on","areaId":[],"deviceId":[],"entityId":["input_boolean.charge"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":910,"y":180,"wires":[["c0b5d5d30dfbbd83"]]},{"id":"37fe8108339c41c4","type":"api-current-state","z":"3e69cdaf73117960","name":"","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.charge_long_interval","state_type":"str","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":290,"y":580,"wires":[["316fff4bc9f3f0ba"],[]]},{"id":"316fff4bc9f3f0ba","type":"api-current-state","z":"3e69cdaf73117960","name":"Interval 20 > 0.5?","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"0.5","halt_if_type":"num","halt_if_compare":"gt","entity_id":"sensor.nordpool_diff_interval_20","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"on","valueType":"str"},{"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":650,"y":560,"wires":[["00e38cfb26f19e37"],[]]},{"id":"00e38cfb26f19e37","type":"api-call-service","z":"3e69cdaf73117960","name":"Charge on","server":"f610b696.ce7818","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_on","areaId":[],"deviceId":[],"entityId":["input_boolean.charge"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":950,"y":560,"wires":[["c0b5d5d30dfbbd83"]]},{"id":"025eba556e0f115c","type":"inject","z":"3e69cdaf73117960","name":"Inject 30s","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"30","crontab":"","once":true,"onceDelay":"1","topic":"","payload":"","payloadType":"date","x":130,"y":80,"wires":[["afe72b3375754982"]]},{"id":"afe72b3375754982","type":"delay","z":"3e69cdaf73117960","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":300,"y":80,"wires":[["b354759ee335037d"]]},{"id":"8adb93a631a3cbe8","type":"api-current-state","z":"3e69cdaf73117960","name":"","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.charge_short_interval","state_type":"str","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":290,"y":660,"wires":[["9daaeb0eb34917f7"],[]]},{"id":"9daaeb0eb34917f7","type":"api-current-state","z":"3e69cdaf73117960","name":"Interval 6 > 0?","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"0","halt_if_type":"num","halt_if_compare":"gt","entity_id":"sensor.nordpool_diff_interval_6","state_type":"num","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"on","valueType":"str"}],"for":"0","forType":"num","forUnits":"minutes","override_topic":false,"state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","x":640,"y":640,"wires":[["8f0d81d271476fc4"],[]]},{"id":"8f0d81d271476fc4","type":"api-call-service","z":"3e69cdaf73117960","name":"Charge on","server":"f610b696.ce7818","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_on","areaId":[],"deviceId":[],"entityId":["input_boolean.charge"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":950,"y":640,"wires":[["c0b5d5d30dfbbd83"]]},{"id":"a65f19fbcded465a","type":"delay","z":"3e69cdaf73117960","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1020,"y":80,"wires":[["9bf4f1e8a804fa95"]]},{"id":"c0b5d5d30dfbbd83","type":"change","z":"3e69cdaf73117960","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1340,"y":320,"wires":[["a65f19fbcded465a"]]},{"id":"84266b72acf4a5db","type":"api-call-service","z":"3e69cdaf73117960","name":"Charge off","server":"f610b696.ce7818","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_off","areaId":[],"deviceId":[],"entityId":["input_boolean.charge"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":930,"y":460,"wires":[[]]},{"id":"b354759ee335037d","type":"api-current-state","z":"3e69cdaf73117960","name":"Wallbox Ready? (= not connected)","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"Ready","halt_if_type":"str","halt_if_compare":"is","entity_id":"sensor.wallbox_portal_status_description","state_type":"str","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":540,"y":80,"wires":[["a25411b7fce0f702"],["a65f19fbcded465a","615e4fcebe049208"]]},{"id":"a25411b7fce0f702","type":"api-call-service","z":"3e69cdaf73117960","name":"Charge off","server":"f610b696.ce7818","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_off","areaId":[],"deviceId":[],"entityId":["input_boolean.charge"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":930,"y":20,"wires":[[]]},{"id":"c53bebd0c6bc9449","type":"api-current-state","z":"3e69cdaf73117960","name":"Charge is off?","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.charge","state_type":"str","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":760,"y":780,"wires":[["645bf126dd182a76"],["2be8becef398085f"]]},{"id":"645bf126dd182a76","type":"api-current-state","z":"3e69cdaf73117960","name":"Battery >=99%","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"99","halt_if_type":"num","halt_if_compare":"gte","entity_id":"sensor.average_battery_state_of_charge","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"on","valueType":"str"},{"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":940,"y":700,"wires":[["516ae73dca691dde"],[]]},{"id":"516ae73dca691dde","type":"api-call-service","z":"3e69cdaf73117960","name":"Charge on","server":"f610b696.ce7818","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_on","areaId":[],"deviceId":[],"entityId":["input_boolean.charge"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1150,"y":700,"wires":[["c0b5d5d30dfbbd83"]]},{"id":"9bf4f1e8a804fa95","type":"api-call-service","z":"3e69cdaf73117960","name":"Charge off","server":"f610b696.ce7818","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_off","areaId":[],"deviceId":[],"entityId":["input_boolean.charge"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1230,"y":80,"wires":[[]]},{"id":"1fe065c1dc9850df","type":"api-current-state","z":"3e69cdaf73117960","name":"","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.charge_from_battery","state_type":"str","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":290,"y":280,"wires":[["61aeb2c7bb69300f"],["640730e15ac8308f"]]},{"id":"61aeb2c7bb69300f","type":"api-current-state","z":"3e69cdaf73117960","name":"Battery start >=?%","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"$number(\t   $entities(\"input_number.start_charging_at_battery_percentage\").state\t)\t","halt_if_type":"jsonata","halt_if_compare":"gte","entity_id":"sensor.average_battery_state_of_charge","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"on","valueType":"str"},{"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":670,"y":280,"wires":[["a18dcc3d8fabacb8"],["cb5eeb9eb1d8bfc5"]]},{"id":"ccf68e320061dd43","type":"api-current-state","z":"3e69cdaf73117960","name":"Battery stop >=?%","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"$number(\t   $entities(\"input_number.stop_charging_at_battery_percentage\").state\t)\t","halt_if_type":"jsonata","halt_if_compare":"gte","entity_id":"sensor.average_battery_state_of_charge","state_type":"str","blockInputOverrides":false,"outputProperties":[{"property":"payload","propertyType":"msg","value":"on","valueType":"str"},{"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":910,"y":360,"wires":[["e4a638116f709566"],["640730e15ac8308f"]]},{"id":"e4a638116f709566","type":"api-call-service","z":"3e69cdaf73117960","name":"Charge on","server":"f610b696.ce7818","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_on","areaId":[],"deviceId":[],"entityId":["input_boolean.charge"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":1090,"y":320,"wires":[["c0b5d5d30dfbbd83"]]},{"id":"a18dcc3d8fabacb8","type":"api-call-service","z":"3e69cdaf73117960","name":"Charge on","server":"f610b696.ce7818","version":5,"debugenabled":false,"domain":"input_boolean","service":"turn_on","areaId":[],"deviceId":[],"entityId":["input_boolean.charge"],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":930,"y":260,"wires":[["c0b5d5d30dfbbd83"]]},{"id":"cb5eeb9eb1d8bfc5","type":"api-current-state","z":"3e69cdaf73117960","name":"Charge is off?","server":"f610b696.ce7818","version":3,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","entity_id":"input_boolean.charge","state_type":"str","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":660,"y":340,"wires":[["640730e15ac8308f"],["ccf68e320061dd43"]]},{"id":"f610b696.ce7818","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]

The main idea is:

  • If the charger is connected to the car turn the charger off with a delay of 5s
  • start the evaluation (seen on the left side) and turn the charger on when one of the conditions is true
  • interrupt turning off the charger if one of the conditions is true (shown on the right)

I might post it on github one day when I find the time to move this from node red to automations and create a testing environment for experimenting.