fix(template): correct and simplify tesla_charge_now logic

- Convert tesla_charge_now to binary_sensor
- Replace strptime with as_timestamp for robust time parsing
- Fix hour alignment (remove 15-min slot mismatch)
- Implement proper deadline filtering using timestamps
- Simplify template to minimal, readable logic

Result:
- Accurate identification of cheapest charging hours
- Eliminates false negatives in charge scheduling
This commit is contained in:
2026-03-17 06:18:27 +01:00
parent bed93b148f
commit dde5ff292a
+24 -12
View File
@@ -1,17 +1,29 @@
sensor: binary_sensor:
- name: tesla_charge_now - name: tesla_charge_now
state: > state: >
{% set deadline = states('input_datetime.tesla_charge_deadline') | default('2026-12-31T23:59:59') %} {% set deadline_raw = states('input_datetime.tesla_charge_deadline') %}
{% set hours_needed = states('sensor.tesla_charge_hours_needed')|float(0)|round(0,'ceil') %} {% 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 hours_needed = states('sensor.tesla_charge_hours_needed') | float(0) | round(0, 'ceil') %}
{% set prices = (state_attr('sensor.energidataservice','today') or [])
+ (state_attr('sensor.energidataservice','tomorrow') or []) %}
{# Filter valid price entries and apply deadline #}
{% set valid = [] %} {% set valid = [] %}
{% for p in prices if as_timestamp(strptime(p.hour,'%Y-%m-%dT%H:%M:%S')) <= as_timestamp(deadline) %} {% for p in prices %}
{% set valid = valid + [p] %} {% 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 %} {% endfor %}
{# Sorter efter pris #}
{% set sorted = valid | sort(attribute='price') %} {# Pick cheapest hours #}
{# Vælg de billigste slots der dækker ladetiden #} {% set cheapest = (valid | sort(attribute='price'))[:hours_needed] %}
{% set cheapest = sorted[:hours_needed] %}
{# Tjek om nuværende slot er i listen #} {# Current hour #}
{% set now_slot = now().replace(minute=(now().minute//15)*15, second=0, microsecond=0).isoformat() %} {% set now_slot = now().replace(minute=0, second=0, microsecond=0).isoformat() %}
{{ cheapest | selectattr('hour','equalto',now_slot) | list | count > 0 }} {{ cheapest | selectattr('hour','equalto',now_slot) | list | count > 0 }}