EVSE Load Balancing EV Charging

Hi,

I’m new here, so I’m sorry for any mistakes I may have made. Anyway, I’m writing this to share my automation for load balancing my EVSE. This is because in my searches I failed to find what I wanted and I think others may have searched for the things I’m about to describe. The whole EVSE load balancing control is designed to support three modes given a PV system:

  • Manual Mode - the user controls the setting for the charging current and the vehicle charges at the specified rate regardless of the solar production power

  • Hybrid Mode - the automation controls the charging current based on the solar production, however a (dynamically configurable) level of power (instant energy) is allowed to be drawn from the grid.

  • Solar Mode - the automation controls the charging current based on the solar production and charges based on solar power excess. In addition if the minimum level of solar power excess is not meet the automation automatically stops the charging or if the minimum level is meet the automation automatically starts the charging.

Requirements:

  • a EVSE integration that exposes entities for starting and stopping the charging, controlling the charging current, has state sensor indicating (at least) if the charger has started or not, and a sensor for the power drawn by the EVSE (I’m using the Lektrico 1p7k, but you can use for example an Wallbox one).

  • a PV System or an independent Power Meter that exposes an entity for power import / export. In my case this an entity indicating positive W value for import and a negative W value for export.

  • You need to create a counter helper that has the minimum, maximum and step size exactly as your EVSE current control allows you to set. The automation will use this counter to increment/decrement and set the numeric state of the EVSE current control entity. In my case I the minimum current setting is 6A, the maximum setting is 32A and the step size is 1A. I also set the initial counter value to the minimum setting of 6A.

  • You need to create an Dropdown (input_select) helper for the charging modes and configure it to have 3 options: Manual, Hybrid and Solar. This will be used to switch between the 3 different charging modes.

  • You also need to create Number (input_number) helper and configure it to have minimum and maximum EVSE supported charging power. This will be used to dynamically configure the Hybrid Mode allowed grid drawn power. In my case, the EVSE minimum is 1.4 kW, while for the maximum I opted to go with half the EVSE capability, which is 3.6 kW. Also, in my case a step size of 0.25 seems to work the best and you may have to adjust it a little bit.

  • Also note that all these charging power levels are supported by my EV and you should take care not to exceed any of them.

The automation:

The automation can be improved in many ways, but it does the job great for me. To work for you need (at least) change the entities to the ones you have available in your HA (I think the easiest way here would be to create a new automation, paste in the yaml and then edit through the UI).

My Automation Entities:

  • sensor.1p7k_state - this is the state of my charger of which in the automation I use “Charging” (indicates that the charger is on), and “Connected,NeedAuth” (indicates that the charger is connected to the car but its stopped). (its exported by my charger integration)

  • number.1p7k_user_limit - this is the current in amps control for my charger which I can vary between 6A and 32A (its exported by my charger integration)

  • sensor.home_meter_total_active_power - this is the my house active power consumption which is negative when exporting power and positive when importing power (its exported by my meter integration)

  • button.1p7k_charge_start - this is a button through which I can command the charger to start charging (its exported by my charger integration)

  • button.1p7k_charge_stop - this is a button through which I can command the charger to stop charging (its exported by my charger integration)

  • input_select.1p7k_charging_mode - this is a drop down helper with 3 states Manual, Hybrid and Solar indicating in the modes that can be set for the charger (Hybrid and Solar are the ones controlled through the automation).

  • counter.1p7k_user_limit_auto_counter - this is a counter helper used to set the number.1p7k_user_limit as the number entities do not have increment and decrement service calls

  • input_number.1p7k_hybrid_charging_limit - this is the helper through which the hybrid mode dynamic limit is set. That is, when in hybrid mode through this I set the maximum power that can still be drawn from the grid if the PV doesn’t produce sufficient power.

First version:

