Skip to content

Instantly share code, notes, and snippets.

@AMajland
Last active July 10, 2024 20:02
Show Gist options
  • Save AMajland/6ffc6814df2a92e99cff2c901447efee to your computer and use it in GitHub Desktop.
Save AMajland/6ffc6814df2a92e99cff2c901447efee to your computer and use it in GitHub Desktop.
# Automations.yaml
alias: PV to EV Dynamic
trigger:
- platform: time_pattern
seconds: /20
condition: []
action:
- choose:
- conditions:
- condition: state
entity_id: input_select.ev_test_charge
state: Solar 3 Phase
sequence:
- service: easee.set_circuit_dynamic_limit
data:
charger_id: CHARGERID
currentP1: >-
{% set min_voltage =
min(states('sensor.ams_cf58_u1'),states('sensor.ams_cf58_u2'),states('sensor.ams_cf58_u3'))
%} {% set current = ( ((states('sensor.pv_to_ev_power') | float)
) / (min_voltage | float ) / 3.0 + 0.5) %} {%if current < 6.0
%}{% set current = 6.0 %} {% endif %} {{ current }}
currentP2: >-
{% set min_voltage =
min(states('sensor.ams_cf58_u1'),states('sensor.ams_cf58_u2'),states('sensor.ams_cf58_u3'))
%} {% set current = ( ((states('sensor.pv_to_ev_power') | float)
) / (min_voltage | float ) / 3.0 + 0.5) %} {%if current < 6.0
%}{% set current = 6.0 %} {% endif %} {{ current }}
currentP3: >-
{% set min_voltage =
min(states('sensor.ams_cf58_u1'),states('sensor.ams_cf58_u2'),states('sensor.ams_cf58_u3'))
%} {% set current = ( ((states('sensor.pv_to_ev_power') | float)
) / (min_voltage | float ) / 3.0 + 0.5) %} {%if current < 6.0
%}{% set current = 6.0 %} {% endif %} {{ current }}
time_to_live: "1"
- conditions:
- condition: state
entity_id: input_select.ev_test_charge
state: Solar 1 Phase
sequence:
- service: easee.set_circuit_dynamic_limit
data:
charger_id: CHARGERID
currentP1: >-
{% set current = ( ((states('sensor.pv_to_ev_power') | float) ) / (states('sensor.ams_cf58_u1') | float) ) + 1.4 %}
{%if current > 16.0 %}{% set current = 16.0 %}
{% endif %}
{{ current }}
currentP2: "0"
currentP3: "0"
time_to_live: "1"
mode: single
alias: PV to EV Phases
description: >-
Change 1 to 3 phases - check every 1 min. 10min min for 10min to change to 3.
Avererage below for 10min to go back
trigger:
- platform: time_pattern
minutes: /1
condition:
- condition: not
conditions:
- condition: template
value_template: "{{ states('sensor.CHARGERID_status') == 'disconnected' }}"
action:
- choose:
- conditions:
- condition: state
entity_id: input_select.ev_test_charge
state: Scheduled
sequence:
- service: easee.set_circuit_dynamic_limit
data:
charger_id: CHARGERID
currentP1: "32"
currentP2: "32"
currentP3: "32"
time_to_live: "15"
- conditions:
- condition: state
entity_id: input_select.ev_test_charge
state: Solar 1 Phase
for:
hours: 0
minutes: 10
seconds: 0
- condition: numeric_state
entity_id: sensor.pv_to_ev_power_10m_min
above: 3680
sequence:
- service: input_select.select_option
target:
entity_id: input_select.ev_test_charge
data:
option: Solar 3 Phase
- conditions:
- condition: state
entity_id: input_select.ev_test_charge
state: Solar 3 Phase
for:
hours: 0
minutes: 10
seconds: 0
- condition: numeric_state
entity_id: sensor.pv_to_ev_power_10_min_avg
below: 3680
sequence:
- service: input_select.select_option
target:
entity_id: input_select.ev_test_charge
data:
option: Solar 1 Phase
mode: single
#configuration.yaml
sensor:
- platform: statistics
name: PV to EV Power (10m min)
unique_id: sensor.pv_to_ev_power_10m_min
entity_id: sensor.pv_to_ev_power
state_characteristic: value_min
max_age:
minutes: 10
- platform: statistics
name: PV to EV Power (10 min avg)
unique_id: sensor.pv_to_ev_power_10m_avg
entity_id: sensor.pv_to_ev_power
state_characteristic: average_linear
max_age:
minutes: 10
- platform: statistics
name: PV to EV Power (2 min avg)
unique_id: sensor.pv_to_ev_power_2m_avg
entity_id: sensor.pv_to_ev_power
state_characteristic: average_linear
max_age:
minutes: 2
- platform: statistics
name: N1 Meter Power Netto (10 min avg)
unique_id: sensor.n1_meter_power_netto_avg
entity_id: sensor.n1_meter_power_netto
state_characteristic: average_linear
max_age:
minutes: 10
template:
- sensor:
- name: "PV to EV Power"
unique_id: sensor.pv_to_ev_power
unit_of_measurement: W
device_class: power
state: >
{% set surplus = (0.001 + ((states("sensor.CHARGERID_power") | float(0)) - (states("sensor.n1_meter_power_netto") | float(0))) | round(0) ) %}
{% if surplus < 0.0 %}{% set surplus = 0.0 %}
{% endif %}
{{ surplus }}
@AMajland
Copy link
Author

AMajland commented May 1, 2023

Input_select ev_test_charge configured in the GUI

image

