Skip to content

Instantly share code, notes, and snippets.

@lsv
Created June 14, 2025 20:32
Show Gist options
  • Save lsv/e617de8a36081e1e658a385f64e943e2 to your computer and use it in GitHub Desktop.
Save lsv/e617de8a36081e1e658a385f64e943e2 to your computer and use it in GitHub Desktop.
Le Mans 2025 - homeassistant component
- id: '1749005648026'
alias: Update Bordlampe Color Based on Le Mans Flags
description: Change light color based on Le Mans flag statuses for 1 minute then reset
trigger:
- platform: state
entity_id:
- sensor.le_mans_main_flag
- sensor.le_mans_flag_status_0
- sensor.le_mans_flag_status_1
- sensor.le_mans_flag_status_2
condition: []
action:
- choose:
- conditions:
- condition: template
# Check if any flag is Red
value_template: >
{{ 'Red' in [
states('sensor.le_mans_main_flag'),
states('sensor.le_mans_flag_status_0'),
states('sensor.le_mans_flag_status_1'),
states('sensor.le_mans_flag_status_2')
] }}
sequence:
- service: light.turn_on
target:
entity_id: light.bordlampe_light
data:
rgb_color: [255, 0, 0] # Red
- conditions:
- condition: template
# Check if any flag is Yellow (and no Red)
value_template: >
{{ 'Yellow' in [
states('sensor.le_mans_main_flag'),
states('sensor.le_mans_flag_status_0'),
states('sensor.le_mans_flag_status_1'),
states('sensor.le_mans_flag_status_2')
] and
not ('Red' in [
states('sensor.le_mans_main_flag'),
states('sensor.le_mans_flag_status_0'),
states('sensor.le_mans_flag_status_1'),
states('sensor.le_mans_flag_status_2')
]) }}
sequence:
- service: light.turn_on
target:
entity_id: light.bordlampe_light
data:
rgb_color: [255, 255, 0] # Yellow
- conditions:
- condition: template
# Check if any flag is Green (and no Red or Yellow)
value_template: >
{{ 'Green' in [
states('sensor.le_mans_main_flag'),
states('sensor.le_mans_flag_status_0'),
states('sensor.le_mans_flag_status_1'),
states('sensor.le_mans_flag_status_2')
] and
not ('Red' in [
states('sensor.le_mans_main_flag'),
states('sensor.le_mans_flag_status_0'),
states('sensor.le_mans_flag_status_1'),
states('sensor.le_mans_flag_status_2')
]) and
not ('Yellow' in [
states('sensor.le_mans_main_flag'),
states('sensor.le_mans_flag_status_0'),
states('sensor.le_mans_flag_status_1'),
states('sensor.le_mans_flag_status_2')
]) }}
sequence:
- service: light.turn_on
target:
entity_id: light.bordlampe_light
data:
rgb_color: [0, 255, 0] # Green
- delay: "00:01:00"
- service: light.turn_on
target:
entity_id: light.bordlampe_light
data:
rgb_color: [255, 190, 135] # Your default warm color
mode: single
{
"domain": "lemans2025",
"name": "Le Mans 2025",
"version": "1.0.0",
"documentation": "",
"dependencies": [],
"codeowners": [],
"requirements": []
}
import logging
import aiohttp
from homeassistant.components.sensor import SensorEntity
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from homeassistant.helpers.typing import HomeAssistantType, ConfigType
from datetime import timedelta
_LOGGER = logging.getLogger(__name__)
SESSION_ID = "7608"
GRAPHQL_URL = "https://live-timing-api.sportall.tv/graphql"
HEADERS = {
"Content-Type": "application/json",
"Origin": "https://livetiming.lemans.org",
"Referer": "https://livetiming.lemans.org/"
}
QUERY = {
"operationName": "Session",
"variables": {
"sessionId": SESSION_ID
},
"query": """
query Session($sessionId: ID!) {
session(sessionId: $sessionId) {
id
liveStatus {
currentFlag {
type
}
}
sectorFlags {
sector
type
}
}
}
"""
}
SCAN_INTERVAL = timedelta(seconds=30)
async def fetch_le_mans_data(hass):
"""Fetch data from the LeMans GraphQL API."""
try:
async with aiohttp.ClientSession() as session:
async with session.post(GRAPHQL_URL, json=QUERY, headers=HEADERS) as response:
if response.status != 200:
raise UpdateFailed(f"Error fetching data: {response.status}")
data = await response.json()
session_data = data.get("data", {}).get("session", {})
if not session_data:
raise UpdateFailed("No session data found in response")
return session_data
except Exception as e:
raise UpdateFailed(f"Exception during API call: {e}")
async def async_setup_platform(hass: HomeAssistantType, config: ConfigType, async_add_entities: AddEntitiesCallback, discovery_info=None):
_LOGGER.debug("LeMans 2025 sensor setup started")
# Create the data coordinator that fetches all data every 30 seconds
coordinator = DataUpdateCoordinator(
hass,
_LOGGER,
name="LeMans 2025 Data Coordinator",
update_method=lambda: fetch_le_mans_data(hass),
update_interval=SCAN_INTERVAL,
)
# Perform initial data fetch
await coordinator.async_refresh()
# Create sensors and pass the coordinator to them
sensors = [LeMansFlagSensor(coordinator)]
for i in range(3):
sensors.append(LeMansSectorFlagSensor(coordinator, i))
async_add_entities(sensors, update_before_add=True)
class LeMansFlagSensor(SensorEntity):
def __init__(self, coordinator: DataUpdateCoordinator):
self.coordinator = coordinator
self._attr_unique_id = "le_mans_main_flag"
self._attr_name = "Le Mans Main Flag"
@property
def native_value(self):
return self.coordinator.data.get("liveStatus", {}).get("currentFlag", {}).get("type")
@property
def available(self):
return self.coordinator.last_update_success
async def async_added_to_hass(self):
self.coordinator.async_add_listener(self.async_write_ha_state)
class LeMansSectorFlagSensor(SensorEntity):
def __init__(self, coordinator: DataUpdateCoordinator, index: int):
self.coordinator = coordinator
self._index = index
self._attr_unique_id = f"le_mans_flag_status_{index}"
self._attr_name = f"Le Mans Flag Status {index + 1}"
@property
def native_value(self):
sector_flags = self.coordinator.data.get("sectorFlags", [])
if self._index < len(sector_flags):
return sector_flags[self._index].get("type")
return None
@property
def available(self):
return self.coordinator.last_update_success
async def async_added_to_hass(self):
self.coordinator.async_add_listener(self.async_write_ha_state)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment