diff --git a/include/automations/tesla_smart_charging.yaml b/include/automations/tesla_smart_charging.yaml index f325841..a4cd55a 100644 --- a/include/automations/tesla_smart_charging.yaml +++ b/include/automations/tesla_smart_charging.yaml @@ -1,71 +1,74 @@ -- alias: Tesla smart charging v4 - id: tesla_smart_charging_v4 +- alias: Tesla smart charging PRO + id: tesla_smart_charging_pro mode: restart trigger: + # Kør hvert 5. min (responsiv) - platform: time_pattern minutes: "/5" + # Sikrer re-evaluering ved ny time + - platform: time_pattern + minutes: "0" + condition: - # Valid future deadline + # Deadline gyldig - condition: template value_template: > {% set deadline = states('input_datetime.tesla_charge_deadline') %} - {{ deadline not in ['unknown','unavailable',''] - and as_timestamp(deadline) > as_timestamp(now()) }} + {{ deadline not in ['unknown','unavailable',''] and as_timestamp(deadline) > as_timestamp(now()) }} - # Car must be connected - - condition: state - entity_id: binary_sensor.snowywhite_charger - state: "on" + # Kun når bilen er tilsluttet + - condition: template + value_template: > + {{ states('binary_sensor.tesla_connected') == 'on' }} action: - variables: - charge_now: "{{ is_state('binary_sensor.tesla_charge_now', 'on') }}" - charger_on: "{{ is_state('switch.home_charging', 'on') }}" + should_charge: "{{ states('binary_sensor.tesla_charge_now') == '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: # ------------------------- - # START charging (cheap hour) + # START / CONTINUE CHARGING # ------------------------- - conditions: - condition: template - value_template: "{{ charge_now and not charger_on }}" + value_template: "{{ should_charge }}" 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: - message: "Tesla: START charging (cheap hour)" - level: info + datetime: "{{ now().isoformat() }}" - service: switch.turn_on target: entity_id: switch.home_charging # ------------------------- - # STOP charging (not cheap) + # STOP CHARGING (med hysterese) # ------------------------- - conditions: - condition: template - value_template: "{{ not charge_now and charger_on }}" + value_template: > + {{ not should_charge and runtime > 3600 }} sequence: - - service: system_log.write - data: - message: "Tesla: STOP charging (not cheap)" - level: info - - service: switch.turn_off target: 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 diff --git a/include/input/datetime/tesla.yaml b/include/input/datetime/tesla.yaml index e821e34..95a27a1 100644 --- a/include/input/datetime/tesla.yaml +++ b/include/input/datetime/tesla.yaml @@ -2,4 +2,8 @@ tesla_charge_deadline: name: Tesla charge deadline has_date: true has_time: true - \ No newline at end of file + +tesla_last_start: + name: Tesla last charge start + has_date: true + has_time: true diff --git a/include/templates/tesla_charging.yaml b/include/templates/tesla_charging.yaml deleted file mode 100644 index d7f0cca..0000000 --- a/include/templates/tesla_charging.yaml +++ /dev/null @@ -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 }}