Back to Home

Raspberry Pi and MIR S-05 meter: BLE GATT

Developers get instructions on connecting Raspberry Pi to MIR S-05.10 meter via Bluetooth. GATT services described, protocol reverse via Android HCI logs, bleak scripts for reading readings. Suitable for integration into smart home systems.

BLE integration of MIR S-05 meter with Raspberry Pi Zero
Advertisement 728x90

Integrating the MIR C-05.10 Electricity Meter with Raspberry Pi via Bluetooth: GATT and Reverse Engineering

The Raspberry Pi Zero 2W, with its built-in Bluetooth module, can read data from the MIR C-05.10-230-5(80)-G2Z1B-KNQ-S-D electricity meter without requiring a USB optical probe. The interface relies on a GATT profile over BLE. Start by installing the necessary Bluetooth packages:

sudo apt update
sudo apt install -y bluez bluez-tools bluetooth python3-pip
python3 -m pip install --break-system-packages bleak
sudo systemctl enable bluetooth
sudo systemctl restart bluetooth

In the bluetoothctl utility, run a scan (scan on), pair with the device (pair MAC), mark it as trusted (trust MAC), and connect (connect MAC). The meters appear as C05-serial_number.

Once connected, GATT services become accessible. The primary service for SPP-over-BLE is 4880c12c-fdcb-4077-8920-a450d7f9b907, featuring the characteristic fec26ec4-6d71-4442-9f81-55bc21d658d6 (notify/write without response). The Silicon Labs OTA service can be safely ignored.

Google AdInline article slot

Reading Basic GATT Characteristics

A Python script using bleak can scan the available characteristics and enable notifications:

import asyncio
from bleak import BleakClient

ADDR = "E4:06:BF:87:CD:69"

CHARS = [
    "00002a29-0000-1000-8000-00805f9b34fb",
    "00002a24-0000-1000-8000-00805f9b34fb",
    "00002a25-0000-1000-8000-00805f9b34fb",
    "00002a27-0000-1000-8000-00805f9b34fb",
    "00002a26-0000-1000-8000-00805f9b34fb",
    "2bb1d64f-451a-4541-ac89-24df683309dc",
    "d24a5138-1448-48ea-a983-f7df274c6d89",
    "4335a5be-fbbd-464e-8659-1a4212239e3e",
    "b3f7e595-2951-42fa-879e-0d9dfa5e846e",
    "fec26ec4-6d71-4442-9f81-55bc21d658d6",
    "f7bf3564-fb6d-4e53-88a4-5e37e0326063",
]

def fmt(data: bytes) -> str:
    try:
        txt = data.decode("utf-8", errors="strict")
        return f'hex={data.hex(" ")} | utf8={txt!r}'
    except Exception:
        return f'hex={data.hex(" ")}' 

async def main():
    def cb(sender, data):
        print(f"NOTIFY {sender}: {fmt(bytes(data))}")

    async with BleakClient(ADDR, timeout=20.0) as client:
        print("connected:", client.is_connected)

        for uuid in CHARS:
            try:
                data = await client.read_gatt_char(uuid)
                print(f"READ {uuid}: {fmt(bytes(data))}")
            except Exception as e:
                print(f"READ {uuid}: ERROR: {e}")

        try:
            await client.start_notify("fec26ec4-6d71-4442-9f81-55bc21d658d6", cb)
            print("notify enabled on fec26...")
        except Exception as e:
            print("notify fec26 error:", e)

        await asyncio.sleep(10)

asyncio.run(main())

The output reveals device details: manufacturer NPO "MIR", model C05, serial number 50912525161818, and firmware version v2.81.9.0. Other characteristics are locked and require authentication (READ_NOT_PERMITTED).

Reverse Engineering the Protocol via Android HCI Logs

To analyze the communication traffic, a rooted Android device is required. Enable Developer Options, turn on Bluetooth HCI snoop logging, and activate USB debugging. After pairing with the official "MIR DP" app, extract the logs using adb bugreport or the following commands:

Google AdInline article slot
adb shell su -c "cp /data/misc/bluetooth/logs/btsnoop_hci.log /sdcard/Download/btsnoop_hci.log && chmod 666 /sdcard/Download/btsnoop_hci.log"
adb pull /sdcard/Download/btsnoop_hci.log

The binary btsnoop_hci.log file can be parsed using Wireshark or AI-assisted tools. This process reveals the exact BLE command sequence used for initialization and data retrieval: total energy consumption, T1/T2 tariff readings, date/time, current draw, and voltage.

Sequential Polling Script for Meter Readings

The protocol requires individual BLE requests for each data point. Here’s a script template:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Reading MIR C-05 meter data via BLE.
1. Connect and initialize.
2. Enable notifications.
3. Send sequential read commands.
"""

# Insert commands extracted from HCI logs here: write-without-response to fec26ec4...

The script handles service initialization, enables notifications, and dispatches read requests. Responses are parsed into standard units: kWh, A, and V.

Google AdInline article slot

Key Takeaways:

  • The BLE connection remains stable without requiring re-pairing.
  • GATT characteristics are protected; a vendor-specific PIN is required for full access.
  • HCI logs are essential for decoding the SPP-over-BLE protocol.
  • Seamless integration into Home Assistant is possible via MQTT or direct script execution.
  • Sequential polling is mandatory; sending batch requests will trigger a connection drop.

— Editorial Team

Advertisement 728x90

Read Next