This is a minimal TypeScript project scaffold.
Quick start
Install dependencies:
npm installBuild:
npm run buildRun (built):
npm startRun (dev):
npm run devArchitecture
The application is an Express server (src/index.ts) that runs the simulations in-process:
src/GeoSimulator.tsowns the running connectors and vehicles and wires them together.src/config/stores the config in SQLite (ConfigStore.ts) and validates API input (validation.ts).src/simulator/contains the simulators.RouteSimulatordrives one OSRM route;RandomRouteSimulatorandEmergencyDispatchSimulatorbuild onMultiRouteSimulator, which chains routes.createSimulator.tsmaps a vehicle config to its simulator. A vehicle's configured speed is its maximum:SpeedProfile.tsmakes it accelerate from standstill, follow the road speeds reported by OSRM, slow down for corners and brake in time for slower sections and the destination.src/connectors/forwards vehicle updates to external systems;createConnector.tsmaps a connector config to its connector.LiveStateConnector.tsis attached to every vehicle. It keeps the live state, stores the history in SQLite and publishes updates to the WebSocket (src/server/websocket.ts).src/server/app.tsandsrc/server/routes/define the HTTP API; the web UI is served frompublic/.src/utils/contains geo math (Geo.ts), the event emitter shared by entities and simulators, and logging.
Server settings (.env):
HOST(default127.0.0.1; use0.0.0.0to expose it on the network. There is no authentication, and anyone who can open the page can read and change the config, including API tokens.)PORT(default8080)DB_PATH(default./data/geosimulator.sqlite)
Configuration
Connectors and vehicles are stored in the database and edited in the web UI under Config. Each change is applied immediately: only the affected connector or vehicle is restarted. Disabled vehicles are stored but not run.
Web UI
Open http://127.0.0.1:8080/. It shows every vehicle's live position, status and current route on a map, plus a per-vehicle history of status changes, routes and positions (kept in the database, so it survives restarts).
API
GET /api/vehicles: live state of all running vehicles;GET /api/vehicles/configs: stored configsGET /api/vehicles/types,GET /api/connectors/types: required data fields per simulator/connector typePOST /api/vehicles,GET|PUT|DELETE /api/vehicles/:id: create, read (live state and config), replace or delete a vehicle. Creating or replacing an enabled vehicle (re)starts itGET|DELETE /api/vehicles/:id/history: stored positions, status changes and routesPOST /api/vehicles/:id/control: steer a runningEmergencyDispatchSimulatororRandomRouteSimulator. Body{"action": ...}withskipWait,extendWait(plus"seconds"),pauseWait,resumeWaitorsetNextDestination(plus"position": {"latitude", "longitude"}, ornullfor random again). The actions available right now are listed in the vehicle'sdetails.controls; others are rejected with409GET|POST /api/connectors,GET|PUT|DELETE /api/connectors/:id: list, add, read, replace or delete a connector. Connectors are identified by a UUIDidthat the server assigns onPOST; vehicles reference connectors by it, and the editablenameis only a label. A connector that cannot be set up is rejected with502. Deleting also removes it from all vehiclesws://<host>/api/ws: WebSocket with live updates as{"type": ..., "data": ...}messages, wheretypeisposition,status,routeorreload. Connections from other websites (foreignOrigin) are rejected.