Speak EV - Electric Car Forums banner

Charging off excess solar using dumb charger and Home Assistant

1 reading
17K views 9 replies 4 participants last post by  kitenski  
#1 · (Edited)
Aug 2024 Edit:
Unless your solar is consistently producing over 1200 W excess, I wouldn't use this.

Tesla limits minimum charge rate to 5 amps in the app. Tesla charge on solar feature requires at least consistent 1.2 kW excess before starting.

There must be a reason it's been set at 5 amps. I've had instances where the car would error out and say unstable input voltage or other errors when charging below 5 amps. So it's not recommended.

----------------------------------------------------------------------
Original post:

I've been asked to share how I am charging my Tesla using excess solar. I am using a software solution with a dumb charge point instead of smart charge points like Zappi.

Key is that the Tesla API allows setting any charge current (amps) from 0 up to whatever is allowed by your charge point. So in this sense, it's better than Zappi because through Tesla API, I can adjust down to 0 amps. Zappi only allows down to 6 amps due to charge standards: the charge point must provide 6 amps minimum, but cars can pull any amount of power up to charge point provided amount. 0 and 1 amp is useless because the car consumes about 250w sitting there. But it's useful to have it idle when a momentary thick cloud flys across. My small solar install means I typically charge at around 4 amps, only up to 6 amps in perfect conditions.

You'll need Home Assistant, talking to Tesla API. Plus some way for HA to get smart meter reading, I'm using Glow IHD, which sends MQTT update to HA every 10s.

Please do carefully look at the automations to make sure it does what you need to do.

First, set up an input_number (input_number.tesla_y_charge_amps) for charging amps and a script to apply the charging amps.
YAML:
  alias: Tesla Set Charge Amp
  mode: restart
  sequence:
    - service: tesla_custom.api
      data:
        command: CHARGING_AMPS
        parameters:
          path_vars:
            vehicle_id: "{{ state_attr('binary_sensor.y_online', 'id') }}"
          charging_amps: "{{ states('input_number.tesla_y_charge_amps') | int(default=30) }}"
          wake_if_asleep: true
I have 3 automations, one to start charging, one to stop charging and one to auto-adjust amps based on excess solar. Start and stop are very simple to do, just need to do "switch.turn_on" for the "switch.car_charger" entity to start charging. You can pre-set charging limit and charging amps before start charging, it is also worth waiting 10-20 seconds between each API call to avoid flooding the server.

Here is the auto-adjust automation, it does the following:
1. trigger: on new smart meter MQTT message
2. condition: car is at home, not night time (avoid messing with overnight cheap tariff)
3. action: wait for another meter data point (10s for me), to avoid spikes
4. then do the charge current increment/decrement, send it to Tesla and wait a time out.
It will not bug Tesla server more than twice a minute if solar production is constantly charging.

YAML:
alias: Tesla - Solar charging adjust
trigger:
  - platform: mqtt
    topic: glow/+/SENSOR/electricitymeter
condition:
  - condition: or
    conditions:
      - condition: numeric_state
        entity_id: sensor.smart_meter_electricity_power_export
        above: 160
      - condition: numeric_state
        entity_id: sensor.smart_meter_electricity_power_import
        above: 150
  - condition: state
    entity_id: device_tracker.tesla_location
    state: home
  - condition: state
    entity_id: switch.y_charger
    state: "on"
  - condition: sun
    before: sunset
    after: sunrise
action:
  - wait_for_trigger:
      - platform: mqtt
        topic: glow/+/SENSOR/electricitymeter
    timeout:
      hours: 0
      minutes: 0
      seconds: 11
      milliseconds: 0
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.smart_meter_electricity_power_export
            above: 930
        sequence:
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.smart_meter_electricity_power_export
            above: 690
        sequence:
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.smart_meter_electricity_power_export
            above: 460
        sequence:
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.smart_meter_electricity_power_export
            above: 140
        sequence:
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.smart_meter_electricity_power_import
            above: 930
        sequence:
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.smart_meter_electricity_power_import
            above: 690
        sequence:
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.smart_meter_electricity_power_import
            above: 460
        sequence:
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.smart_meter_electricity_power_import
            above: 140
        sequence:
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
    default:
      - stop: ""
  - service: script.turn_on
    data: {}
    target:
      entity_id: script.tesla_set_charge_amp
  - delay:
      hours: 0
      minutes: 0
      seconds: 18
      milliseconds: 0