- id: '1704386812345'
  alias: Your name for the automation goes here
  description: ''
  trigger:
  - platform: state
    entity_id:
    - sensor.1p7k_state # change this to your EVSE state sensor
    to: Charging # change this to the started state value of your EVSE
  - platform: state
    entity_id:
    - sensor.1p7k_state # change this to your EVSE state sensor
    to: Connected,NeedAuth # change this to the stopped state value of your EVSE
  - platform: state
    entity_id:
    - input_select.1p7k_charging_mode # change this to your Dropdown helper
    to: Solar
  - platform: state
    entity_id:
    - input_select.1p7k_charging_mode # change this to your Dropdown helper
    to: Hybrid
  - platform: state
    entity_id:
    - number.1p7k_user_limit # change this to your EVSE current configuration entity 
    enabled: false
  - platform: state
    entity_id:
    - input_number.1p7k_hybrid_charging_limit # change this to Number helper for the dynamic limit in hybrid mode
  condition:
  - condition: or
    conditions:
    - condition: state
      entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
      state: Hybrid
    - condition: state
      entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
      state: Solar
  - condition: or
    conditions:
    - condition: state
      entity_id: sensor.1p7k_state # change this to your EVSE state sensor
      state: Charging # change this to the started state value of your EVSE
    - condition: state
      entity_id: sensor.1p7k_state # change this to your EVSE state sensor
      state: Connected,NeedAuth # change this to the stopped state value of your EVSE
  action:
  - repeat:
      sequence:
      - choose:
        - conditions:
          - condition: state
            entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
            state: Solar
          - condition: state
            entity_id: sensor.1p7k_state # change this to your Dropdown helper
            state: Charging # change this to the started state value of your EVSE
            enabled: true
          - condition: numeric_state
            entity_id: number.1p7k_user_limit  # change this to your EVSE current configuration entity 
            above: 6
            below: 32
          - condition: numeric_state
            entity_id: counter.1p7k_user_limit_auto_counter # change this to the Counter helper
            above: 6
            below: 32
            enabled: false
          - condition: numeric_state
            entity_id: sensor.home_meter_total_active_power # change this to the entity indicating grid import or solar export of power
            below: -250 # you can play arround with this limit
            enabled: true
          sequence:
          - service: counter.increment
            target:
              entity_id:
              - counter.1p7k_user_limit_auto_counter # change this to the Counter helper
            data: {}
          - service: number.set_value
            metadata: {}
            data:
              value: '{{ states(''counter.1p7k_user_limit_auto_counter'') }}' # change this to the Counter helper
            target:
              entity_id: number.1p7k_user_limit # change this to your EVSE current configuration entity 
        - conditions:
          - condition: state
            entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
            state: Solar
          - condition: state
            entity_id: sensor.1p7k_state  # change this to your EVSE state sensor
            state: Charging # change this to the started state value of your EVSE
            enabled: true
          - condition: numeric_state
            entity_id: number.1p7k_user_limit # change this to your EVSE current configuration entity 
            above: 6
            below: 32
          - condition: numeric_state
            entity_id: counter.1p7k_user_limit_auto_counter # change this to the Counter helper
            above: 6
            below: 32
            enabled: false
          - condition: numeric_state
            entity_id: sensor.home_meter_total_active_power # change this to the entity indicating grid import or solar export of power
            above: 50
          sequence:
          - service: counter.decrement
            target:
              entity_id:
              - counter.1p7k_user_limit_auto_counter # change this to the Counter helper
            data: {}
          - service: number.set_value
            metadata: {}
            data:
              value: '{{ states(''counter.1p7k_user_limit_auto_counter'') }}' # change this to the Counter helper
            target:
              entity_id: number.1p7k_user_limit # change this to your EVSE current configuration entity 
        - conditions:
          - condition: state
            entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
            state: Hybrid
          - condition: state
            entity_id: sensor.1p7k_state # change this to your EVSE state sensor
            state: Charging # change this to the started state value of your EVSE
            enabled: true
          - condition: numeric_state
            entity_id: number.1p7k_user_limit # change this to your EVSE current configuration entity 
            above: 5
            below: 26
          - condition: numeric_state
            entity_id: counter.1p7k_user_limit_auto_counter # change this to the Counter helper
            above: 6
            below: 25
            enabled: false
          - condition: or
            conditions:
            - condition: numeric_state
              entity_id: sensor.home_meter_total_active_power # change this to the entity indicating grid import or solar export of power
              below: -250
              enabled: true
            - condition: template
              value_template: '{{ (states(''sensor.1p7k_power'')|float | float) <
                (states(''input_number.1p7k_hybrid_charging_limit'')| float - 0.2|float)}}' # replace the entities accordingly
          sequence:
          - service: counter.increment
            target:
              entity_id:
              - counter.1p7k_user_limit_auto_counter # change this to the Counter helper
            data: {}
          - service: number.set_value
            metadata: {}
            data:
              value: '{{ states(''counter.1p7k_user_limit_auto_counter'') }}' # change this to the Counter helper
            target:
              entity_id: number.1p7k_user_limit # change this to your EVSE current configuration entity 
        - conditions:
          - condition: state
            entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
            state: Hybrid
          - condition: state
            entity_id: sensor.1p7k_state # change this to your EVSE state sensor
            state: Charging # change this to the started state value of your EVSE
            enabled: true
          - condition: numeric_state
            entity_id: number.1p7k_user_limit # change this to your EVSE current configuration entity 
            above: 5
            below: 26
          - condition: numeric_state
            entity_id: counter.1p7k_user_limit_auto_counter # change this to the Counter helper
            above: 6
            below: 25
            enabled: false
          - condition: numeric_state
            entity_id: sensor.home_meter_total_active_power # change this to the entity indicating grid import or solar export of power
            above: 50
          - condition: template
            value_template: '{{ (states(''sensor.1p7k_power'')|float|float) > (states(''input_number.1p7k_hybrid_charging_limit'')|float
              + 0.1 |float) }}' # replace the entities accordingly
          sequence:
          - service: counter.decrement
            target:
              entity_id:
              - counter.1p7k_user_limit_auto_counter # change this to the Counter helper
            data: {}
          - service: number.set_value
            metadata: {}
            data:
              value: '{{ states(''counter.1p7k_user_limit_auto_counter'') }}' # change this to the Counter helper
            target:
              entity_id: number.1p7k_user_limit # change this to your EVSE current configuration entity 
        - conditions:
          - condition: state
            entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
            state: Hybrid
          - condition: state
            entity_id: sensor.1p7k_state # change this to your EVSE state sensor
            state: Connected,NeedAuth # change this to the stopped state value of your EVSE
          sequence:
          - service: counter.reset
            metadata: {}
            data: {}
            target:
              entity_id: counter.1p7k_user_limit_auto_counter # change this to the Counter helper
          - service: number.set_value
            metadata: {}
            data:
              value: '{{ states(''counter.1p7k_user_limit_auto_counter'') }}' # change this to the Counter helper
            target:
              entity_id: number.1p7k_user_limit # change this to your EVSE current configuration entity 
          - service: button.press
            metadata: {}
            data: {}
            target:
              entity_id: button.1p7k_charge_start # change this to your EVSE state sensor
          - delay:
              hours: 0
              minutes: 0
              seconds: 30
              milliseconds: 0
        - conditions:
          - condition: state
            entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
            state: Solar
          - condition: state
            entity_id: sensor.1p7k_state # change this to your EVSE state sensor
            state: Connected,NeedAuth # change this to the stopped state value of your EVSE
          - condition: numeric_state
            entity_id: sensor.home_meter_total_active_power # change this to the entity indicating grid import or solar export of power
            below: -1400
          sequence:
          - service: counter.reset
            metadata: {}
            data: {}
            target:
              entity_id: counter.1p7k_user_limit_auto_counter # change this to the Counter helper
          - service: number.set_value
            metadata: {}
            data:
              value: '{{ states(''counter.1p7k_user_limit_auto_counter'') }}' # change this to the Counter helper
            target:
              entity_id: number.1p7k_user_limit # change this to your EVSE current configuration entity 
          - service: button.press
            metadata: {}
            data: {}
            target:
              entity_id: button.1p7k_charge_start # replace this with your entity to start the EVSE charging
          - delay:
              hours: 0
              minutes: 0
              seconds: 30
              milliseconds: 0
        - conditions:
          - condition: state
            entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
            state: Solar
          - condition: state
            entity_id: sensor.1p7k_state # change this to your EVSE state sensor
            state: Charging # change this to the started state value of your EVSE
          - condition: numeric_state
            entity_id: sensor.home_meter_total_active_power # change this to the entity indicating grid import or solar export of power
            above: 300
          sequence:
          - service: counter.reset
            metadata: {}
            data: {}
            target:
              entity_id: counter.1p7k_user_limit_auto_counter # change this to the Counter helper
          - service: number.set_value
            metadata: {}
            data:
              value: '{{ states(''counter.1p7k_user_limit_auto_counter'') }}' # change this to the Counter helper
            target:
              entity_id: number.1p7k_user_limit # change this to your EVSE current configuration entity 
          - service: button.press
            metadata: {}
            data: {}
            target:
              entity_id: button.1p7k_charge_stop # replace this with the entity to stop the EVSE charging
      - delay:
          hours: 0
          minutes: 0
          seconds: 10
          milliseconds: 0
      while:
      - condition: or
        conditions:
        - condition: state
          entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
          state: Hybrid
        - condition: state
          entity_id: input_select.1p7k_charging_mode # change this to your Dropdown helper
          state: Solar
      - condition: or
        conditions:
        - condition: state
          entity_id: sensor.1p7k_state # change this to your EVSE state sensor
          state: Charging # change this to the started state value of your EVSE
        - condition: state
          entity_id: sensor.1p7k_state # change this to your EVSE state sensor
          state: Connected,NeedAuth # change this to the stopped state value of your EVSE
    enabled: true
  mode: single

