MyoLink is an asynchronous Python library for discovering and controlling Open Bionics BLE devices, including Hero RGD/PRO hands and MyoPod EMG sensors.
MyoLink requires Python 3.10 or newer and a Bluetooth adapter supported by
bleak.
python -m pip install -e .For development and graphical examples:
python -m pip install -e ".[test,examples]"
python -m pytestdiscover_devices(timeout, device_type)scans Open Bionics manufacturer data (0x0ABA) and returns the latest advertisement and RSSI by BLE address.discover_identified_devices(timeout, device_type)latches every device seen with its transient Identify bit active during one scan, deduplicates by address, and returns the strongest signal first.filter_identified_devices(devices)selects and orders currently identifying entries from an existing discovery result.Handsends digit/grip commands and reads humidity or temperature responses.MyoPodconfigures streams and manages parsed notification callbacks.ControlCommandClientprovides the reusable asynchronous BLE request/response lifecycle used by device control commands.myolink.discoveryandmyolink.myopod_protocolexpose transport-independent parsers suitable for tests, recordings, or alternative BLE integrations.
Device instances require an already-connected BleakClient:
from bleak import BleakClient
from myolink import CompressionType, EmgStreamSource, MyoPod
async with BleakClient(address) as client:
pod = MyoPod(client)
await pod.configure_stream(
EmgStreamSource.RAW_EMG,
CompressionType.INT16,
average_samples=5,
)
await pod.start_stream(lambda packet: print(packet.data_points))
# Keep the event loop alive while consuming notifications.
await pod.stop_stream()
await pod.configure_stream(EmgStreamSource.NONE)Discovery results are typed DiscoveredDevice tuples, so existing tuple
unpacking remains valid while named fields are available:
from myolink import discover_identified_devices
candidates = await discover_identified_devices(timeout=10.0)
for candidate in candidates:
print(candidate.address, candidate.rssi, candidate.is_identifying)discover_devices() reflects the latest advertisement, including an Identify
bit that clears during the scan. The dedicated identified scan intentionally
latches an earlier active observation for that invocation. Connection ownership
remains with the caller; see
examples/connect_identified_devices.py
for concurrent connections with per-device failure handling and guaranteed
disconnects. For a live one-minute terminal list that shows Identify
transitions, see examples/watch_devices.py.
start_stream accepts a synchronous callback. Keep callback work short; hand
expensive processing to a queue or worker so the BLE notification loop remains
responsive.
Protocol references and usage notes are indexed in Docs/README.md. Runnable workflows are under examples/.
Binary protocol parsers reject unsupported schemas, truncated/trailing payloads, invalid enum values, and non-finite numeric metadata. BLE discovery errors are allowed to propagate so callers can distinguish adapter or permission failures from a valid scan with no devices.
Control Command failures are exposed as typed exceptions. Because schema 0 has no transaction ID, requests are serialized and a timeout prevents further commands until its late response is discarded or BLE is reset. See the Control Command architecture.
This project is in alpha development. Public protocol models are typed, but APIs may still evolve as device firmware support expands.