mode: single
max_exceeded: silent
End result is that you can make your car track solar production, resolution is about 240w because we are changing charging amps and voltage is at around 240v.

This was very sunny Sunday 28th May, charging was started just after 9am on this day: (yellow is solar production used, purple below 0 is exported, blue on top of yellow is import. I think 11-12 import was due to the oven, with the car idling at 0 amps)
Image


Over last 2 weeks of sunny days, with my small 2.9 kW-p W-E install, I charged 40% of "free" energy, well over 100 miles. Starting from 60% up to 84% with a 10% drive in the middle, then another 6% on Sunday.
Image


Hope this is helpful to you, let's drive on sunshine, right now :)
 
#3 ·
In HA, go to Settings -> Automation & Scenes -> Automations tab or Scripts tab. Bottom right floating button to create a new automation or script.
Select "Create new automation" and then click on top right 3 dots -> Edit in YAML. You can then paste the code into here.
You can then switch back to UI mode for easier edits.
Remember to save using the bottom right floating button.
 
#4 ·
Today's generation was not perfect but did the job. The sun initially ducked in and out of clouds, so I thought would be a good show case of charging following solar.

My OpenEnergyMonitor CT clamps derived (calculated by working out difference between 2 CT clamps, less accurate) charge point used 4.47 kWh.
Car reports added 3.66 kWh. So charging efficiency of ~81%.

Car was charging 12:27 to 18.54. This is the resulting power plot in OpenEnergyMonitor using CT clamps, also updates every 10 seconds. Exported 5% and imported less than 6% over this period.

House was in use during this, with computers pulling up to 400w and cooking. The spikes just before 5pm was due to rice cooker, it would pull constant power at the start and then do less than 10s spikes, so the delay in the adjustment automation filters that out.

Image
 
