Skip to main content

Bluetooth Low Energy Heart Rate Monitoring

Project description

blehrm

Bluetooth Low Energy Heart Rate Monitoring

Blehrm is a platform for streaming data from bluetooth low energy (BLE) heart rate monitors. Built on Bleak

Blehrm provides a simple asynchronous platform to connect with commonly available heart rate monitors including the Polar H10.

  • Free software: MIT License

Supported Devices:

  • Polar H10
  • Garmin HRM Pro
  • CL800

Installation

pip install blehrm

Features

  • Stream interbeat interval (time between heart beats), and raw ECG and accelerometer
  • A simple interface to easily extend to other BLE HR monitors
  • Discover supported BLE HR monitors nearby

Usage

To discover (supported) HR monitors:

    from blehrm import blehrm
    from bleak import BleakScanner
    import asyncio

    async def main():
        print('Scanning for devices...')
        ble_devices = await BleakScanner.discover()
        blehrm.print_supported_devices(ble_devices)

    if __name__ == "__main__":
        asyncio.run(main())
╒════════════════════╤══════════════════════════════════════╤══════════════╤═══════════════╕
│ Name               │ Address                              │ Type         │ Services      │
╞════════════════════╪══════════════════════════════════════╪══════════════╪═══════════════╡
│ CL800-0643016      │ CF7582F0-5AA4-7279-63A3-5850A4B6F780 │ CL800        │ ibi, acc      │
├────────────────────┼──────────────────────────────────────┼──────────────┼───────────────┤
│ HRM-Pro:982040     │ 34987821-60E5-03FB-70CC-BF552DC66039 │ GarminHRMPro │ ibi           │
├────────────────────┼──────────────────────────────────────┼──────────────┼───────────────┤
│ Polar H10 79324520 │ 5BE8C8E0-8FA7-CEE7-4662-D49695040AF7 │ PolarH10     │ ibi, acc, ecg │
╘════════════════════╧══════════════════════════════════════╧══════════════╧═══════════════╛

Connect and stream interbeat interval

Consume data stream with a callback

    # examples/print_hr.py 

    import asyncio
    from bleak import BleakScanner
    from blehrm import blehrm
    import sys
    from datetime import datetime

    ADDRESS = "CF7582F0-5AA4-7279-63A3-5850A4B6F780" 
        
    async def main():
        ble_device = await BleakScanner.find_device_by_address(ADDRESS, timeout=20.0)
        if ble_device is None:
            print(f"Device with address {ADDRESS} not found")
            return

        blehrm_client = blehrm.create_client(ble_device) 
        await blehrm_client.connect()
        await blehrm_client.start_ibi_stream(print_callback)

        print("Streaming interbeat-interval data. Press Ctrl+C to stop.")
        while True:
            await asyncio.sleep(1)

    def print_callback(data):
        if data.size > 0:
            t, ibi = data
            t_str = datetime.fromtimestamp(t).strftime("%Y-%m-%d %H:%M:%S.%f")
            hr = round(60000/ibi, 1)
            sys.stdout.write(f"\r{t_str}: {hr} bpm")
            sys.stdout.flush()

    if __name__ == "__main__":
        try:
            asyncio.run(main())
        except KeyboardInterrupt:
            print("\nStream stopped by user.")
python3 examples/print_hr.py 
Streaming interbeat-interval data. Press Ctrl+C to stop.
2024-09-19 15:15:35.011178: 77.2 bpm

Application Examples

Compare HR accuracy between sensors

examples/hr_comparison.py

HR Comparison

Live ECG

examples/live_ecg.py

Live ECG Example

Accelerometer visualisation

examples/live_acc.py

Live ACC Example

Development

Extend support for a custom HR monitor by subclassing the interface base class, and implementing two methods:

    # blehrm/clients/custom_hrm.py

    from blehrm.interface import BlehrmClientInterface
    from blehrm.registry import BlehrmRegistry
    import time
    import numpy as np

    @BlehrmRegistry.register("CustomHRMReader")
    class CustomHRMReader(BlehrmClientInterface):
        
        def __init__(self, ble_device):
            super().__init__(ble_device)
        
        @staticmethod
        def is_supported(device_name):
            return device_name is not None and "Device_name" in device_name
        
        def _ibi_data_processor(self, bytes_data):
            ibi = bytes_data_to_ibi(bytes_data) # Code to process bytes message to ibi

            return np.array([time.time_ns/1.0e9, ibi])

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

blehrm-0.1.4.tar.gz (7.4 MB view details)

Uploaded Source

Built Distribution

blehrm-0.1.4-py3-none-any.whl (15.1 kB view details)

Uploaded Python 3

File details

Details for the file blehrm-0.1.4.tar.gz.

File metadata

  • Download URL: blehrm-0.1.4.tar.gz
  • Upload date:
  • Size: 7.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.6

File hashes

Hashes for blehrm-0.1.4.tar.gz
Algorithm Hash digest
SHA256 3ddd9751ca577db7ca230b63b25baacc78ab5527781c45f8d87ecf6a3816682e
MD5 2ec15a166d41e93cb13bcfd06c81e39e
BLAKE2b-256 9017b3db05b438de66b9972fadeda4774aa4418f757058bb879e4393e11921d0

See more details on using hashes here.

File details

Details for the file blehrm-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: blehrm-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 15.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.6

File hashes

Hashes for blehrm-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 68fad4e40bfa4e21adfc86e241a31f16cd5d1d252384330d8e4e2ba6f17b39ca
MD5 2451d23313233541467ce5e498c87add
BLAKE2b-256 c6cf04bc3a26ce36ad5b8aacc3371434c089d7b31a84736ccf15703f7f9ebf15

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page