@Thomsen-79
Copy link

When inserting line 1-114 in automations.yaml i get this error
image

@AMajland
Copy link
Author

AMajland commented May 6, 2023

Looks like an indentation error

- id: '1682064034424'
  alias: PV to EV Dynamic <<<with two spaces to the left

@Thomsen-79
Copy link

Just made a copy/paste of what you have

@HolgerMiara
Copy link

Hej Anders!
I like your code very much -- especially the delayed and more persistant switch between one- and three-phased charging. I am running something similar, but will most likely adopt some of your code. One little difference is e.g. that I am using a lowpass filter instead of averaging the power production and power export, which performs slightly better in view of spikes (e.g. when switching larger consumers on or off in your home).

  • But I wanted to ask whether you have a battery connected to your installation and how the code performs with that. I am not satisfied yet with the performance of my (similar) code.
  • Further, Easee write that their Equalizer only changes the current setting every 10 minutes to prevent wear on the electronics. And I see that another product (the Wattpilot from Fronius, rf. https://manuals.fronius.com/html/4204260400/en.html#0_m_0000024035) only changes the power every 5 minutes with the same argument. However, your script pushes a new value every 20 seconds. What's your view on this? (No offense, I have honestly no idea myself).
    I look forward to your reply!! And -- by the way -- if you have any updates to your code, I would be interested as well =) Cheers,
    Holger.

@AMajland
Copy link
Author

AMajland commented Aug 9, 2023

Thankyou for your interest.

Yes lowpass filtering might be better than averaging to remove spikes - but the changes i have are real and so not really spikes but fast changing available current. I'm also using the 10 minutes minimum for switching i,e the low spike get me back to 1 phase . In the end the different filtering depends on whether you would balance between selling to much or buying to much. My main issue is not spikes in consumption but spikes in production whenever a cloud passes. With the above automation the excess buying/selling is about evened out (but i'm also runding up the current send to the car to move the average a bit)

When you change the charge current in the easee app it will be stored in the flash memory of the charger. But when you change it with the set_circuit_dynamic_limitlike i do every 20s iin "PV to EV Dynamic" it is not stored so does not cause any wear.

On the other hand the relay switches that is making the easee home a smart charger does wear when used. So i have limited the change between 1 and 3 phases to every 10minutes just like easee does themselves (in "PV to EV Phases"). It also takes my car "some" time to change. Can't remember the "hole" in reported current but HA only updates every 10s. But it is easy to see that first charging is stopped, then the relais switched arround and charging started again

In Denmark you are not allowed to have single phase consumer of more than 16A - otherwise it would make more sense to charge on one phase up to 32A (my skoda Enyaq support that)

In may and june almost all my ev charging was straight from the sun and including july between 45-50% of soloar production was used directly

@Bjarke88
Copy link

Bjarke88 commented Sep 15, 2023

for a noob can you highlight what fields i should change to my own values?
and my energy meter only has one output for excess power can that work with this?

@Bjarke88
Copy link

Bjarke88 commented Sep 18, 2023

what value is expected here: input_select.ev_test_charge ?

what type of sensor is this: sensor.eheexpyg_status?

@AMajland
Copy link
Author

That is the helper i use to shift between charging according to the easee own schedule or 1 / 3 phase solar charging.

Se comment above from May 1

@Bjarke88
Copy link

That is the helper i use to shift between charging according to the easee own schedule or 1 / 3 phase solar charging.

Se comment above from May 1

ok thanks but what with this: sensor.eheexpyg_status ?

@AMajland
Copy link
Author

@Bjarke88 to create a helper variable go to settings, Helpers and create helper.

The EV Charge mode is a drowdown where you (or an automation) can select one of the possibilities.

The sensor.eheexpyg_status is the status of my primary charger that i use for solar charging . Just replace the seriel number parts with yours.. If you go to developer tools, states and search for "config_ledStripBrightness" under attributes you will probably only have one entity that matches

@Bjarke88
Copy link

Thanks

can you give a hint to how you create this part:
image

@AMajland
Copy link
Author

Settings, Devices and services, Helpers

and create helper

The type is a dropdown with the 3 options

@Bjarke88
Copy link

service: easee.set_circuit_dynamic_limit
data:
charger_id: CHARGERID
currentP1: >-
{% set current = ( ((states('sensor.askeengen_146_power') | float) ) /
(states('sensor.watts_live_11d1042220001670_voltage_l1') | float) ) + 1.4
%} {%if current > 16.0 %}{% set current = 16.0 %} {% endif %} {{ current
}}
currentP2: "0"
currentP3: "0"
time_to_live: "1"

what sensor is you expecting to be here: sensor.watts_live_11d1042220001670_voltage_l1

@Bjarke88
Copy link

what sensor is this: sensor.pv_to_ev_power

@AMajland
Copy link
Author

See above from line 150. That is just a helper to calculate available power.
It looks at currente charge rate and the export and a bit of rounding.
If you are charging with 6kW and exporting 4kW you have 10kW available for charging.

The reason i've done it that way is that it was easy to add statistics sensors that looks at 2 and 10 min averages as welle as minimum.

I use those to decide when its time to change between 1 and 3 phase charging. In the above i will first change to 3 fase when the minum surplus has been over 3680W for 10 minutes. The other way it will first drop down to 1 phase again when the average has been below 3680W for 10minutes.

So on a day with many clous the min drop often and it will stay on one phase charging..

On a good sunny day it will stay on 3 phase even troug i use a lot of power for a short while for i.e a cup of coffe (if its get below 6A it will pause for a while)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment