← BlogTutorial · Week 1 of 13

streaming ESP32 sensor data to alerts in 15 minutes

a sensor in the field is silent until it isn’t, and by then the data you needed is already gone. closing the gap takes $9 of hardware: a $5 ESP32, a $4 BME280, four wires.

this tutorial wires it. by the end you’ll have an ESP32 streaming temperature, humidity, and pressure to plexus, with a slack message that fires the moment the room crosses 35°C.

by ann schulte~10 min read
What you’ll build
ESP32 + BME280  ──HTTPS──▶  plexus
   plexus-c lib              monitor on
   reads I²C @ 2 Hz          temperature
                                  │
                                  ▼
                              #your-channel
                              (slack alert)

two boxes and a pipe. the ESP32 reads the BME280 over I²C twice a second and posts each metric to plexus via the plexus-c arduino library — temperature in °C, humidity in %, pressure in hPa. plexus runs the threshold check and posts to your slack channel the moment temperature crosses 35°C.

swap the BME280 for any I²C sensor on the same wires and the rest of the pipeline doesn’t change.

What you need
  • ESP32 dev boardany ESP32 with USB. ~$5–10. (DevKit V1, Wemos D1 Mini ESP32, anything similar.)
  • BME280 sensor on a breakout~$5–10. Adafruit, AliExpress, Sparkfun all stock these.
  • 4 female-female jumper wires
  • a USB cablethat data-syncs, not power-only.
  • a plexus accountfree tier works (sign up)
  • a slack workspace

total parts cost if you start from nothing: ~$15.

Step 1 of 4

wire it up

four wires. BME280 on the left, ESP32 (DevKit V1 pinout) on the right.

BME280ESP32
VIN3.3V
GNDGND
SDAGPIO 21
SCLGPIO 22

use 3.3V, not 5V. some BME280 breakouts have an onboard regulator and tolerate 5V — most don’t, and the chip dies silently if you guess wrong.

a few ESP32 boards print SDA/SCL on the silkscreen. if yours does, use those pins. if not, GPIO 21 and 22 are the Arduino default.

Step 2 of 4

flash the firmware

we don’t write firmware here. plexus-c ships an example sketch that does exactly what you need; install three things, edit four lines, flash.

install the toolchain

  1. 01Arduino IDE 2.x — download from arduino.cc.
  2. 02ESP32 board support. open Preferences → Additional Boards Manager URLs and paste https://espressif.github.io/arduino-esp32/package_esp32_index.json. then Tools → Board → Boards Manager, search “esp32,” install the one by Espressif.
  3. 03two libraries, both from Sketch → Include Library → Manage Libraries: Adafruit BME280 Library and plexus-c.

if plexus-c doesn’t appear yet — the Library Manager index rebuilds on its own schedule — grab the latest release zip and use Sketch → Include Library → Add .ZIP Library.

open the example

File → Examples → plexus-c → BME280_Dashboard. edit four lines at the top:

cpp
const char* WIFI_SSID      = "YourWiFiSSID";
const char* WIFI_PASSWORD  = "YourWiFiPassword";
const char* PLEXUS_API_KEY = "plx_your_api_key_here";  // app.plexus.company/dev/keys
const char* SOURCE_ID      = "esp32-bme280";

in production you’d rotate this key periodically through the dashboard. for the tutorial, hardcoded is fine.

flash

plug the ESP32 in. Tools → Board → ESP32 Dev Module. Tools → Port → /dev/cu.usbserial-… (mac) or COM3 (windows). hit upload.

then Tools → Serial Monitor → 115200 baud. within ~5 seconds:

serial monitor
Connecting to WiFi....
Connected! IP: 192.168.1.42
Plexus SDK v0.1.1 ready — streaming to dashboard
T=22.3°C  H=54.1%  P=1013.2 hPa
T=22.3°C  H=54.0%  P=1013.2 hPa

if no BME280 is connected, the sketch emits simulated data — the rest of the tutorial still works while you wait for shipping.

Step 3 of 4

define the alert

with telemetry flowing, define what’s worth paging for. one curl, one rule.

bash
export PLEXUS_API_KEY=plx_xxx   # same key you put in the firmware

curl -X POST https://app.plexus.company/api/monitors \
  -H "x-api-key: $PLEXUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "source_id": "esp32-bme280",
    "metric": "temperature",
    "threshold": {
      "max": 35.0,
      "severity": "warning",
      "message": "BME280 above 35°C — check the room"
    }
  }'

max: 35.0 means “fire when temperature crosses 35°C.” severity is one of info, warning, critical. the message rides with the alert into whatever integration receives it.

now wire slack. in your plexus dashboard, open integrations → slack → connect. authorize the plexus app, pick a channel ( #alerts, #sensors, whatever you like), enable alert.triggered and alert.resolved, save.

no slack admin? swap it for integrations → email → add with the same event types. delivery is via Resend, no SMTP setup on your end.

Step 4 of 4

warm the sensor

press the BME280 between your fingers. ambient room temperature is somewhere around 22°C; palm contact pushes the chip past 35°C in roughly 15–20 seconds.

three things happen when it crosses, in order:

  1. 01the next plexus.send("temperature", 35.4) from the ESP32 lands at the gateway.
  2. 02the gateway evaluates the rule, finds value > max, and emits an alert.triggered event with your message.
  3. 03the slack integration matches the event and posts to your channel — usually within 2–3 seconds.

confirm in the dashboard: alerts → esp32-bme280 → temperature shows the timestamp and the value that crossed.

let go of the sensor. once temperature drops back under 35°C, plexus emits alert.resolved and slack gets a follow-up. clean.

if nothing arrives, check the slack integration’s last-delivery status in the dashboard — it surfaces errors directly.

Going further

three things to try next

  • add more boards. give each ESP32 a unique SOURCE_ID (esp32-greenhouse, esp32-fridge, esp32-outside) and the same monitor applies to every device that posts to that metric. fleet of 50 from one curl.
  • swap the sensor. any I²C sensor wires the same way: SHT31 for humidity-only, SCD41 for CO₂, ADXL345 for vibration. change one library import, change the metric names, ship.
  • harden the firmware. the example hardcodes the API key. for real deployments, store credentials in ESP32 NVS (non-volatile storage) and provision them once over USB or BLE.

next week: detecting sensor anomalies in 100 lines of python. plain stdlib, rolling z-scores, no ML. plenty of room to catch a sensor going bad before it crosses a hard threshold.

Get the code

clone, run, file an issue if it breaks.

pinout, monitor curl, and links to the firmware example all live in the plexus-tutorials repo on GitHub.

Streaming ESP32 sensor data to alerts in 15 minutes | Plexus