Build · Sketch · v1.4.8

The BLE Sensor Listener.

What it does
Hears cheap BLE sensors, harvests every reading, sends them to your endpoint
Boards
ESP32 · S3 · C3 · C6
License
Open: copy it, change it, own it

Turn a chip that costs a few dollars and a Bluetooth thermometer you may already own into a sensor that streams readings to a place you control. No soldering, no wiring, no app, and not a line of code. You flash it from this page, in your browser, and set it up by filling in a short form on the device itself. This is the first sketch in the library, and the shape the rest will take.

How the BLE Sensor Listener works, end to end. Step 1: nearby Bluetooth sensors (Govee H5100 and H5175 and about 120 other models) continuously broadcast temperature and humidity. Step 2: the ESP32 listener gateway scans the advertisements, recognizes supported sensors, and averages the readings over a configurable window, sending one tidy packet per cycle. Step 3: during setup you choose the destination, either a webhook (HTTPS POST) or an MQTT broker. Step 4: from there any dashboard, alert, analytics, storage, or Home Assistant can use the data. Because it only listens, there is no wiring and no soldering.

What it does.

Plenty of cheap Bluetooth sensors, Govee thermometers and about a hundred and twenty other models, already shout their readings into the air every few seconds. This node listens for them and harvests every measurement each one broadcasts, temperature and humidity, but also soil moisture, conductivity, CO₂, light, air quality, battery and signal, averages the chatty ones into steady numbers, and pushes them to an endpoint you own: your own webhook, an MQTT broker, or Open Agriculture Technology. Because it only listens, there is nothing to wire and nothing to solder, the sensor and the chip never touch.

By default it reports only the devices that broadcast a real sensor reading, so a room full of phones and stray Bluetooth gadgets stays quiet. Want just your sensors, or to include a beacon or a smart lock? Give it an allow-list of the addresses you care about during setup, and it reports those and nothing else.

That is the Collect layer made as small and cheap as it honestly gets. The value is in what you do with the reading later; the job here is just to get it flowing, reliably, to a place that is yours.

Flash it.

Plug your board in, find it below, and press its button. Each button installs the image built for that exact board, and the installer checks the chip really matches before it writes anything, so you can't flash the wrong one.

Your browser can't flash devices, use Chrome or Edge on a desktop. This page must be served over HTTPS to flash. The value pick, cheapest · beta
More memory and pins · beta
Newest, Wi-Fi 6 · tested
May need a USB driver · tested

Not sure which board? Its name is printed on the chip, or see the board guide.

You'll need a data USB cable (not charge-only) and Chrome or Edge on a computer. Once it's flashed, set it up from any phone or laptop.

What you need.

About ten dollars of parts, most of which you may already have:

How it works.

Four steps, and only the middle one is the chip's job:

  1. Your sensor broadcasts its reading over Bluetooth, the way it already does.
  2. The node hears every nearby sensor it recognises and averages the readings over a window you set.
  3. On a timer, it pushes one tidy packet per cycle to your endpoint.
  4. Your dashboard, alert, or store reads it. Your data, your place.

It pushes wherever you point it, Open Agriculture Technology, your own Home Assistant, a broker you run, or a webhook you wrote this afternoon. The node keeps working even if Open Agriculture Technology disappears. That's the own-your-data rule in hardware.

Set it up.

All the setup happens on the device's own page, nothing to install, and it works with no internet, which is exactly what you want if you flashed a few at the extension office to take home.

  1. Power the node from any USB charger or your computer.
  2. On your phone or laptop, join the Wi-Fi network OAT-Setup-XXXXXX (open, no password). A setup page opens by itself; if not, visit http://192.168.4.1.
  3. Sign in, fill in your device name, Wi-Fi, and where the readings should go, then press Save & Connect. It joins your Wi-Fi right away and shows you its new address, no reboot, no hunting for it.
  4. Open the node's Status page and press Push now. A green “OK” means a reading just reached your endpoint. Done.

The setup network stays on, so you can rejoin any time to change a setting, and your settings survive reboots. A fresh firmware flash wipes them clean, on purpose, so a re-used board never carries the last owner's Wi-Fi or endpoint.

On a native-USB board (C3 / C6 / S3) you can skip the Wi-Fi form and set it up over the browser console instead: connect, then type wifi, endpoint, and name. Handy if the setup network is being fussy.

Curious what those readings look like once they land? See the live demo →, a dashboard you can open right now, no sign-in. And when you flash your own, the test endpoint is the quickest way to prove it is talking: point the listener at it and watch your first message arrive, checked against the standard.

Open the printable setup card (PDF)

A one-page field card with the steps and blanks to write each node's settings, print a stack before a workshop, or tuck one in with each board you hand out.

What it sends.

Two kinds of message, both tiny. Every cycle the node sends a batch of readings, one entry per measurement each sensor reports, in canonical units (°C, %RH, ppm, lx…) so the receiver never has to guess; every 60 seconds it sends a lean heartbeat reporting its own health, so your endpoint can tell “alive but quiet” from “dead.” Both carry a schema tag (oat-ods/0.3) so you can route and version them. Big batches are split into several small signed posts automatically, so a busy node never overruns a small chip:

See the two message types

A batch of readings, sent every cycle:

