mirror of
https://github.com/AmanTahiliani/box-box.git
synced 2026-08-07 11:54:59 -04:00
Subscribe to TeamRadio on the F1 live feed, parse defensive capture snapshots and patches, and relay capped captures through live snapshots with the SessionInfo static path. Add the frontend CDN URL helper and ticker using one shared audio element.
176 lines
5.3 KiB
Go
176 lines
5.3 KiB
Go
package live
|
|
|
|
import (
|
|
"encoding/json"
|
|
"time"
|
|
)
|
|
|
|
// F1SignalRMessage is the top-level envelope from the official F1 SignalR feed.
|
|
type F1SignalRMessage struct {
|
|
M []struct {
|
|
A []json.RawMessage `json:"A"`
|
|
} `json:"M"`
|
|
R json.RawMessage `json:"R"`
|
|
}
|
|
|
|
// F1TimingLine is a single driver's timing row from TimingData.
|
|
type F1TimingLine struct {
|
|
GapToLeader interface{} `json:"GapToLeader"`
|
|
IntervalToPositionAhead struct {
|
|
Value interface{} `json:"Value"`
|
|
} `json:"IntervalToPositionAhead"`
|
|
Position interface{} `json:"Position"`
|
|
RacingNumber string `json:"RacingNumber"`
|
|
LastLapTime struct {
|
|
Value string `json:"Value"`
|
|
PersonalFastest bool `json:"PersonalFastest"`
|
|
OverallFastest bool `json:"OverallFastest"`
|
|
} `json:"LastLapTime"`
|
|
BestLapTime struct {
|
|
Value string `json:"Value"`
|
|
PersonalFastest bool `json:"PersonalFastest"`
|
|
OverallFastest bool `json:"OverallFastest"`
|
|
Lap int `json:"Lap"`
|
|
} `json:"BestLapTime"`
|
|
InPit interface{} `json:"InPit"`
|
|
PitOut interface{} `json:"PitOut"`
|
|
Retired interface{} `json:"Retired"`
|
|
KnockedOut interface{} `json:"KnockedOut"`
|
|
Cutoff interface{} `json:"Cutoff"`
|
|
NumberOfLaps interface{} `json:"NumberOfLaps"`
|
|
Sectors json.RawMessage `json:"Sectors"`
|
|
Speeds map[string]json.RawMessage `json:"Speeds"`
|
|
}
|
|
|
|
// F1DriverListEntry is driver metadata from the DriverList topic.
|
|
type F1DriverListEntry struct {
|
|
RacingNumber string `json:"RacingNumber"`
|
|
BroadcastName string `json:"BroadcastName"`
|
|
Tla string `json:"Tla"`
|
|
TeamName string `json:"TeamName"`
|
|
TeamColour string `json:"TeamColour"`
|
|
FirstName string `json:"FirstName"`
|
|
LastName string `json:"LastName"`
|
|
}
|
|
|
|
// LiveTyreData holds current tyre compound and age for a driver.
|
|
type LiveTyreData struct {
|
|
Compound string // SOFT, MEDIUM, HARD, INTERMEDIATE, WET
|
|
New bool
|
|
Age int // laps on current set
|
|
}
|
|
|
|
// LiveRCMessage is a parsed race control message.
|
|
type LiveRCMessage struct {
|
|
Time string // "15:04" formatted
|
|
Category string // Flag, SafetyCar, Drs, Other
|
|
Flag string // GREEN, YELLOW, RED, etc.
|
|
Message string
|
|
Lap int
|
|
}
|
|
|
|
// LiveWeatherData holds session weather readings.
|
|
type LiveWeatherData struct {
|
|
AirTemp float64
|
|
TrackTemp float64
|
|
Humidity float64
|
|
WindSpeed float64
|
|
WindDir int
|
|
Rainfall bool
|
|
}
|
|
|
|
// LiveSessionMeta holds session and meeting metadata.
|
|
type LiveSessionMeta struct {
|
|
MeetingName string
|
|
CircuitName string
|
|
SessionType string
|
|
SessionName string
|
|
Path string
|
|
}
|
|
|
|
// LivePositionData is the latest raw F1 GPS position for one driver.
|
|
type LivePositionData struct {
|
|
X float64 `json:"x"`
|
|
Y float64 `json:"y"`
|
|
Z float64 `json:"z"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
// LiveTelemetryData is the latest car telemetry for one driver.
|
|
type LiveTelemetryData struct {
|
|
Speed int `json:"Speed"`
|
|
Throttle int `json:"Throttle"`
|
|
Brake int `json:"Brake"`
|
|
DRS int `json:"DRS"`
|
|
NGear int `json:"NGear"`
|
|
RPM int `json:"RPM"`
|
|
}
|
|
|
|
// LiveSectorData holds a single sector time and flags.
|
|
type LiveSectorData struct {
|
|
Value string
|
|
PersonalFastest bool
|
|
OverallFastest bool
|
|
}
|
|
|
|
// LiveDriverData is the normalized timing state for one driver.
|
|
type LiveDriverData struct {
|
|
RacingNumber string
|
|
Position int
|
|
PrevPosition int
|
|
GapToLeader string
|
|
Interval string
|
|
LastLapTime string
|
|
LastLapPB bool // personal best
|
|
LastLapOB bool // overall best
|
|
BestLapTime string
|
|
BestLapPB bool // just set a new personal best
|
|
BestLapOB bool // overall fastest in session
|
|
BestLapNum int // lap number when best was set
|
|
InPit bool
|
|
PitOut bool
|
|
Retired bool
|
|
KnockedOut bool // eliminated in qualifying
|
|
Cutoff bool // currently in elimination zone (danger zone)
|
|
OnFlyingLap bool // currently running a timed lap (derived from sector state)
|
|
NumberOfLaps int
|
|
SpeedTrap string // fastest recorded speed at speed trap
|
|
Sectors [3]LiveSectorData
|
|
}
|
|
|
|
// LiveStintData is one stint in a driver's tyre history.
|
|
type LiveStintData struct {
|
|
Compound string
|
|
New bool
|
|
Laps int
|
|
}
|
|
|
|
// LiveRadioCapture is one team radio audio clip from the live timing feed.
|
|
type LiveRadioCapture struct {
|
|
Utc string
|
|
RacingNumber string
|
|
Path string
|
|
}
|
|
|
|
// LiveStreamData is an immutable snapshot of all live timing state.
|
|
type LiveStreamData struct {
|
|
Drivers map[string]LiveDriverData
|
|
DriverInfo map[string]F1DriverListEntry
|
|
Tyres map[string]LiveTyreData
|
|
Telemetry map[string]LiveTelemetryData
|
|
RCMessages []LiveRCMessage
|
|
Weather LiveWeatherData
|
|
Session LiveSessionMeta
|
|
TeamRadio []LiveRadioCapture
|
|
TrackStatus string // "1"=green "2"=yellow "4"=SC "5"=red "6"=VSC
|
|
CurrentLap int
|
|
TotalLaps int
|
|
Clock string // "HH:MM:SS" remaining at ClockRefTime
|
|
ClockRefTime time.Time // UTC when Clock was accurate
|
|
ClockExtrapolating bool // true = actively counting down
|
|
Stints map[string][]LiveStintData
|
|
Positions map[string]LivePositionData `json:"-"`
|
|
PositionUpdated bool `json:"-"`
|
|
SnapshotUpdated bool `json:"-"`
|
|
}
|