diff --git a/gateway/README.md b/gateway/README.md index 0adad50..da28259 100644 --- a/gateway/README.md +++ b/gateway/README.md @@ -1,118 +1,91 @@ -# Gateway — BLE to MQTT - -This component runs on a Raspberry Pi 4 and acts as the communication bridge -between the Nordic Thingy:52 sensor nodes and the rest of the system. -It reads environmental data from the nodes over BLE and publishes it to a -local MQTT broker (Mosquitto) in a structured JSON format. - -## Role in the architecture -``` -Thingy:52 nodes --> (BLE) --> Raspberry Pi --> (MQTT) --> Database / ML / Notifications -``` - -## Dependencies - -Install the required Python libraries: -```bash -pip3 install bleak paho-mqtt --break-system-packages -``` - -Install and start the Mosquitto MQTT broker: -```bash -sudo apt install -y mosquitto mosquitto-clients -sudo systemctl enable mosquitto -sudo systemctl start mosquitto -``` - -## Usage -```bash -python3 gateway.py -``` - -At startup, the script asks for the room ID (e.g. C1, A2, B5). -It then automatically discovers all Thingy:52 nodes in range by filtering -BLE advertising packets on the Nordic Configuration service UUID (ef680100). -Each detected node is assigned a name based on the room ID and a counter -(e.g. C1_thingy1, C1_thingy2). - -To run the gateway in the background and keep it running after closing SSH: -```bash -nohup python3 gateway.py > log.txt 2>&1 & -``` - -## MQTT topic structure -``` -classroom/{room_id}/{node_id} -``` - -Example: `classroom/C1/C1_thingy1` - -## Message format - -Each message is published as a JSON object with the following structure: -```json -{ - "timestamp": "2026-03-26T13:24:05.176072+00:00", - "room_id": "C1", - "node_id": "C1_thingy1", - "sensors": { - "co2_ppm": 400, - "temperature_c": 25.37, - "humidity_pct": 44 - } -} -``` - -| Field | Type | Description | -|---|---|---| -| timestamp | string (ISO 8601 UTC) | Time of measurement, added by the gateway | -| room_id | string | Identifier of the monitored room | -| node_id | string | Identifier of the Thingy:52 node | -| co2_ppm | integer | eCO2 concentration in parts per million | -| temperature_c | float | Indoor air temperature in degrees Celsius | -| humidity_pct | integer | Relative humidity in percent | - -## Output files - -For each session, two local files are created in the gateway directory: - -- `data_{room_id}.csv` — comma-separated file for local analysis -- `data_{room_id}.json` — JSON file following the database team format - -## Publishing interval - -The default publishing interval is 5 minutes (300 seconds). -This can be adjusted by modifying the `INTERVAL` variable in `gateway.py`. - -## Utility scripts - -- `scan.py` — scans for nearby BLE devices and prints their name and MAC address -- `check_uuid.py` — connects to Thingy:52 nodes and prints their advertised service UUIDs - -## Notes on the CO2 sensor - -The Thingy:52 uses a CCS811 sensor which measures eCO2 (equivalent CO2), -estimated from volatile organic compound (VOC) levels rather than directly -measuring CO2 concentration. Values should be interpreted as indicative trends -rather than precise measurements, particularly during the first 24 to 48 hours -of operation while the sensor calibrates. - -## Overnight test results - -An overnight test was conducted with 2 Thingy:52 nodes placed in two separate -rooms (windows closed, 7h session, 5 minute interval). - -- Room 1: 4 occupants (2 adults, 2 children) -- Room 2: unoccupied - -![Overnight measurements](mesures_nuit.png) - -CO2 rose progressively from 400 ppm to a peak of 1071 ppm in the occupied room, -consistent with human respiration in a confined space. The unoccupied room -remained stable between 400 and 465 ppm, confirming that variations in Room 1 -are directly linked to human presence. - -Note: the CCS811 sensor measures eCO2 estimated from VOC levels, not direct CO2. -Occasional spikes (e.g. 877 ppm at 02:45, 1071 ppm at 03:05) may be caused by -factors such as perspiration or movement near the sensor and should be interpreted -with caution. +# 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:** +```json +{ + "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`: + +```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 + +```bash +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 + +```bash +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. \ No newline at end of file