Smart Sensor Simulation 2 (SSS2) Control System with FastAPI backend and Svelte 5 frontend.
The SSS2 Control System is a web-based interface for configuring and controlling the Smart Sensor Simulation 2 hardware device. The system provides real-time control of 16 potentiometers, ECU pin configurations, and hardware state management with snapshot capabilities.
Backend: FastAPI (Python) with asyncio for serial communication
Frontend: Svelte 5 with Runes, Tailwind CSS
Storage: JSON file-based storage (no database required)
Target Platform: Raspberry Pi (optimized for small footprint)
sss2-gui/
├── app-ui/ # FastAPI backend
│ ├── main.py # Application entry point
│ ├── routers/ # API route handlers
│ ├── services/ # Business logic layer
│ ├── middleware/ # Orchestrator for service coordination
│ ├── store/ # File-based JSON storage
│ └── tests/ # pytest tests
├── ui/ # Svelte frontend
│ ├── src/
│ │ ├── lib/
│ │ │ ├── api/ # API client
│ │ │ ├── components/ # Reusable components
│ │ │ ├── pages/ # Page components
│ │ │ └── stores/ # Svelte stores (state management)
│ │ └── routes/ # SvelteKit routes
│ └── static/ # Static assets (served by backend in production)
└── scripts/ # Build scripts
State Management
Serial Communication
serial_asyncio16 Potentiometers (U1-U16)
Power Group Configuration
Hardware Commands
{port},{value} (e.g., 1,128)51,{7|3} for ports 1-16 (7=on, 3=off){25-32},{0|1} (25-32 for groups 1-8, 0=5V, 1=12V)ECU Configuration
Pin Configuration
Touch-Friendly Design
Real-Time Updates
Navigation
Terminal 1 - Backend:
cd app-ui
pip install -r requirements.txt
python main.py
Backend runs on http://localhost:8000
Terminal 2 - Frontend (Hot Reload):
cd ui
npm install
npm run dev
Frontend runs on http://localhost:5173 (Vite default) and proxies API calls to http://localhost:8000
Build UI and copy to backend:
./scripts/build-ui.sh
Run backend (serves API + static UI):
cd app-ui
pip install -r requirements.txt
python main.py
Or using uvicorn directly:
cd app-ui
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
Access the application at http://localhost:8000
The serial port can be configured via environment variable:
export SSS2_SERIAL_PORT=/dev/tty.usbmodem40768801 # Mac default
# or
export SSS2_SERIAL_PORT=/dev/ttyACM0 # Linux/Pi default
Or create a .env file in app-ui/:
SSS2_SERIAL_PORT=/dev/tty.usbmodem40768801
Default Serial Ports:
/dev/tty.usbmodem40768801/dev/ttyACM0GET /api/sss2/state - Get current device statePUT /api/sss2/state - Update device statePOST /api/sss2/ignition - Toggle ignition (body: {"on": true/false})GET /api/catalog - Get peripheral catalogGET /api/health - Health checkGET /api/snapshots - List all snapshotsPOST /api/snapshots - Create snapshot (body: {"label": "optional"})POST /api/snapshots/{id}/revert - Revert to snapshotDELETE /api/snapshots/{id} - Delete snapshotGET /api/ecus - List all ECUsGET /api/ecus/{id} - Get ECU detailsPOST /api/ecus - Create new ECUPUT /api/ecus/{id} - Update ECUDELETE /api/ecus/{id} - Delete ECUGET /api/connection/status - Get connection status (REST)WS /api/connection/ws - WebSocket for connection status updates┌─────────────┐
│ FastAPI │ ← HTTP/WebSocket API
│ Routers │
└──────┬──────┘
│
┌──────▼──────────┐
│ Orchestrator │ ← Service coordination layer
└──────┬──────────┘
│
┌───┴────┬────────────┬──────────────┐
│ │ │ │
┌──▼──┐ ┌──▼─────┐ ┌────▼─────┐ ┌─────▼─────┐
│State│ │Serial │ │ECU │ │Snapshot │
│Svc │ │Service │ │Service │ │Service │
└──┬──┘ └──┬─────┘ └────┬─────┘ └─────┬─────┘
│ │ │ │
│ ┌──▼───┐ │ │
│ │ SSS2 │ │ │
│ │Hardw │ │ │
│ └──────┘ │ │
│ │ │
┌──▼────────────────────▼──────────────▼──┐
│ FileStore (JSON Files) │
│ - device_state.json │
│ - peripheral_catalog.json │
│ - ecus/*.json │
│ - snapshots/*.json │
└─────────────────────────────────────────┘
Hardware Connects
↓
SerialService detects connection
↓
Orchestrator._on_connection_changed() called
↓
Orchestrator.sync_state_to_hardware() triggered
↓
StateService.get_state() loads from file (source of truth)
↓
Apply all settings to hardware:
- Power groups (commands 25-32)
- Potentiometer enabled states (51,7/51,3)
- Potentiometer wiper positions (port,value)
↓
WebSocket broadcasts connection status to UI
↓
UI detects connection established
↓
UI calls fetchState() to get latest backend state
↓
All three systems synchronized: Backend ↔ Hardware ↔ UI
cd app-ui
pytest tests/
On your development machine:
./scripts/build-ui.sh
Copy app-ui/ to Raspberry Pi:
scp -r app-ui [email protected]:~/sss2-gui/
On Raspberry Pi:
cd ~/sss2-gui/app-ui
pip install -r requirements.txt
python main.py
Access from browser:
http://raspberrypi.local:8000
Note: Node.js is NOT required on the Raspberry Pi. Only Python is needed in production.
routers/ - API route handlers (FastAPI routers)services/ - Business logic layer (state, serial, ECU, snapshots)middleware/ - Orchestrator for service coordination and background tasksstore/ - File-based JSON storage (FileStore abstraction)tests/ - pytest testssrc/lib/api/ - TypeScript API clientsrc/lib/stores/ - Svelte 5 runes-based state storessrc/lib/components/ - Reusable Svelte componentssrc/lib/pages/ - Page components (Dashboard, Settings, History)src/routes/ - SvelteKit routesVOUTs Configuration
PWM Configuration
CAN Bus Configuration
J1708 Configuration
Error Handling & Recovery
Testing
Documentation
Advanced Features
UI Enhancements
Performance
For questions or issues, contact Teddy Nyambe teddy@infinityworx.co
LGPL v3 (Lesser GPL v3) - All Rights Reserved