#5 ·
I’ve often wondered if this was possible. It isn’t cost effective to try and charge during the day even when sunny with our small 2.61kW solar install. Can this be adapted to work with other models? We have a Renault Zoe ((ZE50).
 
#7 ·
If your car supports ability to adjust charging current remotely, and HA has the integration to access it, then it will work.

But doesn't look like Renault has this capability (can you do this in the app?), at least nothing in Home Assistant docs: Renault

My only concern would be the amperage going low and any impact on the EV’s battery – I had read somewhere that one of the reasons the zappi waits to 6A to charge is that there is a concern lower amps would result in the car frequently starting and stopping charging with an unknown impact that would have
I think the concern is more on the in-car charger rather than the battery, and as said, frequent starting/stopping the charger. Slowly charging the battery should not have negative impact on its longevity.

As I understand, the reason for floor of 6 Amp is due to charging standards require a minimum of 6 amps of available power from the charge point, some cars can't work with lower current because it is out of spec. Tesla seems to have implemented lower current in its charger for running climate controls via external power.

In another words, charge point must provide minimum of 6 amps. Car can pull any amount up to allowed by charge point and cable, as long as its hardware can do it. I'm exploiting this to charge at very slow rate using excess solar.
 
#6 ·
Great hack - I have thought before that with the appearance of more and more used EV’s sub £6k that would be perfect for a second car for someone with solar, but the cost of solar EV chargers being so high, that a three pin charger that can connect to a CT clamp to re-direct solar excess would be a useful option

My only concern would be the amperage going low and any impact on the EV’s battery – I had read somewhere that one of the reasons the zappi waits to 6A to charge is that there is a concern lower amps would result in the car frequently starting and stopping charging with an unknown impact that would have – certainly with my 5kw panels some days I frequently see such behavior with excess export
 
#8 ·
Thanks for all this, I'm modding your script now to use the Harvi CT clamp, which reports negative figures when excess solar, so do you think the following will work? I do need to change the above to below on the conditions but it's got that far yet so step at a time currently!

It's not hit a high enough - yet to do anything when I run and look at the trace, been far too cloudy in Yorkshire!

Code:
alias: Tesla - Solar charging adjust
description: ""
trigger:
  - type: power
    platform: device
    device_id: 0cd73d80dcccdb69ed1f9e991ba95dbb
    entity_id: sensor.myenergi_harvi_1433157_power_ct_grid
    domain: sensor
    above: -100
    below: -4000
condition:
  - condition: or
    conditions:
      - condition: numeric_state
        entity_id: sensor.myenergi_harvi_1433157_grid_ct1
        below: -160
      - condition: numeric_state
        entity_id: sensor.myenergi_harvi_1433157_grid_ct1
        below: -150
  - condition: state
    entity_id: device_tracker.tesla_location
    state: home
  - condition: state
    entity_id: switch.y_charger
    state: "on"
  - condition: sun
    before: sunset
    after: sunrise
action:
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_harvi_1433157_grid_ct1
            above: 930
        sequence:
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_harvi_1433157_grid_ct1
            above: 690
        sequence:
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_harvi_1433157_grid_ct1
            above: 460
        sequence:
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_harvi_1433157_grid_ct1
            above: 140
        sequence:
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_harvi_1433157_grid_ct1
            above: 930
        sequence:
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_harvi_1433157_grid_ct1
            above: 690
        sequence:
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_harvi_1433157_grid_ct1
            above: 460
        sequence:
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_harvi_1433157_grid_ct1
            above: 140
        sequence:
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
    default:
      - stop: ""
  - service: script.turn_on
    data: {}
    target:
      entity_id: script.tesla_set_charge_amp
  - delay:
      hours: 0
      minutes: 0
      seconds: 18
      milliseconds: 0
mode: single
max_exceeded: silent
 
#9 ·
First, check logs for error/warnings, found in Settings -> System -> Logs.

What's the relationship between sensor.myenergi_harvi_1433157_power_ct_grid and sensor.myenergi_harvi_1433157_grid_ct1 ? You want power reading (in W or kW) from a fast updating source.

I'm not familiar with the newer device trigger platform, I have been sticking to older state or numeric state. For trigger you want this automation to trigger every time you receive any data from your import/export sensor. You can achieve this by triggering off your import/export sensor without any other parameter, so triggers everytime the sensor changes value.

You'll need to tweak conditions as I can see I've used device_tracker.tesla_location, which comes from TeslaMate MQTT, as opposed to from the direct Tesla integration. The entity name for the direct integration should be device_tracker.y_location_tracker. This is assuming you named your car "Y".

If you have a single sensor value that goes negative when exporting, positive when importing. The conditions should be below -ve OR above +ve. So it allows automation to run if either are higher.
Then in the actions, the conditions for increments should be same below -ve for export and above +ve for import.

Here is a shortened example as per my comments, written by hand so may have syntax error, taking out repeated increments/decrements for readability:
YAML:
alias: Tesla - Solar charging adjust
description: ""
trigger:
  - platform:state
    entity_id: sensor.myenergi_harvi_1433157_grid_ct1
condition:
  - condition: or
    conditions:
      - condition: numeric_state
        entity_id: sensor.myenergi_harvi_1433157_grid_ct1
        above: 160
      - condition: numeric_state
        entity_id: sensor.myenergi_harvi_1433157_grid_ct1
        below: -150
  - condition: state
    entity_id: device_tracker.y_location_tracker
    state: home
  - condition: state
    entity_id: switch.y_charger
    state: "on"
  - condition: sun
    before: sunset
    after: sunrise
action:
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_harvi_1433157_grid_ct1
            below: -140
        sequence:
          - service: input_number.increment
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
      - conditions:
          - condition: numeric_state
            entity_id: sensor.myenergi_harvi_1433157_grid_ct1
            above: 140
        sequence:
          - service: input_number.decrement
            data: {}
            target:
              entity_id: input_number.tesla_y_charge_amps
    default:
      - stop: ""
  - service: script.turn_on
    data: {}
    target:
      entity_id: script.tesla_set_charge_amp
  - delay:
      hours: 0
      minutes: 0
      seconds: 18
      milliseconds: 0
mode: single
max_exceeded: silent