Watch 1
Fork 0
You've already forked keychron-m6-battery

keychron-m6-battery

Reads the Keychron M6 mouse battery level over the 2.4 GHz receiver on Linux.

Usage

devenv shell cargo run            # auto-detect receiver, single attempt
devenv shell cargo run -- -n 0    # keep retrying until the mouse wakes up
devenv shell cargo run -- --watch 5   # keep printing every 5s until killed

Output is JSON on stdout:

{"percent":69,"mode":"discharging"}

mode is one of:

  • discharging — running on battery via the dongle
  • charging — plugged into power while linked to the dongle
  • usb — connected by cable (the mouse enumerates as its own USB device)

Available flags:

Flag Meaning
-d, --device <path> Use a specific hidraw node instead of auto-detection
--interval <secs> Seconds between retries (default 10)
-n, --retries <n> Max attempts; 0 = retry forever (default 0)
--timeout <ms> Read timeout per report (default 250; the mouse answers in a few ms when awake)
--watch <secs> Keep the device open and print JSON every N seconds until killed

For a Noctalia or other plugin, call the binary and parse the JSON line. Add --retries 0 so the command waits for the sleeping mouse to wake rather than failing, or use --watch <secs> to avoid re-enumerating USB per poll.

Protocol

The Keychron M6 pairs with the 3434:d026 "Keychron Link-KM" receiver, or enumerates as its own 3434:d060 "Keychron M6" USB device when connected by cable. Both expose the battery protocol on the mouse collection, usage page 0xFFC1, usage 0x01 (dongle: /dev/hidraw5, wired: /dev/hidraw15).

Query (plain HID interrupt write, 64 bytes):

B3 06 00 00 ...   (report, status request)

Response (interrupt read, 64 bytes, report ID B4, command echo 06):

B4 06 ... <battery at offset 20>

Battery field at offset 20: <= 100 means discharging and equals the percentage; > 100 means charging, and the device reports 100% while charging. The mouse sleeps when idle, so the first query often times out; workaround is to retry until it wakes (mirrors the Launcher's queued-with-retry behaviour).

Note: this is a different, simpler protocol than the newer M3/M5 vendor HID (which uses feature reports and 0xE4/0x52 ACK flow control). Verified live against the Keychron Launcher at 69%.