### Setup Backend Development Environment (Rust) Source: https://github.com/slowlydev/f1-dash/blob/main/CONTRIBUTING.md Installs Rust and Cargo if not already present, copies environment variables, and starts the live and API backend services. Assumes Linux, macOS, or WSL. ```bash cd f1-dash/ rustup toolchain install cp .env.example .env cargo r -p live cargo r -p api ``` -------------------------------- ### Setup Frontend Development Environment Source: https://github.com/slowlydev/f1-dash/blob/main/CONTRIBUTING.md Installs Node.js, enables corepack, installs Yarn, and sets up project dependencies for frontend development. Assumes Linux, macOS, or WSL. Requires multiple terminal sessions. ```bash git clone git@github.com:slowlydev/f1-dash.git cd dash/ nvm install corepack enable corepack install yarn cp .env.example .env yarn dev ``` -------------------------------- ### Run Docker Compose with env file Source: https://github.com/slowlydev/f1-dash/blob/main/DOCKER.md Commands to start, build, or stop Docker Compose services using an environment file for variable substitution. Useful for local development and testing environments. ```bash docker compose --env-file ./compose.env up # or docker compose --env-file ./compose.env build # or docker compose --env-file ./compose.env down ``` -------------------------------- ### Build and Start Frontend in Production Mode Source: https://github.com/slowlydev/f1-dash/blob/main/CONTRIBUTING.md Builds the frontend application for production and starts a local server to preview the production build. This helps identify differences between development and production environments. ```bash yarn build yarn start ``` -------------------------------- ### Set environment variables in compose.yaml Source: https://github.com/slowlydev/f1-dash/blob/main/DOCKER.md Example of setting environment variables in a Docker Compose YAML file. Variables are substituted from the environment file specified during compose commands. ```yaml environment: - ORIGIN=${ORIGIN} - API_BACKEND_ADDRESS=${API_BACKEND_ADDRESS} - RUST_LOG=${RUST_LOG} - RUST_BACKTRACE=${RUST_BACKTRACE} ``` -------------------------------- ### Deploy F1 Dash Stack with Docker Compose - Bash Source: https://context7.com/slowlydev/f1-dash/llms.txt Deploys all F1 Dash services, including the frontend, backend, and TimescaleDB, using Docker Compose. This simplifies setup for production or development environments. It involves creating a `.env` file for configuration, starting services with `docker compose up`, and provides commands for viewing logs, checking health, scaling, and stopping services. ```bash # Create .env file cat > .env << EOF LIVE_ADDRESS=0.0.0.0:4000 API_ADDRESS=0.0.0.0:4001 ANALYTICS_ADDRESS=0.0.0.0:4002 ORIGIN=http://localhost:3000 DATABASE_URL=postgres://postgres:password@timescaledb:5432/postgres RUST_LOG=info EOF # Start all services docker compose up -d # Services available at: # - Live service: http://localhost:4000 # - API service: http://localhost:4001 # - Analytics service: http://localhost:4002 # - Frontend: http://localhost:3000 # - TimescaleDB: localhost:5432 # View logs docker compose logs -f live # Check service health curl http://localhost:4000/api/health curl http://localhost:4001/api/health curl http://localhost:4002/api/health # Scale services docker compose up -d --scale importer=3 # Stop all services docker compose down # With volumes cleanup docker compose down -v ``` -------------------------------- ### Run f1-dash Simulator Source: https://github.com/slowlydev/f1-dash/blob/main/CONTRIBUTING.md Starts the simulator for developing features that require a running race simulation. It takes a telemetry recording file as an argument. Assumes Linux, macOS, or WSL. ```bash cd f1-dash/ cargo r -p simulator year-circuit.data.txt ``` -------------------------------- ### Record Telemetry Data with f1-dash Saver Source: https://github.com/slowlydev/f1-dash/blob/main/CONTRIBUTING.md Starts the saver utility to record telemetry data from a running race into a specified file. It's recommended to use the '.data.txt' extension to avoid accidental commits. Assumes Linux, macOS, or WSL. ```bash cd f1-dash/ cargo r -p saver year-circuit.data.txt ``` -------------------------------- ### Fetch F1 Season Schedule (REST API) Source: https://context7.com/slowlydev/f1-dash/llms.txt Retrieves the complete Formula 1 season schedule from a REST API endpoint, which is parsed from official calendar feeds. The response is a JSON array of Grand Prix events, each detailing the race name, location, start and end times, and a list of its sessions. The bash example shows how to fetch the full schedule and the next upcoming race. ```bash # Get full season schedule curl http://localhost:4001/api/schedule # Response: # [ # { # "name": "BAHRAIN GRAND PRIX", # "countryName": "Bahrain International Circuit, Bahrain", # "countryKey": null, # "start": "2025-02-28T13:00:00Z", # "end": "2025-03-02T18:00:00Z", # "sessions": [ # { # "kind": "Practice 1", # "start": "2025-02-28T13:00:00Z", # "end": "2025-02-28T14:00:00Z" # }, # { # "kind": "Practice 2", # "start": "2025-02-28T16:30:00Z", # "end": "2025-02-28T17:30:00Z" # }, # { # "kind": "Practice 3", # "start": "2025-03-01T13:30:00Z", # "end": "2025-03-01T14:30:00Z" # }, # { # "kind": "Qualifying", # "start": "2025-03-01T17:00:00Z", # "end": "2025-03-01T18:00:00Z" # }, # { # "kind": "Race", # "start": "2025-03-02T17:00:00Z", # "end": "2025-03-02T18:00:00Z" # } # ], # "over": false # } # ] # Get only next upcoming race weekend curl http://localhost:4001/api/schedule/next ``` -------------------------------- ### Connect to Live F1 Telemetry Stream (SSE) Source: https://context7.com/slowlydev/f1-dash/llms.txt Connects to the Server-Sent Events (SSE) endpoint to receive real-time Formula 1 telemetry data. This endpoint provides incremental updates and initial state synchronization. The client-side JavaScript example demonstrates how to listen for 'initial' and 'update' events and handle potential connection errors. ```bash # Connect to live telemetry stream curl -N http://localhost:4000/api/sse # Response format: # event: initial # data: {"timingData":{"Lines":{"1":{"RacingNumber":"1","Position":"1","LastLapTime":{"Value":"1:23.456"}}...}}}... # # event: update # data: {"timingData":{"Lines":{"1":{"LastLapTime":{"Value":"1:22.123"}}}}} # # event: update # data: {"timingAppData":{"Lines":{"1":{"Stints":{"0":{"Compound":"SOFT","TotalLaps":12}}}}}} ``` ```javascript const eventSource = new EventSource('http://localhost:4000/api/sse'); eventSource.addEventListener('initial', (event) => { const state = JSON.parse(event.data); console.log('Initial race state:', state); // Full state includes: timingData, timingAppData, driverList, lapCount, sessionInfo, etc. }); eventSource.addEventListener('update', (event) => { const updates = JSON.parse(event.data); console.log('Incremental update:', updates); // Merge updates into your local state }); eventSource.onerror = (error) => { console.error('SSE connection error:', error); // Connection will auto-reconnect }; ``` -------------------------------- ### API: Get Driver Lap Times (cURL and JavaScript) Source: https://context7.com/slowlydev/f1-dash/llms.txt This snippet demonstrates how to retrieve historical lap time data for a specific Formula 1 driver using both cURL and JavaScript. The API endpoint returns lap times in milliseconds. The JavaScript example converts these times to seconds for display and finds the fastest lap, with a placeholder for plotting using a charting library like D3.js. ```bash # Get lap times for driver #1 curl http://localhost:4002/api/laptime/1 # Response: # [ # { # "time": "2025-03-02T17:05:23Z", # "lap": 1, # "laptime": 95234 # }, # { # "time": "2025-03-02T17:06:58Z", # "lap": 2, # "laptime": 87456 # }, # { # "time": "2025-03-02T17:08:26Z", # "lap": 3, # "laptime": 86891 # } # ] # Note: laptime is in milliseconds ``` ```javascript async function fetchAndPlotLapTimes(driverNumber) { const response = await fetch(`http://localhost:4002/api/laptime/${driverNumber}`); const laptimes = await response.json(); // Convert milliseconds to seconds for display const data = laptimes.map(lt => ({ lap: lt.lap, seconds: lt.laptime / 1000, time: new Date(lt.time) })); // Find fastest lap const fastest = data.reduce((min, curr) => curr.seconds < min.seconds ? curr : min ); console.log(`Fastest lap: Lap ${fastest.lap} - ${fastest.seconds.toFixed(3)}s`); // Plot with your charting library // plotChart(data); return data; } fetchAndPlotLapTimes('44'); // Lewis Hamilton ``` -------------------------------- ### Fetch Current F1 Drivers List (REST API) Source: https://context7.com/slowlydev/f1-dash/llms.txt Retrieves the current list of drivers participating in the live Formula 1 race session via a REST API endpoint. The response includes detailed information for each driver, such as their number, name, team, and country. The Rust example demonstrates how to make the GET request and parse the JSON response to display driver names and teams. ```bash # Get current drivers in session curl http://localhost:4000/api/drivers # Response: # { # "1": { # "RacingNumber": "1", # "BroadcastName": "M VERSTAPPEN", # "FullName": "Max VERSTAPPEN", # "Tla": "VER", # "Line": 1, # "TeamName": "Red Bull Racing", # "TeamColour": "3671C6", # "CountryCode": "NED" # }, # "44": { # "RacingNumber": "44", # "BroadcastName": "L HAMILTON", # "FullName": "Lewis HAMILTON", # "Tla": "HAM", # "Line": 2, # "TeamName": "Mercedes", # "TeamColour": "27F4D2", # "CountryCode": "GBR" # } # } ``` ```rust use reqwest; use serde_json::Value; #[tokio::main] async fn main() -> Result<(), Box> { let response = reqwest::get("http://localhost:4000/api/drivers").await?; let drivers: Value = response.json().await?; for (number, driver) in drivers.as_object().unwrap() { let name = driver["FullName"].as_str().unwrap(); let team = driver["TeamName"].as_str().unwrap(); println!("Driver #{}: {} ({})", number, name, team); } Ok(()) } ``` -------------------------------- ### Python: Filter F1 Schedule and Find Next Qualifying Source: https://context7.com/slowlydev/f1-dash/llms.txt This Python script fetches the F1 race schedule from an API and filters it to find races in a specific month. It also identifies and prints the name and start time of the next qualifying session. Dependencies include the 'requests' library for API calls and 'datetime' for date manipulation. ```python import requests from datetime import datetime response = requests.get('http://localhost:4001/api/schedule') schedule = response.json() # Find races in specific month march_races = [ race for race in schedule if datetime.fromisoformat(race['start'].replace('Z', '+00:00')).month == 3 ] # Get next qualifying session for race in schedule: if not race['over']: quali = next(s for s in race['sessions'] if s['kind'] == 'Qualifying') print(f"Next qualifying: {race['name']} at {quali['start']}") break ``` -------------------------------- ### GET /api/schedule - Season Schedule Source: https://context7.com/slowlydev/f1-dash/llms.txt This endpoint provides the complete F1 season schedule, parsed from official sources, including all race weekends with session details like practice, qualifying, and race times. Each event includes start/end times, location, and session kinds. It is ideal for applications needing calendar data. ```APIDOC ## GET /api/schedule ### Description Returns the full F1 season schedule with details on races, sessions, and timings. ### Method GET ### Endpoint http://localhost:4001/api/schedule ### Parameters No parameters required. ### Request Example ```bash curl http://localhost:4001/api/schedule ``` ### Response #### Success Response (200) - Array of race events with sessions. #### Response Example [ { "name": "BAHRAIN GRAND PRIX", "countryName": "Bahrain International Circuit, Bahrain", "countryKey": null, "start": "2025-02-28T13:00:00Z", "end": "2025-03-02T18:00:00Z", "sessions": [ { "kind": "Practice 1", "start": "2025-02-28T13:00:00Z", "end": "2025-02-28T14:00:00Z" }, { "kind": "Practice 2", "start": "2025-02-28T16:30:00Z", "end": "2025-02-28T17:30:00Z" }, { "kind": "Practice 3", "start": "2025-03-01T13:30:00Z", "end": "2025-03-01T14:30:00Z" }, { "kind": "Qualifying", "start": "2025-03-01T17:00:00Z", "end": "2025-03-01T18:00:00Z" }, { "kind": "Race", "start": "2025-03-02T17:00:00Z", "end": "2025-03-02T18:00:00Z" } ], "over": false } ] ``` -------------------------------- ### GET /api/sse - Real-time Telemetry Stream Source: https://context7.com/slowlydev/f1-dash/llms.txt This Server-Sent Events (SSE) endpoint streams real-time F1 telemetry data from the live timing WebSocket. It delivers an initial full race state followed by incremental updates for efficient client synchronization. The stream includes timing data, lap times, sector times, tire information, and session details, with automatic reconnection support. ```APIDOC ## GET /api/sse ### Description Provides real-time F1 telemetry data via Server-Sent Events with initial state and incremental updates for race timing, driver positions, and more. ### Method GET ### Endpoint http://localhost:4000/api/sse ### Parameters No parameters required. ### Request Example Connect using curl or EventSource in JavaScript: ```bash curl -N http://localhost:4000/api/sse ``` ### Response #### Success Response (200) - Streams events: 'initial' for full state, 'update' for changes. - Data includes timingData, timingAppData, driverList, etc. #### Response Example ``` event: initial data: {"timingData":{"Lines":{"1":{"RacingNumber":"1","Position":"1","LastLapTime":{"Value":"1:23.456"}}}}} event: update data: {"timingData":{"Lines":{"1":{"LastLapTime":{"Value":"1:22.123"}}}}} event: update data: {"timingAppData":{"Lines":{"1":{"Stints":{"0":{"Compound":"SOFT","TotalLaps":12}}}}}} ``` ``` -------------------------------- ### API: Get Driver Gap to Leader (cURL and Go) Source: https://context7.com/slowlydev/f1-dash/llms.txt This snippet shows how to retrieve historical gap-to-leader data for a Formula 1 driver using cURL and a Go program. The API returns gap data in milliseconds. The Go code fetches this data and calculates the rate of gap change per second to determine if the driver is gaining or losing time relative to the leader. ```bash # Get gap data for driver #44 curl http://localhost:4002/api/gap/44 # Response: # [ # { # "time": "2025-03-02T17:05:23Z", # "gap": 0 # }, # { # "time": "2025-03-02T17:06:58Z", # "gap": 1230 # }, # { # "time": "2025-03-02T17:08:26Z", # "gap": 2450 # } # ] # Note: gap is in milliseconds ``` ```go package main import ( "encoding/json" "fmt" "net/http" "time" ) type Gap struct { Time time.Time `json:"time"` Gap int64 `json:"gap"` } func main() { resp, err := http.Get("http://localhost:4002/api/gap/44") if err != nil { panic(err) } defer resp.Body.Close() var gaps []Gap json.NewDecoder(resp.Body).Decode(&gaps) // Calculate rate of gap change for i := 1; i < len(gaps); i++ { gapDelta := gaps[i].Gap - gaps[i-1].Gap timeDelta := gaps[i].Time.Sub(gaps[i-1].Time).Seconds() ratePerLap := float64(gapDelta) / timeDelta if gapDelta > 0 { fmt.Printf("Losing %.2f ms/s to leader\n", ratePerLap) } else { fmt.Printf("Gaining %.2f ms/s on leader\n", -ratePerLap) } } } ``` -------------------------------- ### GET /api/drivers - Current Drivers Source: https://context7.com/slowlydev/f1-dash/llms.txt This REST endpoint returns the list of drivers currently in the session, including details such as racing number, full name, team, and country. It is useful for displaying driver information in dashboards during live races. The response is keyed by racing number for easy lookup. ```APIDOC ## GET /api/drivers ### Description Retrieves the current driver list from the live race state, including names, teams, and other metadata. ### Method GET ### Endpoint http://localhost:4000/api/drivers ### Parameters No parameters required. ### Request Example ```bash curl http://localhost:4000/api/drivers ``` ### Response #### Success Response (200) - Object keyed by racing number with driver details. #### Response Example { "1": { "RacingNumber": "1", "BroadcastName": "M VERSTAPPEN", "FullName": "Max VERSTAPPEN", "Tla": "VER", "Line": 1, "TeamName": "Red Bull Racing", "TeamColour": "3671C6", "CountryCode": "NED" }, "44": { "RacingNumber": "44", "BroadcastName": "L HAMILTON", "FullName": "Lewis HAMILTON", "Tla": "HAM", "Line": 2, "TeamName": "Mercedes", "TeamColour": "27F4D2", "CountryCode": "GBR" } } ``` -------------------------------- ### GET /api/schedule/next - Next Race Weekend Source: https://context7.com/slowlydev/f1-dash/llms.txt This endpoint fetches only the next upcoming race weekend from the F1 season schedule. It returns a single event object with session details, useful for highlighting current or imminent events in user interfaces. The structure mirrors the full schedule but limited to one entry. ```APIDOC ## GET /api/schedule/next ### Description Returns details of the next upcoming F1 race weekend, including sessions and timings. ### Method GET ### Endpoint http://localhost:4001/api/schedule/next ### Parameters No parameters required. ### Request Example ```bash curl http://localhost:4001/api/schedule/next ``` ### Response #### Success Response (200) - Single race event object similar to full schedule entries. #### Response Example { "name": "BAHRAIN GRAND PRIX", "countryName": "Bahrain International Circuit, Bahrain", "countryKey": null, "start": "2025-02-28T13:00:00Z", "end": "2025-03-02T18:00:00Z", "sessions": [ { "kind": "Practice 1", "start": "2025-02-28T13:00:00Z", "end": "2025-02-28T14:00:00Z" } ], "over": false } ``` -------------------------------- ### Format Frontend Code with Prettier Source: https://github.com/slowlydev/f1-dash/blob/main/CONTRIBUTING.md Runs the Prettier command to format frontend code according to project standards. This ensures consistent code style across the project. ```bash yarn run prettier ``` -------------------------------- ### Rust: Connect to F1 Live Timing WebSocket Stream Source: https://context7.com/slowlydev/f1-dash/llms.txt This Rust code snippet demonstrates how to establish and manage a connection to the Formula 1 live timing WebSocket stream using a provided client library. It processes incoming messages, distinguishing between initial state snapshots and incremental updates for various data types like timing, app, and telemetry. Dependencies include 'client', 'tokio-stream', and 'tokio'. ```rust // In your Rust service: use client; use tokio_stream::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { // Initialize connection with auto-reconnect and session management let mut stream = client::manage(); // Process messages from F1 WebSocket while let Some(message) = stream.next().await { match message { client::message::Message::Initial(state) => { println!("Received initial state snapshot"); // state is a serde_json::Value with complete race data if let Some(timing) = state.get("timingData") { println!("Timing data: {}", timing); } } client::message::Message::Updates(updates) => { println!("Received {} updates", updates.len()); for (topic, value) in updates { match topic.as_str() { "timingData" => { println!("Lap time update: {}", value); } "timingAppData" => { println!("Tire data update: {}", value); } "carData.z" => { println!("Car telemetry update: {}", value); } _ => {} // Ignore other topics } } } } } Ok(()) } ``` -------------------------------- ### Replay WebSocket Data for Testing - Bash Source: https://context7.com/slowlydev/f1-dash/llms.txt Simulates live F1 WebSocket data for development and testing by replaying saved data from a file. This allows testing services without a live connection. Requires saving data first with a 'saver' utility and then using the 'simulator' binary with the data file and playback speed. ```bash # First, save live data to file using saver utility RUST_LOG=info cargo run --bin saver -- /tmp/monaco_race.jsonl # Later, replay the data with simulator cargo run --bin simulator -- /tmp/monaco_race.jsonl 100 # Output: # Simulator listening on localhost:8000 # Broadcasting message 1/2543 # Broadcasting message 2/2543 # ... # Configure your services to use simulator export WS_URL=ws://localhost:8000/ws cargo run --bin live # Now live service connects to simulator instead of F1 # Perfect for: # - Testing without waiting for race weekend # - Debugging specific race scenarios # - Load testing with accelerated playback # - Integration tests with known data ``` -------------------------------- ### Rust Custom Notification Service for Fastest Laps Source: https://context7.com/slowlydev/f1-dash/llms.txt Implements a notification service in Rust using the f1-dash client library. It connects to the F1 telemetry stream, processes live timing data, and checks for fastest lap improvements. Dependencies include `client`, `tokio`, and `tokio-stream`. The service takes driver number and lap time as input and outputs notifications for lap time improvements. ```rust // Cargo.toml // [dependencies] // client = { path = "../../crates/client" } // tokio = { version = "1", features = ["full"] } // tokio-stream = "0.1" use client; use tokio_stream::StreamExt; use std::collections::HashMap; struct NotificationService { fastest_laps: HashMap, } impl NotificationService { fn new() -> Self { Self { fastest_laps: HashMap::new(), } } async fn check_fastest_lap(&mut self, driver_nr: &str, laptime: i64) { let prev_fastest = self.fastest_laps.get(driver_nr).copied(); match prev_fastest { Some(prev) if laptime < prev => { let improvement = prev - laptime; println!("🏎️ Driver {} improved fastest lap by {}ms!", driver_nr, improvement); // Send push notification, email, SMS, etc. } None => { self.fastest_laps.insert(driver_nr.to_string(), laptime); } _ => {} } } async fn run(&mut self) { let mut stream = client::manage(); while let Some(message) = stream.next().await { if let client::message::Message::Updates(updates) = message { for (topic, value) in updates { if topic == "timingData" { if let Some(lines) = value.get("Lines") { for (nr, driver) in lines.as_object().unwrap() { if let Some(best_lap) = driver.get("BestLapTime") { if let Some(lap_str) = best_lap.get("Value") { if let Some(laptime_ms) = parse_laptime(lap_str.as_str().unwrap()) { self.check_fastest_lap(nr, laptime_ms).await; } } } } } } } } } } } fn parse_laptime(s: &str) -> Option { // "1:23.456" -> 83456 let parts: Vec<&str> = s.split(':').collect(); if parts.len() != 2 { return None; } let minutes: i64 = parts[0].parse().ok()?; let seconds: f64 = parts[1].parse().ok()?; Some((minutes * 60000) + (seconds * 1000.0) as i64) } #[tokio::main] async fn main() { let mut service = NotificationService::new(); service.run().await; } ``` -------------------------------- ### Broadcast F1 Data to Multiple Consumers (Rust) Source: https://context7.com/slowlydev/f1-dash/llms.txt Utilizes a broadcast channel to distribute F1 data streams to several concurrent consumers. It manages automatic reconnection and allows different consumers to process data for database storage, SSE clients, or console logging. Dependencies include the 'client' and 'tokio-stream' crates. ```rust use client; use tokio_stream::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { // Get managed stream with auto-reconnect let stream = client::manage(); // Create broadcast channel let (tx, rx1) = client::broadcast(stream); let rx2 = tx.subscribe(); let rx3 = tx.subscribe(); // Consumer 1: Save to database tokio::spawn(async move { let mut stream = tokio_stream::wrappers::BroadcastStream::new(rx1); while let Some(Ok(message)) = stream.next().await { // Save to TimescaleDB // importer_logic(message).await; } }); // Consumer 2: Send to SSE clients tokio::spawn(async move { let mut stream = tokio_stream::wrappers::BroadcastStream::new(rx2); while let Some(Ok(message)) = stream.next().await { // Broadcast to SSE connections // sse_broadcast(message).await; } }); // Consumer 3: Log to console tokio::spawn(async move { let mut stream = tokio_stream::wrappers::BroadcastStream::new(rx3); while let Some(Ok(message)) = stream.next().await { println!("Message: {:?}", message); } }); // Keep main alive tokio::signal::ctrl_c().await?; Ok(()) } ``` -------------------------------- ### Maintain F1 Race State with Live Data Sync (Rust) Source: https://context7.com/slowlydev/f1-dash/llms.txt Maintains an in-memory, synchronized state with live F1 data, featuring automatic merging of updates. This enables querying the current race status, including lap counts and leader positions, at any time. It depends on the 'client', 'tokio-stream', and 'serde_json' crates. ```rust use client; use std::sync::{Arc, Mutex}; use serde_json::Value; use tokio_stream::StreamExt; #[tokio::main] async fn main() -> Result<(), Box> { let stream = client::manage(); let (tx, rx) = client::broadcast(stream); // Maintain synchronized state let state: Arc> = client::keep_state(rx); // Clone state for use in API endpoint let api_state = state.clone(); // Query current state at any time tokio::spawn(async move { loop { tokio::time::sleep(tokio::time::Duration::from_secs(10)).await; let state_lock = api_state.lock().unwrap(); // Extract current lap count if let Some(lap_count) = state_lock.get("lapCount") { let current = lap_count["CurrentLap"].as_i64().unwrap_or(0); let total = lap_count["TotalLaps"].as_i64().unwrap_or(0); println!("Lap {}/{}", current, total); } // Extract leader position if let Some(timing_data) = state_lock.get("timingData") { if let Some(lines) = timing_data.get("Lines") { for (_, driver) in lines.as_object().unwrap() { if driver["Position"].as_str() == Some("1") { let name = driver["BroadcastName"].as_str().unwrap(); println!("Leader: {}", name); break; } } } } } }); tokio::signal::ctrl_c().await?; Ok(()) } ``` -------------------------------- ### Store Timing Data in TimescaleDB - Rust Source: https://context7.com/slowlydev/f1-dash/llms.txt Inserts timing data into a TimescaleDB hypertable for time-series analysis. Requires the 'timescale' crate and a running TimescaleDB instance. It takes a TimingDriverInsert struct as input and returns a Result indicating success or failure. ```rust use timescale::timing::{insert_timing_driver, TimingDriverInsert}; use timescale::init_timescaledb; use chrono::Utc; #[tokio::main] async fn main() -> Result<(), Box> { // Initialize database connection pool let pool = init_timescaledb(true).await?; // Create timing record let timing = TimingDriverInsert { nr: "44".to_string(), lap: Some(15), gap: Some(1250), // milliseconds behind car ahead leader_gap: Some(3450), // milliseconds behind leader laptime: Some(87234), // lap time in milliseconds sector_1: Some(28123), // sector 1 in milliseconds sector_2: Some(31456), // sector 2 in milliseconds sector_3: Some(27655), // sector 3 in milliseconds }; // Insert into database insert_timing_driver(&pool, &timing).await?; println!("Inserted timing data for driver #{}", timing.nr); // Data is automatically timestamped and retained for 4 hours // Query it back with get_laptimes() or get_gaps() Ok(()) } ``` -------------------------------- ### Merge JSON Updates Incrementally (Rust) Source: https://context7.com/slowlydev/f1-dash/llms.txt Provides intelligent JSON merging capabilities for efficiently updating state with incremental data from F1 WebSockets. It handles nested structures and array updates, ensuring data integrity. This function requires the 'serde_json' crate for JSON manipulation. ```rust use serde_json::{json, Value}; use data::merge::merge; fn main() { // Base state let mut state = json!({ "timingData": { "Lines": { "1": { "Position": "1", "LastLapTime": {"Value": "1:23.456"} } } } }); // Incremental update let update = json!({ "timingData": { "Lines": { "1": { "LastLapTime": {"Value": "1:22.123"} } } } }); // Merge update into state merge(&mut state, update); // Result: Position preserved, LastLapTime updated println!("{}", serde_json::to_string_pretty(&state).unwrap()); // { // "timingData": { // "Lines": { // "1": { // "Position": "1", // "LastLapTime": {"Value": "1:22.123"} // } // } // } // } // Array merging with index updates let mut array_state = json!({ "drivers": ["VER", "HAM", "LEC"] }); let array_update = json!({ "drivers": { "1": "PER" // Update index 1 } }); merge(&mut array_state, array_update); // Result: ["VER", "PER", "LEC"] } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.