Skip to content

Repository files navigation

BLE Sensor Exporter

A lightweight, dependency-free Rust application designed for the Raspberry Pi Zero W (or any Linux machine) to read advertising beacons from various BLE thermometers and export their metrics to Prometheus and OpenTelemetry (OTLP).

Features

  • Broad Device Support:
    • Govee: H5075 and other H-series BLE beacons.
    • Xiaomi Mijia (LYWSD03MMC): Custom ATC or PVVX firmwares (broadcasting Environmental Sensing data under UUID 0x181A).
    • Inkbird: IBS-TH1 and IBS-TH2 temperature/humidity beacons.
    • RuuviTag: RAWv2 (Data Format 5) environmental beacons.
  • Zero-Dependency Bluetooth Parsing: Spawns and streams output from hcitool and btmon, bypassing complex Bluetooth C library dependency chains to ensure simple, robust cross-compilation.
  • Built-in Prometheus Exporter: Exposes a lightweight Prometheus HTTP scraper endpoint (default port: 9103).
  • OTLP Metrics Pushing: Pushes gauge metrics directly to any standard OpenTelemetry HTTP JSON receiver (e.g. http://loki:4318/v1/metrics).
  • Autodiscovery: Auto-discovers any broadcasting supported BLE sensor in range, or can be restricted to specific target MAC addresses.
  • Custom Naming Labels: Allows associating user-friendly location names (like living_room) with device MAC addresses.

Metric Mappings

Prometheus Endpoint

Metric Name Type Description Labels
sensor_temperature_celsius Gauge Temperature in Celsius location, mac, brand
sensor_temperature_fahrenheit Gauge Temperature in Fahrenheit location, mac, brand
sensor_humidity_percent Gauge Relative humidity percentage location, mac, brand
sensor_battery_percent Gauge Battery level percentage location, mac, brand
sensor_rssi_dbm Gauge Bluetooth signal strength (RSSI) location, mac, brand
sensor_last_seen_seconds Gauge Timestamp of last received packet location, mac, brand

OpenTelemetry (OTLP) Metrics

OTLP Metric Unit Description Resource / Attributes
sensor.temperature.celsius Cel Temperature in Celsius location, mac, brand
sensor.temperature.fahrenheit F Temperature in Fahrenheit location, mac, brand
sensor.humidity % Relative humidity percentage location, mac, brand
sensor.battery % Battery level percentage location, mac, brand
sensor.rssi dBm BLE signal strength location, mac, brand

Installation & Deployment

1. Prerequisites (Target Pi)

The exporter relies on the standard Linux Bluetooth tools (hcitool and btmon). Install them on the target Raspberry Pi:

sudo apt update
sudo apt install bluez

2. Compilation

Option A: Build Natively on the Target Pi

If the target Pi has Rust installed, compile the binary natively:

make build

Option B: Cross-Compile from a Dev Machine

If compiling from your local machine to deploy to a Pi Zero W (which uses the 32-bit ARMv6 architecture), cross-compile using the musl toolchain:

cargo build --release --target arm-unknown-linux-musleabihf

3. Deploying and Running the Service (Target Pi)

  1. Copy the compiled binary to /usr/local/bin/ble-sensor-exporter on the target Pi and ensure it is executable:
    chmod +x /usr/local/bin/ble-sensor-exporter
  2. Copy the defaults file ble-sensor-exporter.default to /etc/default/ble-sensor-exporter and customize it:
    sudo cp ble-sensor-exporter.default /etc/default/ble-sensor-exporter
    sudo nano /etc/default/ble-sensor-exporter
  3. Copy the service definition ble-sensor-exporter.service to /etc/systemd/system/ble-sensor-exporter.service.
  4. Install and enable the systemd service:
    sudo make setup-service

Monitoring Multiple Sensors

You can configure the exporter to monitor multiple sensors in two different modes by editing /etc/default/ble-sensor-exporter on the target Pi:

Option A: Explicit Filtering Mode (Recommended)

Restricts decoding to only the specified MAC addresses and assigns custom location labels to each:

BLE_SENSOR_EXPORTER_OPTS="-prom-port 9103 \
  -mac A4:C1:38:54:6B:55 -location A4:C1:38:54:6B:55=first_floor_office \
  -mac A4:C1:38:12:34:56 -location A4:C1:38:12:34:56=living_room \
  -mac A4:C1:38:78:90:AB -location A4:C1:38:78:90:AB=master_bedroom \
  -otlp-endpoint http://prom.k.net:4318/v1/metrics \
  -interval 15"

Option B: Autodiscovery Mode

Omits the -mac filters entirely. The exporter will automatically detect, decode, and push metrics for every supported BLE sensor it hears in Bluetooth range. You can still supply optional location mappings for known devices:

BLE_SENSOR_EXPORTER_OPTS="-prom-port 9103 \
  -location A4:C1:38:54:6B:55=first_floor_office \
  -location A4:C1:38:12:34:56=living_room \
  -otlp-endpoint http://prom.k.net:4318/v1/metrics \
  -interval 15"

Any discovered sensor without an explicit location mapping will default to using its MAC address as its location label value.

After saving your configuration changes, restart the service to apply them:

sudo systemctl restart ble-sensor-exporter

Resource Usage

The exporter is highly optimized for resource-constrained environments like the Raspberry Pi Zero W:

  • Binary Size: ~860 KB (statically linked, fully stripped, compiled with Link-Time Optimization (LTO) and size optimizations enabled).
  • Exporter Memory (RAM): ~790 KB RSS (0.1% memory).
  • Exporter CPU Usage: ~1.5% CPU on a single-core Pi Zero W.
  • Helper Tool (btmon): ~2.9 MB RAM, ~12% CPU.

CLI Options

BLE Sensor Exporter
Usage: ble-sensor-exporter [options]

Options:
  -prom-port <port>       Port for Prometheus metrics (default: 9103)
  -enable-prom <true|false> Enable/disable Prometheus endpoint (default: true)
  -otlp-endpoint <url>    OTLP HTTP receiver endpoint
  -interval <secs>        OTLP metric push interval in seconds (default: 15)
  -mac <address>          Target MAC address to monitor (can specify multiple times)
  -location <mac=location_name> Custom location label for a MAC address (can specify multiple times)
  -debug                  Enable verbose debug logging
  -h, --help              Print this help menu

About

A generic BLE sensor Prometheus/OTLP exporter in Rust

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages