Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/AngelAmoSanchez/TFG-RaspberryPi-BLE/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you from a fresh machine to a fully working BLE people-counting setup. By the end you will have the cloud backend running in Docker, the Raspberry Pi agent scanning and sending anonymized detections, and the web dashboard showing live zone counts. The whole process takes roughly 15 minutes on a Pi that already has Python 3 and a Bluetooth adapter.
Prerequisites before you begin:
  • A Raspberry Pi (any model with a built-in or USB Bluetooth adapter) running Raspberry Pi OS (Bullseye or later)
  • Python 3 and pip available on the Pi
  • A machine (or the Pi itself) that can run Docker and Docker Compose for the backend
  • A PostgreSQL instance — Docker Compose in step 3 provides one automatically
1

Clone the repository

Clone the project on both the machine that will run the backend and on the Raspberry Pi (they can be the same device).
git clone https://github.com/AngelAmoSanchez/TFG-RaspberryPi-BLE.git
cd TFG-RaspberryPi-BLE
2

Start the cloud backend with Docker Compose

The docker-compose.yml in backend-cloud/ starts a PostgreSQL 14 database and the FastAPI backend together. The database connection string is wired up automatically between the two services.
cd backend-cloud
docker compose up -d
This brings up the following services:
services:
  postgres:
    image: postgres:14-alpine
    container_name: tfg-postgres
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: tfg_detections
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  backend:
    build: .
    container_name: tfg-backend
    environment:
      DATABASE_URL: postgresql+asyncpg://postgres:postgres@postgres:5432/tfg_detections
      ENVIRONMENT: development
      DEBUG: "true"
      MQTT_ENABLED: "false"
    ports:
      - "8000:8000"
    depends_on:
      postgres:
        condition: service_healthy
    command: uvicorn src.api.main:app --host 0.0.0.0 --port 8000 --reload
Once the containers start, verify the backend is healthy:
curl http://localhost:8000/health
You should see a JSON response with "status": "healthy".
If you want to enable MQTT instead of HTTP, set MQTT_ENABLED: "true" and add MQTT_BROKER, MQTT_TOPIC, MQTT_USERNAME, and MQTT_PASSWORD under the backend service’s environment block before running docker compose up.
3

Configure the Pi agent

On the Raspberry Pi, navigate to the raspberry-pi/ directory and copy the example environment file:
cd raspberry-pi
cp .env.example .env
nano .env
The .env file controls every aspect of the agent. The minimum required fields are shown below. Fill them in before running the installer.
# Device identity (required — must be at least 3 characters)
DEVICE_ID=rpi-001

# Optional human-readable labels
DEVICE_NAME=
DEVICE_LOCATION=ETSII, Sevilla

# Transport mode: "mqtt" for production, "http" for local dev
COMMUNICATION_MODE=mqtt

# Logging level
LOG_LEVEL=INFO

# ── MQTT settings (used when COMMUNICATION_MODE=mqtt) ──────────
MQTT_BROKER=.eu-central-1.emqxsl.com
MQTT_PORT=8883
MQTT_TOPIC=
MQTT_USERNAME=
MQTT_PASSWORD=
MQTT_BUFFER_SIZE=100

# ── HTTP settings (used when COMMUNICATION_MODE=http) ──────────
HTTP_BASE_URL=http://localhost:8000
HTTP_API_KEY=
HTTP_TIMEOUT=10

# ── Scanner settings ───────────────────────────────────────────
SCAN_DURATION=10      # seconds per scan window
SCAN_INTERVAL=30      # seconds between scan cycles

# Zone RSSI thresholds (dBm, must be negative)
NEAR_THRESHOLD=-60
MEDIUM_THRESHOLD=-75

# Set to "true" to simulate detections without real hardware
USE_MOCK_SCANNER=false
DEVICE_ID is required and must be at least 3 characters. The agent will refuse to start without it. If you are running multiple Pi devices, give each a unique ID (for example rpi-001, rpi-002).
If you are using HTTP mode for a local setup, change COMMUNICATION_MODE to http and set HTTP_BASE_URL to the LAN IP of your backend machine:
COMMUNICATION_MODE=http
HTTP_BASE_URL=http://192.168.1.100:8000
4

Run the installer on the Pi

The install.sh script updates the system, installs Bluetooth and Python dependencies, creates a virtual environment, grants the necessary BLE capabilities to the Python binary, and generates a run.sh launch script. It also configures a systemd service so the agent can start on boot.
cd raspberry-pi
bash install.sh
The installer performs these steps automatically:
# System dependencies
sudo apt-get update -qq
sudo apt-get install -y python3 python3-pip python3-venv bluetooth bluez git

# Enable Bluetooth service
sudo systemctl enable bluetooth
sudo systemctl start bluetooth

# Python virtual environment
python3 -m venv --copies venv
source venv/bin/activate
pip install --upgrade pip -q
pip install -r requirements.txt -q

# Grant raw BLE socket capabilities (avoids running as root)
sudo setcap cap_net_raw,cap_net_admin+eip "$PROJECT_ROOT/venv/bin/python3"
The installer creates a run.sh wrapper and a systemd unit file (ble-scanner.service) but does not enable the service automatically. Enable auto-start manually after verifying the agent works correctly (see the next step).
5

Start scanning

Run the agent manually first to confirm everything is configured correctly:
cd raspberry-pi
./run.sh
You should see log output similar to:
============================================================
Agente IoT iniciado...
============================================================
Ciclo de Escaneo #1 - 2024-01-15 10:23:45
============================================================
 Distribución de zonas: NEAR=2, MEDIUM=5, FAR=11
OK - Cliente conectado y operativo
Esperando 30s hasta el próximo escaneo...
Once you have confirmed it works, enable the systemd service to start the agent automatically on boot:
sudo systemctl enable ble-scanner
sudo systemctl start ble-scanner
To watch live logs from the service:
sudo journalctl -u ble-scanner -f
During initial development or when there is no real Bluetooth hardware available, set USE_MOCK_SCANNER=true in .env. The agent will generate simulated detections instead of scanning the radio, letting you verify the full pipeline end-to-end.
6

Open the web dashboard

With the backend running and the Pi agent sending detections, open the web dashboard in your browser. If you started the backend on your local machine, navigate to:
http://localhost:3000
The dashboard connects to the backend’s WebSocket endpoint (ws://localhost:8000/ws) on load and begins rendering real-time zone charts. New detection batches appear automatically as the Pi completes each 30-second scan cycle.
The dashboard source lives in the frontend/ directory of the repository. See the frontend setup guide for instructions on building and deploying it.

What to do next

Calibrate zone thresholds

Adjust NEAR_THRESHOLD and MEDIUM_THRESHOLD to match your physical space.

Privacy and anonymization

Understand exactly how SHA-256 anonymization works and what data is stored.

Deploy to production

Move from a local Docker setup to a hosted backend on Fly.io or similar.

API reference

Explore the REST endpoints for detections, statistics, devices, and CSV export.

Build docs developers (and LLMs) love