feat(race-day): add warm-up transponder check before a heat
Race Day gets a 1-3 minute warm-up per heat with a green check per driver when their transponder is seen, countdown announcements (sv/en), quick transponder fix from the panel, and a start warning that still allows starting when someone is missing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,8 +12,7 @@ export async function freePort() {
|
||||
|
||||
// Accepts the WebSocket upgrade handshake so the frontend's real decoder-connect path
|
||||
// (src/decoder_runtime.js) reaches `connected: true` without a physical AMMC decoder.
|
||||
// No frames are sent or parsed: scenarios using this only need an established socket,
|
||||
// not lap data.
|
||||
// sendPassing() pushes a PASSING frame for scenarios that need the app to see a transponder.
|
||||
export async function startFakeDecoder() {
|
||||
const port = await freePort();
|
||||
const server = createServer();
|
||||
@@ -40,6 +39,14 @@ export async function startFakeDecoder() {
|
||||
// handshake) to simulate a decoder/network interruption, while the server keeps
|
||||
// listening so the frontend's own reconnect logic has somewhere to reconnect to.
|
||||
dropConnections: () => { for (const socket of sockets) socket.destroy(); },
|
||||
// Sends an AMMC-style PASSING message as an unmasked server->client WebSocket text frame.
|
||||
sendPassing: (transponder) => {
|
||||
const payload = Buffer.from(JSON.stringify({ msg: "PASSING", transponder: String(transponder), rtc_time: new Date().toISOString() }));
|
||||
const header = payload.length < 126
|
||||
? Buffer.from([0x81, payload.length])
|
||||
: Buffer.from([0x81, 126, payload.length >> 8, payload.length & 0xff]);
|
||||
for (const socket of sockets) socket.write(Buffer.concat([header, payload]));
|
||||
},
|
||||
close: () => new Promise(resolve => {
|
||||
for (const socket of sockets) socket.destroy();
|
||||
server.close(() => resolve());
|
||||
|
||||
Reference in New Issue
Block a user