{
  "schema": "oat-ods/0.3",
  "msg_type": "batch",
  "sent_at": "2026-07-01T04:26:00Z",
  "seq": 2000006,
  "source": { "tier": "oat-ble-listener", "gateway_id": "gb-c6",
              "fw": "OAT-BLE-Listener/1.4.8" },
  "messages": [
    { "observed_at": "2026-07-01T04:26:00Z",
      "stream": { "id": "A4:C1:38:9E:AB:CD", "name": "GH2 North air",
                  "location": "Greenhouse 2 / North bench" },
      "measurement": "temperature", "value": 23.41, "unit": "Cel",
      "agg": { "window_s": 60, "samples": 9, "method": "mean" },
      "source": { "physical_id": "A4:C1:38:9E:AB:CD",
                  "brand": "Govee", "model": "H5075", "rssi": -67 } },
    { "observed_at": "2026-07-01T04:26:00Z",
      "stream": { "id": "A4:C1:38:9E:AB:CD", "name": "GH2 North air" },
      "measurement": "humidity", "value": 58.7, "unit": "%RH",
      "agg": { "window_s": 60, "samples": 9, "method": "mean" } },
    { "observed_at": "2026-07-01T04:26:00Z",
      "stream": { "id": "AA:BB:CC:00:11:22", "name": "Bed 3 soil" },
      "measurement": "soil_moisture", "value": 34.0, "unit": "%",
      "agg": { "window_s": 60, "samples": 7, "method": "mean" },
      "source": { "physical_id": "AA:BB:CC:00:11:22",
                  "brand": "Xiaomi", "model": "HHCCJCY01", "rssi": -71 } }
  ]
}

A heartbeat, sent every 60 s, so the endpoint knows the node is alive even when a big batch can't get through:

{
  "schema": "oat-ods/0.3",
  "msg_type": "status",
  "observed_at": "2026-07-01T04:26:00Z",
  "state": "online",
  "source": { "tier": "oat-ble-listener", "gateway_id": "gb-c6",
              "fw": "OAT-BLE-Listener/1.4.8" },
  "health": {
    "uptime_s": 315, "boot_count": 2, "reset": "poweron",
    "free_heap": 184200, "min_free_heap": 172400, "largest_block": 106496,
    "rssi": -74, "wifi_reconnects": 0, "push_ok": 5, "push_fail": 0,
    "transport": "https", "tls_ok": true, "chip": "ESP32-C6",
    "temp_c": 61.6, "loops_per_sec": 993,
    "lan_ip": "192.168.1.37", "ssid": "BarnWiFi", "mdns": "oat-gb-c6.local",
    "ble_seen": 886, "ble_decoded": 886, "ble_matched": 663
  }
}

Want the whole format, both message types, every field, and the full measurement vocabulary? See the developer reference, or read the machine-readable JSON Schema.

Supported boards.

The firmware needs both Wi-Fi and Bluetooth. We build a ready image for each board below; you pick yours on the flasher and the installer checks it matches before writing. The rule is support broad, recommend narrow.

Recommended, native USB

  • ESP32-C3, the value pick, cheapest.
  • ESP32-S3, more memory and pins to grow into.
  • ESP32-C6, newest, Wi-Fi 6.
  • All flash with no driver to install. Pick one with a USB-C socket.

Works, with a catch

  • Classic ESP32, fine, but its USB chip (CP2102 / CH340) may need a one-time driver.
  • ESP32-S2 / H2 / P4, not supported: missing Bluetooth, Wi-Fi, or a radio entirely.

New to these chips? The ESP32 family field guide explains the differences and which one to buy. A blessed buy-list with exact boards and links is being finalised.

For makers & trainers.

Frequently asked questions.

Do you need to know how to code to flash an ESP32?

No. Browser-based installers flash a prebuilt firmware image to an ESP32 with one button, over a USB cable, using Chrome or Edge. Setup afterward is filling in a short form served by the device itself, or typing a couple of commands into a serial console. There is no code to read or edit unless you want to change how the firmware behaves.

How much does a DIY Bluetooth sensor gateway cost?

A few dollars for the ESP32 board that does the work. The sensor it listens to is a consumer Bluetooth thermometer many people already own, such as a Govee, which runs about $10 to $20 new. The firmware is free and open source, so a complete node, bought entirely new, typically totals $25 to $50 including the sensor.

Can you flash an ESP32 from a web browser?

Yes, on a computer running Chrome or Edge. Browser flashing uses Web Serial, a feature that lets the browser talk to the board over USB, and Safari, Firefox, and phone or tablet browsers do not support it. The initial flash therefore needs a desktop or laptop, but once the firmware is on the board, configuration works from any phone or computer on the network.

Where does the data from a DIY sensor node go?

Only to the endpoint configured on the device. A node running open firmware pushes each reading to whatever destination you enter during setup: your own webhook, your own MQTT broker, a hub such as Home Assistant, or a cloud service you choose. Nothing is transmitted anywhere else, and the destination can be changed later in the device's settings.

Can you sell devices flashed with open-source firmware?

Yes, in general. Open-source firmware licenses allow flashing boards and selling or giving away the result, provided the license terms are followed. This is a common pattern in grower and maker communities: one technically comfortable person flashes a batch of inexpensive ESP32 boards, and others nearby buy or receive a ready-to-configure node without touching the flashing step. Check the specific license, since some require sharing any modifications.