From 9bd873cf5c3737e4c7c48cab2cee2b2feb8b5755 Mon Sep 17 00:00:00 2001 From: larssand Date: Mon, 16 Mar 2026 16:25:29 +0100 Subject: [PATCH] Add English primary README and keep Swedish copy --- README.md | 459 ++++++++++++++++++++++++++------------------------- README.sv.md | 301 +++++++++++++++++++++++++++++++++ 2 files changed, 536 insertions(+), 224 deletions(-) create mode 100644 README.sv.md diff --git a/README.md b/README.md index 056d3f4..e6a1e77 100644 --- a/README.md +++ b/README.md @@ -1,208 +1,219 @@ # JMK RB RaceController -RC timing app med sponsor-eventflöde (delade bilar/transpondrar mellan olika heat/finaler), AMMC WebSocket och lokal SQLite-lagring på Windows. +English README. Swedish version: [`README.sv.md`](README.sv.md) -## Vad som ingår -- Event-lägen: +JMK RB RaceController is an RC timing and race-control system with support for sponsor events with shared cars/transponders, AMMC WebSocket input, and local persistence through SQLite. + +## Features +- Event modes: - `Race (driver transponders)` - `Track Event (shared cars)` -- UI-separering: - - `Event` = sponsor-event med delade bilar/transpondrar - - `Race Setup` = riktiga race med personlig transponder per förare - - `Race Setup` innehåller nu även: - - välj exakt vilka förare som är med i racet - - practice-ranking - - kval-ranking med `poäng` eller `bästa resultat` - - inbyggd guide för hur man skapar race steg för steg - - beskrivningar direkt i alla fält under `Raceformat` - - `Follow-up tid` efter ordinarie racetid innan heatet stängs - - `Min varvtid` och `Max varvtid` för att filtrera shortcuts/felträffar och styra bättre statistik/stintlogik - - seedmetoder för practice/kval: bästa N varv som summa, snitt eller konsekutiva varv - - valbar kval-poängtabell och tie-break-regler - - presets i `Raceformat` för kort teknisk bana, klubbrace, IFMAR-liknande upplägg och endurance - - schemaavvikelse på `Översikt` mellan planerad och faktisk körtid - - sessionstyp `Free Practice` för löpande varvtider utan seedning - - auto-generering av kvalheat från practice-ranking eller klasslista - - reseeding av kommande kvalheat från aktuell ranking - - auto-generering av `A/B/C...` finaler från ranking - - sparad manuell grid per session via dragbar grid-editor - - auto-reseed hoppar över heat där manuell grid har låsts tills du återställer den - - tydlig `Lås/Lås upp grid` i grid-editorn per session - - final-ranking över flera leg med räknade finalheat - - valbar `bump-up` mellan finaler - - reserverade bump-platser i högre finaler - - visuell finalmatris med reserverade bump-platser - - dragbar grid-editor för positionsstart - - utskrift/export av heatsheets per kval/final - - overlay-vy för extern leaderboard-skärm - - flera overlay-lägen: leaderboard, speaker och results - - speaker-overlay med eventmarkörer och separata speaker-cues - - live speaker-panel i `Timing` för att slå av/på cues under pågående session - - speaker-cues och klubbinfo/PDF-header styrs från `Settings` - - logo-upload för overlay från `Settings` - - branding per event/race med egen logo, tagline, footer och PDF-tema i `Hantera` - - extra speaker-cues för `session start`, `new best lap` och `top 3 change` - - valbart PDF-tema: `classic`, `minimal`, `motorsport` - - utskrift av startlistor och resultat med vald branding - - servergenererad PDF-export för startlistor, heatsheets och resultat med inbäddad logo - - genererade kval/finaler ärver tid och starttyp från raceformatet - - finish-ljud som siren i stället för browser-röst -- Sessioner: `practice`, `qualification`, `heat`, `final` -- Sponsor-verktyg: - - Skapa rundor automatiskt (`qualification`, `heat`, `final`) - - Auto-assign förare -> bil per session -- Live timing från AMMC WebSocket (`msg: "PASSING"`) -- Hanterad AMMC från webbgränssnittet: - - backend kan starta/stoppa lokal `ammc-amb` på Windows, Linux och macOS - - läser bundlade binärer från `AMMC/windows64`, `AMMC/linux_x86-64`, `AMMC/apple_m` -- Redigering i UI: - - Klasser, eventnamn/datum, förare och bilar kan redigeras direkt -- Live race-kontroll: - - Nedräkning under pågående session - - Auto-finish vid tidslut med status `Race is finished` - - Leaderboard-sortering: varv först, därefter närmast måltid för sessionen (t.ex. 5 min = 600s) - - Browserljud för passing (`blipp` eller tala förarnamn) och målgång - - Sessioninställningar för `Mass start`, `Position start`, `Staggered` - - `Timing` visar grid/startordning för aktiv `Position start`-session - - leaderboard visar både `gap till ledaren`, `gap till bilen framför` och `eget delta` mot förra varvet - - `Senaste passeringar` visar nu även ogiltiga varv med status `För kort varv` eller `Över maxvarv` - - manuella korrigeringar i `Tidtagning -> Detaljer`: `+1/-1 varv`, `+1/+5/-1 sek`, `Nollställ korrigering` - - Practice/Kval kan seedas på bästa `2` eller `3` varv i sessionsinställningar -- Persistens: - - Frontend state i browser (`localStorage`) - - Samma state + passeringar sparas i lokal SQLite via Node-backend -- Inbyggd `Guide`-meny i appen med steg-för-steg för: - - Sponsor-event (10 personer / 4 bilar) - - Vanligt race - - ogiltiga varv, follow-up och manuella korrigeringar - - AMMC + npm setup på Windows och Linux -- Språkval i UI: `SV` / `EN` +- UI separation: + - `Event` = sponsor events with shared cars/transponders + - `Race Setup` = competition races with personal driver transponders +- Race Setup includes: + - explicit race participant selection + - practice standings + - qualifying standings with `points` or `best result` + - built-in step-by-step guide + - inline descriptions for all `Race Format` fields + - `Follow-up time` after scheduled race time before a heat fully closes + - `Min lap time` and `Max lap time` filtering for shortcuts/false hits and better stint/stat logic + - seeding modes for practice/qualifying: best N laps total, average, or consecutive + - selectable qualifying points tables and tie-break rules + - `Race Format` presets for short technical tracks, club races, IFMAR-style layouts, and endurance + - schedule drift on `Dashboard` between planned and actual runtime + - session type `Free Practice` for rolling lap-time display without seeding + - automatic qualifying heat generation from practice standings or class list + - re-seeding of upcoming qualifying heats from current standings + - automatic `A/B/C...` finals generation from rankings + - persistent manual grid per session with drag-and-drop grid editor + - auto-reseed skips heats with locked manual grid + - explicit `Lock/Unlock grid` per session + - multi-leg final standings with counted final legs + - optional bump-up between finals + - reserved bump-up slots in higher finals + - visual finals matrix with reserved bump slots + - drag-and-drop grid editor for position starts + - print/export of heat sheets per qualifying/final + - overlay modes for external display screens + - multiple overlay modes: leaderboard, speaker, results, TV, team + - speaker overlay with event markers and separate speaker cues + - live speaker panel in `Timing` + - speaker cues and club/PDF branding from `Settings` + - overlay logo upload from `Settings` + - per-event/per-race branding in `Manage` + - extra speaker cues for `session start`, `new best lap`, and `top 3 change` + - selectable PDF themes: `classic`, `minimal`, `motorsport` + - branded print and PDF exports + - server-generated PDF exports with embedded logo + - generated qualifying/finals inherit duration and start mode from race format + - finish sound uses a siren instead of browser TTS +- Sessions: + - `practice` + - `qualification` + - `heat` + - `final` + - `free_practice` + - `open_practice` + - `team_race` +- Sponsor event tools: + - automatic round creation (`qualification`, `heat`, `final`) + - auto-assign driver -> car per session +- Live timing from AMMC WebSocket (`msg: "PASSING"`) +- Managed AMMC from the web UI: + - backend can start/stop local `ammc-amb` on Windows, Linux, and macOS + - bundled binaries from `AMMC/windows64`, `AMMC/linux_x86-64`, `AMMC/apple_m` +- Editing in UI: + - classes, event names/dates, drivers, and cars can be edited directly +- Live race control: + - countdown during timed sessions + - auto-finish at end of session time with `Race is finished` + - leaderboard sorting by laps first, then nearest to target time when applicable + - browser audio for passings (`beep` or driver name) and finish + - session start types: `Mass start`, `Position start`, `Staggered` + - `Timing` shows grid/order for the active `Position start` session + - leaderboard shows `gap to leader`, `gap ahead`, and `own delta` + - `Recent Passings` shows invalid laps such as `Short lap` and `Over max lap` + - manual corrections in `Timing -> Details`: `+1/-1 lap`, `+1/+5/-1 sec`, reset + - practice/qualifying seeding on best `2` or `3` laps +- Persistence: + - frontend state in browser `localStorage` + - same state and passings persisted to local SQLite through the Node backend +- Built-in `Guide` page in the app covering: + - sponsor events (for example 10 drivers / 4 cars) + - standard race setup + - invalid laps, follow-up, and manual corrections + - AMMC + npm setup on Windows and Linux +- UI language selection: + - `SV` + - `EN` -## Nya racefunktioner +## Race features ### Follow-up time -- Ställs i `Race Setup -> Hantera -> Raceformat` -- Kan också sättas per session när du skapar eller redigerar en session -- När ordinarie tid går ut går sessionen först in i `Follow-up aktiv` -- När follow-up-tiden är slut stängs sessionen automatiskt -- Genererade kval/finaler ärver follow-up från raceformatet +- Configure it in `Race Setup -> Manage -> Race Format` +- It can also be set per session when creating or editing a session +- When scheduled time ends, the session enters follow-up first +- When follow-up ends, the session closes automatically +- Generated qualifying/finals inherit follow-up from race format -### Min / Max varvtid -- Ställs i `Race Setup -> Hantera -> Raceformat` -- `Min varvtid`: - - varv snabbare än gränsen ignoreras som shortcut eller felträff -- `Max varvtid`: - - varv långsammare än gränsen räknas inte som giltigt varv - - används också för att bryta stintar och förbättra statistik +### Min / Max lap time +- Configure it in `Race Setup -> Manage -> Race Format` +- `Min lap time`: + - laps faster than the threshold are ignored as shortcuts or false hits +- `Max lap time`: + - laps slower than the threshold are not counted as valid laps + - also used to split stints and improve statistics -Praktiskt exempel: -- bana runt `16 sek/varv` -- `Min varvtid = 11 sek` -- `Max varvtid = 60 sek` +Example: +- track around `16 sec/lap` +- `Min lap time = 11 sec` +- `Max lap time = 60 sec` -### Ogiltiga passeringar -- `Tidtagning -> Senaste passeringar` visar nu både giltiga och ogiltiga passeringar -- status som visas: - - `För kort varv` - - `Över maxvarv` -- ogiltiga passeringar markeras visuellt i listan +### Invalid passings +- `Timing -> Recent Passings` shows both valid and invalid passings +- displayed statuses include: + - `Short lap` + - `Over max lap` +- invalid passings are visually highlighted -### Manuella korrigeringar -- öppna `Tidtagning` -- klicka `Detaljer` på en förare / ett lag -- där finns: - - `+1 varv` - - `-1 varv` - - `+1 sek` - - `+5 sek` - - `-1 sek` - - `Nollställ korrigering` -- korrigeringarna uppdaterar leaderboard och resultat direkt +### Manual corrections +- open `Timing` +- click `Details` on a driver or team +- available actions: + - `+1 lap` + - `-1 lap` + - `+1 sec` + - `+5 sec` + - `-1 sec` + - `Reset correction` +- leaderboard and results update immediately ### Best laps / average / consecutive -- Ställs per session med `Seedmetod` när `Seed bästa varv` är större än `0` -- tillgängliga lägen: - - `Bästa N varv, summa` - - `Bästa N varv, snitt` - - `Bästa N konsekutiva varv` -- leaderboard och ranking visar rätt format beroende på läge: - - summa: `3/00:48.321` - - snitt: `3 avg 16.107` - - konsekutiva: `3 con 00:49.005` +- Configure per session with `Seed Method` when `Best laps for seeding` is greater than `0` +- available modes: + - `Best N laps, total` + - `Best N laps, average` + - `Best N consecutive laps` +- leaderboard and standings use the correct format: + - total: `3/00:48.321` + - average: `3 avg 16.107` + - consecutive: `3 con 00:49.005` -### Poängtabeller och tie-break -- Ställs i `Race Setup -> Hantera -> Raceformat` -- poängtabeller för kval: - - `Placeringstal (1,2,3...)` - - `Fallande efter fältstorlek` +### Points tables and tie-break +- Configure in `Race Setup -> Manage -> Race Format` +- qualifying points tables: + - `Placement values (1,2,3...)` + - `Descending by field size` - `10-9-8-7-6-5-4-3-2-1` -- tie-break för kvalranking: - - `Jämför räknade rundor` - - `Bästa enskilda varv` - - `Bästa runda / heatresultat` -- kvalrankingen visar även en underrad med aktiv tie-break-information i tabellen +- qualifying tie-break options: + - `Compare counted rounds` + - `Best single lap` + - `Best round / heat result` +- qualifying standings also show an inline tie-break note in the table -### Raceformat presets -- `Race Setup -> Hantera -> Raceformat` -- välj ett preset och klicka `Applicera preset` -- tillgängliga presets: - - `Kort teknisk bana 16s` - - `Klubbrace kval + final` - - `IFMAR-stil kval/final` - - `Endurance / lagrace` -- efter applicering kan alla fält fortfarande justeras manuellt och sparas som vanligt -- `Spara klubb-preset` lagrar egna lokala presets i appens state så de kan återanvändas på samma installation -- `Ta bort klubb-preset` tar bort ett lokalt preset igen -- `Inställningar -> Klubb-presetar` kan exportera/importera presetbiblioteket som JSON mellan installationer +### Race format presets +- `Race Setup -> Manage -> Race Format` +- choose a preset and click `Apply preset` +- built-in presets: + - `Short technical track 16s` + - `Club race qual + finals` + - `IFMAR-style qual/finals` + - `Endurance / team race` +- after applying, all fields can still be adjusted manually and saved as usual +- `Save club preset` stores your own local presets in app state +- `Delete club preset` removes a local preset +- `Settings -> Club presets` can export/import the preset library as JSON between installations -### Schemaavvikelse på Översikt -- `Översikt` visar nu om dagen ligger före eller efter schema -- planerad tid räknar: - - sessionens varaktighet - - plus follow-up tid -- faktisk tid räknar: - - verklig tid från start till stopp - - eller pågående körtid om sessionen fortfarande kör +### Schedule drift on Dashboard +- `Dashboard` shows whether the day is ahead of or behind schedule +- planned time includes: + - session duration + - follow-up time +- actual time includes: + - real time from start to stop + - or live runtime if the session is still running -### Invalid-lap markering i leaderboard -- om senaste mottagna passing för en förare/ett lag var ogiltig markeras raden även i leaderboard och overlay -- det gör det lättare att se felträffar utan att behöva stå i `Senaste passeringar` +### Invalid-lap marker in leaderboard +- if the latest passing for a driver or team is invalid, the row is marked in both leaderboard and overlay +- this makes it easier to see problems without staying in `Recent Passings` -### Manuell invalidate last lap -- `Tidtagning -> Detaljer` -- knappen `Ogiltigförklara senaste varv` markerar senaste räknade varv som manuellt ogiltigt -- leaderboard, overlay och passings-historik uppdateras direkt -- `Återställ senaste manuellt ogiltiga varv` lägger tillbaka senaste manuellt ogiltiga varvet om du ångrar dig +### Manual invalidate / restore last lap +- `Timing -> Details` +- `Invalidate last lap` marks the latest counted lap as manually invalid +- leaderboard, overlay, and lap history update immediately +- `Restore latest manually invalidated lap` puts the latest manually invalidated lap back if needed -### Domarvy -- ny meny `Domare` -- visar aktiv session, leaderboard, lap history och domarlogg i samma vy -- samma korrigeringar som i `Tidtagning -> Detaljer` finns där som snabbknappar -- filter för: - - `Alla` - - `Ogiltiga` - - `Korrigerade` +### Judging view +- separate `Judging` menu +- shows active session, leaderboard, lap history, and judging log in one view +- same corrections as `Timing -> Details` +- row filters: + - `All` + - `Invalid` + - `Corrected` - `Team race` -- domarloggen kan exporteras per session som JSON -- både `Ångra senaste` och undo-knapp per loggrad finns för flera manuella åtgärder +- judging log can be exported per session as JSON +- supports `Undo latest` and per-log-row undo for multiple recent manual actions ## Windows installation -Kör i PowerShell i projektmappen. +Run in PowerShell in the project directory. -1. Installera Node.js LTS (18+). -2. Installera dependencies: +1. Install Node.js LTS (18+). +2. Install dependencies: ```powershell npm install ``` -3. Starta servern i bakgrunden: +3. Start the server in the background: ```powershell npm start ``` -4. Öppna: - - `http://localhost:8081` - - eller från annan dator: `http://:8081` +4. Open: +- `http://localhost:8081` +- or from another computer: `http://:8081` -Vanliga kommandon: +Common commands: ```powershell npm start npm stop @@ -211,82 +222,82 @@ npm run status npm run start:fg ``` -- `npm start` startar `live_event` i bakgrunden -- `npm stop` stoppar processen via `data/server.pid` -- `npm restart` startar om backend -- `npm run status` visar om backend kör -- `npm run start:fg` kör i foreground för felsökning +- `npm start` starts the backend in the background +- `npm stop` stops the process via `data/server.pid` +- `npm restart` restarts the backend +- `npm run status` shows whether the backend is running +- `npm run start:fg` runs in foreground for troubleshooting -### Windows scripts (bakgrundsstart) -Det finns färdiga `.bat`-filer i mappen `windows/`: -- `windows\\start_ammc.bat` startar AMMC i bakgrunden -- `windows\\start_backend.bat` startar `npm start` i bakgrunden (logg: `logs\\backend.log`) -- `windows\\start_all.bat` startar både AMMC + backend och öppnar webbsidan -- `windows\\stop_all.bat` stoppar backend på port `8081` och `ammc-amb.exe` +### Windows scripts +The `windows/` folder includes: +- `windows\\start_ammc.bat` starts AMMC in the background +- `windows\\start_backend.bat` starts `npm start` in the background (log: `logs\\backend.log`) +- `windows\\start_all.bat` starts both AMMC + backend and opens the web page +- `windows\\stop_all.bat` stops the backend on port `8081` and `ammc-amb.exe` -SQLite-filen skapas automatiskt här: +SQLite database file: - `data\\rc_timing.sqlite` -## Koppla mot AMMC -Det finns nu två sätt: +## Connect to AMMC +There are two supported modes. -### A. Hanterad AMMC i webbgränssnittet -Viktigt: -- AMMC körs på samma host där `npm start` / `node server.js` körs. -- Om du öppnar sidan från en annan laptop startas ingen AMMC där. -- Fältet `AMMC binär` i `Settings` är en sökväg på backend-hosten, inte på klienten som surfar in. +### A. Managed AMMC from the web UI +Important: +- AMMC runs on the same host where `npm start` / `node server.js` runs +- if you only browse from another laptop, no process starts there +- the `AMMC executable` field in `Settings` is a path on the backend host, not the client browser machine -1. Lägg AMMC-binärerna i projektmappen `AMMC/` (redan gjort i denna repo). -2. Öppna `Settings`. -3. Aktivera `Hanterad AMMC / Managed AMMC`. -4. Sätt `Decoder IP / host`, kontrollera port `9000`, spara. -5. Klicka `Starta AMMC / Start AMMC`. -6. Klicka `Använd serverns WS-url / Use server WS URL` så sätts klienten till t.ex. `ws://:9000`. +1. Place AMMC binaries in the `AMMC/` project folder. +2. Open `Settings`. +3. Enable `Managed AMMC`. +4. Set `Decoder IP / host`, verify port `9000`, save. +5. Click `Start AMMC`. +6. Click `Use server WS URL` so the client uses for example `ws://:9000`. -Standardbinärer: -- Linux-host: `AMMC/linux_x86-64/ammc-amb` -- Windows-host: `AMMC/windows64/ammc-amb.exe` -- macOS-host: `AMMC/apple_m/ammc-amb` +Default binaries: +- Linux host: `AMMC/linux_x86-64/ammc-amb` +- Windows host: `AMMC/windows64/ammc-amb.exe` +- macOS host: `AMMC/apple_m/ammc-amb` -### B. Manuell start -Starta AMMC med WebSocket (exempel): +### B. Manual start +Example: ```powershell ammc-amb.exe -w 9000 192.168.1.11 ``` -I appen: -1. `Settings` -2. Sätt `WebSocket URL` till t.ex. `ws://127.0.0.1:9000` -3. Sätt `Backend URL` till `http://127.0.0.1:8081` -4. Klicka `Test Backend` -5. Gå till `Timing` och klicka `Connect Decoder` +In the app: +1. Open `Settings` +2. Set `WebSocket URL`, for example `ws://127.0.0.1:9000` +3. Set `Backend URL` to `http://127.0.0.1:8081` +4. Click `Test Backend` +5. Go to `Timing` and click `Connect Decoder` -Om du kör Linux-brandvägg (UFW), öppna porten: +If Linux firewall/UFW is enabled: ```bash sudo ufw allow 8081/tcp ``` -## Auto reload vid uppdatering -- Servern bevakar `index.html`, `src/app.js` och `src/styles.css`. -- När du uppdaterar filer i `Live_RC` och sparar, laddar klienten om sidan automatiskt. -- Om backendkoden ändras, kör `npm restart`. +## Auto reload during development +- The server watches `index.html`, `src/app.js`, and `src/styles.css` +- When files in `Live_RC` change, the client reloads automatically +- If backend code changes, run `npm restart` -## Verifiera att SQLite sparar -Hämta senaste passeringar via API: +## Verify SQLite persistence +Latest passings via API: - `http://localhost:8081/api/passings` -Hämta sparad app-state: +Saved app state via API: - `http://localhost:8081/api/state` -## Viktig regel för sponsor-event -- I **samma pågående session** måste varje aktiv bil ha unikt transponder-ID. -- Samma transponder-ID kan återanvändas i **nästa session** (Heat 1 -> Heat 2 -> Heat 3 -> Final 1 ...). +## Important rule for sponsor events +- In the same running session, every active car must have a unique transponder ID +- The same transponder ID can be reused in the next session (`Heat 1 -> Heat 2 -> Heat 3 -> Final 1 ...`) -## Referens AMMC JSON -Officiell quick-start: +## AMMC JSON reference +Official quick start: - https://www.ammconverter.eu/docs/intro/quick-start/ -Exempelmeddelande: +Example message: ```json { "msg": "PASSING", diff --git a/README.sv.md b/README.sv.md new file mode 100644 index 0000000..056d3f4 --- /dev/null +++ b/README.sv.md @@ -0,0 +1,301 @@ +# JMK RB RaceController + +RC timing app med sponsor-eventflöde (delade bilar/transpondrar mellan olika heat/finaler), AMMC WebSocket och lokal SQLite-lagring på Windows. + +## Vad som ingår +- Event-lägen: + - `Race (driver transponders)` + - `Track Event (shared cars)` +- UI-separering: + - `Event` = sponsor-event med delade bilar/transpondrar + - `Race Setup` = riktiga race med personlig transponder per förare + - `Race Setup` innehåller nu även: + - välj exakt vilka förare som är med i racet + - practice-ranking + - kval-ranking med `poäng` eller `bästa resultat` + - inbyggd guide för hur man skapar race steg för steg + - beskrivningar direkt i alla fält under `Raceformat` + - `Follow-up tid` efter ordinarie racetid innan heatet stängs + - `Min varvtid` och `Max varvtid` för att filtrera shortcuts/felträffar och styra bättre statistik/stintlogik + - seedmetoder för practice/kval: bästa N varv som summa, snitt eller konsekutiva varv + - valbar kval-poängtabell och tie-break-regler + - presets i `Raceformat` för kort teknisk bana, klubbrace, IFMAR-liknande upplägg och endurance + - schemaavvikelse på `Översikt` mellan planerad och faktisk körtid + - sessionstyp `Free Practice` för löpande varvtider utan seedning + - auto-generering av kvalheat från practice-ranking eller klasslista + - reseeding av kommande kvalheat från aktuell ranking + - auto-generering av `A/B/C...` finaler från ranking + - sparad manuell grid per session via dragbar grid-editor + - auto-reseed hoppar över heat där manuell grid har låsts tills du återställer den + - tydlig `Lås/Lås upp grid` i grid-editorn per session + - final-ranking över flera leg med räknade finalheat + - valbar `bump-up` mellan finaler + - reserverade bump-platser i högre finaler + - visuell finalmatris med reserverade bump-platser + - dragbar grid-editor för positionsstart + - utskrift/export av heatsheets per kval/final + - overlay-vy för extern leaderboard-skärm + - flera overlay-lägen: leaderboard, speaker och results + - speaker-overlay med eventmarkörer och separata speaker-cues + - live speaker-panel i `Timing` för att slå av/på cues under pågående session + - speaker-cues och klubbinfo/PDF-header styrs från `Settings` + - logo-upload för overlay från `Settings` + - branding per event/race med egen logo, tagline, footer och PDF-tema i `Hantera` + - extra speaker-cues för `session start`, `new best lap` och `top 3 change` + - valbart PDF-tema: `classic`, `minimal`, `motorsport` + - utskrift av startlistor och resultat med vald branding + - servergenererad PDF-export för startlistor, heatsheets och resultat med inbäddad logo + - genererade kval/finaler ärver tid och starttyp från raceformatet + - finish-ljud som siren i stället för browser-röst +- Sessioner: `practice`, `qualification`, `heat`, `final` +- Sponsor-verktyg: + - Skapa rundor automatiskt (`qualification`, `heat`, `final`) + - Auto-assign förare -> bil per session +- Live timing från AMMC WebSocket (`msg: "PASSING"`) +- Hanterad AMMC från webbgränssnittet: + - backend kan starta/stoppa lokal `ammc-amb` på Windows, Linux och macOS + - läser bundlade binärer från `AMMC/windows64`, `AMMC/linux_x86-64`, `AMMC/apple_m` +- Redigering i UI: + - Klasser, eventnamn/datum, förare och bilar kan redigeras direkt +- Live race-kontroll: + - Nedräkning under pågående session + - Auto-finish vid tidslut med status `Race is finished` + - Leaderboard-sortering: varv först, därefter närmast måltid för sessionen (t.ex. 5 min = 600s) + - Browserljud för passing (`blipp` eller tala förarnamn) och målgång + - Sessioninställningar för `Mass start`, `Position start`, `Staggered` + - `Timing` visar grid/startordning för aktiv `Position start`-session + - leaderboard visar både `gap till ledaren`, `gap till bilen framför` och `eget delta` mot förra varvet + - `Senaste passeringar` visar nu även ogiltiga varv med status `För kort varv` eller `Över maxvarv` + - manuella korrigeringar i `Tidtagning -> Detaljer`: `+1/-1 varv`, `+1/+5/-1 sek`, `Nollställ korrigering` + - Practice/Kval kan seedas på bästa `2` eller `3` varv i sessionsinställningar +- Persistens: + - Frontend state i browser (`localStorage`) + - Samma state + passeringar sparas i lokal SQLite via Node-backend +- Inbyggd `Guide`-meny i appen med steg-för-steg för: + - Sponsor-event (10 personer / 4 bilar) + - Vanligt race + - ogiltiga varv, follow-up och manuella korrigeringar + - AMMC + npm setup på Windows och Linux +- Språkval i UI: `SV` / `EN` + +## Nya racefunktioner + +### Follow-up time +- Ställs i `Race Setup -> Hantera -> Raceformat` +- Kan också sättas per session när du skapar eller redigerar en session +- När ordinarie tid går ut går sessionen först in i `Follow-up aktiv` +- När follow-up-tiden är slut stängs sessionen automatiskt +- Genererade kval/finaler ärver follow-up från raceformatet + +### Min / Max varvtid +- Ställs i `Race Setup -> Hantera -> Raceformat` +- `Min varvtid`: + - varv snabbare än gränsen ignoreras som shortcut eller felträff +- `Max varvtid`: + - varv långsammare än gränsen räknas inte som giltigt varv + - används också för att bryta stintar och förbättra statistik + +Praktiskt exempel: +- bana runt `16 sek/varv` +- `Min varvtid = 11 sek` +- `Max varvtid = 60 sek` + +### Ogiltiga passeringar +- `Tidtagning -> Senaste passeringar` visar nu både giltiga och ogiltiga passeringar +- status som visas: + - `För kort varv` + - `Över maxvarv` +- ogiltiga passeringar markeras visuellt i listan + +### Manuella korrigeringar +- öppna `Tidtagning` +- klicka `Detaljer` på en förare / ett lag +- där finns: + - `+1 varv` + - `-1 varv` + - `+1 sek` + - `+5 sek` + - `-1 sek` + - `Nollställ korrigering` +- korrigeringarna uppdaterar leaderboard och resultat direkt + +### Best laps / average / consecutive +- Ställs per session med `Seedmetod` när `Seed bästa varv` är större än `0` +- tillgängliga lägen: + - `Bästa N varv, summa` + - `Bästa N varv, snitt` + - `Bästa N konsekutiva varv` +- leaderboard och ranking visar rätt format beroende på läge: + - summa: `3/00:48.321` + - snitt: `3 avg 16.107` + - konsekutiva: `3 con 00:49.005` + +### Poängtabeller och tie-break +- Ställs i `Race Setup -> Hantera -> Raceformat` +- poängtabeller för kval: + - `Placeringstal (1,2,3...)` + - `Fallande efter fältstorlek` + - `10-9-8-7-6-5-4-3-2-1` +- tie-break för kvalranking: + - `Jämför räknade rundor` + - `Bästa enskilda varv` + - `Bästa runda / heatresultat` +- kvalrankingen visar även en underrad med aktiv tie-break-information i tabellen + +### Raceformat presets +- `Race Setup -> Hantera -> Raceformat` +- välj ett preset och klicka `Applicera preset` +- tillgängliga presets: + - `Kort teknisk bana 16s` + - `Klubbrace kval + final` + - `IFMAR-stil kval/final` + - `Endurance / lagrace` +- efter applicering kan alla fält fortfarande justeras manuellt och sparas som vanligt +- `Spara klubb-preset` lagrar egna lokala presets i appens state så de kan återanvändas på samma installation +- `Ta bort klubb-preset` tar bort ett lokalt preset igen +- `Inställningar -> Klubb-presetar` kan exportera/importera presetbiblioteket som JSON mellan installationer + +### Schemaavvikelse på Översikt +- `Översikt` visar nu om dagen ligger före eller efter schema +- planerad tid räknar: + - sessionens varaktighet + - plus follow-up tid +- faktisk tid räknar: + - verklig tid från start till stopp + - eller pågående körtid om sessionen fortfarande kör + +### Invalid-lap markering i leaderboard +- om senaste mottagna passing för en förare/ett lag var ogiltig markeras raden även i leaderboard och overlay +- det gör det lättare att se felträffar utan att behöva stå i `Senaste passeringar` + +### Manuell invalidate last lap +- `Tidtagning -> Detaljer` +- knappen `Ogiltigförklara senaste varv` markerar senaste räknade varv som manuellt ogiltigt +- leaderboard, overlay och passings-historik uppdateras direkt +- `Återställ senaste manuellt ogiltiga varv` lägger tillbaka senaste manuellt ogiltiga varvet om du ångrar dig + +### Domarvy +- ny meny `Domare` +- visar aktiv session, leaderboard, lap history och domarlogg i samma vy +- samma korrigeringar som i `Tidtagning -> Detaljer` finns där som snabbknappar +- filter för: + - `Alla` + - `Ogiltiga` + - `Korrigerade` + - `Team race` +- domarloggen kan exporteras per session som JSON +- både `Ångra senaste` och undo-knapp per loggrad finns för flera manuella åtgärder + +## Windows installation +Kör i PowerShell i projektmappen. + +1. Installera Node.js LTS (18+). +2. Installera dependencies: + ```powershell + npm install + ``` +3. Starta servern i bakgrunden: + ```powershell + npm start + ``` +4. Öppna: + - `http://localhost:8081` + - eller från annan dator: `http://:8081` + +Vanliga kommandon: +```powershell +npm start +npm stop +npm restart +npm run status +npm run start:fg +``` + +- `npm start` startar `live_event` i bakgrunden +- `npm stop` stoppar processen via `data/server.pid` +- `npm restart` startar om backend +- `npm run status` visar om backend kör +- `npm run start:fg` kör i foreground för felsökning + +### Windows scripts (bakgrundsstart) +Det finns färdiga `.bat`-filer i mappen `windows/`: +- `windows\\start_ammc.bat` startar AMMC i bakgrunden +- `windows\\start_backend.bat` startar `npm start` i bakgrunden (logg: `logs\\backend.log`) +- `windows\\start_all.bat` startar både AMMC + backend och öppnar webbsidan +- `windows\\stop_all.bat` stoppar backend på port `8081` och `ammc-amb.exe` + +SQLite-filen skapas automatiskt här: +- `data\\rc_timing.sqlite` + +## Koppla mot AMMC +Det finns nu två sätt: + +### A. Hanterad AMMC i webbgränssnittet +Viktigt: +- AMMC körs på samma host där `npm start` / `node server.js` körs. +- Om du öppnar sidan från en annan laptop startas ingen AMMC där. +- Fältet `AMMC binär` i `Settings` är en sökväg på backend-hosten, inte på klienten som surfar in. + +1. Lägg AMMC-binärerna i projektmappen `AMMC/` (redan gjort i denna repo). +2. Öppna `Settings`. +3. Aktivera `Hanterad AMMC / Managed AMMC`. +4. Sätt `Decoder IP / host`, kontrollera port `9000`, spara. +5. Klicka `Starta AMMC / Start AMMC`. +6. Klicka `Använd serverns WS-url / Use server WS URL` så sätts klienten till t.ex. `ws://:9000`. + +Standardbinärer: +- Linux-host: `AMMC/linux_x86-64/ammc-amb` +- Windows-host: `AMMC/windows64/ammc-amb.exe` +- macOS-host: `AMMC/apple_m/ammc-amb` + +### B. Manuell start +Starta AMMC med WebSocket (exempel): +```powershell +ammc-amb.exe -w 9000 192.168.1.11 +``` + +I appen: +1. `Settings` +2. Sätt `WebSocket URL` till t.ex. `ws://127.0.0.1:9000` +3. Sätt `Backend URL` till `http://127.0.0.1:8081` +4. Klicka `Test Backend` +5. Gå till `Timing` och klicka `Connect Decoder` + +Om du kör Linux-brandvägg (UFW), öppna porten: +```bash +sudo ufw allow 8081/tcp +``` + +## Auto reload vid uppdatering +- Servern bevakar `index.html`, `src/app.js` och `src/styles.css`. +- När du uppdaterar filer i `Live_RC` och sparar, laddar klienten om sidan automatiskt. +- Om backendkoden ändras, kör `npm restart`. + +## Verifiera att SQLite sparar +Hämta senaste passeringar via API: +- `http://localhost:8081/api/passings` + +Hämta sparad app-state: +- `http://localhost:8081/api/state` + +## Viktig regel för sponsor-event +- I **samma pågående session** måste varje aktiv bil ha unikt transponder-ID. +- Samma transponder-ID kan återanvändas i **nästa session** (Heat 1 -> Heat 2 -> Heat 3 -> Final 1 ...). + +## Referens AMMC JSON +Officiell quick-start: +- https://www.ammconverter.eu/docs/intro/quick-start/ + +Exempelmeddelande: +```json +{ + "msg": "PASSING", + "passing_number": 1, + "transponder": 232323, + "rtc_time": "2022-10-11T22:57:36.099+02:00", + "strength": 0.0, + "resend": false, + "tran_code": "ID:232323", + "loop_id": "55" +} +```