Tesla Charging, Fully Offgrid, Maximize Solar Charging

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

My first attempt at SHARING my automations instead of downloading everyone else’s work. Hope this help those at least start who want to refine or update.


A fully off-grid Tesla Charging Automation designed to maximize charging with excess solar power.

Requirements: Tessie or another 3rd party plugin giving access to your tesla.

This Home Assistant blueprint allows you to adjust the charging current for your Tesla based on battery state of charge (SOC), comparison of PV and AC loads, and predefined maximum current limits based on SOC. The blueprint is designed to be highly configurable, allowing users to select their entities, thresholds, and battery levels. The automation relies on looking at your AC loads and PV Watts to determine an effective charging rate and whether to increase, decrease or leave it the same.

Since HA won’t toggle an entity that is already in that state, this relies on that to minimize API calls to your Tesla if the charger is ALREADY in the desired position (either on or off).

Features

  • Adjusts charging current based on battery SOC.
  • Considers PV and AC loads to dynamically change charging rates.
  • Sets maximum current limits based on SOC caps.
  • Turns off charging when the charge cable is not connected.

Inputs

  • Charge Cable Entity: The entity representing the charge cable status.
  • Battery SOC Sensor: The entity representing the battery state of charge.
  • VE.Bus Alarm: The entity representing the VE.Bus alarm status.
  • Charge Current Number: The entity representing the charge current.
  • Charge Switch: The switch to control charging.
  • PV Watts Sensor: The entity representing the PV watts.
  • AC Loads Sensor: The entity representing the AC loads.
  • Increase Threshold: The threshold for increasing the charging current (default: 0 W).
  • Maintain Threshold: The threshold for maintaining the charging current (default: 100 W).
  • Decrease Threshold: The threshold for decreasing the charging current (default: 200 W).
  • SOC Cap 95%: Maximum charging current for SOC below 95% (default: 1 A).
  • SOC Cap 97%: Maximum charging current for SOC between 95% and 97% (default: 2 A).
  • SOC Cap 99%: Maximum charging current for SOC between 97% and 99% (default: 5 A).
  • SOC Cap 100%: Maximum charging current for SOC above 99% (default: 10 A).

How It Works

  1. The blueprint triggers every minute to check the conditions.
  2. If the charge cable is not connected, the sequence stops.
  3. If the battery SOC is below 93%, the charging is turned off.
  4. If the VE.Bus alarm is in a WARNING state, the charging current is reduced by 2 A.
  5. If the charge current is unknown, it is set to 1 A, and charging is turned off.
  6. Based on the battery SOC, different charging current limits are set:
  • Below 95% SOC: Charging current is set to the SOC Cap 95% value.
  • Between 95% and 97% SOC: Charging current is dynamically adjusted within the SOC Cap 97% value.
  • Between 97% and 99% SOC: Charging current is dynamically adjusted within the SOC Cap 99% value.
  • Above 99% SOC: Charging current is dynamically adjusted within the SOC Cap 100% value.
  name: Tesla, Full Off-Grid, Maximize Solar Charging
  description: Adjust the charging current based on battery SOC, PV vs AC loads comparison.  Works with Tessie.
  domain: automation
  input:
    charge_cable:
      name: Charge Cable Entity
      description: The entity representing the charge cable status.
      selector:
        entity:
          domain: binary_sensor
    battery_soc:
      name: Battery SOC Sensor
      description: The entity representing the battery SOC.
      selector:
        entity:
          domain: sensor
    vebus_alarm:
      name: VE.Bus Alarm
      description: The entity representing the VE.Bus alarm.
      selector:
        entity:
          domain: sensor
    charge_current:
      name: Charge Current Number
      description: The entity representing the charge current.
      selector:
        entity:
          domain: number
    charge_switch:
      name: Charge Switch
      description: The switch to control charging.
      selector:
        entity:
          domain: switch
    pv_watts:
      name: PV Watts Sensor
      description: The entity representing the PV watts.
      selector:
        entity:
          domain: sensor
    ac_loads:
      name: AC Loads Sensor
      description: The entity representing the AC loads.
      selector:
        entity:
          domain: sensor
    increase_threshold:
      name: Increase Threshold
      description: The threshold for increasing the charging current.
      default: 0
      selector:
        number:
          min: 0
          max: 5000
          unit_of_measurement: W
    maintain_threshold:
      name: Maintain Threshold
      description: The threshold for maintaining the charging current.
      default: 100
      selector:
        number:
          min: 0
          max: 5000
          unit_of_measurement: W
    decrease_threshold:
      name: Decrease Threshold
      description: The threshold for decreasing the charging current.
      default: 200
      selector:
        number:
          min: 0
          max: 5000
          unit_of_measurement: W
    soc_cap_95:
      name: SOC Cap 95%
      description: Maximum charging current for SOC below 95%.
      default: 1
      selector:
        number:
          min: 1
          max: 48
          unit_of_measurement: A
    soc_cap_97:
      name: SOC Cap 97%
      description: Maximum charging current for SOC between 95% and 97%.
      default: 2
      selector:
        number:
          min: 1
          max: 48
          unit_of_measurement: A
    soc_cap_99:
      name: SOC Cap 99%
      description: Maximum charging current for SOC between 97% and 99%.
      default: 5
      selector:
        number:
          min: 1
          max: 48
          unit_of_measurement: A
    soc_cap_100:
      name: SOC Cap 100%
      description: Maximum charging current for SOC above 99%.
      default: 10
      selector:
        number:
          min: 1
          max: 48
          unit_of_measurement: A

