Optimizing use of unused Solar Power to charge a Tesla

Thanks @markpurcell this is exactly the functionality that I need to take my home energy management system forward - I was so happy to see the amp change functionality appear in the Tesla app and was sure somebody had found out how to make use of it.

I was going to ask for help to get the tesla_custom.api to work, but found out through writing the request that I didn’t have the latest version which introduced the service call!

Can’t wait to get my charging matched up to my excess solar production - my custom energy dashboard below for interest.

1 Like

I have taken a slightly different approach because I have a battery aswell. The Tesla junction box decides when and how much to charge the battery so the amount directed to the car has to take into account what the box decides to do next. This code estimates how much solar can be directed to the car and works out the amount of amps by dividing by 0.26. I’m polling the automation every 30s.

service: tesla_custom.api
data:
  command: CHARGING_AMPS
  parameters:
    path_vars:
      vehicle_id: '{{ state_attr(''binary_sensor.<name>_online_sensor'', ''id'') }}'
    charging_amps: >-
      {% if ((states('sensor.powerwall_solar_now') | float -
      states('sensor.powerwall_load_now') | float -
      states('sensor.powerwall_battery_now') | float) / 0.26) | int  < 0 %}

          {{ 0 }}

      {% elif ((states('sensor.powerwall_solar_now') | float -
      states('sensor.powerwall_load_now') | float -
      states('sensor.powerwall_battery_now') | float) / 0.26) | int  >16 %} 

          {{ 16 }}

      {% else %}

          {{ ((states('sensor.powerwall_solar_now') | float - states('sensor.powerwall_load_now') | float - states('sensor.powerwall_battery_now') | float) / 0.26) | int }}

      {% endif %}

Thanks Frédéric! (pretty sure we’ve met on the Tesla fb group)
I have created the first automation, and a second one to stop charging on “sunset”.
The balancing is not necessary for me (simply because of the fact that my car is more empty than full).

sorry for my stupid question, I’m still new to HA, where do you put this script?
in the automation config? or in the developer tools > service?
Thanks
Andrea

You need to put this in the Scripts section:

Note the 3 phase scaling factor of * 1.4, 1000 W / ( 3 phase * 230 volt), for a single phase system you should use a factor of * 4.2, 1000 W / ( 1 phase * 230 volt)

Or you can automate the phase calculation as follows

service: tesla_custom.api
data:
  command: CHARGING_AMPS
  parameters:
    path_vars:
      vehicle_id: '{{ state_attr(''binary_sensor.<car>_online_sensor'', ''id'') }}'
    charging_amps: >-
      {{ (states('sensor.solaredge_modbus_meter_m1_ac_power')|int /
      states('sensor.ev_phases')|int / states('sensor.ev_voltage')|int)|int}}

If you run the script manually it will set the charging rate for you once.

You can then create an Automation to call this script every minute.

I have tesla m3 and powerwall 2 as well. I am using the below python script and it works well so far.
Basically I leave my powerwall with 60% reserve at sunset (which is equal to my home usage during the night) and dump every last watt into my tesla. once my tesla is 100% I charge up my powerwall to 100% and the rest goes back to grid for credit.

####################################################################
             ###### tesla charging automation #####
####################################################################

tesla_charge_level = ''
tesla_is_awake = True

try:
    tesla_charge_level = int(float(hass.states.get('sensor.red3_battery_sensor').state))
except:
    logger.info('tesla is sleeping')
    tesla_is_awake = False

if tesla_is_awake:
    powerwall_charge_level = int(float(hass.states.get('sensor.powerwall_charge').state))
    powerwall_reserve = int(float(hass.states.get('input_number.powerwall_reserve').state))
    vehicle_id = hass.states.get('binary_sensor.red3_online_sensor').attributes['id']
    tesla_charge_rate = int(float(hass.states.get('sensor.red3_charging_rate_sensor').state) * 140/240)  ## convert from km to amps
    target_charge_rate = int(float(hass.states.get('input_number.target_charge_rate').state))
    tesla_charge_switch_entity = 'switch.red3_charger_switch'
    tesla_is_charging = True if hass.states.get(tesla_charge_switch_entity).state == 'on' else False
    tesla_is_home = True if hass.states.get('device_tracker.red3_location_tracker').state == 'home' else False
    tesla_is_plugged_in = True if hass.states.get('binary_sensor.red3_charger_sensor').state == 'on' else False
    tesla_is_not_fully_charged = True if tesla_charge_level != 100 else False
    grid_not_in_use = True if float(hass.states.get('sensor.powerwall_site_now').state) * 1000 < 100 else False
    solar_production_is_active = True if float(hass.states.get('sensor.powerwall_solar_now').state) * 1000 > 2000 else False

    # logger.info('vehicle_id:' + str(vehicle_id) +'pwcl:' + str(powerwall_charge_level) + ' pwr:' + str(powerwall_reserve) \
    #     + ' tcl:' + str(tesla_charge_level) + ' tcr:' + str(tesla_charge_rate) + ':' + str(target_charge_rate))

    ##### functions ##############
    def start_tesla_charging(tesla_is_charging, tesla_charge_rate, target_charge_rate):
        if not tesla_is_charging:
            hass.services.call('switch','turn_on', service_data={ 'entity_id': tesla_charge_switch_entity})
        
        if tesla_is_charging and target_charge_rate != tesla_charge_rate:
            hass.services.call('tesla_custom','api', service_data={ 'command': 'CHARGING_AMPS', 'parameters': { 'path_vars': {'vehicle_id': vehicle_id }, 'charging_amps': target_charge_rate}})
            
    def stop_tesla_charging(tesla_is_charging):
        if tesla_is_charging:
            hass.services.call('switch','turn_off', service_data={ 'entity_id': tesla_charge_switch_entity})
        
    ##### main ###########
    if tesla_is_home and tesla_is_plugged_in and tesla_is_not_fully_charged:
        if grid_not_in_use and powerwall_charge_level > powerwall_reserve:
            if solar_production_is_active:
                if powerwall_charge_level >= 80:
                    start_tesla_charging(tesla_is_charging, tesla_charge_rate, target_charge_rate) 
            else:
                start_tesla_charging(tesla_is_charging, tesla_charge_rate, target_charge_rate)
        else:
            stop_tesla_charging(tesla_is_charging)
