tesla charging
This commit is contained in:
@@ -1,71 +1,74 @@
|
|||||||
- alias: Tesla smart charging v4
|
- alias: Tesla smart charging PRO
|
||||||
id: tesla_smart_charging_v4
|
id: tesla_smart_charging_pro
|
||||||
mode: restart
|
mode: restart
|
||||||
|
|
||||||
trigger:
|
trigger:
|
||||||
|
# Kør hvert 5. min (responsiv)
|
||||||
- platform: time_pattern
|
- platform: time_pattern
|
||||||
minutes: "/5"
|
minutes: "/5"
|
||||||
|
|
||||||
|
# Sikrer re-evaluering ved ny time
|
||||||
|
- platform: time_pattern
|
||||||
|
minutes: "0"
|
||||||
|
|
||||||
condition:
|
condition:
|
||||||
# Valid future deadline
|
# Deadline gyldig
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >
|
value_template: >
|
||||||
{% set deadline = states('input_datetime.tesla_charge_deadline') %}
|
{% set deadline = states('input_datetime.tesla_charge_deadline') %}
|
||||||
{{ deadline not in ['unknown','unavailable','']
|
{{ deadline not in ['unknown','unavailable',''] and as_timestamp(deadline) > as_timestamp(now()) }}
|
||||||
and as_timestamp(deadline) > as_timestamp(now()) }}
|
|
||||||
|
|
||||||
# Car must be connected
|
# Kun når bilen er tilsluttet
|
||||||
- condition: state
|
- condition: template
|
||||||
entity_id: binary_sensor.snowywhite_charger
|
value_template: >
|
||||||
state: "on"
|
{{ states('binary_sensor.tesla_connected') == 'on' }}
|
||||||
|
|
||||||
action:
|
action:
|
||||||
- variables:
|
- variables:
|
||||||
charge_now: "{{ is_state('binary_sensor.tesla_charge_now', 'on') }}"
|
should_charge: "{{ states('binary_sensor.tesla_charge_now') == 'on' }}"
|
||||||
charger_on: "{{ is_state('switch.home_charging', 'on') }}"
|
last_start: "{{ states('input_datetime.tesla_last_start') }}"
|
||||||
|
last_start_ts: >
|
||||||
|
{% if last_start not in ['unknown','unavailable',''] %}
|
||||||
|
{{ as_timestamp(last_start) }}
|
||||||
|
{% else %}
|
||||||
|
0
|
||||||
|
{% endif %}
|
||||||
|
runtime: "{{ as_timestamp(now()) - last_start_ts }}"
|
||||||
|
|
||||||
- choose:
|
- choose:
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# START charging (cheap hour)
|
# START / CONTINUE CHARGING
|
||||||
# -------------------------
|
# -------------------------
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ charge_now and not charger_on }}"
|
value_template: "{{ should_charge }}"
|
||||||
|
|
||||||
sequence:
|
sequence:
|
||||||
- service: system_log.write
|
# Hvis ikke allerede i gang → registrer start
|
||||||
|
- condition: template
|
||||||
|
value_template: >
|
||||||
|
{{ states('switch.home_charging') != 'on' }}
|
||||||
|
|
||||||
|
- service: input_datetime.set_datetime
|
||||||
|
target:
|
||||||
|
entity_id: input_datetime.tesla_last_start
|
||||||
data:
|
data:
|
||||||
message: "Tesla: START charging (cheap hour)"
|
datetime: "{{ now().isoformat() }}"
|
||||||
level: info
|
|
||||||
|
|
||||||
- service: switch.turn_on
|
- service: switch.turn_on
|
||||||
target:
|
target:
|
||||||
entity_id: switch.home_charging
|
entity_id: switch.home_charging
|
||||||
|
|
||||||
# -------------------------
|
# -------------------------
|
||||||
# STOP charging (not cheap)
|
# STOP CHARGING (med hysterese)
|
||||||
# -------------------------
|
# -------------------------
|
||||||
- conditions:
|
- conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ not charge_now and charger_on }}"
|
value_template: >
|
||||||
|
{{ not should_charge and runtime > 3600 }}
|
||||||
|
|
||||||
sequence:
|
sequence:
|
||||||
- service: system_log.write
|
|
||||||
data:
|
|
||||||
message: "Tesla: STOP charging (not cheap)"
|
|
||||||
level: info
|
|
||||||
|
|
||||||
- service: switch.turn_off
|
- service: switch.turn_off
|
||||||
target:
|
target:
|
||||||
entity_id: switch.home_charging
|
entity_id: switch.home_charging
|
||||||
|
|
||||||
# -------------------------
|
|
||||||
# Default: do nothing
|
|
||||||
# -------------------------
|
|
||||||
- service: system_log.write
|
|
||||||
data:
|
|
||||||
message: >
|
|
||||||
Tesla: No action (charge_now={{ charge_now }},
|
|
||||||
charger_on={{ charger_on }})
|
|
||||||
level: debug
|
|
||||||
|
|||||||
@@ -3,3 +3,7 @@ tesla_charge_deadline:
|
|||||||
has_date: true
|
has_date: true
|
||||||
has_time: true
|
has_time: true
|
||||||
|
|
||||||
|
tesla_last_start:
|
||||||
|
name: Tesla last charge start
|
||||||
|
has_date: true
|
||||||
|
has_time: true
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
sensors:
|
|
||||||
tesla_kwh_needed:
|
|
||||||
friendly_name: "Tesla kWh Needed"
|
|
||||||
unit_of_measurement: "kWh"
|
|
||||||
value_template: >
|
|
||||||
{% set capacity = 75 %}
|
|
||||||
{% set soc = states('sensor.snowywhite_battery') | float(0) %}
|
|
||||||
{% set limit = states('number.snowywhite_charge_limit') | float(100) %}
|
|
||||||
{{ [0, ((limit - soc)/100 * capacity)] | max | round(2) }}
|
|
||||||
|
|
||||||
tesla_charge_hours_needed:
|
|
||||||
friendly_name: "Tesla Charge Hours Needed"
|
|
||||||
unit_of_measurement: "h"
|
|
||||||
value_template: >
|
|
||||||
{% set power = 11 %}
|
|
||||||
{% set kwh = states('sensor.tesla_kwh_needed') | float(0) %}
|
|
||||||
{{ (kwh / power)|round(2) }}
|
|
||||||
|
|
||||||
tesla_charging_plan:
|
|
||||||
friendly_name: "Tesla Charging Plan"
|
|
||||||
value_template: >
|
|
||||||
{% set deadline_raw = states('input_datetime.tesla_charge_deadline') %}
|
|
||||||
{% set deadline_ts = as_timestamp(deadline_raw)
|
|
||||||
if deadline_raw not in ['unknown','unavailable',''] else none %}
|
|
||||||
|
|
||||||
{% set hours_needed = [1,
|
|
||||||
states('sensor.tesla_charge_hours_needed') | float(0) | round(0, 'ceil')
|
|
||||||
] | max %}
|
|
||||||
|
|
||||||
{% set prices = (state_attr('sensor.energidataservice','today') or [])
|
|
||||||
+ (state_attr('sensor.energidataservice','tomorrow') or []) %}
|
|
||||||
|
|
||||||
{% set valid = [] %}
|
|
||||||
{% for p in prices %}
|
|
||||||
{% if p.hour is defined and p.hour %}
|
|
||||||
{% set ts = as_timestamp(p.hour) %}
|
|
||||||
{% if not deadline_ts or ts <= deadline_ts %}
|
|
||||||
{% set valid = valid + [p] %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% set cheapest = (valid | sort(attribute='price'))[:hours_needed] %}
|
|
||||||
|
|
||||||
{% set times = cheapest
|
|
||||||
| map(attribute='hour')
|
|
||||||
| map('as_timestamp')
|
|
||||||
| map('timestamp_local')
|
|
||||||
| list %}
|
|
||||||
|
|
||||||
{{ times | join(', ') if times | count > 0 else 'none' }}
|
|
||||||
|
|
||||||
binary_sensors:
|
|
||||||
tesla_charge_now:
|
|
||||||
friendly_name: "Tesla Charge Now"
|
|
||||||
device_class: power
|
|
||||||
value_template: >
|
|
||||||
{% set hours_needed = [1, states('sensor.tesla_charge_hours_needed') | float(0) | round(0, 'ceil')] | max %}
|
|
||||||
{% set deadline_raw = states('input_datetime.tesla_charge_deadline') %}
|
|
||||||
{% set deadline_ts = as_timestamp(deadline_raw) if deadline_raw not in ['unknown','unavailable',''] else none %}
|
|
||||||
{% set prices = (state_attr('sensor.energidataservice','today') or []) + (state_attr('sensor.energidataservice','tomorrow') or []) %}
|
|
||||||
{% set valid_prices = [] %}
|
|
||||||
{% for p in prices %}
|
|
||||||
{% if p.hour is defined and p.hour %}
|
|
||||||
{% set ts = as_timestamp(p.hour) %}
|
|
||||||
{% if not deadline_ts or ts <= deadline_ts %}
|
|
||||||
{% set valid_prices = valid_prices + [p] %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
{% set cheapest = (valid_prices | sort(attribute='price'))[:hours_needed] %}
|
|
||||||
{% set now_ts = now().replace(minute=0, second=0, microsecond=0).timestamp() %}
|
|
||||||
{% set cheapest_ts = cheapest | map(attribute='hour') | map('as_timestamp') | list %}
|
|
||||||
{{ now_ts in cheapest_ts }}
|
|
||||||
Reference in New Issue
Block a user