Events¶
Ein Event sagt: am Platz ist gerade etwas passiert. Eine Session startet, der Countdown läuft, ein Pilot fliegt durchs Ziel, ein Ergebnis wird bestätigt, ein Pilot wird angelegt. Jedes Event geht gleichzeitig
- an alle Programme am WebSocket
/api/v1/ws, - über die Server-Verbindung (falls eingerichtet; ohne Verbindung bis zu 5 min gepuffert),
- an die Hooks, die auf dieses Event (oder
*) eingestellt sind.
Events sind Mitteilungen, keine Befehle: man kann nichts darauf antworten. Wer reagieren will (z. B. ein Rennen bestätigen), schickt einen Befehl.
Aufbau¶
{"type": "event", "event": "pilot_pass", "seq": 17, "time_us": 1792697215501133, "data": {…}}
| Feld | Inhalt |
|---|---|
type |
immer "event" (unterscheidet sie von hello, reply im WebSocket) |
event |
Name, siehe unten |
seq |
laufende Nummer, ab dem Start des Laptimers von 1 an. Steigt sie um mehr als 1, fehlen Events. Nach einem Neustart des Laptimers beginnt sie wieder bei 1 |
time_us |
wann das Event entstand (µs seit 1970, Uhr des Timers) |
data |
die Felder des Events, je nach Event |
time_us ist der Zeitpunkt der Meldung, nicht unbedingt des Geschehens: Ein Durchflug wird
erst gemeldet, wenn die Erkennung sicher ist (etwa 1 s, nachdem die Drohne das Gate verlassen
hat). Die Zeit des Durchflugs selbst steht in data.time_us, und mit der rechnen die Runden.
Sitz¶
Viele Events betreffen einen Piloten auf einem Kanal. Diese Felder heißen hier kurz Sitz
und stehen direkt in data:
| Feld | Inhalt |
|---|---|
channel |
Index des Kanals (0 = Slot 1) |
channel_name |
"R3" |
mhz |
5732 |
pilot_id |
ID des Piloten, null bei einem Gast (Freitext) |
pilot |
angezeigter Name: Callsign, Freitext oder Kanalname |
Ablauf eines Rennens¶
So sieht ein Rennen über 2 Runden mit Holeshot-Start, 3 s Countdown und zwei Piloten aus (vereinfacht):
| seq | event | data (Auszug) | was passiert |
|---|---|---|---|
| 1 | session_started |
race: true, countdown_s: 3, seats: [ACE, NITRO] |
Start gedrückt |
| 2 | countdown |
seconds_left: 3 |
|
| 3 | countdown |
seconds_left: 2 |
|
| 4 | countdown |
seconds_left: 1 |
|
| 5 | start_signal |
start_us |
Startton |
| 6 | pilot_pass |
ACE, kind: "holeshot" |
erster Durchflug: die Zeit läuft |
| 7 | pilot_pass |
NITRO, kind: "holeshot" |
|
| 8 | pilot_pass |
ACE, kind: "lap", lap: 1, lap_time_s: 13.1, position: 1 |
|
| 9 | pilot_pass |
NITRO, kind: "lap", lap: 1, lap_time_s: 13.8, position: 2 |
|
| 10 | pilot_pass |
ACE, kind: "lap", lap: 2, finished: true |
ACE im Ziel … |
| 11 | pilot_finished |
ACE, position: 1, total_s |
… und als eigenes Event |
| 12 | pilot_pass |
NITRO, kind: "lap", lap: 2, finished: true |
|
| 13 | pilot_finished |
NITRO, position: 2 |
|
| 14 | session_stopped |
reason: "finished", needs_confirmation: true, winner: "ACE", results |
alle im Ziel: das Rennen stoppt von selbst |
| 15 | race_confirmed |
winner: "ACE", results |
jemand bestätigt (Seite oder session.confirm) |
Darauf kann man sich verlassen:
session_startedkommt vor allem anderen der Session,start_signalvor dem erstenpilot_passnach dem Start.- Der
pilot_pass, der einen Piloten ins Ziel bringt (finished: true), kommt vor seinempilot_finished, und allepilot_finishedvor demsession_stoppedmitreason: "finished". - Ein beendetes Rennen wartet auf
race_confirmedodersession_deleted; vorher startet keine neue Session.
Andere Fälle:
- Training: kein Countdown;
start_signalkommt gleich nachsession_started. Der erste Durchflug jedes Piloten istkind: "start", danach Runden. Es endet nur von Hand (session_stoppedmitreason: "stopped",needs_confirmation: false); bestätigt wird nichts. - Von Hand gestoppt:
session_stoppedmitreason: "stopped"; ein Rennen braucht danach trotzdem Bestätigung. - Abgebrochen (Seite: „Abbrechen“, API
session.cancel):session_stoppedmitreason: "cancelled", gleich danachsession_deleted. - Verworfen (beendetes Rennen nicht bestätigt):
session_deleted.
Korrekturen¶
Ein pilot_pass ist eine Live-Meldung. Er kann später noch falsch werden:
- Die Erkennung nimmt nach dem 3. Durchflug eines Kanals frühe Fehltreffer zurück.
- Die Rennleitung löscht, verschiebt oder ergänzt Durchflüge im Editor, auch nach dem Rennen.
- Ein Programm ruft
passes.add,passes.deleteoderpasses.restore.
Dann kommt passes_changed mit der session_id, ohne Einzelheiten: Runden, Plätze und
Bestzeiten können sich danach alle verschoben haben. Wer ein Ergebnis anzeigt, holt die Session
neu (sessions.get). Deshalb:
- Für Live-Anzeigen (Overlay, Ansage)
pilot_passnehmen. - Für das, was zählt (Tabelle, Website, Rangliste), das Ergebnis aus
race_confirmed, oder nachpasses_changedneu holen.session_stoppedhat auch ein Ergebnis, aber vor der Durchsicht der Rennleitung.
Durchflüge, die die Freigabe-Regel ablehnt (Zwei Gates), erscheinen
gar nicht als pilot_pass; sie sind als gelöscht gespeichert. Durchflüge am Freigabe-Gate
selbst sind keine Events.
Alle Events¶
Sessions¶
| Event | wann | data |
|---|---|---|
session_started |
Start gedrückt (vor dem Countdown) | session_id, race, start_mode, end (open/laps/seconds), end_value, countdown_s, created_us (Druck auf Start), start_us (Startsignal), pilot_count, seats (Liste der Sitze) |
countdown |
jede volle Sekunde des Countdowns | session_id, race, seconds_left (z. B. 5, 4, … 1) |
start_signal |
Startsignal; im Training gleich nach session_started |
session_id, race, start_us |
session_stopped |
Session beendet | session_id, race, reason, ended_us, needs_confirmation, winner, results |
race_confirmed |
Ergebnis eines Rennens bestätigt | session_id, race, confirmed_us, winner, results |
session_deleted |
Session gelöscht (verworfen, abgebrochen, auf der Seite gelöscht) | session_id, race |
sessions_reset |
alle Sessions gelöscht (Einstellungen → System; Piloten bleiben) | deleted (Anzahl) |
start_mode:holeshot(Zeit läuft ab dem ersten Durchflug),from_start(ab dem Startsignal),flying(fliegender Start: der erste Durchflug startet die erste Runde).reason:stopped(von Hand),finished(alle im Ziel),cancelled(wird gleich gelöscht).needs_confirmation:truebei einem Rennen, das nicht abgebrochen wurde.winner: Name des Ersten (wiepilot),nullim Training oder ohne Runde.results: ein Eintrag pro Sitz, wie in Datenformate → Session.
Durchflüge¶
| Event | wann | data |
|---|---|---|
pilot_pass |
ein Pilot fliegt durchs Ziel (erkannt oder von Hand) | Sitz, session_id, race, pass_id, time_us, manual, kind, lap, lap_time_us, lap_time_s, laps, best_lap_us, best_lap_s, personal_best, session_best, holeshot_us, finished, position |
pilot_finished |
ein Pilot hat das Rennende erreicht | Sitz, session_id, laps, total_us, total_s, best_lap_us, best_lap_s, position |
passes_changed |
Durchflüge korrigiert (oben) | session_id |
pilot_pass im Detail:
| Feld | Inhalt |
|---|---|
pass_id |
ID des Durchflugs (für passes.delete) |
time_us |
Zeit des Durchflugs |
manual |
von Hand: Taster über passes.add oder Editor |
kind |
lap: beendet Runde lap. holeshot: erster Durchflug bei Holeshot-Start. start: erster Durchflug im Training oder bei fliegendem Start, startet die erste Runde. ignored: zählt nicht (vor dem Startsignal, oder der Pilot ist schon im Ziel) |
lap, lap_time_us, lap_time_s |
Nummer und Dauer der Runde, nur bei kind: "lap", sonst null |
laps |
fertige Runden des Piloten bis jetzt |
best_lap_us, best_lap_s |
seine beste Runde in dieser Session |
personal_best |
diese Runde ist seine beste in der Session |
session_best |
diese Runde ist die beste aller Piloten in der Session |
holeshot_us |
Zeit vom Startsignal bis zum ersten Durchflug (Holeshot), sonst null |
finished |
dieser Durchflug war der Zieldurchflug |
position |
Platz jetzt (Rennen: mehr Runden, dann frühere Gesamtzeit; Training: Bestzeit; null ohne Runde) |
Beispiel:
{"type": "event", "event": "pilot_pass", "seq": 23, "time_us": 1792697174751210, "data": {
"session_id": 1, "race": true, "pass_id": 6, "time_us": 1792697173739494, "manual": false,
"channel": 1, "channel_name": "R3", "mhz": 5732, "pilot_id": 2, "pilot": "ACE",
"kind": "lap", "lap": 2, "lap_time_us": 13712000, "lap_time_s": 13.712, "laps": 2,
"best_lap_us": 13104106, "best_lap_s": 13.104, "personal_best": false, "session_best": false,
"holeshot_us": 2303763, "finished": false, "position": 1}}
total_us in pilot_finished: Zeit vom Startsignal bis zum Zieldurchflug (beim Holeshot
also mit dem Weg bis zum ersten Durchflug); beim fliegenden Start null.
Kanäle und Piloten¶
| Event | wann | data |
|---|---|---|
channels_changed |
Kanäle, ihre Frequenzen oder Piloten geändert (Seite oder API) | channels (Liste der Kanäle) |
pilot_added |
Pilot angelegt | pilot_id, name, full_name |
pilot_updated |
Pilot geändert | pilot_id, name, full_name |
pilot_deleted |
Pilot gelöscht (er verlässt auch seinen Slot: danach channels_changed) |
pilot_id, name |
Testen¶
Auf der Seite API & Hooks → Testen läuft ein Log aller Events mit. Ohne Boards geht es
auch: Session starten und Durchflüge mit passes.add eintragen; die zählen wie erkannte
(manual: true).