System Architecture
LibreScoot runs on two embedded Linux computers that communicate via Redis over USB Ethernet.
Overview
The Two Computers
MDB - Middle Driver Board
The main controller. Talks to the ECU, batteries, NFC reader, modem, and nRF52 co-processor.
Hardware interfaces:
- CAN bus (ECU communication)
- I2C/GPIO (battery BMS, sensors)
- NFC reader (keycard authentication)
- 4G modem (cellular connectivity)
- GPS receiver
Key services:
- vehicle-service - State machine, lock/unlock, LED control
- battery-service - BMS communication, charge monitoring
- ecu-service - Motor controller (Bosch/Votol)
- uplink-service - Remote telemetry and commands
- alarm-service - Motion detection
DBC - Dashboard Computer
Handles the user interface, navigation, and display.
Hardware interfaces:
- LCD display (480x480)
- Ambient light sensor
Key services:
- scootui - Flutter dashboard UI
- dbc-backlight-service - Display brightness control
- carplay-service - CarPlay dongle support
Redis IPC
Services communicate through Redis pub/sub and hash fields. The redis-ipc library provides a common interface.
Key patterns:
- State hashes -
vehicle,battery:0,engine-ecu - Command queues -
scooter:state,scooter:power - Pub/sub channels - Real-time state change notifications
The MDB runs the primary Redis instance. DBC connects to it over USB Ethernet (192.168.7.1:6379).
Power States
The scooter has two state machines: vehicle state (operational mode) and power manager state (power/suspend).
Vehicle States
stateDiagram-v2
state "stand-by" as stand_by
state "ready-to-drive" as ready_to_drive
state "shutting-down" as shutting_down
[*] --> stand_by: Boot
stand_by --> ready_to_drive: Unlock (conditions met)
stand_by --> parked: Unlock (kickstand down)
ready_to_drive --> parked: Kickstand down (1s)
parked --> ready_to_drive: Kickstand up + ready
parked --> shutting_down: Lock
shutting_down --> stand_by: ~5s
Ready-to-drive requires: dashboard ready, kickstand up, seatbox closed, handlebar unlocked.
Power Manager States
stateDiagram-v2
state "suspending-imminent" as suspending_imminent
state "hibernating-imminent" as hibernating_imminent
[*] --> booting
booting --> running: ~5s
running --> suspending_imminent: Suspend request
suspending_imminent --> suspending: ~60s delay
suspending_imminent --> running: Abort
suspending --> running: Wake
suspending --> hibernating_imminent: Low battery / manual
hibernating_imminent --> hibernating: ~20s
hibernating --> booting: Wake (brakes 10s / BLE)
Wake from hibernation: hold both brakes 10s, or BLE connection. Keycard does not wake from hibernate.
OTA Updates
Updates are managed by update-service using Mender for atomic A/B partition updates.
- Delta updates - Only download changed bytes
- Channels - stable, testing, nightly
- Independent updates - MDB and DBC update separately