From cff053ad2ad2a9db5a98e3810ba82db666d98f62 Mon Sep 17 00:00:00 2001 From: DjeAvd Date: Fri, 24 Apr 2026 09:55:38 +0100 Subject: [PATCH] docs(gateway): add deployment checklist, systemd service and update README --- gateway/README.md | 167 +++++++++++++++++++++++++++++++++------- gateway/gateway.service | 16 ++++ 2 files changed, 156 insertions(+), 27 deletions(-) create mode 100644 gateway/gateway.service diff --git a/gateway/README.md b/gateway/README.md index 245353e..52596b9 100644 --- a/gateway/README.md +++ b/gateway/README.md @@ -1,19 +1,20 @@ # 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. +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)──> [Mosquitto] +[Thingy #2] ──┼──(BLE)──> [Raspberry Pi / gateway.py] ──(MQTT)──> [Broker] [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. + +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 @@ -27,33 +28,31 @@ Example: `gateway_lausanne_01/C4:64:02:60:D9:16/update` "timestamp": "2026-04-08T07:53:28Z", "temp": 25.37, "humidity": 44, - "co2_ppm": 400 + "co2_ppm": 400, + "window_open": false } ``` -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. +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 -All environment-specific parameters are defined in `config.json`: +A `config.example.json` template is provided. Copy it to `config.json` and +edit the values before running: ```json { - "gateway_id": "gateway_lausanne_01", + "gateway_id": "gateway_example", "mqtt": { - "broker": "localhost", - "port": 1883 + "broker": "mqtt.example.com", + "port": 8883, + "username": "your_username", + "tls": true }, "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" - } + "service_uuid": "ef680100-9b35-4933-9b10-52ffa9740042" } } ``` @@ -65,12 +64,16 @@ identical across all deployments. ```bash sudo apt install -y mosquitto mosquitto-clients -sudo systemctl enable mosquitto -sudo systemctl start mosquitto +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 @@ -78,6 +81,9 @@ pip install -r requirements.txt Set the MQTT password as an environment variable before running: ```bash +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 @@ -85,10 +91,117 @@ python gateway.py The password is never stored in config files or source code. +## Systemd service + +To run the gateway automatically on boot: + +```bash +sudo cp gateway.service /etc/systemd/system/ +sudo systemctl daemon-reload +sudo systemctl enable gateway +sudo systemctl start gateway +``` + +Check status and logs: + +```bash +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** +```bash +ssh pi@raspberrypi.local +``` + +**2. Update the system** +```bash +sudo apt update && sudo apt upgrade -y +``` + +**3. Check and enable Bluetooth** +```bash +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) +```bash +sudo apt install -y mosquitto mosquitto-clients +``` + +**5. Clone the repository** +```bash +git clone https://github.com/PI-E2EEDA/Plein-de-eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-project.git +cd Plein-de-eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-project/gateway +``` + +**6. Create Python environment** +```bash +python3 -m venv venv +source venv/bin/activate +pip install -r requirements.txt +``` + +**7. Create configuration file** +```bash +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** +```bash +mkdir -p ~/secrets +echo "MQTT_PASSWORD=your_password" > ~/secrets/mqtt.env +chmod 600 ~/secrets/mqtt.env +``` + +**9. Install the systemd service** +```bash +sudo cp gateway.service /etc/systemd/system/ +sudo systemctl daemon-reload +sudo systemctl enable gateway +sudo systemctl start gateway +``` + +**10. Verify everything works** +```bash +sudo systemctl status gateway +# Expected: "active (running)" +sudo journalctl -u gateway -f +# Expected: Gateway ID, MQTT connected, BLE scan started +``` + +**11. Test automatic restart** +```bash +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, and a warm-up -of approximately 20 minutes on each startup before readings stabilize. +The sensor requires a burn-in period of 48 hours on first use before +readings stabilize. diff --git a/gateway/gateway.service b/gateway/gateway.service new file mode 100644 index 0000000..ac8b490 --- /dev/null +++ b/gateway/gateway.service @@ -0,0 +1,16 @@ +[Unit] +Description=BLE to MQTT Gateway +After=network.target bluetooth.target +Wants=bluetooth.target + +[Service] +Type=simple +User=pi +WorkingDirectory=/home/pi/Plein-de-eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-project/gateway +EnvironmentFile=/home/pi/secrets/mqtt.env +ExecStart=/home/pi/Plein-de-eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee-project/gateway/venv/bin/python gateway.py +Restart=on-failure +RestartSec=10 + +[Install] +WantedBy=multi-user.target