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.
All configuration is centralised in src/config.py using a Pydantic Settings class that reads values from environment variables (and an optional .env file). Every variable has a default that allows the server to start for local development, but several must be overridden before going to production.
Complete production .env example
Copy .env.example.prod as your starting point and fill in the blanks:
ENVIRONMENT=production
DEBUG=false
HOST=0.0.0.0
PORT=8000
DATABASE_URL=
MQTT_ENABLED=true
MQTT_BROKER=.eu-central-1.emqxsl.com
MQTT_PORT=8883
MQTT_TOPIC=
MQTT_USERNAME=
MQTT_PASSWORD=
SECRET_KEY=
API_KEY=
DEVICES_PER_PERSON=1.5
NEAR_THRESHOLD=-60
MEDIUM_THRESHOLD=-75
LOG_LEVEL=INFO
CORS_ORIGINS=["http://localhost:5173","http://localhost:3000"]
Application
| Variable | Default | Description |
|---|
APP_NAME | TFG Bluetooth Detection Backend | Name shown in API docs and logs. |
ENVIRONMENT | development | Runtime environment. Set to production to enable production guards. |
DEBUG | true | Enables uvicorn --reload and verbose error responses. Set to false in production. |
API_VERSION | v1 | Prefix appended to all routes: /api/v1/…. |
DEBUG=true in production exposes internal stack traces in API error responses. Always set DEBUG=false for any publicly reachable deployment.
Server
| Variable | Default | Description |
|---|
HOST | 0.0.0.0 | Address the uvicorn server binds to. |
PORT | 8000 | TCP port the server listens on. Also set as an ENV in the Dockerfile. |
Database
| Variable | Default | Description |
|---|
DATABASE_URL | postgresql+asyncpg://postgres:postgres@localhost:5432/tfg_detections | Full SQLAlchemy async connection URL. The +asyncpg driver is required for async queries. |
The settings class also exposes a helper get_database_url_sync() that strips +asyncpg for Alembic, which uses a synchronous psycopg2 connection.
def get_database_url_sync(self) -> str:
return self.database_url.replace("+asyncpg", "")
In the Docker Compose stack the hostname is postgres (the service name), not localhost. Make sure DATABASE_URL reflects this when overriding inside a container.
MQTT broker
These variables control the embedded MQTT subscriber. The subscriber only starts when MQTT_ENABLED=true and MQTT_BROKER is set.
| Variable | Default | Description |
|---|
MQTT_ENABLED | false | Set to true to start the MQTT subscriber on application startup. |
MQTT_BROKER | (none) | Hostname or IP of the MQTT broker, e.g. abc.eu-central-1.emqxsl.com. |
MQTT_PORT | 1883 | Broker port. Use 8883 for TLS (EMQX Cloud). |
MQTT_TOPIC | tfg/detections/raw | Topic the backend subscribes to for incoming detection payloads. |
MQTT_USERNAME | (none) | Optional broker username. |
MQTT_PASSWORD | (none) | Optional broker password. |
EMQX Cloud free-tier clusters use port 8883 with TLS. The backend subscriber calls tls_set() automatically when it connects, so no extra certificate configuration is needed.
WebSocket
| Variable | Default | Description |
|---|
WEBSOCKET_ENABLED | true | Reserved flag. The WebSocket endpoint at /ws is always registered; this variable is available for future conditional logic. |
The WebSocket manager broadcasts two event types to connected dashboard clients:
detection_event — fired when new detections arrive from a Pi agent.
stats_update — fired when aggregated statistics are recalculated.
CORS
The cors_origins list is hardcoded in config.py with sensible development defaults, and can be extended via the CORS_ORIGINS environment variable in production:
cors_origins: list = [
"http://localhost:3000",
"http://localhost:5173",
"http://127.0.0.1:5173",
"https://*.vercel.app",
]
For production, set CORS_ORIGINS as a JSON array string:
CORS_ORIGINS=["https://your-frontend.vercel.app","https://your-custom-domain.com"]
Security
| Variable | Default | Description |
|---|
SECRET_KEY | dev-secret-key-change-in-production | Used for signing tokens and other cryptographic operations. Must be changed in production. |
API_KEY | (none) | Optional API key. When set, Pi agents should send it in the X-API-Key request header. |
Never commit a real SECRET_KEY or API_KEY to source control. Generate a secure value with openssl rand -hex 32.
Statistics
| Variable | Default | Description |
|---|
DEVICES_PER_PERSON | 1.5 | Divisor used to estimate the number of people from unique detected BLE devices. estimated_people = unique_devices / devices_per_person. |
Adjust this ratio based on your deployment context. In a consumer environment where most people carry one or two Bluetooth devices, 1.5 is a reasonable estimate.
The backend classifies each detection into one of three zones based on its RSSI value (signal strength in dBm):
| Variable | Default | Zone assigned when |
|---|
NEAR_THRESHOLD | -60 | rssi >= NEAR_THRESHOLD → zone near |
MEDIUM_THRESHOLD | -75 | rssi >= MEDIUM_THRESHOLD and rssi < NEAR_THRESHOLD → zone medium |
| (implicit) | — | rssi < MEDIUM_THRESHOLD → zone far |
These thresholds match the Pi agent scanner defaults and the ZoneEnum values stored in the detections table (near, medium, far).
Logging
| Variable | Default | Description |
|---|
LOG_LEVEL | INFO | Python logging level. Accepted values: DEBUG, INFO, WARNING, ERROR, CRITICAL. |
Log lines follow the format:
%(asctime)s - %(name)s - %(levelname)s - %(message)s