try removing the quotes around ā30ā (seconds) so itās a number and not text
Sorry, I should have explained that the problem is around the value statement:
value: {{ (states.number.t_ray_charging_amps.state | int ) + 1 }}
If I put in a number eg. like this:
value: 5
the automation works perfectly. But with the curly bracket statement, I get an error message:
Message malformed: expected float for dictionary value @ data['value']
Any help is greatly appreciated.
UPDATE: SOLUTION FOUND
Action statement changed to this:
action:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') | int %} {{
current_amps + 1 }}
Now it works.
Hi! Iām looking to create an automation to do the same thing.
A couple of questions:
-
I think your automation will constantly adjust 1 A up or down every 30 seconds. Currently there is no option for it to leave the charging current as it is.
-
The Tesla app has a minimum set charging current of 5 A. Does the API allow it to go lower? Edit: it does! I thought you had to do a minimum of 5 A charging. Thatās cool!
Alright, just played around with it for a bit.
Seeing the current to 0 (zero) amps and turning it on seems to draw around 400-500 Watts, but Iām not sure it charges the car. I think it just powers on the onboard charger. So I think the efficiency will be very low at low amps.
My electrical bill is net metering per hour (if import == export within a clock hour, my bill will be zero), so I might want to do things in bursts of 5A for low solar surplus, if that increases charging efficiency.
I will post my automation here when I get it woeking, either with or without burst charging.
Cheers!
True. I just had troubles to make the value statement (+/- amps) working. Now I start building the complete set of triggers, conditions etc. around the +/- amp function.
Also agree on the probably low efficiency at low amps, but want to try it and see how it works.
I will post as I progress and appreciate your thoughts.
Thanks.
Hello @Finnray
I tried your automation, and it seems awesomeā¦ I just cannot make it work.
Can you or anyone else help me?
Be aware that im not very skilled at this stuff.
YALM from automation (Im not getting any error):
alias: Tesla Charging
description: ""
trigger:
- platform: time_pattern
minutes: "2"
condition:
- condition: sun
before: sunset
after: sunrise
- type: is_plugged_in
condition: device
device_id: 4ebe9b1fbd57c840e4235fbb8af7cbbb
entity_id: binary_sensor.charger
domain: binary_sensor
action:
- if:
- condition: numeric_state
entity_id: sensor.omcsbln02t_export_to_grid
above: 0.6
then:
- service: input_number.set_value
entity_id: number.charging_amps
data_template:
value: >-
{% set current_amps = states('number.charging_amps') | int %} {{
current_amps + 1 }}
else:
- service: input_number.set_value
entity_id: number.charging_amps
data_template:
value: >-
{% set current_amps = states('number.charging_amps') | int %} {{
current_amps - 1 }}
mode: single
Currently Iām charging my car with 6 amps. And āsensor.omcsbln02t_export_to_gridā is below 0.6 so it should change the amps to 5, which it actually seems like its trying, but nothing happens.
Log from Trace:
Executed: April 9, 2023 at 10:35:56
Result:
params:
domain: input_number
service: set_value
service_data:
value: 5
entity_id:
- number.charging_amps
target:
entity_id:
- number.charging_amps
running_script: false
limit: 10
There is something in value: called ācurrent_ampsā. Iām not sure what this value/sensor is, and maybe this could be the issue. I just thought that as soon as it gives the right value, it would change number.charging_amps to this value?
Thanks a lot
I got it working!
I think the problem was
input_number.set_value
was changed to:
number.set_value
Thanks
Glad to hear that you got it working Karsten.
Actually, I also got it working and have since refined it quite a bit. Here is the code that I use today:
alias: T-Ray solar charging
description: ""
trigger:
# Time interval for triggering set
- platform: time_pattern
seconds: "30"
condition:
# Continue if T-Ray is plugged in charger (or exit)
- type: is_plugged_in
condition: device
device_id: b4929c45bca6cfb24b68e22f7f0f9977
entity_id: binary_sensor.t_ray_charger
domain: binary_sensor
# Continue if T-Ray SOC is below 1% of charge limit (or exit)
- condition: template
value_template: >-
{{(states('number.t_ray_charge_limit') | int -
states('sensor.t_ray_battery') | int) > 1}}
action:
# Continue if more than 688w EXPORT power is available (else)
- if:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_po
domain: sensor
above: 688
then:
# Turn ON charger if it is OFF and continue (or just continue)
- if:
- condition: device
type: is_off
device_id: b4929c45bca6cfb24b68e22f7f0f9977
entity_id: switch.t_ray_charger
domain: switch
then:
- type: turn_on
device_id: b4929c45bca6cfb24b68e22f7f0f9977
entity_id: switch.t_ray_charger
domain: switch
# Choose number of charging amps to add relative to current EXPORT power (Note: If current EXPORT power is below 688w -> no change)
- choose:
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_po
domain: sensor
above: 5504
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') |
int %} {{ current_amps + 8 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_po
domain: sensor
above: 4816
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') |
int %} {{ current_amps + 7 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_po
domain: sensor
above: 4128
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') |
int %} {{ current_amps + 6 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_po
domain: sensor
above: 3440
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') |
int %} {{ current_amps + 5 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_po
domain: sensor
above: 2752
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') |
int %} {{ current_amps + 4 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_po
domain: sensor
above: 2064
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') |
int %} {{ current_amps + 3 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_po
domain: sensor
above: 1376
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') |
int %} {{ current_amps + 2 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_po
domain: sensor
above: 688
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') |
int %} {{ current_amps + 1 }}
else:
# Check if power is being imported
- if:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_p
domain: sensor
above: 0
then:
# Turn OFF charger if power is being imported, but current charging power is below 550w and exit
- if:
- type: is_power
condition: device
device_id: 3efa4551c778fefe170f4c0c7b4dad6f
entity_id: sensor.go_echarger_110504_nrg_12
domain: sensor
below: 550
then:
- type: turn_off
device_id: b4929c45bca6cfb24b68e22f7f0f9977
entity_id: switch.t_ray_charger
domain: switch
else:
# Choose number of charging amps to subtract relative to current IMPORT power (Note: If current IMPORT power is below 688w -> no change)
- choose:
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_p
domain: sensor
above: 5504
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps =
states('number.t_ray_charging_amps') | int %} {{
current_amps - 8 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_p
domain: sensor
above: 4816
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps =
states('number.t_ray_charging_amps') | int %} {{
current_amps - 7 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_p
domain: sensor
above: 4128
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps =
states('number.t_ray_charging_amps') | int %} {{
current_amps - 6 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_p
domain: sensor
above: 3440
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps =
states('number.t_ray_charging_amps') | int %} {{
current_amps - 5 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_p
domain: sensor
above: 2752
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps =
states('number.t_ray_charging_amps') | int %} {{
current_amps - 4 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_p
domain: sensor
above: 2064
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps =
states('number.t_ray_charging_amps') | int %} {{
current_amps - 3 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_p
domain: sensor
above: 1376
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps =
states('number.t_ray_charging_amps') | int %} {{
current_amps - 2 }}
- conditions:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_p
domain: sensor
above: 688
sequence:
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps =
states('number.t_ray_charging_amps') | int %} {{
current_amps - 1 }}
mode: single
Hi @Finnray
I wondered why you made the long list of conditions. Is there any obvious reason that you couldnāt just calculate the number you want to adjust the charging current with?
E.g:
value: >-
{{ states('number.charging_amps') | int - (states('sensor.active_import_average_5_min')|int / 688) | round(0,'floor') }}
Then you could make the automation much simpler.
And another thing: Did you choose the 30 seconds interval for some specific reason?
I donāt have a better value, but I choose every 5 minutes and made the export value a 5 minutes moving average.
Just because I thought it was too often to adjust the charging current more often than this. But I have no strong considerations behind my choice.
Hi @vester,
Thanks for your input. Calculating the charging current adjustment is definitely more rational. I just got down another avenue and blindsighted on that obvious improvement to the code.
The 30 second interval is because I want to adjust close to real time, so that any change in solar production (for instance a cloud passing) and house consumption (for instance a thermostat turning on the electric heating in my garage) is (almost) immediately reflected in the charging amps. Thus minimizing the import of power from the grid.
Here is my updated code:
alias: T-Ray solar charging
description: ""
trigger:
# Time interval for triggering set
- platform: time_pattern
seconds: "30"
condition:
# Continue if T-Ray is plugged in charger (or exit)
- type: is_plugged_in
condition: device
device_id: b4929c45bca6cfb24b68e22f7f0f9977
entity_id: binary_sensor.t_ray_charger
domain: binary_sensor
# Continue if T-Ray SOC is below 1% of charge limit (or exit)
- condition: template
value_template: >-
{{(states('number.t_ray_charge_limit') | int -
states('sensor.t_ray_battery') | int) > 1}}
action:
# Continue if more than 688w EXPORT power is available (else)
- if:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_po
domain: sensor
above: 688
then:
# Turn ON charger if it is OFF and continue (or just continue)
- if:
- condition: device
type: is_off
device_id: b4929c45bca6cfb24b68e22f7f0f9977
entity_id: switch.t_ray_charger
domain: switch
then:
- type: turn_on
device_id: b4929c45bca6cfb24b68e22f7f0f9977
entity_id: switch.t_ray_charger
domain: switch
# Calculate number of charging amps to add relative to current EXPORT power (Note: If current EXPORT power is below 688w -> no change)
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') | int %}
{% set add_amps = (states('sensor.pow_k_po') | int / 688) | round(0,'floor') %}
{{ current_amps + add_amps }}
else:
# Check if power is being imported
- if:
- type: is_power
condition: device
device_id: 5ab015508a4f0ce2f17d992b8f68c3f0
entity_id: sensor.pow_k_p
domain: sensor
above: 0
then:
# Turn OFF charger if power is being imported, but current charging power is below 550w and exit
- if:
- type: is_power
condition: device
device_id: 3efa4551c778fefe170f4c0c7b4dad6f
entity_id: sensor.go_echarger_110504_nrg_12
domain: sensor
below: 550
then:
- type: turn_off
device_id: b4929c45bca6cfb24b68e22f7f0f9977
entity_id: switch.t_ray_charger
domain: switch
else:
# Calculate number of charging amps to subtract relative to current IMPORT power (Note: If current IMPORT power is below 688w -> no change)
- service: number.set_value
data_template:
entity_id: number.t_ray_charging_amps
value: >-
{% set current_amps = states('number.t_ray_charging_amps') | int %}
{% set sub_amps = (states('sensor.pow_k_p') | int / 688) | round(0,'floor') %}
{{ current_amps - sub_amps }}
mode: single
Hi there,
Many thanks for all your work. I am a full novice to coding
Got enphase solar, a shelly that shows the net total returned to the grid (positive value) or negative value if I import.
Also go 2 tesla home.
Got an issue: amps rapidly rocket to the max (32A) and then stop, but it seem to not adapt.
Here is the code, if you could help
Alias: Cocotte solar charging
description: ""
trigger:
- platform: time_pattern
seconds: "30"
condition:
- type: is_plugged_in
condition: device
device_id: b27fa242ee51ac63d7d7c1d3db0a2b99
entity_id: binary_sensor.cocotte_charger
domain: binary_sensor
- condition: template
value_template: >-
{{(states('number.cocotte_charge_limit') | int -
states('sensor.cocotte_battery') | int) > 1}}
- condition: device
device_id: b27fa242ee51ac63d7d7c1d3db0a2b99
domain: device_tracker
entity_id: device_tracker.cocotte_location_tracker
type: is_home
action:
- if:
- type: is_power
condition: device
device_id: c65fef9bafaa8cbba8bf3eeb386fb2b8
entity_id: sensor.shellyem_244cab43175e_channel_1_power
domain: sensor
above: 688
then:
- if:
- condition: device
type: is_off
device_id: b27fa242ee51ac63d7d7c1d3db0a2b99
entity_id: switch.cocotte_charger
domain: switch
then:
- type: turn_on
device_id: b27fa242ee51ac63d7d7c1d3db0a2b99
entity_id: switch.cocotte_charger
domain: switch
- service: number.set_value
data_template:
entity_id: number.cocotte_charging_amps
value: >-
{% set current_amps = states('number.cocotte_charging_amps') | int
%} {% set add_amps =
(states('sensor.shellyem_244cab43175e_channel_1_power') | int / 688)
| round(0,'floor') %} {{ current_amps + add_amps }}
else:
- if:
- type: is_power
condition: device
device_id: c65fef9bafaa8cbba8bf3eeb386fb2b8
entity_id: sensor.shellyem_244cab43175e_channel_1_power
domain: sensor
below: 300
then:
- if:
- type: is_power
condition: device
device_id: c65fef9bafaa8cbba8bf3eeb386fb2b8
entity_id: sensor.shellyem_244cab43175e_channel_2_power
domain: sensor
below: 6000
then:
- type: turn_off
device_id: b27fa242ee51ac63d7d7c1d3db0a2b99
entity_id: switch.cocotte_charger
domain: switch
else:
- service: number.set_value
data_template:
entity_id: number.cocotte_charging_amps
value: >-
{% set current_amps = states('number.cocotte_charging_amps')
| int %} {% set sub_amps =
(states('sensor.shellyem_244cab43175e_channel_1_power') |
int / 688) | round(0,'floor') %} {{ current_amps - sub_amps
}}
mode: single
OP, is 688 the standard power draw for your house? I keep getting errors saying 17 is out of the range, which it is. 16 is the max ampage for my house.
Iām trying to work out where the math is going wrong.
@finnarne and everyone who is trying this. This is a great idea and thanks for sharing the code. I tried to make it work but i found one issue so far.
My condition always pass to check that Tesla charger in:
type: is_plugged_in
condition: device
device_id: 322d00bd1327c12f2a7be379c7ce50d2 (TeslaCar)
entity_id: 0b60e87852146865b8bd6a6394622eaf (TeslaCar Charger is plugged in)
domain: binary_sensor
My Car polling is on, i had to do force data update in that Tesla Custom Integration plugin. And here are my settings any recommendations?
Tesla at home also makes sense, thatās at least what I did
Hello everyone Iām new here, Iām trying to figure things out ! (Sorry for my bad English, Iām french !).
I just bought 6 solar panels for 2.88kw (plug and play), and of course, I would like to charge my tesla with the excess power instead of putting it into the grid. Home Assistant seems to be awesome and I canāt wait to get it (just bought a raspberryPi). You code is awesome, but how you car is connected, I mean with an EvStation (Mine is 7kw/h) ? Through a connected plug (max 3kw/h) ? Thank you !
@Finnray I could flipping kiss you right now, man!
Your last post showing the updated YAML was just the info I needed to finally rewrite my horrible, clunky set of 24 automations down to 1 automation that calculated the max available charging amps that I can shove into the Model S, without importing anything.
YOU ARE MAGNIFICENT!!!
For years I have struggled, knowing there was a nice way to calculate the amps from the available watts and voltage, but my YAML skills are far too crap to put the maths into practice. Your code is bang on and my car is now merrily lapping up my solar, with the amps being adjusted every 30 seconds.
I made a few little tweaks, but here is the code that works with my Tesla (using @alandtseās nice integration) and my SolarEdge inverter (using @WillCodeForCatsās brilliant Modbus multi integration).
alias: Tesla Solar Charging Automation
description: ""
trigger:
- platform: time_pattern
seconds: /30
condition:
- condition: and
conditions:
- condition: sun
before: sunset
- condition: sun
after: sunrise
- condition: state
entity_id: device_tracker.nikita_location_tracker
state: home
- condition: state
entity_id: binary_sensor.nikita_charger
state: "on"
- condition: template
value_template: >-
{{ (states('number.nikita_charge_limit') | int -
states('sensor.nikita_battery') | int) > 0.1 }}
action:
- if:
- condition: numeric_state
entity_id: sensor.solaredge_m1_ac_power
above: 250
then:
- if:
- condition: state
entity_id: switch.nikita_charger
state: "off"
then:
- entity_id: switch.nikita_charger
action: switch.turn_on
- data_template:
entity_id: number.nikita_charging_amps
value: >-
{% set current_amps = states('number.nikita_charging_amps') | int %}
{% set add_amps = (states('sensor.solaredge_m1_ac_power') | int /
240) | round(0,'floor') %} {{ [current_amps + add_amps, 8] | min }}
action: number.set_value
else:
- if:
- condition: numeric_state
entity_id: sensor.solaredge_m1_ac_power
below: 0
then:
- entity_id: switch.nikita_charger
action: switch.turn_off
else:
- data_template:
entity_id: number.nikita_charging_amps
value: >-
{% set current_amps = states('number.nikita_charging_amps') |
int %} {% set sub_amps = (states('sensor.solaredge_m1_ac_power')
| int / 240) | round(0,'floor') %} {{ current_amps - sub_amps }}
action: number.set_value
mode: single
I added some conditions to ensure the automation only runs during daylight hours, and when the car is at home (to limit messing with the car when charging elsewhere), as well as converting to single phase power and capping the amps at 8A (I am running on the UMC plugged into a sketchy garage socket at the moment after having moved house). I will bump those back up to 400V and 32A once my schpanking new 3 phase cabling has gotten the HPWC online. I also trimmed out the device IDs as they were throwing a lot of errors (is that a bad thing to remove them?). I also changed the time pattern from ā30ā to /30 as I find that to be a more reliable trigger.
My next improvement will be to take the voltage sensor of the SolarEdge meter/inverter and input that into the amperage calculation so the maths improves as the voltage fluctuates throughout the day, which it does a surprising amount.
For those with knowledge of this with 3 phase SolarEdge inverters, is āsensor.solaredge_m1_ac_voltage_lnā the best sensor to use, or do I need to do yet more maths to average out the 3 phase voltages?
Thanks again @Finnray !!!
Ah wait, I celebrated too soon.
When the sun started to go down, instead of gradually reducing the amps, and then stopping when there is zero solar, the automation kept first stopping the charge, and then restarting with too maps amps, and then stopping ad infinitum.
I suspect the āactionā part of the automation is in the wrong order. Can anyone assist me in rewriting it to first ramp down the amps until there is no solar juice, then to stop the charge?
action:
- if:
- condition: numeric_state
entity_id: sensor.solaredge_m1_ac_power
above: 250
then:
- if:
- condition: state
entity_id: switch.nikita_charger
state: "off"
then:
- entity_id: switch.nikita_charger
action: switch.turn_on
- data_template:
entity_id: number.nikita_charging_amps
value: >-
{% set current_amps = states('number.nikita_charging_amps') | int %}
{% set add_amps = (states('sensor.solaredge_m1_ac_power') | int /
240) | round(0,'floor') %} {{ [current_amps + add_amps, 8] | min }}
action: number.set_value
else:
- if:
- condition: numeric_state
entity_id: sensor.solaredge_m1_ac_power
below: 0
then:
- entity_id: switch.nikita_charger
action: switch.turn_off
else:
- data_template:
entity_id: number.nikita_charging_amps
value: >-
{% set current_amps = states('number.nikita_charging_amps') |
int %} {% set sub_amps = (states('sensor.solaredge_m1_ac_power')
| int / 240) | round(0,'floor') %} {{ current_amps - sub_amps }}
action: number.set_value
Charging the car with excess solar power is a really great idea. Your approach has been very inspiring . I used a slightly different approach which I like to share here.
Let me know what you think.
My main concern is that with an incremental approach, there is a theoretical risk get into an unrealistic number (e.g. negative or unrealistically high). I am not saying that it is bad; it is just a risk. Therefore I decided to directly estimate the expected power draw of the house and use an input_number
that is limited to my electrical setupās amperage (between 5 and 16).
Since the minimal amount of charge current for my Tesla Model Y is 5 Amps (~1100 W), and sometimes the total power would not be enough, I am OK to charge with a mixture of 50% solar and 50% grid energy. I wanted to make sure that I also can accommodate that.
Further, for me it is OK that the routine still draws from or returns to the grid a bit of current. Therefore I decided to update once per 5 minutes.
I therefore splitted up the protocol into four parts/automations:
- Calculate the Tesla Charge current every 5 minutes (see below)
- Update the Tesla Charge current into the Tesla
- Interrupt the charging in case of too little power (less than 1kW)
- Resume the charging in case of sufficient power (more than 1.2kW)
The last three are quite obvious to implement.
I have several Shelly power meters, so those can be added up + a rest power that I cannot measure and therefore estimated at 350 W. Then I subtract this āhouse powerā from the āsolar powerā which can go into the Tesla.
I use an input_number
helper to store the amount of current. Whenever this value changes and the car is charging at home (+ several other conditions), I update the Teslaās charging current value. This routine is always running every 5 minutes (I could change that if that really has significant impact).
Further, have an input_boolean
to turn on āGreen Chargingā so I can also use conventional night charging.
Calculate charge current
alias: Tesla Groen charging - caluclate charge current
trigger:
- platform: time_pattern
minutes: /5
condition: []
action:
- variables:
Phouse: >-
{{ (states.sensor.boiler_en_wasmachine_power.state | float +
states.sensor.droger_en_oven_power.state | float +
states.sensor.werkplek_power.state | float +
states.sensor.vaatwasser_power.state | float +
states.sensor.airco_power.state | float) | round(0) }}
Prest: 350
Psolar: "{{ -1 * states.sensor.zonnepanelen_power.state | float }}"
Pcar: "{{ (Psolar - Phouse - Prest) | round (1) }}"
Voltage: "{{ states.sensor.laadpaal_voltage.state | float }}"
Icar: "{{ (Pcar / Voltage) | round (0) }}"
- action: input_number.set_value
metadata: {}
data:
value: "{{ Icar }}"
target:
entity_id: input_number.tesla_solar_current
mode: single
Whenever I transfer an action to the car (update current, interrupt/resume charging), I always check the following conditions:
- Tesla is plugged in
- Tesla is at home
- Tesla User present is off
- Tesla Shift State is Park
- It is day time
- Input_boolean Green Charging is āonā
On my first try, I was able to achieve 93% direct consumption of my solar energy. Hope to hear from you what levels you achieve.
After some head scratching and a lot of trial and error, I now have a working automation that starts the charge, increases amps as solar excess is available, reduces charge amps when power dips into import, and then stops the charge when there are no available amps.
Feel free to use, edit and critique the following automation:
alias: "*Tesla Solar Charging Automation"
description: ""
trigger:
- platform: time_pattern
seconds: /30
condition:
- condition: and
conditions:
- condition: sun
before: sunset
- condition: sun
after: sunrise
- condition: state
entity_id: device_tracker.nikita_location_tracker
state: home
- condition: state
entity_id: binary_sensor.nikita_charger
state: "on"
- condition: template
value_template: >
{{ (states('number.nikita_charge_limit') | int -
states('sensor.nikita_battery') | int) > 0.1 }}
action:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.solaredge_m1_ac_power
above: 250
sequence:
- choose:
- conditions:
- condition: state
entity_id: switch.nikita_charger
state: "off"
sequence:
- target:
entity_id: switch.nikita_charger
action: switch.turn_on
data: {}
- data:
entity_id: number.nikita_charging_amps
value: >
{% set current_amps = states('number.nikita_charging_amps') |
float %} {% set add_amps =
(states('sensor.solaredge_m1_ac_power') | float / 236) |
round(0, 'floor') %} {% set new_amps = current_amps + add_amps
%} {{ [new_amps, 8] | min | float }}
action: number.set_value
- conditions:
- condition: numeric_state
entity_id: sensor.solaredge_m1_ac_power
below: 0
sequence:
- choose:
- conditions:
- condition: numeric_state
entity_id: number.nikita_charging_amps
above: 1
sequence:
- data:
entity_id: number.nikita_charging_amps
value: >
{% set current_amps =
states('number.nikita_charging_amps') | float %} {% set
sub_amps = ((states('sensor.solaredge_m1_ac_power') |
float * -1) / 236) | round(0, 'floor') %} {% set
new_amps = current_amps - sub_amps %} {{ [new_amps, 1] |
max | float }}
action: number.set_value
- conditions:
- condition: numeric_state
entity_id: number.nikita_charging_amps
below: 1.1
sequence:
- target:
entity_id: switch.nikita_charger
action: switch.turn_off
data: {}
mode: single
So far it seems pretty quick to react to changes in solar output (clouds, other loads in the house etc), reliable, and robust.
Enjoy!