Skip to content

digitalerdude/whoop-reader

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

whoop-reader

Open-source BLE data reader for the Whoop 4.0 fitness band.

Connects to a Whoop 4.0 over Bluetooth Low Energy and reads real-time sensor data -- heart rate, R-R intervals, SpO2, skin temperature, and accelerometer readings. Built for researchers, tinkerers, and anyone who wants raw access to their own biometric data.

How it works

The Whoop 4.0 exposes a custom BLE GATT service (61080000-8d6d-82b8-614a-1c8cb0f8dcc6) with five characteristics for commands, responses, events, data streaming, and diagnostics. This tool sends command frames to the device and parses the 96-byte real-time data packets that come back.

Protocol knowledge comes from community reverse-engineering:

What data it can read

Field Status Bytes
Heart rate (BPM) Decoded 1-2
R-R interval (ms) Decoded 3-4
SpO2 (%) Decoded 5
Skin temperature (C) Decoded 6
Accelerometer X/Y/Z Candidate (unconfirmed) 7-12
Motion intensity Candidate (unconfirmed) 13
PPG amplitude Candidate (unconfirmed) 14-15
Ambient light Candidate (unconfirmed) 16-17
PPG signal quality Candidate (unconfirmed) 18-19
Battery level Decoded (separate command)
Device info Decoded (separate command)

Bytes 20-91 of the 96-byte real-time packet are not yet decoded. They likely contain additional sensor channels (gyroscope, respiration rate, PPG waveform samples). The codebase includes structured TODO comments at each byte position so contributors can fill them in.

Setup

Requires Python 3.10+ and a Bluetooth adapter that supports BLE.

# Clone the repo
git clone https://github.com/whoop-reader/whoop-reader.git
cd whoop-reader

# Install in development mode
pip install -e ".[dev]"

Platform notes

  • Linux: may require bluez and running as root (or adding your user to the bluetooth group)
  • macOS: works out of the box with the built-in Bluetooth stack
  • Windows: requires Windows 10+ with a compatible Bluetooth adapter

Usage

Scan for devices

whoop-reader scan
whoop-reader scan --timeout 15

Check battery

whoop-reader battery --address AA:BB:CC:DD:EE:FF

If you omit --address, the tool scans and lets you pick from discovered devices.

Device info

whoop-reader info --address AA:BB:CC:DD:EE:FF

Stream real-time data

# Stream to console
whoop-reader stream --address AA:BB:CC:DD:EE:FF

# Stream to CSV file
whoop-reader stream --address AA:BB:CC:DD:EE:FF --output session.csv

# Stream to JSON lines file
whoop-reader stream --address AA:BB:CC:DD:EE:FF --output session.jsonl --format jsonl

# Stop after 100 packets
whoop-reader stream --address AA:BB:CC:DD:EE:FF --count 100

# Verbose logging (shows raw BLE traffic)
whoop-reader -v stream --address AA:BB:CC:DD:EE:FF

Press Ctrl+C to stop streaming. Data is flushed to disk after every packet, so nothing is lost if you interrupt.

Python API

import asyncio
from whoop_reader.ble import scan_for_whoops, WhoopConnection

async def main():
    devices = await scan_for_whoops()
    async with WhoopConnection(devices[0]) as whoop:
        print(f"Battery: {await whoop.get_battery()}%")

        async for packet in await whoop.stream_realtime():
            print(f"HR: {packet.heart_rate_bpm} BPM")
            if packet.heart_rate_bpm and packet.heart_rate_bpm > 180:
                break

        await whoop.stop_realtime()

asyncio.run(main())

Project structure

whoop-reader/
  whoop_reader/
    __init__.py      -- Package metadata
    protocol.py      -- BLE UUIDs, command codes, CRC-32 implementation
    parser.py        -- 96-byte packet parser, response parsers
    ble.py           -- Connection management (scan, connect, notify, stream)
    export.py        -- CSV and JSON/JSONL export (batch and streaming)
    cli.py           -- Click CLI (scan, connect, info, battery, stream)
  pyproject.toml     -- Package configuration (hatchling)
  LICENSE            -- MIT
  README.md

Contributing

The biggest area for contribution is decoding the unknown bytes in the 96-byte real-time packet. Here is how to help:

  1. Capture an HCI snoop log while wearing the Whoop and performing known activities (resting, exercising, etc.)
  2. Open the log in Wireshark and filter for the data characteristic (61080004-...)
  3. Correlate byte values with the known activity (e.g., accelerometer values should change with movement)
  4. Open a PR with your findings, including the byte positions and your interpretation

The parser (whoop_reader/parser.py) contains TODO comments at each undecoded byte range to guide this work.

Protocol details

CRC-32

The Whoop 4.0 uses a CRC-32 variant with:

  • Polynomial: 0x04C11DB7
  • Initial value: 0xFFFFFFFF
  • Input/output reflection: yes
  • Final XOR: 0xF43F44AC

Command frame format

[0xAA] [CMD] [LENGTH_LO] [LENGTH_HI] [PAYLOAD...] [CRC32_LE]

Real-time data packet

96 bytes, delivered as BLE notifications on 61080004-8d6d-82b8-614a-1c8cb0f8dcc6. The last 4 bytes are the CRC-32 of the preceding 92 bytes.

Legal

This project is an independent, community-driven interoperability effort conducted under the DMCA Section 1201(f) reverse engineering exemption for the purpose of achieving interoperability between the Whoop hardware and third-party software.

This project does not extract, distribute, or modify proprietary firmware, algorithms, or copyrighted content. It only observes and documents the BLE communication protocol.

Disclaimer

This project is not affiliated with, endorsed by, or connected to Whoop, Inc. All trademarks are the property of their respective owners.

This software is provided as-is, without warranty. Use at your own risk. The authors are not responsible for any impact on your device's operation, warranty status, or Whoop subscription.

This tool only reads data from your own device. It does not circumvent any subscription paywall, modify firmware, or access Whoop's cloud services.

License

MIT -- see LICENSE.

About

Open source BLE data reader for the Whoop 4.0 fitness band

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages