| .gitignore | Initial work by Antigravity | |
| .python-version | Initial work by Antigravity | |
| blegate.service.default | Initial work by Antigravity | |
| config.toml.default | Reduce CPU, scheduled scans | |
| govee_decoder.py | Initial work by Antigravity | |
| main.py | Reduce CPU, scheduled scans | |
| pyproject.toml | Initial work by Antigravity | |
| README.md | aliases | |
| tui_client.py | Initial work by Antigravity | |
| uv.lock | Initial work by Antigravity | |
BLE-Sensor to MQTT Gateway (Govee)
An elegant, asynchronous Python application designed to run on a Raspberry Pi (or macOS/Linux) that passively scans Govee Bluetooth Low Energy (BLE) sensor advertisements, decodes real-time measurements, and publishes them to an MQTT broker. Includes a live terminal-based monitor interface (TUI).
Developed and implemented by Antigravity, an agentic AI coding assistant designed by the Google DeepMind team.
Features
- Asynchronous Processing: Built on top of
bleakfor BLE scanning andaiomqttfor MQTT publishing. - Robust Reconnection: Decouples the BLE scanner and MQTT client; the gateway scans continuously and reconnects to the MQTT broker automatically (retrying every 5 seconds) if connection drops.
- Dynamic Topic Structure: Formats topics dynamically using the local gateway hostname and stripped lowercase sensor MAC address.
- TUI Client: Includes a Terminal User Interface client using
richfor dynamic, color-coded, live sensor updates (Celsius-only, colored warning states for battery and signal strength). - Service-Ready: Packaged with a
systemdservice file configuration for persistent background operation on Raspberry Pi.
Topics & Payloads
The gateway publishes sensor data to the following topics:
blegate/<gateway-hostname>/<shortened-mac>/sensor/[temperature|humidity|batteryperc|signal]
<gateway-hostname>: Dynamically fetched local system hostname.<shortened-mac>: Sensor MAC address with colons/dashes removed and converted to lowercase (e.g.a1b2c3d4e5f6). On macOS, this will be the device's masked UUID.- Payloads: Number-only strings:
temperature: Celsius degree value (e.g.,22.4)humidity: Relative humidity percentage (e.g.,45.2)batteryperc: Current battery level (e.g.,98) - published only if availablesignal: Bluetooth RSSI strength in dBm (e.g.,-74)
Configuration
Set your MQTT broker host, port, and custom sensor aliases in config.toml:
[mqtt]
broker = "nalanda"
port = 1883
[aliases]
# Map shortened sensor MAC addresses to user-friendly names
# Format: <shortened_mac_lowercase> = "<alias_name>"
a4c138ed5ab8 = "living"
Installation & Setup
-
Install Dependencies (uses
uvpackage manager):uv sync -
Run the Gateway:
# Run the MQTT publishing gateway uv run python main.py # Or run the gateway with a live terminal dashboard view uv run python main.py --dashboardNote: On Linux, accessing Bluetooth hardware requires root permissions or net capability. See service configuration details below.
-
Run the Monitor TUI Client:
# Run the live terminal sensor table uv run python tui_client.py
Service Deployment (Raspberry Pi)
To run the gateway persistently in the background on boot:
- Copy the systemd service template to the system directory:
sudo cp blegate.service /etc/systemd/system/blegate.service - Reload systemd configurations:
sudo systemctl daemon-reload - Enable and start the gateway service:
sudo systemctl enable blegate.service sudo systemctl start blegate.service - Check running service logs:
sudo journalctl -u blegate.service -f
Troubleshooting: Resource Not Ready
If you see bleak.exc.BleakDBusError: [org.bluez.Error.NotReady] Resource Not Ready in the service log, it usually indicates that the Bluetooth controller is soft-blocked by the system.
To resolve this one-time issue, unblock the Bluetooth radio:
sudo rfkill unblock bluetooth