I've solidified on an architecture after my latest conversation with Grandpa. We want the track to have control of race starts and lane events. This may seem a little complicated for such a "simple" project, but it comes with three wins:
Realtime frontend updates of race times/results
GPIO events can be mocked entirely - great for writing tests for the application logic
Event Driven: features are coupled to real life occurrences, not data models
---
title: Architecture
---
flowchart TD
subgraph Hardware IO
track[Physical Race Track]
gpio[GPIO Handler - Python]
end
subgraph Application Control
server[Application Server - NodeJS]
ws-server[Server Socket]
end
subgraph User Interface
subgraph Client Features
client[Browser GUI]
participants[Lane Assignments]
csv[CSV Download]
end
ws-client[Client Socket]
end
track-- Triggers Race -->gpio
track-- Reads Lane Events -->gpio
gpio-- Notifies Lane Times -->server;
gpio-- Notifies Race Start -->server;
client-- Store Race Results to FS -->server;
ws-client-- Realtime Race Results -->client;
ws-server-- Lane States -.->ws-client
server-- Lane States -.->ws-server;
server-- Converts Race Data -->csv;
participants-->client;
Hardware Layer
Responsibilities:
Read physical lane events
Time each lane
Notify Application of events and results
calls POST <server-port>/gpio/start when a new race has started
calls POST <server-port>/gpio/time?lane=<lane-number>&time=<lane-time> when a lane has finished
Application Control Layer
Responsibilities:
Respond to events from the GPIO service
Forward (via WebSockets) lane events to the frontend
Persist race data from the frontend
Serve client application files
User Interface
Responsibilities:
Enforce BSA racing guidelines
Determine lane assignments for individual cars
Determine stages of racing (rounds and heats)
Determine wins and rankings
Display realtime race results for each heat
Respond to events from the WebSocket service
Store ephemeral data relating to user flow
Environment
To keep all services in sync, the .env file at the root of the project maintains configuration constants that are shared or globally known, such as the port locations of callable services and track information.
I've solidified on an architecture after my latest conversation with Grandpa. We want the track to have control of race starts and lane events. This may seem a little complicated for such a "simple" project, but it comes with three wins:
Hardware Layer
Responsibilities:
POST <server-port>/gpio/start
when a new race has startedPOST <server-port>/gpio/time?lane=<lane-number>&time=<lane-time>
when a lane has finishedApplication Control Layer
Responsibilities:
User Interface
Responsibilities:
Environment
To keep all services in sync, the
.env
file at the root of the project maintains configuration constants that are shared or globally known, such as the port locations of callable services and track information.