# garmin-ble: a Python client for Garmin's GFDI watch protocol

> Python library that talks to Garmin watches over their proprietary GFDI V2 Bluetooth LE protocol, with no Garmin Connect, phone or cloud service. It implements the handshake, multi-link routing, COBS framing, CRC16 checks and protobuf service messages, streams typed readings such as heart rate, HRV, SpO2, stress, Body Battery and accelerometer data, and adds a simulator and recorded-session replay for work without hardware. Its acknowledgements credit Gadgetbridge for the protocol logic and schemas, while a published journal shows how the author decoded the accelerometer payload, which Gadgetbridge only logged, from labelled recordings.

- Type: Case study
- Targets: Protocol
- Category: Independent reconstruction cases
- Relationship: Independent reconstruction project
- Sources reviewed: 2026-10-20
- Added to the catalog: 2026-11-02
- Original resource: <https://github.com/gwerneckp/garmin-ble>
- Primary source: <https://github.com/gwerneckp/garmin-ble/blob/b66203232f0abb314aeb7dc9e448680184f28ed3/README.md>
- Catalog page: <https://awesomerea.org/resources/garmin-ble-gfdi-protocol-case/>
- Record JSON: <https://awesomerea.org/resources/garmin-ble-gfdi-protocol-case/record.json>
- Chinese version: [简体中文](https://awesomerea.org/zh/resources/garmin-ble-gfdi-protocol-case/index.md)

## Requirements & limits

- Reviewed at main commit b662032 (2026-09-27), four commits after v0.3.2 of 2026-08-01, which is also the latest PyPI release; those commits add examples and an announcement video. pyproject marks the package Alpha and the CHANGELOG warns that the pre-1.0 API may change. The README roadmap lists BLE transport, live telemetry, the Watch API, simulator and replay as done, protobuf settings and device state as in progress, and notifications, media control and FIT/GPX file transfers as planned.
- Requires the user's own Garmin watch and a Bluetooth LE adapter on the computer; the README warns that the watch allows one BLE connection at a time, so it must be disconnected from the phone first. No Garmin Connect, firmware or SDK is used, and the repository's data files are the author's labelled accelerometer recordings. The README gives no list of tested watches; the bundled simulator profiles model a fenix 7 and a Venu 3, and the CHANGELOG notes that GFDI has no capability query, so a metric's support shows only when the watch accepts or declines its service.
- Python 3.10+ with bleak and protobuf, installed from PyPI or from source; development extras add pytest, pytest-mock and pytest-asyncio. Compiled protobuf modules are committed next to their .proto sources, and most examples accept --simulate.
- CI runs the pytest suite on Ubuntu with Python 3.10–3.13. Tests cover COBS, CRC16, GFDI, MLR and Smart framing, the bleak-backed transport with mocks, frame tracing, capture files and replay, and watch lifecycle, protobuf and telemetry behavior against the simulator. rev_eng.md documents how the 17-byte accelerometer packet was decoded from nine labelled recordings. Behavior on real watches remains author-reported.
- AGPL-3.0-only, matching the Gadgetbridge-derived code the README acknowledges, although the README also calls the library clean-room. Garmin watches, apps and trademarks keep their own rights. One commit message calls the tilt game example a test of unsupervised vibe coding.

## Primary sources

1. <https://github.com/gwerneckp/garmin-ble/blob/b66203232f0abb314aeb7dc9e448680184f28ed3/README.md>
2. <https://github.com/gwerneckp/garmin-ble/blob/b66203232f0abb314aeb7dc9e448680184f28ed3/reverse_engineering/accelerometer/rev_eng.md>
3. <https://github.com/gwerneckp/garmin-ble/blob/b66203232f0abb314aeb7dc9e448680184f28ed3/CHANGELOG.md>
4. <https://github.com/gwerneckp/garmin-ble/blob/b66203232f0abb314aeb7dc9e448680184f28ed3/pyproject.toml>
5. <https://github.com/gwerneckp/garmin-ble/blob/b66203232f0abb314aeb7dc9e448680184f28ed3/.github/workflows/test.yml>
6. <https://github.com/gwerneckp/garmin-ble/blob/b66203232f0abb314aeb7dc9e448680184f28ed3/garmin_ble/protocol/gfdi.py>
7. <https://github.com/gwerneckp/garmin-ble/blob/b66203232f0abb314aeb7dc9e448680184f28ed3/garmin_ble/transport/simulated.py>
8. <https://github.com/gwerneckp/garmin-ble/tree/b66203232f0abb314aeb7dc9e448680184f28ed3/proto>
9. <https://github.com/gwerneckp/garmin-ble/tree/b66203232f0abb314aeb7dc9e448680184f28ed3/tests>
10. <https://github.com/gwerneckp/garmin-ble/blob/b66203232f0abb314aeb7dc9e448680184f28ed3/LICENSE>
11. <https://github.com/gwerneckp/garmin-ble/commit/69b6ed1cccfce79482fd13ca3fad292551b99a18>
12. <https://github.com/gwerneckp/garmin-ble/releases/tag/v0.3.2>
13. <https://pypi.org/project/garmin-ble/0.3.2/>

## More in Protocols

- [bosectl: reconstructing Bose’s BMAP headphone protocol](https://awesomerea.org/resources/bosectl-bose-bmap-protocol-case/index.md) · Case study
- [lib-osmo-ble: DJI Osmo Pocket 3 Bluetooth LE protocol library](https://awesomerea.org/resources/osmo-pocket-3-ble-protocol-case/index.md) · Case study
- [DJI MIMO BLE artifacts: reconstructing the DJI Osmo control protocol](https://awesomerea.org/resources/dji-mimo-ble-reveng-case/index.md) · Case study
- [Cat Printer BLE: reconstructing the MXW01 thermal printer protocol](https://awesomerea.org/resources/catprinterble-mxw01-printer-case/index.md) · Case study
- [a0rfid: an open driver for A0-protocol UHF RFID readers](https://awesomerea.org/resources/a0rfid-uhf-reader-protocol-case/index.md) · Case study
- [Xiaomi Kettle BLE protocol: reconstructing a smart kettle's control interface](https://awesomerea.org/resources/xiaomi-kettle-ble-protocol-case/index.md) · Case study

## About this entry

The description was reviewed against primary sources.
Original editorial content: MIT. Linked projects, papers and assets retain their own rights and licenses.