Update (tweaked version):

alias: 1P7K Charging Hybrid Solar Control
description: Controls the Hybrid and Solar Modes of the 1P7K EVSE
trigger:
  - platform: state
    entity_id:
      - sensor.1p7k_state
    to: Charging
  - platform: state
    entity_id:
      - sensor.1p7k_state
    to: Connected,NeedAuth
  - platform: state
    entity_id:
      - input_select.1p7k_charging_mode
    to: Solar
  - platform: state
    entity_id:
      - input_select.1p7k_charging_mode
    to: Hybrid
  - platform: state
    entity_id:
      - number.1p7k_user_limit
    enabled: false
  - platform: state
    entity_id:
      - input_number.1p7k_hybrid_charging_limit
  - platform: state
    entity_id:
      - sensor.inverter_active_power
condition:
  - condition: or
    conditions:
      - condition: state
        entity_id: input_select.1p7k_charging_mode
        state: Hybrid
      - condition: state
        entity_id: input_select.1p7k_charging_mode
        state: Solar
  - condition: or
    conditions:
      - condition: state
        entity_id: sensor.1p7k_state
        state: Charging
      - condition: state
        entity_id: sensor.1p7k_state
        state: Connected,NeedAuth
action:
  - repeat:
      sequence:
        - choose:
            - conditions:
                - condition: state
                  entity_id: input_select.1p7k_charging_mode
                  state: Solar
                - condition: state
                  entity_id: sensor.1p7k_state
                  state: Charging
                  enabled: true
                - condition: numeric_state
                  entity_id: number.1p7k_user_limit
                  above: 5
                  below: 25
                - condition: numeric_state
                  entity_id: counter.1p7k_user_limit_auto_counter
                  above: 6
                  below: 25
                  enabled: false
                - condition: numeric_state
                  entity_id: sensor.home_meter_total_active_power
                  below: -250
                  enabled: true
              sequence:
                - service: counter.increment
                  target:
                    entity_id:
                      - counter.1p7k_user_limit_auto_counter
                  data: {}
                - service: number.set_value
                  metadata: {}
                  data:
                    value: "{{ states('counter.1p7k_user_limit_auto_counter') }}"
                  target:
                    entity_id: number.1p7k_user_limit
            - conditions:
                - condition: state
                  entity_id: input_select.1p7k_charging_mode
                  state: Solar
                - condition: state
                  entity_id: sensor.1p7k_state
                  state: Charging
                  enabled: true
                - condition: numeric_state
                  entity_id: number.1p7k_user_limit
                  above: 6
                  below: 26
                - condition: numeric_state
                  entity_id: counter.1p7k_user_limit_auto_counter
                  above: 6
                  below: 25
                  enabled: false
                - condition: numeric_state
                  entity_id: sensor.home_meter_total_active_power
                  above: 50
              sequence:
                - service: counter.decrement
                  target:
                    entity_id:
                      - counter.1p7k_user_limit_auto_counter
                  data: {}
                - service: number.set_value
                  metadata: {}
                  data:
                    value: "{{ states('counter.1p7k_user_limit_auto_counter') }}"
                  target:
                    entity_id: number.1p7k_user_limit
            - conditions:
                - condition: state
                  entity_id: input_select.1p7k_charging_mode
                  state: Hybrid
                - condition: state
                  entity_id: sensor.1p7k_state
                  state: Charging
                  enabled: true
                - condition: numeric_state
                  entity_id: number.1p7k_user_limit
                  above: 5
                  below: 25
                - condition: numeric_state
                  entity_id: counter.1p7k_user_limit_auto_counter
                  above: 6
                  below: 25
                  enabled: false
                - condition: or
                  conditions:
                    - condition: numeric_state
                      entity_id: sensor.home_meter_total_active_power
                      below: -250
                      enabled: true
                    - condition: template
                      value_template: >-
                        {{ (states('sensor.1p7k_power')|float | float) <
                        (states('input_number.1p7k_hybrid_charging_limit')|
                        float - 0.2|float)}}
              sequence:
                - service: counter.increment
                  target:
                    entity_id:
                      - counter.1p7k_user_limit_auto_counter
                  data: {}
                - service: number.set_value
                  metadata: {}
                  data:
                    value: "{{ states('counter.1p7k_user_limit_auto_counter') }}"
                  target:
                    entity_id: number.1p7k_user_limit
            - conditions:
                - condition: state
                  entity_id: input_select.1p7k_charging_mode
                  state: Hybrid
                - condition: state
                  entity_id: sensor.1p7k_state
                  state: Charging
                  enabled: true
                - condition: numeric_state
                  entity_id: number.1p7k_user_limit
                  above: 6
                  below: 26
                - condition: numeric_state
                  entity_id: counter.1p7k_user_limit_auto_counter
                  above: 6
                  below: 25
                  enabled: false
                - condition: numeric_state
                  entity_id: sensor.home_meter_total_active_power
                  above: 50
                - condition: template
                  value_template: >-
                    {{ (states('sensor.1p7k_power')|float|float) >
                    (states('input_number.1p7k_hybrid_charging_limit')|float +
                    0.1 |float) }}
              sequence:
                - service: counter.decrement
                  target:
                    entity_id:
                      - counter.1p7k_user_limit_auto_counter
                  data: {}
                - service: number.set_value
                  metadata: {}
                  data:
                    value: "{{ states('counter.1p7k_user_limit_auto_counter') }}"
                  target:
                    entity_id: number.1p7k_user_limit
            - conditions:
                - condition: state
                  entity_id: input_select.1p7k_charging_mode
                  state: Hybrid
                - condition: state
                  entity_id: sensor.1p7k_state
                  state: Connected,NeedAuth
              sequence:
                - service: counter.reset
                  metadata: {}
                  data: {}
                  target:
                    entity_id: counter.1p7k_user_limit_auto_counter
                - service: number.set_value
                  metadata: {}
                  data:
                    value: "{{ states('counter.1p7k_user_limit_auto_counter') }}"
                  target:
                    entity_id: number.1p7k_user_limit
                - service: button.press
                  metadata: {}
                  data: {}
                  target:
                    entity_id: button.1p7k_charge_start
                - delay:
                    hours: 0
                    minutes: 0
                    seconds: 30
                    milliseconds: 0
            - conditions:
                - condition: state
                  entity_id: input_select.1p7k_charging_mode
                  state: Solar
                - condition: state
                  entity_id: sensor.1p7k_state
                  state: Connected,NeedAuth
                - condition: numeric_state
                  entity_id: sensor.home_meter_total_active_power
                  below: -1400
              sequence:
                - service: counter.reset
                  metadata: {}
                  data: {}
                  target:
                    entity_id: counter.1p7k_user_limit_auto_counter
                - service: number.set_value
                  metadata: {}
                  data:
                    value: "{{ states('counter.1p7k_user_limit_auto_counter') }}"
                  target:
                    entity_id: number.1p7k_user_limit
                - service: button.press
                  metadata: {}
                  data: {}
                  target:
                    entity_id: button.1p7k_charge_start
                - delay:
                    hours: 0
                    minutes: 0
                    seconds: 30
                    milliseconds: 0
            - conditions:
                - condition: state
                  entity_id: input_select.1p7k_charging_mode
                  state: Solar
                - condition: state
                  entity_id: sensor.1p7k_state
                  state: Charging
                - condition: numeric_state
                  entity_id: sensor.home_meter_total_active_power
                  above: 500
                - condition: state
                  entity_id: number.1p7k_user_limit
                  state: "6"
              sequence:
                - service: counter.reset
                  metadata: {}
                  data: {}
                  target:
                    entity_id: counter.1p7k_user_limit_auto_counter
                - service: number.set_value
                  metadata: {}
                  data:
                    value: "{{ states('counter.1p7k_user_limit_auto_counter') }}"
                  target:
                    entity_id: number.1p7k_user_limit
                - service: button.press
                  metadata: {}
                  data: {}
                  target:
                    entity_id: button.1p7k_charge_stop
        - delay:
            hours: 0
            minutes: 0
            seconds: 10
            milliseconds: 0
      while:
        - condition: or
          conditions:
            - condition: state
              entity_id: input_select.1p7k_charging_mode
              state: Hybrid
            - condition: state
              entity_id: input_select.1p7k_charging_mode
              state: Solar
        - condition: or
          conditions:
            - condition: state
              entity_id: sensor.1p7k_state
              state: Charging
            - condition: state
              entity_id: sensor.1p7k_state
              state: Connected,NeedAuth
    enabled: true
mode: single

After the automation is configured to your liking you can use your favorite UI cards to import the Dropdown entity and Number entity for the dynamic limit.

1 Like

Can you update your Requirements section with the name of the sensor/input/dropdown that matches what you are using in your automation?

See above “My Automation Entities”, also added my tweaked version that I’ve been testing for the last month.

Hi @ndan

I try to implement your logic.

I miss the description of entity sensor.1p7k_power

I use a Wallbox charger, so I need to tweak the entities.

Thanks,
Rien

Hi,

The 1p7k_power is the entity that indicates the power (instant energy) that the charger currently draws. For me, its extorted by the EVSE integration, can also be replaced by a power meter entity (i.e. a meter on the power lines for the EVSE).

Hope this helps,
Dan.

1 Like