Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- template:
- - triggers:
- - trigger: state
- entity_id:
- # A helper saving the SoC% the precise moment the cable is plugged in.
- - input_number.yeti_ev_battery_level_on_connection
- # Your EV charger's current charging power (measured in Watts).
- - sensor.peblar_ev_charger_effekt
- # Energy added during the current session (kWh)
- - sensor.peblar_ev_charger_session_energy
- # Entity showing 'on' when the cable is physically connected to the car.
- - switch.ev_smart_charging_ev_connected
- # Entity showing 'on' when actively pumping energy into the car.
- - binary_sensor.ev_charging_status
- # Your car's official cloud API SoC sensor (e.g., Bluelink, Tesla, VW).
- - sensor.yeti_ev_battery_level
- - trigger: homeassistant
- event: start
- - trigger: event
- event_type: event_template_reloaded
- sensor:
- name: Yeti Resterende Ladetid
- unique_id: 0d9abfbb80bf4d6e95ade0a215818074
- icon: mdi:timer-sand
- unit_of_measurement: "min"
- state_class: measurement
- variables:
- # --- 1. SENSOR DATA ---
- # Energy added in current session (kWh)
- session_energy_kwh: "{{ states('sensor.peblar_ev_charger_session_energy') | float(0) }}"
- # SoC% frozen at the time of plug-in
- soc_start: "{{ states('input_number.yeti_ev_battery_level_on_connection') | float(0) }}"
- # Actual SoC% from the car's cloud API
- soc_api: "{{ states('sensor.yeti_ev_battery_level') | float(0) }}"
- # Current charging power converted from Watts to kW
- charge_power_kw: "{{ states('sensor.peblar_ev_charger_effekt') | float(0) / 1000 }}"
- # Expected charging speed (in % per hour)
- soc_rate_hr: "{{ states('number.ev_smart_charging_charging_speed') | float(0) }}"
- # Boolean flag: True if the EV is physically plugged into the charger
- is_connected: "{{ is_state('switch.ev_smart_charging_ev_connected', 'on') }}"
- # Boolean flag: True if the charger is actively delivering power right now
- is_charging: "{{ is_state('binary_sensor.ev_charging_status', 'on') }}"
- # Fallback value: The car API's own estimated charge time, used when unplugged
- fallback_charge_duration: "{{ states('sensor.yeti_estimated_station_charge_duration') | int(0) }}"
- # --- 2. GLOBAL CONSTANTS ---
- # The desired end-goal for the battery level (typically 100% for PHEVs).
- # Adjust this if you routinely limit charging to e.g., 80% or 90% for battery health.
- TARGET_SOC_PCT: 100
- # Net battery size (usable capacity in kWh)
- # BATTERY_SIZE_KWH. 13.8
- BATTERY_SIZE_KWH: "{{ state_attr('sensor.variables', 'variables').YETI_BATTERY_SIZE_KWH | float(0) }}"
- # Average kW your charger delivers during an active session
- # CHARGER_ACTIVE_POWER_AVERAGE: 3.39
- CHARGER_ACTIVE_POWER_AVERAGE: "{{ state_attr('sensor.variables', 'variables').PEBLAR_ACTIVE_POWER_AVERAGE | float(0) }}"
- # Charging efficiency to account for heat/inverter loss (e.g., 90% = 0.90)
- # CHARGER_EFFICIENCY: 0.775
- CHARGER_EFFICIENCY: "{{ state_attr('sensor.variables', 'variables').PEBLAR_CHARGING_EFFICIENCY | float(0) / 100 }}"
- state: >-
- {# Calculate actual energy added considering efficiency loss #}
- {% set real_energy_added = session_energy_kwh * CHARGER_EFFICIENCY %}
- {% set added_soc_pct = ((real_energy_added / BATTERY_SIZE_KWH) * 100) if is_charging else 0 %}
- {# Check if target is already reached (using the highest known truth) #}
- {% if [soc_start + added_soc_pct, soc_api] | max >= TARGET_SOC_PCT %}
- 0
- {% elif is_connected %}
- {% if is_charging %}
- {# Active charging: Calculate remaining time dynamically based on current power #}
- {% set soc_needed_pct = TARGET_SOC_PCT - (soc_start + added_soc_pct) %}
- {% set time_at_ref_power = (soc_needed_pct / soc_rate_hr) %}
- {% set power_scaling_factor = CHARGER_ACTIVE_POWER_AVERAGE / (charge_power_kw if charge_power_kw > 0.1 else CHARGER_ACTIVE_POWER_AVERAGE) %}
- {% set remaining_hours = time_at_ref_power * power_scaling_factor %}
- {% else %}
- {# Suspended state: Calculate time based on theoretical reference speed #}
- {% set remaining_hours = ((TARGET_SOC_PCT - soc_start) / soc_rate_hr) %}
- {% endif %}
- {{ [(remaining_hours * 60), 0] | max | int(0) }}
- {% else %}
- {# Fallback when disconnected #}
- {{ fallback_charge_duration }}
- {% endif %}
- attributes:
- soc_start: "{{ soc_start }}"
- soc_api: "{{ soc_api }}"
- simulated_live_soc: >-
- {# Fetch previous state to use as our ratchet #}
- {% set previous_soc = this.attributes.get('simulated_live_soc', soc_api) | float(soc_api) if this is defined else soc_api %}
- {% if is_connected %}
- {% set calculated_soc = 0 %}
- {# Only calculate added energy if actually charging #}
- {% if is_charging %}
- {% set real_energy_added = session_energy_kwh * CHARGER_EFFICIENCY %}
- {% set calculated_soc = soc_start + ((real_energy_added / BATTERY_SIZE_KWH) * TARGET_SOC_PCT) %}
- {% endif %}
- {# The Ratchet: Pick the highest truth while plugged in #}
- {% set best_soc = [soc_api, previous_soc, calculated_soc] | max %}
- {{ [best_soc, TARGET_SOC_PCT] | min | int(0) }}
- {% else %}
- {# Cable unplugged: Disable ratchet and mirror API #}
- {{ soc_api | int(0) }}
- {% endif %}
Advertisement
Add Comment
Please, Sign In to add comment