DEV Community

Cover image for Stream DB01 Beacon Alerts via Webhook MQTT Dashboard — code in Python/Node.js
applekoiot
applekoiot

Posted on

Stream DB01 Beacon Alerts via Webhook MQTT Dashboard — code in Python/Node.js

Introduction

EELINK’s DB01 BLE Temperature & Humidity Sensor Beacon is a small, battery‑powered tracker designed for cold‑chain logistics, warehouse monitoring and other industrial applications. The device detects movement via an accelerometer, measures temperature and humidity, senses light levels and fall events and periodically broadcasts this information over Bluetooth Low Energy. It is compatible with both iBeacon and Eddystone (UID, URL, TLM) protocols, meaning that it can be discovered by smartphones or gateways and its broadcast payload decoded in a standard way. The beacon’s IP‑rated enclosure protects it from dust and water, and its high‑capacity button battery allows it to run for months or years. During normal operation it broadcasts every few seconds with a range up to hundreds of metres. These design choices allow it to collect environmental data over long periods and to survive harsh logistics environments.

For asset‑tracking or environmental monitoring projects, it is often desirable to stream the beacon’s sensor data and alarms into a cloud platform so that alerts can be acted upon or dashboards created. Because DB01 uses BLE advertisements rather than a long‑range cellular link, it requires a gateway: a smartphone, dedicated tracking device or a Raspberry Pi that listens for BLE advertisements, extracts the sensor payload and forwards it to a server. In this tutorial you will learn how to:

  1. Collect DB01 BLE advertisements on a gateway and expose them via a webhook (HTTP POST) interface.
  2. Convert webhook events into MQTT messages so that any MQTT‑capable dashboard (e.g. Node‑RED, Grafana, ThingsBoard) can visualise the data.
  3. Build simple Python and Node.js scripts that handle the entire process.

By the end you will have a working pipeline that streams DB01 alerts into an MQTT dashboard and notifies you when temperatures exceed safe limits or when a package is dropped. You can learn more about the DB01 device itself on its product page.

Understanding DB01 Data

A DB01 beacon continuously broadcasts small BLE advertisement packets. Each packet contains a frame type (iBeacon/Eddystone), a unique identifier, battery level and sensor measurements. The following information is essential for decoding and interpreting the payload:

  • Sensors – The device reports temperature, humidity and light intensity. When the accelerometer detects motion or a fall, a movement or fall event flag is set. These alarms are useful for detecting handling shocks or if a package is opened (light exposure).
  • Data retention – DB01’s on‑board memory can store tens of thousands of history records, ensuring that data isn’t lost when there is no gateway nearby. Once a gateway connects, it can download the history.
  • Broadcast interval – The advertisement interval is configurable; shorter intervals provide finer‑grained data but reduce battery life.

When designing a gateway, you should set thresholds for temperature and humidity to generate alerts. For example, if the cold‑chain threshold is 8 °C and the beacon reports 9 °C, your gateway should trigger a webhook event. Similarly, you might trigger an alert when a fall event is detected or when the battery level falls below 20 %. DB01’s wide broadcast range (hundreds of metres in open environments) means that a single gateway can cover a large area.

Architecture: Webhook to MQTT

While there are many ways to forward beacon data to the cloud, this tutorial uses a webhook → MQTT bridge because it decouples the gateway from the dashboard. Webhooks are simple HTTP callbacks triggered when an event occurs. MQTT is a lightweight publish/subscribe protocol widely used in IoT; a broker relays messages from publishers (our gateway) to subscribers (our dashboard). The architecture is as follows:

  1. BLE Gateway – A smartphone, ESP32 or Raspberry Pi running a script that scans for DB01 advertisements using a BLE library (e.g. bluepy for Python or noble for Node.js). When a packet is parsed and an alert is triggered, the gateway sends an HTTP POST request (webhook) to a server. The payload includes the beacon ID, timestamp, sensor values and type of event (temperature, humidity, movement, battery, etc.).
  2. Webhook server – A small server (Flask for Python or Express for Node.js) that receives the POST request. It can perform simple validation and then republish the data to an MQTT broker using topics such as db01/<beacon_id>/temperature or db01/<beacon_id>/alert.
  3. MQTT broker – We will use a public test broker (test.mosquitto.org) or a local Mosquitto instance. This broker holds the messages and delivers them to any subscribed clients.
  4. Dashboard – Tools like Node‑RED or Grafana subscribe to the MQTT topics and display graphs, gauge widgets or send notifications when thresholds are exceeded. You can also store data in InfluxDB or an SQL database if historical analysis is required.

The decoupling means that multiple dashboards or analysis services can subscribe to the same data stream without changing the gateway code.

Implementing the Gateway in Python

Below is a simplified Python gateway using bluepy to scan DB01 BLE advertisements, detect alerts and forward them to a Flask webhook:

# Install dependencies: pip install bluepy paho-mqtt flask requests
import struct
import time
import requests
from bluepy import btle

# Constants
WEBHOOK_URL = 'http://localhost:5000/webhook'  # address of Flask server
TEMP_THRESHOLD = 8.0   # temperature alert threshold in degrees Celsius
HUMIDITY_THRESHOLD = 80.0  # humidity threshold in percent

class DB01Delegate(btle.DefaultDelegate):
    def __init__(self):
        super().__init__()

    def handleDiscovery(self, dev, is_new, is_new_data):
        # filter by manufacturer specific data (Eddystone/Beacon) or MAC prefix if known
        for (adtype, desc, value) in dev.getScanData():
            if desc == 'Manufacturer' and len(value) >= 20:
                # decode DB01 payload: temperature (2 bytes), humidity (2 bytes), light (1), motion (1)
                payload = bytes.fromhex(value)
                temp_raw = struct.unpack('>h', payload[0:2])[0]  # big‑endian signed
                humidity_raw = struct.unpack('>h', payload[2:4])[0]
                light = payload[4]
                motion_flag = payload[5]  # 1 for motion or fall
                temperature = temp_raw / 100.0
                humidity = humidity_raw / 100.0
                event_type = None
                if temperature > TEMP_THRESHOLD:
                    event_type = 'temperature'
                elif humidity > HUMIDITY_THRESHOLD:
                    event_type = 'humidity'
                elif motion_flag:
                    event_type = 'motion'

                if event_type:
                    data = {
                        'beacon_id': dev.addr,
                        'timestamp': int(time.time()),
                        'event_type': event_type,
                        'temperature': temperature,
                        'humidity': humidity,
                        'light': light
                    }
                    try:
                        requests.post(WEBHOOK_URL, json=data, timeout=5)
                        print(f"Alert sent: {data}")
                    except requests.exceptions.RequestException as e:
                        print(f"Webhook failed: {e}")

# Main scanning loop
scanner = btle.Scanner().withDelegate(DB01Delegate())
print('Scanning for DB01 advertisements...')
while True:
    scanner.scan(5.0)  # scan for 5 seconds
Enter fullscreen mode Exit fullscreen mode

This script decodes DB01 sensor values, checks them against thresholds and sends an alert to the webhook. In a production system you would enhance the parser to handle DB01’s full data format (battery level, history retrieval, etc.) and run the script as a system service.

Flask Webhook and MQTT Bridge

To receive alerts and republish them to MQTT, create a simple Flask application that uses the paho‑mqtt library. The code below listens for POST requests at /webhook, prints the data and publishes it to a topic based on the event type.

# Install dependencies: pip install flask paho-mqtt
from flask import Flask, request, jsonify
import paho.mqtt.client as mqtt

app = Flask(__name__)

# configure MQTT broker
MQTT_BROKER = 'test.mosquitto.org'
MQTT_PORT = 1883
mqtt_client = mqtt.Client()
mqtt_client.connect(MQTT_BROKER, MQTT_PORT, 60)

