Files
MSE-PI-E2EEDA-Plein-de-eeee…/gateway/README.md

5.1 KiB

Gateway

BLE-to-MQTT gateway running on a Raspberry Pi 4. Listens to Nordic Thingy:52 sensor nodes broadcasting environmental data over BLE and publishes it to a remote MQTT broker on each reception.

Architecture

[Thingy #1] ──┐
[Thingy #2] ──┼──(BLE)──> [Raspberry Pi / gateway.py] ──(MQTT)──> [Broker]
[Thingy #n] ──┘

The gateway listens passively to BLE advertising packets and filters on the Nordic Configuration service UUID (ef680100). Each received packet is decoded following the firmware key/value specification and published immediately to the MQTT broker.

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,
  "window_open": false
}

Fields are included only if present in the advertising packet. Values outside the valid range defined in the firmware specification indicate a failed sensor reading and are discarded.

Configuration

A config.example.json template is provided. Copy it to config.json and edit the values before running:

{
  "gateway_id": "gateway_example",
  "mqtt": {
    "broker": "mqtt.example.com",
    "port": 8883,
    "username": "your_username",
    "tls": true
  },
  "ble": {
    "service_uuid": "ef680100-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 rfkill unblock bluetooth
sudo systemctl enable bluetooth
sudo bluetoothctl power on

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

cp config.example.json config.json
# Edit config.json with your gateway_id, broker address and username

Usage

Set the MQTT password as an environment variable before running:

mkdir -p ~/secrets
echo "MQTT_PASSWORD=your_password" > ~/secrets/mqtt.env
chmod 600 ~/secrets/mqtt.env
export MQTT_PASSWORD="your_password"
source venv/bin/activate
python gateway.py

The password is never stored in config files or source code.

Systemd service

To run the gateway automatically on boot:

sudo cp gateway.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable gateway
sudo systemctl start gateway

Check status and logs:

sudo systemctl status gateway
sudo journalctl -u gateway -f

Deployment checklist

Follow these steps to deploy the gateway on a new Raspberry Pi.

1. Connect to the Pi

ssh pi@raspberrypi.local

2. Update the system

sudo apt update && sudo apt upgrade -y

3. Check and enable Bluetooth

sudo rfkill unblock bluetooth
sudo systemctl enable bluetooth
sudo systemctl start bluetooth
sudo bluetoothctl power on
# Expected: "Changing power on succeeded"

4. Install Mosquitto (for local testing)

sudo apt install -y mosquitto mosquitto-clients

5. Clone the repository

git clone https://github.com/PI-E2EEDA/Plein-de-eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-project.git
cd Plein-de-eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-project/gateway

6. Create Python environment

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

7. Create configuration file

cp config.example.json config.json
nano config.json
# Set a unique gateway_id for this Pi
# Example: "gateway_id": "gateway_fribourg_01"

8. Create the secret file

mkdir -p ~/secrets
echo "MQTT_PASSWORD=your_password" > ~/secrets/mqtt.env
chmod 600 ~/secrets/mqtt.env

9. Install the systemd service

sudo cp gateway.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable gateway
sudo systemctl start gateway

10. Verify everything works

sudo systemctl status gateway
# Expected: "active (running)"
sudo journalctl -u gateway -f
# Expected: Gateway ID, MQTT connected, BLE scan started

11. Test automatic restart

sudo reboot
# After reboot, reconnect via SSH
sudo systemctl status gateway
# Expected: "active (running)" without any manual intervention

Validation checklist

  • active (running) in systemctl status
  • Correct gateway ID in logs
  • MQTT connection established (MQTT client connected)
  • TLS enabled (TLS enabled)
  • BLE scan started (BLE scan started)
  • Thingy:52 nodes detected in logs after power on
  • Service restarts automatically after reboot

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 before readings stabilize.