Add English primary README and keep Swedish copy

This commit is contained in:
larssand
2026-03-16 16:25:29 +01:00
parent f64879b6d8
commit 9bd873cf5c
2 changed files with 536 additions and 224 deletions

459
README.md
View File

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

301
README.sv.md Normal file
View File

@@ -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://<server-ip>: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://<server-ip>: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"
}
```