Het is nogal een verhaal geworden maar daar gaan we...
Ik was begonnen met aansturen van mijn smarEvse via EVCC maar heb liever dat de Evse zelf de solar en smart mode doet. Sneller en direct contact met mijn slimmelezer. Maar hoe dit te regelen via Home Assistant?
Het doel is om een modus te hebben waarbij
- de auto 's-ochtends om 06:00 vol is
- zo veel mogelijk zonnestroom wordt gebruikt
- eventueel tekort na zon wordt aangevuld op de goedkoopste uren
- aansturing zo veel mogelijk via de Evse
- laadplan wordt berekend door de EV smart charge integratie
- solar en smart mode blijven behouden als optie
Nu ik er uit ben neem ik jullie even mee in mijn oplossing. Misschien heeft iemand er wat aan.
Stap 1. Zorg dat de smartEvse scrollt tussen 3 modi.
voor de nieuwe modus wordt de off mode gebruikt omdat deze niet meteen gaat laden. met de volgende code gaat de Evse met de meegeleverde knop tussen 3 modi scrollen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| alias: "SmartEVSE: Schakelen + Kleuren"
description: Schakelen tussen 3 modi (Off, Smart, Solar) met dynamische kleur aanpassing
triggers:
- entity_id: select.smartevse_custombutton_2
trigger: state
actions:
- variables:
next_mode: >
{% set current = states('select.smartevse_mode_2') %} {% if current ==
'Off' %}
Smart
{% elif current == 'Smart' %}
Solar
{% else %}
Off
{% endif %}
target_color: |
{% if next_mode == 'Smart' %}
{{ states('text.smartevse_ledcolorsmart_2') }}
{% elif next_mode == 'Solar' %}
{{ states('text.smartevse_ledcolorsolar_2') }}
{% else %}
{# Gebruik de kleur van 'Normal' als indicator voor 'Off' of stel een eigen kleur in #}
{{ states('text.smartevse_ledcolornormal_2') }}
{% endif %}
- target:
entity_id: select.smartevse_mode_2
data:
option: "{{ next_mode }}"
action: select.select_option
- target:
entity_id: text.smartevse_ledcolorcustom_2
data:
value: "{{ target_color }}"
action: text.set_value
mode: restart |
stap 2 Bereken hoeveel solar beschikbaar is.
solar forecast geeft in HA aan hoe veel zonnestroom er nog wordt verwacht vandaag. Een deel daarvan wordt door het huis gebruikt dus niet alles is beschikbaar voor de auto. Op basis van de afgelopen twee weken wordt uitgerekend welk percentage naar verwachting de auto in kan:
code:
1
2
3
4
5
6
7
8
9
10
| {% set opwek = states('sensor.opwek_14_dagen_totaal') | float(0) %}
{% set terug = states('sensor.gecorrigeerde_teruglevering_14_dagen_totaal') | float(0) %}
{% if opwek > 10 %}
{# Wat we NIET hebben teruggeleverd is ons eigen verbruik #}
{{ (((opwek - terug) / opwek) * 100) | round(0) }}
{% else %}
{# Fallback voor winter/nacht #}
80
{% endif %} |
3. bereken hoeveel kWh er nog in de auto moet
Op basis van de accucapaciteit, huidige SOC (state of charge) en de gewenste SOC wordt uitgerekend hoe veel kWh er nog in de auto moet.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
| {% set capaciteit = 64 %}
{% set efficiëntie_factor = 1.15 %} {# Voegt 15% extra toe voor laadverliezen #}
{% set soc = states('sensor.kona_ev_battery_level') | float(0) %}
{% set limit = states('number.kona_ac_charging_limit') | float(100) %}
{% set resterend_percentage = limit - soc %}
{# Berekening: (Capaciteit * percentage) * 1.15 voor laadverlies #}
{% if resterend_percentage > 0 %}
{{ (capaciteit * (resterend_percentage / 100) * efficiëntie_factor) | round(2) }}
{% else %}
0
{% endif %} |
4. maak een laadplan met EV smart charging
Op basis de beschikbare zonnestroom en hoeveel kWh nog in de auto moet kunnen we uitrekenen hoe veel er nog moet worgen bijgeladen uit het net. De volgende helper rekent op basis daarvan een Dynamic Target SOC uit voor ev smart charger. Een doel voor de integratie om tot een laadplan te komen. Is er meer zonnestroom dan laadbehoefte, dan is het doel gelijk aan de laadstatus van de auto. Is er geen zonnestroom dan is het doel gelijk aan de gewenste SOC bij vertrek. Alles tussenin wordt berekend.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| {% set echt_doel = states('number.kona_ac_charging_limit') | float(100) %}
{% set capaciteit = 64 %}
{% set solar_kwh = states('sensor.energy_production_today_remaining') | float(0) %}
{# 1. Haal je schuifbalk op (bijv. 100 voor 'alles naar huis') #}
{% set eigen_verbruik_input = states('input_number.eigen_verbruik_solar') | float(0) %}
{# 2. Bereken wat er OVERBLIJFT voor de auto (bij 100% huis blijft er 0% over) #}
{% set factor_voor_auto = (100 - eigen_verbruik_input) / 100 %}
{# 3. Reken uit hoeveel % de auto nog van de zon krijgt #}
{% set shadow_soc_solar = ((solar_kwh * factor_voor_auto) / capaciteit) * 100 %}
{# 4. Het doel voor de stekker #}
{% set berekening = echt_doel - shadow_soc_solar %}
{# 5. Output: pakt de laagste waarde tussen de berekening en de limiet, afgerond #}
{{ ([berekening, echt_doel] | min) | round(0) }} |
Omdat niet kan worden gerekend met de prijzen van morgen als die nog niet beschikbaar zijn wordt de doeltijd met een automation aangepast naar 00:00 uur. Zodra prijzen beschikbaar zijn wordt de doeltijd aangepast aan 6:00 uur.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| alias: "smartEVSE: Tijdstip vol (Check morgen)"
description: "Zet doeltijd op 06:00 zodra prijzen voor MORGEN binnen zijn, anders 00:00"
triggers:
- entity_id: sensor.zonneplan_current_electricity_tariff
trigger: state
- entity_id: sensor.smartevse_evplugstate_2
to: Connected
trigger: state
- at: "06:00:00" # Reset moment naar de dag-modus
trigger: time
actions:
- action: select.select_option
target:
entity_id: select.ev_smart_charging_charge_completion_time
data:
option: >
{% set forecast = state_attr('sensor.zonneplan_current_electricity_tariff', 'forecast') %}
{% set morgen = (now() + timedelta(days=1)).strftime('%Y-%m-%d') %}
{# Check of de forecast bestaat en of er prijzen in staan voor de datum van morgen #}
{% if forecast is not none and forecast | selectattr('datetime', 'search', morgen) | list | length > 0 %}
06:00
{% else %}
00:00
{% endif %}
mode: restart |
het laadplan wordt vervolgens met de tijden weergegeven in een grafiek:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
| type: custom:apexcharts-card
header:
show: false
title: Laadplan solar+
show_states: false
graph_span: 24h
span:
start: hour
offset: "-2h"
now:
show: true
label: Nu
apex_config:
chart:
height: 215px
legend:
show: false
tooltip:
shared: true
marker:
show: false
x:
show: false
"y":
formatter: |
EVAL:function (val) {
return val.toFixed(2);
}
title:
formatter: |
EVAL:function() { return ''; }
yaxis:
labels:
formatter: |
EVAL:function (val) {
return val.toFixed(2);
}
xaxis:
tooltip:
enabled: false
labels:
datetimeFormatter:
hour: HH:mm
day: HH:mm
month: HH:mm
year: HH:mm
series:
- entity: sensor.zonneplan_current_electricity_tariff
name: Stroomprijs
type: area
curve: stepline
opacity: 0.3
unit: " €/kWh"
stroke_width: 2
data_generator: |
return entity.attributes.forecast.map((entry) => {
return [new Date(entry.datetime).getTime(), entry.electricity_price / 10000000];
});
- entity: sensor.ev_smart_charging_charging
name: Solar+
type: area
color: var(--primary-color)
curve: stepline
stroke_width: 2
opacity: 0.4
data_generator: |
return entity.attributes.charging_schedule.map((entry) => {
return [new Date(entry.start).getTime(), entry.value > 0 ? 0.3 : 0];
});
show:
in_header: false |
5. gebruik het laadplan
Ok, maar hoe nu het laadplan in te zetten terwijll de smartEvse in off staat? Ik gebruik 4 automatiseringen en een boolean. input_boolean.smartevse_departure_mode houdt bij of is ingeplugd in de "departure mode"
dus, Evse in off en de stekker gaat er in: boolean aan, kijk naar het laadplan en zet de evse op solar of smart.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| alias: "SmartEVSE: Start Automatische Sessie"
description: ""
triggers:
- entity_id: sensor.smartevse_evplugstate_2
to: Connected
trigger: state
conditions:
- condition: state
entity_id: select.smartevse_mode_2
state: "Off"
actions:
- target:
entity_id: input_boolean.smartevse_departure_mode
action: input_boolean.turn_on
- target:
entity_id: select.smartevse_mode_2
data:
option: |
{% if states('sensor.ev_smart_charging_status') == 'charging' %}
Smart
{% else %}
Solar
{% endif %}
action: select.select_option |
We zijn begonnen. maar geeft het laadplan aan dat er gewisseld moet worden van modus dan moet de evse worden aangestuurd.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| alias: "SmartEVSE: Volg Laadplan (met vertraging)"
description: "Schakelt tussen Smart en Solar op basis van laadplan, met 1 minuut stabilisatie"
triggers:
- entity_id: sensor.ev_smart_charging_status
trigger: state
# De status moet minimaal 1 minuut ongewijzigd blijven voordat we de EVSE echt omschakelen
for:
minutes: 1
conditions:
- condition: state
entity_id: input_boolean.smartevse_departure_mode
state: "on"
actions:
- target:
entity_id: select.smartevse_mode_2
data:
option: |
{% if states('sensor.ev_smart_charging_status') == 'charging' %}
Smart
{% else %}
Solar
{% endif %}
action: select.select_option
mode: restart |
waneer we klaar zijn met laden en de stekker gaat er uit, dan wordt alles gereset:
code:
1
2
3
4
5
6
7
8
9
10
| alias: "SmartEVSE: Reset bij ontkoppelen"
description: ""
triggers:
- entity_id: sensor.smartevse_evplugstate_2
from: Connected
trigger: state
actions:
- target:
entity_id: input_boolean.smartevse_departure_mode
action: input_boolean.turn_off |
En als ik handmatig iets wijzig moet er ook worden gereset
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| alias: "SmartEVSE: Handmatige Override Detectie"
description: ""
triggers:
- entity_id: select.smartevse_mode_2
trigger: state
conditions:
- condition: state
entity_id: input_boolean.smartevse_departure_mode
state: "on"
actions:
- if:
- condition: template
value_template: >
{% set plan_mode = 'Smart' if
states('sensor.ev_smart_charging_status') == 'charging' else 'Solar'
%} {{ trigger.to_state.state != plan_mode }}
then:
- target:
entity_id: input_boolean.smartevse_departure_mode
action: input_boolean.turn_off |
6. Laden maar.
De afgelopen twee dagen getest en werkt als een zonnetje