[LEFT EARBUD] [CHARGING CRADLE] [RIGHT EARBUD]
( L: 85% ) ( C: 100% ) ( R: 90% )
| | |
+-----------------------+------------------------+
|
BLE GAP Advertisements (UUID: 0xFE2C)
v
[Linux Desktop Panel UI]
The Xiaomi Redmi Buds 6 Active hardware transmits transducer power reserves and charging circuit telemetry across Bluetooth Low Energy (BLE) non-connectable undirected advertisements adhering to the Google Fast Pair Service (GFPS) specification (0xFE2C).
Byte Index:
0x00 0x01 0x02 0x03 0x0B 0x0C 0x0D 0x0E
+---------+---------+---------+------------------+---------+---------+---------+---------+
| Model ID (3B) | Salt / Encrypted State | LEFT | RIGHT | CASE |
| [ 0x00FE2C ] | [ 9 Bytes ] | BATTERY | BATTERY | BATTERY |
+---------+---------+---------+------------------+---------+---------+---------+---------+
| | |
| | +-- Byte 14
| +------------ Byte 13
+---------------------- Byte 12
Each individual battery byte
Bit 7 (MSB) Bit 0 (LSB)
+-----------------------+---------------------------------------------+
| CHARGING FLAG (1b) | STATE OF CHARGE (0 - 100%) (7b) |
| 0: Discharging | Bitmask: 0x7F |
| 1: Active Charging | |
+-----------------------+---------------------------------------------+
-
Presence Detection: If
$B = \text{0xFF}$ , the peripheral is absent from the cradle or turned off$\rightarrow$ decoded as metric-1(absent). -
Level Extraction:
$\text{Level} = B \ & \ \text{0x7F}$ . -
Charging Extraction:
$\text{IsCharging} = (B \ & \ \text{0x80}) \neq 0$ .
+-------------------------------------------------------------+
| Hardware Bluetooth Controller |
| (hci0 / BlueZ Linux Subsystem) |
+------------------------------+------------------------------+
|
| HCI BLE LeScan Events
v
+-------------------------------------------------------------+
| Python Asynchronous Background Daemon |
| (redmibuds-daemon.py) |
| |
| +------------------------+ +-------------------------+ |
| | BleakScanner Loop | | Cancellable Watchdog | |
| | Suffix Filtering | | 10s Silence Auto-Decay | |
| +------------------------+ +-------------------------+ |
| | |
| +-------------------------------------------------------+ |
| | dasbus GObject Interface (org.redmibuds.Battery) | |
| +-------------------------------------------------------+ |
+------------------------------+------------------------------+
|
| D-Bus Signal (BatteryChanged) & Property Reads
v
+-------------------------------------------------------------+
| GNOME Shell Desktop Extension |
| (redmibuds-battery@istisu) |
| |
| - St.BoxLayout Panel Widget (L:XX% * R:XX% * C:XX%) |
| - Automatic Panel Visibility Toggling |
| - Dropdown Details Menu with Real-time Status |
+-------------------------------------------------------------+
The service registers on the D-Bus session bus with the following properties:
<node>
<interface name="org.redmibuds.Battery">
<property name="Left" type="i" access="read"/>
<property name="Right" type="i" access="read"/>
<property name="Case" type="i" access="read"/>
<property name="LeftCharging" type="b" access="read"/>
<property name="RightCharging" type="b" access="read"/>
<property name="CaseCharging" type="b" access="read"/>
<signal name="BatteryChanged"/>
</interface>
</node># Arch Linux
sudo pacman -S python-bleak python-dasbus bluez bluez-utils
# Debian / Ubuntu / Mint
sudo apt install python3-bleak python3-dasbus bluezmkdir -p ~/.local/share/gnome-shell/extensions/redmibuds-battery@istisu
cp -r redmibuds-battery@istisu/* ~/.local/share/gnome-shell/extensions/redmibuds-battery@istisu/
cp redmibuds-daemon.py ~/.local/share/gnome-shell/extensions/redmibuds-battery@istisu/
gnome-extensions enable redmibuds-battery@istisuEnable the background service to start automatically on login:
mkdir -p ~/.config/systemd/user
cp redmibuds-battery.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now redmibuds-battery.serviceThe daemon supports optional target MAC address configuration:
python3 redmibuds-daemon.py --mac "14:6C:27:2C:CF:8D"Or via environment variable:
export REDMI_BUDS_MAC="14:6C:27:2C:CF:8D"
python3 redmibuds-daemon.pyDistributed under the terms of the GNU General Public License v3.0 (GPL-3.0).