Project Structure
Understanding the directory layout helps you navigate the codebase, contribute effectively, and customise RosFit for your use case.
Overview
The RosFit repository is organised as a monorepo. Each service lives in its own top-level directory with its own dependencies and Dockerfile.
rosfit/
├── bridge/ # Robot-side MQTT bridge (Python)
│ ├── rosfit_bridge/
│ │ ├── __init__.py
│ │ ├── bridge.py # Core bridge logic
│ │ ├── config.py # YAML config parser
│ │ ├── mqtt_client.py # MQTT connection manager
│ │ ├── ros_client.py # ROS 2 subscriber/publisher
│ │ ├── shadow.py # Device shadow sync
│ │ └── ota.py # OTA update handler
│ ├── tests/
│ ├── pyproject.toml
│ └── Dockerfile
├── api/ # FastAPI backend
│ ├── app/
│ │ ├── __init__.py
│ │ ├── main.py # App entrypoint & middleware
│ │ ├── models/ # SQLAlchemy / Pydantic models
│ │ ├── routes/ # REST endpoints
│ │ │ ├── devices.py
│ │ │ ├── commands.py
│ │ │ ├── telemetry.py
│ │ │ ├── shadows.py
│ │ │ ├── ota.py
│ │ │ └── fleet.py
│ │ ├── services/ # Business logic
│ │ ├── auth/ # JWT & API key auth
│ │ └── ws/ # WebSocket handlers
│ ├── tests/
│ ├── requirements.txt
│ └── Dockerfile
├── handler/ # MQTT message consumer
│ ├── rosfit_handler/
│ │ ├── __init__.py
│ │ ├── consumer.py # MQTT subscription loop
│ │ ├── processors/ # Per-topic message processors
│ │ │ ├── telemetry.py # Persist to TimescaleDB
│ │ │ ├── shadow.py # Update Redis shadow
│ │ │ ├── status.py # Device status tracker
│ │ │ └── ota.py # OTA progress handler
│ │ └── db.py # Database connection pool
│ ├── tests/
│ ├── requirements.txt
│ └── Dockerfile
├── dashboard/ # React frontend (Vite + TypeScript)
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── pages/ # Route pages
│ │ ├── hooks/ # Custom React hooks
│ │ ├── services/ # API client & WebSocket
│ │ ├── stores/ # Zustand state management
│ │ └── types/ # TypeScript type definitions
│ ├── public/
│ ├── package.json
│ ├── vite.config.ts
│ └── Dockerfile
├── config/ # Shared configuration
│ ├── emqx/
│ │ ├── acl.conf # MQTT ACL rules
│ │ └── emqx.conf # Broker settings
│ ├── certs/ # TLS certificates (gitignored)
│ │ └── .gitkeep
│ └── examples/
│ ├── bridge.yaml # Example bridge config
│ └── .env.example # Example environment file
├── migrations/ # Database migrations (Alembic)
│ ├── alembic.ini
│ ├── env.py
│ └── versions/
│ ├── 001_initial.py
│ ├── 002_telemetry_hypertable.py
│ └── 003_device_shadows.py
├── docker/ # Additional Dockerfiles
│ ├── docker-compose.yml
│ ├── docker-compose.prod.yml
│ └── nginx.conf # Reverse proxy config
├── docs/ # Documentation site (this site)
├── .env.example
├── docker-compose.yml # Development compose file
├── Makefile
└── README.md
Bridge
The bridge/ directory contains the robot-side Python package that runs on each device. It connects to the local ROS 2 network and forwards messages to the MQTT broker.
bridge.py— Orchestrates the ROS 2 ↔ MQTT mapping. Reads the YAML config, sets up subscribers and publishers, and manages the message loop.config.py— Parsesbridge.yaml, validates topic mappings, and resolves environment variable substitutions.mqtt_client.py— Manages the MQTT connection lifecycle: connect, reconnect, TLS, authentication, and last-will messages.ros_client.py— Creates ROS 2 subscribers and publishers dynamically based on the topic mapping configuration.shadow.py— Implements the device shadow protocol. Reports the current state and applies desired state changes received from the cloud.ota.py— Handles over-the-air firmware update commands. Downloads artefacts from MinIO, verifies checksums, and applies updates.
Install it on any machine with ROS 2:
pip install rosfit-bridge
API
The api/ directory contains the FastAPI backend that serves the REST API and WebSocket endpoints.
models/— SQLAlchemy ORM models for devices, commands, telemetry records, and user accounts. Pydantic schemas for request/response validation.routes/— One module per resource: devices, commands, telemetry, shadows, OTA, and fleet. Each defines the endpoint handlers.services/— Business logic separated from HTTP concerns. Handles command routing, telemetry aggregation, and shadow conflict resolution.auth/— JWT token issuance and verification, API key validation, and role-based permission checks.ws/— WebSocket handlers for real-time telemetry streaming and live device status updates.
The API starts on port 8000 by default and serves the OpenAPI spec at /docs.
Message Handler
The handler/ directory contains the MQTT message consumer that runs as a background service. It subscribes to all rosfit/# topics on the broker and processes incoming messages.
consumer.py— Connects to EMQX, subscribes to wildcard topics, and routes messages to the appropriate processor based on the topic pattern.processors/telemetry.py— Parses telemetry payloads and inserts them into TimescaleDB hypertables for time-series queries.processors/shadow.py— Updates the reported state in Redis and computes diffs against the desired state.processors/status.py— Tracks device online/offline status using MQTT last-will and keepalive messages.processors/ota.py— Monitors OTA update progress reports and updates the rollout status in the database.
The handler has no exposed ports — it communicates exclusively through MQTT and the database.
Dashboard
The dashboard/ directory contains the React frontend built with Vite and TypeScript.
components/— Reusable UI components: device cards, telemetry charts (Recharts), command forms, fleet map (Leaflet), and status indicators.pages/— Route-level pages: fleet overview, device detail, command console, OTA management, and settings.hooks/— Custom hooks for WebSocket subscriptions, API queries (React Query), and responsive layout.services/— API client (Axios) and WebSocket connection manager.stores/— Zustand stores for global state: selected device, active filters, user preferences.
The dashboard connects to the API over HTTP and receives real-time updates over WebSocket. It runs on port 3000.
Configuration
The config/ directory contains shared configuration that is mounted into Docker containers.
emqx/acl.conf— MQTT access control list. Restricts which devices can publish or subscribe to which topics, preventing cross-device access.emqx/emqx.conf— EMQX broker settings: listeners, authentication backends, rate limits, and clustering.certs/— Directory for TLS certificates. Gitignored by default. Generate certs withrosfit certs generateor place your own CA-signed certificates here.examples/— Example configuration files for new users. Thebridge.yamlshows a minimal topic mapping, and.env.exampledocuments all environment variables.
The migrations/ directory uses Alembic to manage database schema evolution. Run migrations with:
alembic upgrade head
The docker/ directory contains production-oriented compose files and an Nginx reverse proxy config for TLS termination and routing.