2026-10-18 04:52:48 -07:00
2026-10-18 04:52:48 -07:00
2026-10-14 06:29:21 -07:00

Xiaomii BLE Sensor Dashboard

Summary

This is a web dashboard for monitoring Temperature and Humidity data for Xiaomii LYWSD03MMC BLE sensors. This app has a Python API to discover and monitor the sensors, and will have a website that interfaces with it. The website will load the intial static content with the API, and has a Node.js server for handling live web socket data using the Redis server.

The Python API will scan for any of these devices by looking for the Bluetooth MAC octet and then filtering by model. Once it has a list of MACs, it will then attempt to read the Temp/Humidity data for each MAC and record it. This data can be interacted with through an API. The app has a Redis publishing function for use with websockets. The comment field for sensors can be configured using the appropriate variable in the config.py as well. This app uses Pickle to persist Sensor object data between App launches. This doesn't keep history like Telegraf would, but it will allow for faster API startup.

The web dashboard lives in a Docker container based on PHP with Node and Redis added, and is managed by Supervisord. The static page is rendered with PHP and live data will be updated with Node.js based on the data received by Redis. The tech stack is Apache+PHP for the HTML, and Node.js for Websockets. The page loads statically with the API initially and will get updates from the Node server when Redis data is received.

Some product info for these sensors can be found here at my Knowledgebase:

https://kb.matt-cloud.com/books/07-saved-articles/page/xiaomii-temperaturehumidity-sensor

API Details

There are several primary API endpoints with varying levels of details.

0.0.0.0:5000/macs is the endpoint for a simple list of MACs. This will return a list of MACs and a count.

{
  "count": 4,
  "macs": [
    "A4:C1:38:00:11:10",
    "A4:C1:38:00:11:11",
    "A4:C1:38:00:11:12",
    "A4:C1:38:00:11:13"
  ]
}

0.0.0.0:5000/summary will return a summary of devices and current data.

{
  "sensors": [
    {
      "comment": "A4:C1:38:00:11:10",
      "data": {
        "humidity": 50,
        "temp": 17.4
      },
      "name": "A4:C1:38:00:11:10"
    },
    {
      "comment": "A4:C1:38:00:11:11",
      "data": {
        "humidity": 50,
        "temp": 18.03
      },
      "name": "A4:C1:38:00:11:11"
    },
    {
      "comment": "A4:C1:38:00:11:12",
      "data": {
        "humidity": 49,
        "temp": 17.99
      },
      "name": "A4:C1:38:00:11:12"
    },
    {
      "comment": "A4:C1:38:00:11:13",
      "data": {
        "humidity": 49,
        "temp": 18.12
      },
      "name": "A4:C1:38:00:11:13"
    }
  ]
}

0.0.0.0:5000/details returns the summary info along with timestamps for first seen and last seen dates for each MAC and each data.

{
  "sensors": [
    {
      "comment": "A4:C1:38:100:11:10",
      "data": {
        "data": [
          {
            "first_seen": 1791856362,
            "last_seen": 1791882172,
            "name": "temp",
            "value": 17.4
          },
          {
            "first_seen": 1791856362,
            "last_seen": 1791882172,
            "name": "humidity",
            "value": 50
          }
        ]
      },
      "first_seen": 1791856072,
      "last_seen": 1791882172,
      "name": "A4:C1:38:100:11:10"
    },
    {
      "comment": "A4:C1:38:00:11:11",
      "data": {
        "data": [
          {
            "first_seen": 1791856362,
            "last_seen": 1791882239,
            "name": "temp",
            "value": 17.97
          },
          {
            "first_seen": 1791856362,
            "last_seen": 1791882239,
            "name": "humidity",
            "value": 50
          }
        ]
      },
      "first_seen": 1791856072,
      "last_seen": 1791882239,
      "name": "A4:C1:38:00:11:11"
    },
    {
      "comment": "A4:C1:38:00:11:12",
      "data": {
        "data": [
          {
            "first_seen": 1791856300,
            "last_seen": 1791882239,
            "name": "temp",
            "value": 17.97
          },
          {
            "first_seen": 1791856300,
            "last_seen": 1791882239,
            "name": "humidity",
            "value": 50
          }
        ]
      },
      "first_seen": 1791856072,
      "last_seen": 1791882239,
      "name": "A4:C1:38:00:11:12"
    },
    {
      "comment": "A4:C1:38:00:11:13",
      "data": {
        "data": [
          {
            "first_seen": 1791856224,
            "last_seen": 1791882239,
            "name": "temp",
            "value": 18.07
          },
          {
            "first_seen": 1791856224,
            "last_seen": 1791882239,
            "name": "humidity",
            "value": 49
          }
        ]
      },
      "first_seen": 1791856072,
      "last_seen": 1791882239,
      "name": "A4:C1:38:00:11:13"
    }
  ]
}

File Structure

The Python API code is split across multiple files with different files having code for different areas of need.

api/
├─ app.py                 # Flask + Scheduler + API
├─ ble.py                 # BLE helper functions to read temp+humidity data
├─ scanner.py             # Async BLE scan + cache logic
├─ config.py              # Shared constants (prefix, interval, etc.)
├─ requirements.txt       # Python VENV requirements
├─ run.sh                 # Run API from shell
├─ scanner.py             # Handles scanning for Mii sensors, other helper functions
├─ sensors.py             # Object classifier
S
Description
API for Mii BLE Temp/Humidity Sensors
Readme
975 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 57.5%
JavaScript 18.5%
CSS 13%
PHP 9.3%
Dockerfile 1.5%
Other 0.2%