trigger:
  - platform: time_pattern
    minutes: /1

condition: []

action:
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ is_state('binary_sensor.mystique_charge_cable', 'off') }}"
        sequence: []
      - conditions:
          - condition: numeric_state
            entity_id: !input battery_soc
            below: 93
        sequence: []
      - conditions:
          - condition: template
            value_template: "{{ is_state(states('!input vebus_alarm'), 'WARNING') }}"
        sequence:
          - service: number.set_value
            target:
              entity_id: !input charge_current
            data_template:
              value: >
                {% set current_charge = states('number.mystique_charge_current').split(' ')[0] | float %}
                {{ [1, current_charge - 2] | max }}
          - service: switch.turn_on
            target:
              entity_id: !input charge_switch
            data: {}
      - conditions:
          - condition: template
            value_template: "{{ is_state(states('!input charge_current'), 'unknown') }}"
        sequence:
          - service: number.set_value
            target:
              entity_id: !input charge_current
            data:
              value: 1
          - service: switch.turn_off
            target:
              entity_id: !input charge_switch
            data: {}
      - conditions:
          - condition: numeric_state
            entity_id: !input battery_soc
            below: 95
        sequence:
          - service: number.set_value
            target:
              entity_id: !input charge_current
            data:
              value: !input soc_cap_95
          - service: switch.turn_off
            target:
              entity_id: !input charge_switch
            data: {}
      - conditions:
          - condition: numeric_state
            entity_id: !input battery_soc
            above: 95
            below: 97
        sequence:
          - service: number.set_value
            target:
              entity_id: !input charge_current
            data_template:
              value: >
                {% set pv_watts = states('!input pv_watts') | float %}
                {% set ac_loads = states('!input ac_loads') | float %}
                {% set current_charge = states('number.mystique_charge_current').split(' ')[0] | float %}
                {% set proposed_current = current_charge %}

                {% if ac_loads + 150 < pv_watts + states('!input increase_threshold') %}
                  {% set proposed_current = current_charge + 1 %}
                {% elif ac_loads + 150 > pv_watts + states('!input decrease_threshold') %}
                  {% set proposed_current = current_charge - 1 %}
                {% else %}
                  {% set proposed_current = current_charge %}
                {% endif %}
                {{ [1, [proposed_current, states('!input soc_cap_97')] | min] | max }}
          - service: switch.turn_on
            target:
              entity_id: !input charge_switch
            data: {}
      - conditions:
          - condition: numeric_state
            entity_id: !input battery_soc
            above: 96
            below: 99
        sequence:
          - service: number.set_value
            target:
              entity_id: !input charge_current
            data_template:
              value: >
                {% set pv_watts = states('!input pv_watts') | float %}
                {% set ac_loads = states('!input ac_loads') | float %}
                {% set current_charge = states('number.mystique_charge_current').split(' ')[0] | float %}
                {% set proposed_current = current_charge %}

                {% if ac_loads + 150 < pv_watts + states('!input increase_threshold') %}
                  {% set proposed_current = current_charge + 1 %}
                {% elif ac_loads + 150 > pv_watts + states('!input decrease_threshold') %}
                  {% set proposed_current = current_charge - 1 %}
                {% else %}
                  {% set proposed_current = current_charge %}
                {% endif %}
                {{ [1, [proposed_current, states('!input soc_cap_99')] | min] | max }}
          - service: switch.turn_on
            target:
              entity_id: !input charge_switch
            data: {}
      - conditions:
          - condition: numeric_state
            entity_id: !input battery_soc
            above: 99
        sequence:
          - service: number.set_value
            target:
              entity_id: !input charge_current
            data_template:
              value: >
                {% set pv_watts = states('!input pv_watts') | float %}
                {% set ac_loads = states('!input ac_loads') | float %}
                {% set current_charge = states('number.mystique_charge_current').split(' ')[0] | float %}
                {% set proposed_current = current_charge %}

                {% if ac_loads + 150 < pv_watts + states('!input increase_threshold') %}
                  {% set proposed_current = current_charge + 1 %}
                {% elif ac_loads + 150 > pv_watts + states('!input decrease_threshold') %}
                  {% set proposed_current = current_charge - 1 %}
                {% else %}
                  {% set proposed_current = current_charge %}
                {% endif %}
                {{ [1, [proposed_current, states('!input soc_cap_100')] | min] | max }}
          - service: switch.turn_on
            target:
              entity_id: !input charge_switch
            data: {}
variables:
  increase_threshold: !input increase_threshold
  maintain_threshold: !input maintain_threshold
  decrease_threshold: !input decrease_threshold
  soc_cap_95: !input soc_cap_95
  soc_cap_97: !input soc_cap_97
  soc_cap_99: !input soc_cap_99
  soc_cap_100: !input soc_cap_100

2 Likes