For monitoring telemetry and remote rocket setup.
- Required Tools:
- Git
- Node.js
- npm
- Docker
- Mosquitto
- Python 3.x
# Clone your project repository
git clone http://nakujaproject/n4-basestation
cd n4-basestation
# Switch to specific branch if needed
git checkout -b <branch-name>
# Install project dependencies for the React frontend
npm install
The backend is built using Python and Flask to handle serial communications and provide API endpoints. It works with the ESP Now configuration to receive the data through a serial port directly from the ESP then send this data via http to the frontend.
python -m venv venv
# Activate the virtual environment:
# On macOS/Linux:
source venv/bin/activate
# On Windows:
venv\Scripts\activate
pip install flask flask-cors pyserial
python server.py
This will start the Flask backend on http://localhost:5000.
You can verify it by visiting http://localhost:5000/debug.
Install Docker on your computer.
- Windows: Follow Docker Desktop for Windows installation.
- macOS: Follow Docker Desktop for Mac installation.
- Linux: Follow the instructions for Docker Engine and Docker Desktop for Linux.
-
Create a Docker group
sudo groupadd docker
-
Add your user to the
docker
groupsudo usermod -aG docker $USER
-
Log out and log back in so that your group membership is re-evaluated.
-
Verify that you can run
docker
commands withoutsudo
. -
For more details, see the Docker post-installation steps.
TileServer-GL is used to serve the map.
-
Pull the TileServer-GL Docker image:
docker pull maptiler/tileserver-gl
-
Download the vector tiles (MBTiles file):
Visit Kenya's MapTiler page and download the relevant MBTiles file. -
Run the TileServer-GL container:
Replaceosm-2020-02-10-v3.11_africa_kenya.mbtiles
with your downloaded file name.docker run --rm -it -v $(pwd):/data -p 8080:8080 maptiler/tileserver-gl --file osm-2020-02-10-v3.11_africa_kenya.mbtiles
In your browser, visit http://localhost:8080 (or your server IP if running remotely).
Place this file in the root directory of the project.
# MQTT Configuration
VITE_MQTT_HOST="localhost"
VITE_WS_PORT=1783
# Video Configuration
VITE_VIDEO_URL="192.168.X.X:XXXX"
In separate terminal windows (or tabs), run the following services:
-
Run the Backend Server
python server.py
- Flask backend will run at http://localhost:5000.
-
Run the Frontend (React) Application
npm run dev
- The Vite development server typically runs at http://localhost:5173.
-
Start the TileServer-GL Docker Container (Map Server)
docker run --rm -it -v $(pwd):/data -p 8080:8080 maptiler/tileserver-gl --file osm-2020-02-10-v3.11_africa_kenya.mbtiles
- Access the map at http://localhost:8080.
-
Start Mosquitto (MQTT Broker)
mosquitto -c mosquitto.conf
- Verify that all required services (Docker, Mosquitto, backend, and frontend) are running.
- Ensure environment configurations in the
.env
file are correct. - Check that network ports are available and not blocked by a firewall.
- Confirm you are using compatible versions of Node.js and Python.
# Resolve npm install dependency conflicts
npm install --force
# If the map is not rendering, try restarting Docker.
The system uses MQTT for bi-directional communication between the flight computer and the ground station.
Ensure your .env
file includes the following variables:
# MQTT Configuration
VITE_MQTT_HOST=localhost # WebSocket URL for the MQTT broker
VITE_WS_PORT=1783 # WebSocket port for MQTT
# API Configuration
VITE_STREAM_URL=http://ip-addr:port # Video stream server URL
Service | Specified Port | Description |
---|---|---|
MQTT WebSocket | 1783 | MQTT broker WebSocket port for dashboard communication |
MQTT TCP | 1882 | MQTT broker TCP port for Wi-Fi device connections |
Video Stream | XXXX | RTSP stream server port |
Dashboard | 5173 | Development server port (when running npm run dev ) |
Dashboard | 80 | Production server port (when running the built version) |
Flask Server | 5000 | Backend server port |
- Protocol: MQTT over WebSocket
- Default Port: Use the
VITE_WS_PORT
environment variable - Host: Use the
VITE_MQTT_HOST
environment variable - Client ID Format:
dashboard-[random-hex]
- Keep Alive Interval: 3600 seconds
The dashboard subscribes to the following topics:
n4/telemetry
- Main telemetry data from the flight computern4/logs
- System logs and status messages
The dashboard publishes to:
n4/commands
- Control commands to the flight computer (e.g., arm/disarm)
{
"state": number, // Flight state (0-6)
"operation_mode": number, // 0: Safe, 1: Armed
"gps_data": {
"latitude": number,
"longitude": number,
"gps_altitude": number
},
"alt_data": {
"pressure": number,
"temperature": number,
"AGL": number, // Altitude above ground level
"velocity": number
},
"acc_data": {
"ax": number, // Acceleration X-axis
"ay": number, // Acceleration Y-axis
"az": number // Acceleration Z-axis
},
"chute_state": {
"pyro1_state": number, // Drogue parachute state
"pyro2_state": number // Main parachute state
},
"battery_voltage": number
}
{
"level": string, // "INFO", "ERROR", "WARN", "DEBUG"
"message": string, // Log message content
"source": string // "Flight Computer", "Base Station", or another identifier
}
{
"command": string // "ARM" or "DISARM"
}
The system recognizes the following flight states:
- 0: Pre-Flight
- 1: Powered Flight
- 2: Apogee
- 3: Drogue Deployed
- 4: Main Deployed
- 5: Rocket Descent
- 6: Post Flight
- Base station connection status is monitored continuously.
- Flight computer data staleness is checked every 500ms.
- Connection is marked as "No Recent Data" if no telemetry is received for > 5 seconds.
- The dashboard expects an RTSP stream at the URL specified by
VITE_STREAM_URL
. - Ensure the RTSP server is properly configured and accessible from the dashboard's network.
- Connection failures are logged with timestamps.
- Parsing errors for incoming messages are captured and reported.
- Command transmission failures are logged and reported to the user.
- Data staleness is monitored and reflected in the UI.
// Connect to MQTT broker
const client = new MQTT.Client(
mqtt_host,
ws_port,
`dashboard-${Math.random().toString(16).slice(2, 8)}`
);
// Configure connection
client.connect({
onSuccess: () => {
client.subscribe(["n4/telemetry", "n4/logs"]);
},
keepAliveInterval: 3600
});
// Send command example
const message = new MQTT.Message(
JSON.stringify({
command: "ARM"
})
);
message.destinationName = "n4/commands";
client.send(message);