2.5 KiB
Gateway
BLE-to-MQTT gateway running on a Raspberry Pi 4. Discovers Nordic Thingy:52 sensor nodes, reads environmental data over BLE and publishes it to a local MQTT broker on each notification received.
Architecture
Thingy:52 nodes Raspberry Pi MQTT broker
[Thingy #1] --+
|
[Thingy #2] --+--> (BLE) --> [gateway.py] --> (MQTT) --> [Mosquitto]
|
[Thingy #n] --+
The gateway discovers nodes automatically by filtering BLE advertising packets
on the Nordic Configuration service UUID (ef680100). Once connected, it
subscribes to GATT notifications for temperature, humidity and CO2. Each
received value triggers an immediate MQTT publication.
MQTT interface
Topic: {gateway_id}/{thingy_mac}/update
Example: gateway_lausanne_01/C4:64:02:60:D9:16/update
Payload:
{
"timestamp": "2026-04-08T07:53:28Z",
"temp": 25.37,
"humidity": 44,
"co2_ppm": 400
}
Fields temp, humidity and co2_ppm are included only once the
corresponding value has been received from the node. The CO2 sensor
requires a warm-up period of approximately 60 seconds before returning
valid readings.
Configuration
All environment-specific parameters are defined in config.json:
{
"gateway_id": "gateway_lausanne_01",
"mqtt": {
"broker": "localhost",
"port": 1883
},
"ble": {
"service_uuid": "ef680100-9b35-4933-9b10-52ffa9740042",
"characteristics": {
"temperature": "ef680201-9b35-4933-9b10-52ffa9740042",
"co2": "ef680204-9b35-4933-9b10-52ffa9740042",
"humidity": "ef680203-9b35-4933-9b10-52ffa9740042"
}
}
}
Each deployed gateway has its own config.json. The source code remains
identical across all deployments.
Installation
sudo apt install -y mosquitto mosquitto-clients
sudo systemctl enable mosquitto
sudo systemctl start mosquitto
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Usage
source venv/bin/activate
python gateway.py
Notes on the CO2 sensor
The Thingy:52 embeds a CCS811 sensor which measures eCO2 — an estimated CO2 value derived from volatile organic compound (VOC) levels rather than a direct CO2 measurement. Values should be interpreted as indicative trends. The sensor requires a burn-in period of 48 hours on first use, and a warm-up of approximately 20 minutes on each startup before readings stabilize.