Skip to main content

Driver Positions

Driver positions and lap times. Use sensor.f1_driver_positions in dashboards, templates, and automations.

See live data availability for session and data-source requirements. The details below describe any additional conditions for this entity.

Find your entity

These are standard entity IDs. If Home Assistant assigned a different ID, or you renamed an entity, use your existing ID in the examples.

State and attributes

sensor.f1_driver_positions - Live driver positions and lap-by-lap timing data for all drivers in the session.

State

  • Integer: current lap number (leader's lap), or unknown when not available.

Example

45

Attributes

AttributeTypeDescription
driverslistList of drivers, sorted by position when available
total_lapsnumberTotal race distance in laps, when known
fastest_lapobjectFastest lap details during races and sprints; null in other session types
current_qualifying_partnumberActive qualifying segment (1, 2, or 3); null outside qualifying sessions

Each entry in drivers contains:

FieldTypeDescription
racing_numberstringCar number
tlastringThree-letter abbreviation (driver code)
namestringDriver's full name
teamstringTeam name
team_colorstringTeam color as hex code (e.g., "#3671C6")
team_color_rgblistTeam color as RGB values (e.g., [54, 113, 198])
grid_positionstringStarting grid position
current_positionstringCurrent position in the session
lapsobjectMap of lap numbers to lap times (e.g., {"1": "1:32.456", "2": "1:31.789"})
completed_lapsnumberNumber of laps completed by this driver
best_lap_timestringDriver's personal best lap time; null when unknown or removed by the timing source
best_lap_time_secsnumberPersonal best lap time in seconds; null when no valid best time is available
best_lap_lapnumberLap number for the personal best; null when the source does not provide it
statusstringDriver status: on_track, pit_in, pit_out, or out
gap_to_leaderstringPublic live timing gap to the session leader when available
interval_to_position_aheadstringPublic live timing interval to the car directly ahead when available
in_pitbooleanWhether driver is currently in pit lane
pit_outbooleanWhether driver just exited pits
retiredbooleanWhether driver has retired from the session
stoppedbooleanWhether driver has stopped on track
fastest_lapbooleanTrue if this driver currently holds the session's fastest lap (race/sprint only)
fastest_lap_timestringSession's fastest lap time for its current holder; null for other drivers and outside races/sprints
fastest_lap_time_secsnumberSession's fastest lap time in seconds for its current holder; otherwise null
fastest_lap_lapnumberLap number of the session's fastest lap for its current holder; otherwise null
sector_1numberCurrent sector 1 time in seconds; null while sector has not been completed this lap
sector_2numberCurrent sector 2 time in seconds; null while not yet completed
sector_3numberCurrent sector 3 time in seconds; null while not yet completed
sector_1_lapnumberLap number associated with the current sector 1 value
sector_2_lapnumberLap number associated with the current sector 2 value
sector_3_lapnumberLap number associated with the current sector 3 value
sector_1_sourcestringSource used for the current sector 1 value
sector_2_sourcestringSource used for the current sector 2 value
sector_3_sourcestringSource used for the current sector 3 value
sector_1_overall_fastestbooleanTrue if the current sector 1 time is the fastest by any driver this session
sector_1_personal_fastestbooleanTrue if the current sector 1 time is this driver's personal best
sector_2_overall_fastestbooleanTrue if the current sector 2 time is the overall fastest
sector_2_personal_fastestbooleanTrue if the current sector 2 time is this driver's personal best
sector_3_overall_fastestbooleanTrue if the current sector 3 time is the overall fastest
sector_3_personal_fastestbooleanTrue if the current sector 3 time is this driver's personal best
best_sector_1numberDriver's personal best sector 1 time this session (or segment, in qualifying)
best_sector_2numberDriver's personal best sector 2 time this session (or segment, in qualifying)
best_sector_3numberDriver's personal best sector 3 time this session (or segment, in qualifying)
best_sector_1_lapnumberLap number for the driver's personal best sector 1
best_sector_2_lapnumberLap number for the driver's personal best sector 2
best_sector_3_lapnumberLap number for the driver's personal best sector 3
best_sector_1_session_partstringQualifying segment/session part for the best sector 1 value
best_sector_2_session_partstringQualifying segment/session part for the best sector 2 value
best_sector_3_session_partstringQualifying segment/session part for the best sector 3 value
sector_statestringCurrent sector tracking state for the driver
sector_current_lapnumberLap currently being tracked for sector timing
last_completed_sectornumberLast completed sector number
sectorsobjectStructured sector details with current and personal_best sector objects
q1_timestringBest lap time set in Q1; null if no time was set or outside qualifying
q1_knocked_outbooleanTrue if the driver did not advance past Q1; null outside qualifying
q1_positionnumberFinishing rank in Q1 based on best lap time; null if no time was set
q2_timestringBest lap time set in Q2; null if did not participate or no time set
q2_knocked_outbooleanTrue if the driver did not advance past Q2; null outside qualifying
q2_positionnumberFinishing rank in Q2; null if no time was set
q3_timestringBest lap time set in Q3; null if did not participate
q3_knocked_outbooleanAlways false (Q3 is the final segment); null outside qualifying
q3_positionnumberFinishing rank in Q3; null if no time was set

Personal best and session fastest lap

Use best_lap_time for each driver's BEST time in practice, qualifying, races, and sprints. It follows the timing source's personal best even when earlier laps are missing from laps, for example after joining a session late. Before the source supplies a personal best value, the integration uses the best lap it has observed, when available.

Source corrections replace the personal best even when the corrected time is slower. If the source removes the value, the personal best fields become null until a valid value arrives; an older observed lap is not restored. best_lap_lap can also be null when a time is available but its lap number is unknown. The separate fastest_lap fields continue to identify the overall fastest driver during races and sprints.

JSON Structure Example — Race
{
"drivers": [
{
"racing_number": "1",
"tla": "VER",
"name": "Max Verstappen",
"team": "Red Bull Racing",
"team_color": "#3671C6",
"team_color_rgb": [54, 113, 198],
"grid_position": "1",
"current_position": "1",
"laps": {
"1": "1:32.456",
"2": "1:31.789",
"3": "1:31.234"
},
"completed_laps": 45,
"best_lap_time": "1:29.123",
"best_lap_time_secs": 89.123,
"best_lap_lap": 42,
"status": "on_track",
"in_pit": false,
"pit_out": false,
"retired": false,
"stopped": false,
"fastest_lap": true,
"fastest_lap_time": "1:29.123",
"fastest_lap_time_secs": 89.123,
"fastest_lap_lap": 42,
"sector_1": 28.123,
"sector_2": null,
"sector_3": null,
"sector_1_overall_fastest": true,
"sector_1_personal_fastest": true,
"sector_2_overall_fastest": null,
"sector_2_personal_fastest": null,
"sector_3_overall_fastest": null,
"sector_3_personal_fastest": null,
"best_sector_1": 27.891,
"best_sector_2": 31.456,
"best_sector_3": 29.776,
"q1_time": null,
"q1_knocked_out": null,
"q1_position": null,
"q2_time": null,
"q2_knocked_out": null,
"q2_position": null,
"q3_time": null,
"q3_knocked_out": null,
"q3_position": null
}
],
"total_laps": 70,
"fastest_lap": {
"racing_number": "1",
"tla": "VER",
"name": "Max Verstappen",
"team": "Red Bull Racing",
"team_color": "#3671C6",
"team_color_rgb": [54, 113, 198],
"lap": 42,
"time": "1:29.123",
"time_secs": 89.123
},
"current_qualifying_part": null
}
JSON Structure Example — Qualifying
{
"drivers": [
{
"racing_number": "1",
"tla": "VER",
"name": "Max Verstappen",
"team": "Red Bull Racing",
"team_color": "#3671C6",
"team_color_rgb": [54, 113, 198],
"grid_position": "1",
"current_position": "1",
"laps": {},
"completed_laps": 6,
"best_lap_time": "1:21.987",
"best_lap_time_secs": 81.987,
"best_lap_lap": null,
"status": "on_track",
"in_pit": false,
"pit_out": false,
"retired": false,
"stopped": false,
"fastest_lap": false,
"fastest_lap_time": null,
"fastest_lap_time_secs": null,
"fastest_lap_lap": null,
"sector_1": 16.911,
"sector_2": null,
"sector_3": null,
"sector_1_overall_fastest": true,
"sector_1_personal_fastest": true,
"sector_2_overall_fastest": null,
"sector_2_personal_fastest": null,
"sector_3_overall_fastest": null,
"sector_3_personal_fastest": null,
"best_sector_1": 16.802,
"best_sector_2": 44.213,
"best_sector_3": 22.087,
"q1_time": "1:23.100",
"q1_knocked_out": false,
"q1_position": 3,
"q2_time": "1:22.500",
"q2_knocked_out": false,
"q2_position": 2,
"q3_time": "1:21.987",
"q3_knocked_out": false,
"q3_position": 1
},
{
"racing_number": "10",
"tla": "GAS",
"name": "Pierre Gasly",
"team": "Alpine",
"team_color": "#FF87BC",
"grid_position": "16",
"current_position": "16",
"laps": {},
"completed_laps": 4,
"best_lap_time": "1:24.892",
"best_lap_time_secs": 84.892,
"best_lap_lap": null,
"status": "on_track",
"in_pit": false,
"pit_out": false,
"retired": false,
"stopped": false,
"fastest_lap": false,
"fastest_lap_time": null,
"fastest_lap_time_secs": null,
"fastest_lap_lap": null,
"sector_1": null,
"sector_2": null,
"sector_3": null,
"sector_1_overall_fastest": null,
"sector_1_personal_fastest": null,
"sector_2_overall_fastest": null,
"sector_2_personal_fastest": null,
"sector_3_overall_fastest": null,
"sector_3_personal_fastest": null,
"best_sector_1": null,
"best_sector_2": null,
"best_sector_3": null,
"q1_time": "1:24.892",
"q1_knocked_out": true,
"q1_position": 16,
"q2_time": null,
"q2_knocked_out": false,
"q2_position": null,
"q3_time": null,
"q3_knocked_out": false,
"q3_position": null
}
],
"total_laps": null,
"fastest_lap": null,
"current_qualifying_part": 3
}
Jinja2 Template Examples

Get the race leader:

{% set drivers = state_attr('sensor.f1_driver_positions', 'drivers') %}
{% if drivers %}
{% set leader = drivers | selectattr('current_position', 'eq', '1') | first %}
{% if leader %}
Leader: {{ leader.tla }} ({{ leader.name }})
{% endif %}
{% endif %}

Get a specific driver by number:

{% set drivers = state_attr('sensor.f1_driver_positions', 'drivers') %}
{% set driver = drivers | selectattr('racing_number', 'eq', '44') | first %}
{% if driver %}
{{ driver.name }} is in P{{ driver.current_position }}
{% endif %}

Get driver's last lap time:

{% set drivers = state_attr('sensor.f1_driver_positions', 'drivers') %}
{% set driver = drivers | selectattr('racing_number', 'eq', '1') | first %}
{% if driver and driver.laps %}
{% set last_lap = driver.completed_laps | string %}
Last lap: {{ driver.laps.get(last_lap, 'N/A') }}
{% endif %}

List all drivers in pit lane:

{% set drivers = state_attr('sensor.f1_driver_positions', 'drivers') %}
{% for d in drivers if d.status == 'pit_in' %}
{{ d.tla }} is in the pits
{% endfor %}

Show race progress:

{% set current = states('sensor.f1_driver_positions') %}
{% set total = state_attr('sensor.f1_driver_positions', 'total_laps') %}
{% if current != 'unknown' and total %}
Lap {{ current }} of {{ total }}
{% endif %}

Get position changes from grid:

{% set drivers = state_attr('sensor.f1_driver_positions', 'drivers') %}
{% for d in drivers %}
{% set change = d.grid_position | int - d.current_position | int %}
{{ d.tla }}: {% if change > 0 %}+{% endif %}{{ change }}
{% endfor %}

Get Q3 qualifying results sorted by position:

{% set drivers = state_attr('sensor.f1_driver_positions', 'drivers') %}
{% set q3 = drivers | selectattr('q3_time', 'ne', None) | sort(attribute='q3_position') %}
{% for d in q3 %}
P{{ d.q3_position }}: {{ d.tla }} — {{ d.q3_time }}
{% endfor %}

List drivers knocked out in Q1:

{% set drivers = state_attr('sensor.f1_driver_positions', 'drivers') %}
{% for d in drivers if d.q1_knocked_out %}
{{ d.tla }} eliminated in Q1 ({{ d.q1_time or 'no time' }})
{% endfor %}

Show active qualifying segment:

{% set part = state_attr('sensor.f1_driver_positions', 'current_qualifying_part') %}
{% if part %}
Q{{ part }} in progress
{% endif %}
info

Fastest lap details are only exposed during races and sprints. In practice and qualifying, fastest_lap is null and each driver has fastest_lap: false.

info

Sector times (sector_1, sector_2, sector_3) update live as drivers complete each sector during a lap. The companion sector_*_lap and sector_*_source fields identify which lap and timing source produced the value. The sectors object exposes the same data in a structured shape with current.sector_1, current.sector_2, current.sector_3, and matching personal_best sector objects.

info

Gap data (gap_to_leader and interval_to_position_ahead) comes from public live timing when available. These fields may be null or blank outside race/sprint running, at the start of a session, or when the broadcast feed withholds intervals.

info

Qualifying segment data (q1_time, q2_time, q3_time and their associated _knocked_out and _position fields) is only populated during qualifying and sprint shootout sessions. In all other session types these fields are null. All 20 drivers are always present regardless of whether they set a time. q1_knocked_out: true means the driver did not advance to Q2, and q2_knocked_out: true means the driver did not reach Q3.

Next steps