16 KiB
JMK RB RaceController
English README. Swedish version: README.sv.md
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.
Architecture
- JavaScript module overview:
docs/javascript-architecture.md - Swedish operational guide:
README.sv.md
Screenshots
Overview
Timing
Overlay
Event
Race Setup
Team Overlay
Judging
Public Overlay And OBS
The app now supports a dedicated public overlay route so you do not need to expose the full admin UI externally.
- Public overlay route:
/public-overlay/<mode> - OBS mode:
/public-overlay/obs - OBS overlay can be configured from the
Overlaymenu:- rows
- layout:
leaderboard,grid,lowerthird - theme:
panel,transparent,chroma - visible columns and blocks
- Use
Copy OBS URLto generate a ready-to-paste browser-source link for OBS.
If you want simple protection for public overlays, set this environment variable on the server:
PUBLIC_OVERLAY_TOKEN=your-secret-token
Then the public overlay URL must include:
/public-overlay/obs?token=your-secret-token
Recommended deployment:
- publish only
/public-overlay/*through your reverse proxy - keep the main app/admin UI internal
Features
- Event modes:
Race (driver transponders)Track Event (shared cars)
- UI separation:
Event= sponsor events with shared cars/transpondersRace Setup= competition races with personal driver transponders
- Storage/import tools:
- full race-data export/import for backup or moving to another machine
- directory export/import for only classes, drivers and cars
- CSV export for drivers and cars when you want simple spreadsheet lists
- single race-package export/import from
Race Setup -> Manage -> Race Actions
- Race Setup includes:
- grouped
ParticipantsandTeamssections inManage - a four-step
Create Race Wizardfor new races Managesplit intoSetup,Format,Generation, andLive / results- Basic mode now reacts to the selected preset, including a cleaner endurance view
Basic / Advancedmode forRace Format- a right-side race summary card
- a preset-aware summary card that changes between endurance and normal race focus
- status badges for
Setup,Format,Generation, andLive / results - summary warnings when participants, sessions, teams, or lap-window settings are missing
- clickable summary warnings that jump to the relevant Manage section
- clickable step cards that act as quick navigation inside
Manage - compact step cards with live counters such as drivers, teams, sessions, and active/results state
- separate
Race actionsfor generation, reseeding and bump-up - reorganized in-app
Guidewith overview cards and two-column sections - explicit race participant selection
- practice standings
- qualifying standings with
pointsorbest result - built-in step-by-step guide
- inline descriptions for all
Race Formatfields Follow-up timeafter scheduled race time before a heat fully closesMin lap timeandMax lap timefiltering 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 Formatpresets for short technical tracks, club races, IFMAR-style layouts, and endurance- schedule drift on
Dashboardbetween planned and actual runtime - session type
Free Practicefor 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 gridper 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, andtop 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
- grouped
- Sessions:
practicequalificationheatfinalfree_practiceopen_practiceteam_race
- Sponsor event tools:
- automatic round creation (
qualification,heat,final) - auto-assign driver -> car per session
- automatic round creation (
- Live timing from AMMC WebSocket (
msg: "PASSING") - Managed AMMC from the web UI:
- backend can start/stop local
ammc-ambon Windows, Linux, and macOS - bundled binaries from
AMMC/windows64,AMMC/linux_x86-64,AMMC/apple_m
- backend can start/stop local
- Editing in UI:
- classes, event names/dates, drivers, and cars can be edited directly
- drivers and cars support optional
brandfields for team, sponsor, manufacturer, or model data DriversandCarscan be searched by name, transponder, or brand directly in the UI- race start lists and heat sheets include driver brand in print, CSV, and PDF exports
- 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 (
beepor driver name) and finish - session start types:
Mass start,Position start,Staggered Timingshows grid/order for the activePosition startsession- leaderboard shows
gap to leader,gap ahead, andown delta Recent Passingsshows invalid laps such asShort lapandOver max lap- manual corrections in
Timing -> Details:+1/-1 lap,+1/+5/-1 sec, reset - practice/qualifying seeding on best
2or3laps
- Persistence:
- frontend state in browser
localStorage - same state and passings persisted to local SQLite through the Node backend
- frontend state in browser
- Built-in
Guidepage 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:
SVEN
Create Race Wizard
Race Setupnow starts with a four-step wizard for new races:BasicsParticipantsSession planConfirm
- The wizard is intended to create the first race structure quickly:
- choose class and preset
- scope valid race drivers
- create practice, qualifying, and/or team-race sessions automatically
- Finals are still generated later from
Race Actionsafter practice or qualifying is complete.
Manage workflow
- After the race is created,
Manageis split into four clear stages:SetupFormatGenerationLive / results
Setuphandles race participants and teams. The top step cards also act as quick navigation between the four blocks.Formathandles practice/qualifying, finals, validation, presets, and advanced settings. In Basic mode, endurance hides most qualifying/finals fields until Advanced is opened.Generationis kept separate so actions like qualifying generation, reseeding, finals generation, and bump-up do not clutter the format form.Live / resultsis where grid, standings, print, PDF, and finals matrix are used once the structure is ready.
Export / Import
Settings -> Storagenow supports:- full JSON export/import for the complete competition database
- directory JSON export/import for only classes, drivers, and cars
- CSV export for drivers and cars
Race Setup -> Manage -> Race Actionsnow supports single race packages:- export one race with its sessions, results, and referenced classes/drivers/cars
- import that package into another installation as a new race entry
- JSON export files now include export metadata and a schema version field so future imports can be handled more safely.
Race features
Follow-up time
- 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 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
Example:
- track around
16 sec/lap Min lap time = 11 secMax lap time = 60 sec
Invalid passings
Timing -> Recent Passingsshows both valid and invalid passings- displayed statuses include:
Short lapOver max lap
- invalid passings are visually highlighted
Manual corrections
- open
Timing - click
Detailson a driver or team - available actions:
+1 lap-1 lap+1 sec+5 sec-1 secReset correction
- leaderboard and results update immediately
Best laps / average / consecutive
- Configure per session with
Seed MethodwhenBest laps for seedingis greater than0 - available modes:
Best N laps, totalBest N laps, averageBest 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
- total:
Points tables and tie-break
- Configure in
Race Setup -> Manage -> Race Format - qualifying points tables:
Placement values (1,2,3...)Descending by field size10-9-8-7-6-5-4-3-2-1
- qualifying tie-break options:
Compare counted roundsBest single lapBest round / heat result
- qualifying standings also show an inline tie-break note in the table
Race format presets
Race Setup -> Manage -> Race Format- choose a preset and click
Apply preset - built-in presets:
Short technical track 16sClub race qual + finalsIFMAR-style qual/finalsEndurance / team race
- after applying, all fields can still be adjusted manually and saved as usual
Save club presetstores your own local presets in app stateDelete club presetremoves a local presetSettings -> Club presetscan export/import the preset library as JSON between installations
Schedule drift on Dashboard
Dashboardshows 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 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
Manual invalidate / restore last lap
Timing -> DetailsInvalidate last lapmarks the latest counted lap as manually invalid- leaderboard, overlay, and lap history update immediately
Restore latest manually invalidated lapputs the latest manually invalidated lap back if needed
Judging view
- separate
Judgingmenu - shows active session, leaderboard, lap history, and judging log in one view
- same corrections as
Timing -> Details - row filters:
AllInvalidCorrectedTeam race
- judging log can be exported per session as JSON
- supports
Undo latestand per-log-row undo for multiple recent manual actions
Windows installation
Run in PowerShell in the project directory.
- Install Node.js LTS (18+).
- Install dependencies:
npm install - Start the server in the background:
npm start - Open:
http://localhost:8081- or from another computer:
http://<server-ip>:8081
Common commands:
npm start
npm stop
npm restart
npm run status
npm run start:fg
npm startstarts the backend in the backgroundnpm stopstops the process viadata/server.pidnpm restartrestarts the backendnpm run statusshows whether the backend is runningnpm run start:fgruns in foreground for troubleshooting
Windows scripts
The windows/ folder includes:
windows\\start_ammc.batstarts AMMC in the backgroundwindows\\start_backend.batstartsnpm startin the background (log:logs\\backend.log)windows\\start_all.batstarts both AMMC + backend and opens the web pagewindows\\stop_all.batstops the backend on port8081andammc-amb.exe
SQLite database file:
data\\rc_timing.sqlite
Connect to AMMC
There are two supported modes.
A. Managed AMMC from the web UI
Important:
- AMMC runs on the same host where
npm start/node server.jsruns - if you only browse from another laptop, no process starts there
- the
AMMC executablefield inSettingsis a path on the backend host, not the client browser machine
- Place AMMC binaries in the
AMMC/project folder. - Open
Settings. - Enable
Managed AMMC. - Set
Decoder IP / host, verify port9000, save. - Click
Start AMMC. - Click
Use server WS URLso the client uses for examplews://<server-ip>:9000.
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. Manual start
Example:
ammc-amb.exe -w 9000 192.168.1.11
In the app:
- Open
Settings - Set
WebSocket URL, for examplews://127.0.0.1:9000 - Set
Backend URLtohttp://127.0.0.1:8081 - Click
Test Backend - Go to
Timingand clickConnect Decoder
If Linux firewall/UFW is enabled:
sudo ufw allow 8081/tcp
Auto reload during development
- The server watches
index.html,src/app.js, andsrc/styles.css - When files in
Live_RCchange, the client reloads automatically - If backend code changes, run
npm restart
Verify SQLite persistence
Latest passings via API:
http://localhost:8081/api/passings
Saved app state via API:
http://localhost:8081/api/state
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 ...)
AMMC JSON reference
Official quick start:
Example message:
{
"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"
}