1 Like

I too have a power wall and would like to integrate this

I have just installed the power wall integration; what integration are you using for the car?

@icepicknz I am using the HACS tesla integration (for the car)

Thanks,

just trying your script now, have the HACS integration going and the Tesla Powerwall one too now.
I take it your script can be copy pasted into an automation?

I have 2 Tesla Models (a model3 and an X), we only have a single phase 63A phase into the house; I’d like to somehow have one slow down (AMPS) if the other is already charging, as we cant do 2 x 32A else fuse will pop at the road :confused: any ideas?

@icepicknz You need to -

  1. Save the above code as “auto_charge_tesla.py” and place it in /config/python_scripts folder
  2. Create a regular automation as below
- id: '1621561764507'
  alias: auto manage tesla charging
  description: ''
  trigger:
  - platform: state
    entity_id: sensor.powerwall_site_now, input_number.tesla_charge_rate
  condition: []
  action:
  - service: python_script.auto_charge_tesla
  mode: single
  1. Obviously change the entity_ids in the file as per your entity_ids.
  2. And create the inputs as required
1 Like

@icepicknz

If your power wall has charge, that will give another 20A.

Hi there,
I’m (kinda) new to Home Assistant and am attempting to get this PW2 / Tesla EV integration up and running. If it matters, am running via Docker (latest stable versions of HA/HACS).

I have installed the HACS Tesla integration as well as the PW2 integration which is working fine. I have also enabled the python_script addon and inserted the above file into the ‘/config/python_scripts’ directory.

I have replaced the entity_ids for my Tesla vehicle to match my own. Where I believe I am getting stuck is in relation to the input_number entities. I can see that there is two required:

input_number.tesla_charge_rate
and
input_number.powerwall_reserve

I have created two input_numbert helpers manually using the above names, but the automation doesn’t seem to be working as intended. The automation is triggering the python script, but it does not appear to be matching the car charging amps to the solar output in any way.

Being new to Home Assistant, I believe the issue may lie with the input_numbers. This page (Input Number - Home Assistant) seems to indicate that they could (should?) be defined as part of the yaml file. I’ve defined them manually via Helpers, but no idea if I’ve done that correctly.

Any help appreciated!

@mkjif43r5

  1. inputs created from yaml and helper are exactly same. so I dont think that would be the issue
  2. That input “tesla_charge_rate” should have been “target_charge_rate”. (i fixed it in my original code post)

Do you see any log messages at all? try placing some debug messages and let me know what you see.

I’m experiencing the following (haven’t read it in this discussion):
Whenever Tesla is offline, the start or stop charging commands don’t work. Probably nothing to do with the automation, because of: when you start charging manually via HA (button f.e.), you experience the same thing (I have to click it twice).

In other words: is there a way to wake up the car before sending the “start charge” command?

I’ve got it installed, however I dont seem to have a powerwall_reserve so am getting this error…

2021-12-04 10:35:46 ERROR (SyncWorker_7) [homeassistant.components.python_script.auto_charge_tesla.py] Error executing script: float() argument must be a string or a number, not 'NoneType'
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/python_script/__init__.py", line 222, in execute
    exec(compiled.code, restricted_globals)
  File "auto_charge_tesla.py", line 16, in <module>
TypeError: float() argument must be a string or a number, not 'NoneType'

@icepicknz

you need to create two input numbers with below names. Also I made slight changes to my code (in my original code above), so please make sure you got those changes.

target_charge_rate
powerwall_reserve

Thanks,

I got around this by setting the values as static variables for now…

    powerwall_reserve = int('60')
    target_charge_rate = int('32')

I’m seeing log entries but it doesn’t appear to be changing the cars amps…

2021-12-04 11:24:16 ERROR (SyncWorker_2) [homeassistant.components.python_script.auto_charge_tesla.py] vehicle_id:14929324xxxxxxxxpwcl:61 pwr:60 tcl:82 tcr:4:32
2021-12-04 11:27:16 ERROR (SyncWorker_2) [homeassistant.components.python_script.auto_charge_tesla.py] vehicle_id:14929324xxxxxxxxpwcl:61 pwr:60 tcl:82 tcr:6:32

I think I got it working; though the charge rate I think I may need to play with as I have a Tesla model X so the values may differ to model3

@cpuram I wonder if you wouldn’t mind helping me, I’m trying to dumb down your script a little by just setting my cars to 16A when two cars are plugged in, or 32A if only one car is plugged in.