{"id":19691220,"url":"https://github.com/wideopensource/polarpy","last_synced_at":"2025-10-04T06:31:57.860Z","repository":{"id":183948385,"uuid":"619238979","full_name":"wideopensource/polarpy","owner":"wideopensource","description":"Tools for reading and fusing live data streams from Polar OH1 (PPG) and H10 (ECG) sensors. pip install polarpy.","archived":false,"fork":false,"pushed_at":"2023-03-26T17:16:27.000Z","size":9,"stargazers_count":17,"open_issues_count":1,"forks_count":7,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-05T14:34:43.456Z","etag":null,"topics":["h10","oh1","pip","polar","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wideopensource.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-03-26T17:10:35.000Z","updated_at":"2025-03-25T22:49:27.000Z","dependencies_parsed_at":"2023-07-26T14:03:35.368Z","dependency_job_id":null,"html_url":"https://github.com/wideopensource/polarpy","commit_stats":null,"previous_names":["wideopensource/polarpy"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wideopensource%2Fpolarpy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wideopensource%2Fpolarpy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wideopensource%2Fpolarpy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wideopensource%2Fpolarpy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wideopensource","download_url":"https://codeload.github.com/wideopensource/polarpy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251465447,"owners_count":21593882,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["h10","oh1","pip","polar","python"],"created_at":"2024-11-11T19:08:25.777Z","updated_at":"2025-10-04T06:31:57.794Z","avatar_url":"https://github.com/wideopensource.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# polarpy\n\nTools for reading and fusing live data streams from Polar OH1 (PPG) and H10 (ECG) sensors.\n\n## Requirements\n\nIf installing from the repo you need [`pygatttool`](https://github.com/wideopensource/pygatttool) (`pip install pygatttool`).\n\n## Installation\n\n```\npip install polarpy\n```\n\n## Usage\n\nThe following code starts the raw PPG and IMU streams on a Polar OH1, fuses the blocks pf data in the two streams at 135Hz, and provides a single output stream, each record having a timestamp, the PPG signal values for each of the 3 pairs of LEDs, and the corresponding accerelometer x, y and z readings.\n\n```\nfrom polarpy import OH1\n\nOH1_ADDR = \"A0:9E:1A:7D:3C:5D\"\nOH1_CONTROL_ATTRIBUTE_HANDLE = 0x003f\nOH1_DATA_ATTRIBUTE_HANDLE = 0x0042\n\ndef callback(type: str, timestamp: float, payload: dict):\n    print(f'{timestamp} {payload}')\n\nif '__main__' == __name__:\n    device = OH1(address=OH1_ADDR,\n                 control_handle=OH1_CONTROL_ATTRIBUTE_HANDLE,\n                 data_handle=OH1_DATA_ATTRIBUTE_HANDLE,\n                 callback=callback)\n\n    if device.start():\n        while device.run():\n            pass\n```\n\nThe output looks something like this:\n\n```\n3.94 {'ppg0': 263249, 'ppg1': 351764, 'ppg2': 351928, 'ax': 0.775, 'ay': -0.42, 'az': 0.476}\n3.947 {'ppg0': 263297, 'ppg1': 351964, 'ppg2': 352077, 'ax': 0.775, 'ay': -0.42, 'az': 0.476}\n3.954 {'ppg0': 263319, 'ppg1': 352062, 'ppg2': 352013, 'ax': 0.778, 'ay': -0.417, 'az': 0.481}\n3.962 {'ppg0': 263293, 'ppg1': 352106, 'ppg2': 352082, 'ax': 0.778, 'ay': -0.417, 'az': 0.481}\n3.969 {'ppg0': 263440, 'ppg1': 352273, 'ppg2': 352199, 'ax': 0.778, 'ay': -0.417, 'az': 0.481}\n\n...\n```\n\nThe callback is used (rather than returning data from `run()`) because the blocks of PPG, ECG and IMU data arrive with different lengths and at different speeds. The individual samples from each channel must be buffered and interleaved, timestamps interpolated, then delivered asynchronously through the callback. \n\nThe address and attribute handles for your particular device can be found using `gatttool` or another BLE tool such as nRF Connect.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwideopensource%2Fpolarpy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwideopensource%2Fpolarpy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwideopensource%2Fpolarpy/lists"}