Files
MSE-PI-E2EEDA-Plein-de-eeee…/gateway
DjeAvd dd659cbc66 refactor(gateway): switch from GATT connection to passive BLE advertising
Replace active GATT connection with passive BLE advertising scan.
The gateway now listens to advertising packets and decodes the key/value
payload defined in the firmware specification (keys 0x01 to 0x04).

- Remove GATT connection logic (connect_device, BleakClient)
- Add decode_payload method following firmware spec
- Fix mqtt.Client instantiation with callback_api_version keyword argument
- Add window_open field support in MQTT payload

Assisted-by: Claude:claude-sonnet-4-6 — payload decoding implementation
2026-06-04 12:32:46 +02:00
..
2026-03-19 12:32:17 +01:00

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 #1] ──┐
[Thingy #2] ──┼──(BLE)──> [Raspberry Pi / 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.