Add English primary README and keep Swedish copy
This commit is contained in:
459
README.md
459
README.md
@@ -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 på 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
301
README.sv.md
Normal 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"
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user