Template sensor to pick F1 event type based on track state and current time

So I’m trying to create a template sensor to “figure out” what kind of session is currently happening in F1. I am using the F1 HACS integration ( Nicxe/f1_sensor: A Home Assistant Custom Integration that provides information about the next Formula 1 race and the full season calendar). The integration has many useful sensors, but (as of this writing) does not provide a sensor to indicate what type of session is active, so I want to try and ‘guess’ based on other data. Here is the logic I’m trying (and failing) to implement:

Create a sensor.f1_session_type template sensor that behaves as follows based on the state of sensor.f1_session_status:

If sensor.f1_session_status is ended then f1_session_type should be None. Otherwise, set f1_session_type based on the closest (absolute before or after) session start time, which are listed as attributes of sensor.f1_next_race as follows:
now() is closest to sensor.f1_next_race.first_practice_start = “Free Practice 1”
now() is closest to sensor.f1_next_race.second_practice_start = “Free Practice 2”
now() is closest to sensor.f1_next_race.third_practice_start = “Free Practice 3”
now() is closest to sensor.f1_next_race.sprint_qualifying_start = “Sprint Qualifying”
now() is closest to sensor.f1_next_race.sprint_start = “Sprint Race”
now() is closest to sensor.f1_next_race.qualifying_start = “Qualifying”
now() is closest to sensor.f1_next_race.race_start = “Race”

Note, some of those attributes can be “null” based on what session types are happening during a given race weekend.

I haven’t been able to find an elegent (or in-elegant) way to do this in a template sensor script, and hoped one of you experts might take a crack at it? :slight_smile: Thanks in advance!

I’m sure there’s some refinement that can be done, but here’s a rough draft:

{%- set now_var = now()%}
{% set attr_list =["race_start_local", "first_practice_start_local",
"second_practice_start_local","third_practice_start_local",
"qualifying_start_local","sprint_qualifying_start_local","sprint_start_local"] %}

{% macro get_attr(attr) %}
{{- state_attr('sensor.f1_next_race',attr) -}}
{% endmacro%}

{% set dt_list = attr_list|map('apply', get_attr)|map('as_datetime')|list %}
{% set d = dict(zip(attr_list, dt_list)|rejectattr(1, 'in', [none])) %}
{%- set new_list = ([now_var] + d.values()|list)|sort %}
{% set nl_count = new_list|count %}
{%- set now_index = new_list.index(now_var) %}
{% if now_index == 0 %}
  {% set event = (d.keys()|list)[1] %}
{% elif now_index == nl_count-1 %}
  {% set event = (d.keys()|list)[now_index-1] %}
{% else %}
  {%- set remaining = new_list[now_index-1:now_index+2] %}
  {% set nearest_time = remaining[0] if (remaining[0] - now_var > now_var - remaining[2]) else remaining[2] %} 
  {% set event = (d.items()|list|selectattr(1,'eq', nearest_time)|first)[0] %}
{% endif %}
{{ event|replace('_start_local','')|replace('_',' ')|title}}

1 Like

Incredible, thank you!