Wilbert's website at SocSci

> Software> Python> Polar OH1

python/polar.html 2022-11-14

Polar

Here is an example reading the Polar OH1 heart rate sensor from python

Python, with the pygatt library

#!/usr/bin/env python3

import pygatt
#import logging

#logging.basicConfig()
#logging.getLogger('pygatt').setLevel(logging.DEBUG)

address       = "A0:9E:1A:71:96:37"
model_uid     = "00002a24-0000-1000-8000-00805f9b34fb"
battery_uid   = "00002a19-0000-1000-8000-00805f9b34fb"
heartbeat_uid = "00002a37-0000-1000-8000-00805f9b34fb"

#adapter = pygatt.BGAPIBackend() # for bluegiga dongle on all os'ses
adapter = pygatt.GATTToolBackend() # for posix compliant os'ses

try:
	adapter.start()
	device = adapter.connect(address, timeout=15)
	model = device.char_read(model_uid).decode("utf-8")
	battery = device.char_read(battery_uid)[0]
	print("device: {:s}, battery {:d}%, press enter to stop recording heart rate".format(model, battery))
	device.subscribe(heartbeat_uid, callback=lambda handle, value: print("\r{:d} bpm ".format(value[1]), end=""))
	input()
finally:
	adapter.stop()

Python, with the bleak library (os agnostic)

#!/usr/bin/env python3

import asyncio
from bleak import BleakClient

address       = "A0:9E:1A:71:96:37"
model_uid     = "00002a24-0000-1000-8000-00805f9b34fb"
battery_uid   = "00002a19-0000-1000-8000-00805f9b34fb"
heartbeat_uid = "00002a37-0000-1000-8000-00805f9b34fb"

running = True
async def run(address):
	async with BleakClient(address) as client:
		model = await client.read_gatt_char(model_uid)
		model = model.decode("utf-8")
		battery = await client.read_gatt_char(battery_uid)
		battery = battery[0]
		print("device: {:s}, battery: {:d}%, press enter to stop".format(model, battery))

		await client.start_notify(heartbeat_uid, lambda sender, data: print("\r{:d} bpm ".format(data[1]), end=""))
		while await client.is_connected()i and running:
			await asyncio.sleep(1)

#asyncio.run(run(address)) # event based
threading.Thread(target=asyncio.run, args=(run(address),)).start() # mix of paradigms: event loop in background
input()
running=False

From the command line

sudo hcitool lescan # get the device address
sudo gatttool -b A0:9E:1A:71:96:37 -I
connect
primary
#attr handle: 0x0026, end grp handle: 0x0029 uuid: 0000180d-0000-1000-8000-00805f9b34fb
#attr handle: 0x002a, end grp handle: 0x002d uuid: 0000180f-0000-1000-8000-00805f9b34fb

char-desc 0x0026 0x0029
#handle: 0x0028, uuid: 00002a37-0000-1000-8000-00805f9b34fb
#handle: 0x0029, uuid: 00002902-0000-1000-8000-00805f9b34fb
char-write-req 0x0029 0100
#Notification handle = 0x0028 value: 00 53 
char-write-req 0x0029 0000

As a class

gitlab

H10

H1: [NEW] Device C1:B6:3B:5B:BB:19 Polar H10 83917628