@app.route('/webhook', methods=['POST'])
def receive_webhook():
    data = request.get_json()
    if not data:
        return jsonify({'error': 'Invalid JSON'}), 400

    beacon_id = data.get('beacon_id', 'unknown')
    event_type = data.get('event_type', 'unknown')
    topic = f'db01/{beacon_id}/{event_type}'
    mqtt_client.publish(topic, payload=str(data), qos=1, retain=False)
    print(f"Published {data} to {topic}")
    return jsonify({'status': 'success'}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
Enter fullscreen mode Exit fullscreen mode

Run the Flask app and the scanner script on your gateway. When an alert is triggered, you will see log messages like:

Alert sent: {'beacon_id': 'c8:4b:39:fa:2f:1e', 'timestamp': 1691185010,
             'event_type': 'temperature', 'temperature': 9.2, 'humidity': 75.0,
             'light': 120}
Published {'beacon_id': 'c8:4b:39:fa:2f:1e', ...} to db01/c8:4b:39:fa:2f:1e/temperature
Enter fullscreen mode Exit fullscreen mode

Node.js Implementation

If you prefer JavaScript, the Node.js ecosystem offers similar libraries. The snippet below shows how to create a gateway using noble for BLE scanning, express for the webhook and mqtt.js for publishing:

// Install dependencies: npm install noble mqtt express
const noble   = require('noble');
const mqtt    = require('mqtt');
const express = require('express');
const app = express();
app.use(express.json());

const MQTT_BROKER = 'mqtt://test.mosquitto.org';
const client = mqtt.connect(MQTT_BROKER);

// decode BLE advertisement (simplified)
function decodeDb01(manufacturerData) {
  const tempRaw     = manufacturerData.readInt16BE(0);
  const humidityRaw = manufacturerData.readInt16BE(2);
  const light       = manufacturerData.readUInt8(4);
  const motion      = manufacturerData.readUInt8(5);
  return {
    temperature: tempRaw / 100.0,
    humidity:    humidityRaw / 100.0,
    light,
    motion
  };
}

noble.on('stateChange', state => {
  if (state === 'poweredOn') {
    noble.startScanning([], true);
    console.log('Scanning for DB01 beacons...');
  } else {
    noble.stopScanning();
  }
});

noble.on('discover', peripheral => {
  const manufacturerData = peripheral.advertisement.manufacturerData;
  if (!manufacturerData) return;
  const data = decodeDb01(manufacturerData);
  const id   = peripheral.address;
  let eventType = null;
  if (data.temperature > 8)      eventType = 'temperature';
  else if (data.humidity > 80)   eventType = 'humidity';
  else if (data.motion)          eventType = 'motion';
  if (eventType) {
    const payload = { beacon_id: id, timestamp: Date.now()/1000,
                      event_type: eventType, ...data };
    // publish directly to MQTT
    const topic = `db01/${id}/${eventType}`;
    client.publish(topic, JSON.stringify(payload));
    console.log('Published', payload);
  }
});

// optional: expose webhook to receive data from other devices and republish
app.post('/webhook', (req, res) => {
  const data = req.body;
  const { beacon_id, event_type } = data;
  const topic = `db01/${beacon_id}/${event_type}`;
  client.publish(topic, JSON.stringify(data));
  res.json({ status: 'ok' });
});

app.listen(5000, () => console.log('Webhook server listening'));
Enter fullscreen mode Exit fullscreen mode

This Node.js version eliminates the need for a separate HTTP POST because it publishes directly to MQTT. If you wish to support a webhook for other gateways or integrate with web services, the Express handler will handle those POST requests.

Building the Dashboard

Once your gateway publishes data to MQTT, you can use Node‑RED or Grafana to build a dashboard. Node‑RED (an open‑source flow‑based programming tool) has built‑in nodes for MQTT and chart widgets. A typical flow looks like:

  1. MQTT‑in node subscribes to db01/+/+ (plus wildcards) and outputs JSON messages.
  2. Function node extracts sensor values and triggers notifications when thresholds are exceeded.
  3. Chart node plots temperature and humidity over time.
  4. Dashboard node creates an interactive UI accessible via the browser or smartphone.

Grafana, on the other hand, excels at long‑term historical analysis. You can configure Telegraf to subscribe to MQTT and write data into InfluxDB, then build panels in Grafana with alerts. Because DB01’s broadcast interval is relatively low, storing data points at high resolution can produce large datasets; consider down‑sampling or increasing the broadcast interval to save battery life and storage.

Advanced Tips

  • Battery monitoring – DB01 uses a high‑capacity button battery. At a short advertisement interval, battery life can exceed two years. Increase the interval to 10–15 seconds to extend battery life further. Also publish battery level to MQTT so you can replace beacons proactively.
  • History retrieval – When a beacon reconnects after being offline, your gateway can query the internal storage (thousands of entries) to backfill missed data.
  • Multiple beacons – If you deploy dozens of DB01 units, include the unique beacon ID in the MQTT topic. Tools like Grafana can group series by tags.
  • Security – Use TLS on your MQTT broker or run Mosquitto behind a reverse proxy. DB01 advertisements are not encrypted; if confidentiality is required, instruct the gateway to encrypt payloads before publishing.

Conclusion

By combining DB01’s BLE capabilities with a webhook→MQTT bridge, you can build a scalable monitoring system with minimal effort. The gateway listens for DB01 advertisements, decodes sensor values, triggers alerts when thresholds are breached and forwards data to MQTT, where any subscriber (dashboard, alarm system or analytics engine) can act on it. The Python and Node.js scripts provided here serve as a foundation; you can extend them to download historical records, manage battery status or integrate with asset‑tracking platforms. Because DB01 supports standard beacon protocols and has a rugged enclosure, it is well suited for cold‑chain logistics, warehouse monitoring, greenhouse management and other applications where reliable environmental sensing and alerting are essential.

Top comments (0)