{
  "id": "aioble",
  "name": "aioble",
  "description": "",
  "version": "0.6.2",
  "author": "",
  "license": "MIT",
  "tags": [
    "micropython",
    "bluetooth"
  ],
  "status": "HUMAN_REVIEWED",
  "official": true,
  "source": "https://github.com/micropython/micropython-lib/tree/master/micropython/bluetooth/aioble",
  "updatedAt": "2026-08-07T03:55:17.891Z",
  "page": "https://checkmim.com/packages/aioble",
  "createdAt": "2025-05-27T04:19:19.510Z",
  "install": {
    "mpremote": "mpremote mip install aioble",
    "mip": "import mip; mip.install(\"aioble\")"
  },
  "readme": "aioble\n======\n\nThis library provides an object-oriented, asyncio-based wrapper for MicroPython's\n[bluetooth](https://docs.micropython.org/en/latest/library/bluetooth.html) API.\n\n**Note**: aioble requires MicroPython v1.17 or higher.\n\nFeatures\n--------\n\nBroadcaster (advertiser) role:\n* Generate advertising and scan response payloads for common fields.\n* Automatically split payload over advertising and scan response.\n* Start advertising (indefinitely or for duration).\n\nPeripheral role:\n* Wait for connection from central.\n* Wait for MTU exchange.\n\nObserver (scanner) role:\n* Scan for devices (passive + active).\n* Combine advertising and scan response payloads for the same device.\n* Parse common fields from advertising payloads.\n\nCentral role:\n* Connect to peripheral.\n* Initiate MTU exchange.\n\nGATT Client:\n* Discover services, characteristics, and descriptors (optionally by UUID).\n* Read / write / write-with-response characters and descriptors.\n* Subscribe to notifications and indications on characteristics (via the CCCD).\n* Wait for notifications and indications.\n\nGATT Server:\n* Register services, characteristics, and descriptors.\n* Wait for writes on characteristics and descriptors.\n* Intercept read requests.\n* Send notifications and indications (and wait on response).\n\nL2CAP:\n* Accept and connect L2CAP Connection-oriented-channels.\n* Manage channel flow control.\n\nSecurity:\n* JSON-backed key/secret management.\n* Initiate pairing.\n* Query encryption/authentication state.\n\nAll remote operations (connect, disconnect, client read/write, server indicate, l2cap recv/send, pair) are awaitable and support timeouts.\n\nInstallation\n------------\n\nYou can install any combination of the following packages.\n- `aioble-central` -- Central (and Observer) role functionality including\n  scanning and connecting.\n- `aioble-client` -- GATT client, typically used by central role devices but\n  can also be used on peripherals.\n- `aioble-l2cap` -- L2CAP Connection-oriented-channels support.\n- `aioble-peripheral` -- Peripheral (and Broadcaster) role functionality\n  including advertising.\n- `aioble-security` -- Pairing and bonding support.\n- `aioble-server` -- GATT server, typically used by peripheral role devices\n  but can also be used on centrals.\n\nAlternatively, install the `aioble` package, which will install everything.\n\nUsage\n-----\n\n#### Passive scan for nearby devices for 5 seconds: (Observer)\n\n```py\nasync with aioble.scan(duration_ms=5000) as scanner:\n    async for result in scanner:\n        print(result, result.name(), result.rssi, result.services())\n```\n\nActive scan (includes \"scan response\" data) for nearby devices for 5 seconds\nwith the highest duty cycle: (Observer)\n\n```py\nasync with aioble.scan(duration_ms=5000, interval_us=30000, window_us=30000, active=True) as scanner:\n    async for result in scanner:\n        print(result, result.name(), result.rssi, result.services())\n```\n\n#### Connect to a peripheral device: (Central)\n\n```py\n# Either from scan result\ndevice = result.device\n# Or with known address\ndevice = aioble.Device(aioble.ADDR_PUBLIC, \"aa:bb:cc:dd:ee:ff\")\n\ntry:\n    connection = await device.connect(timeout_ms=2000)\nexcept asyncio.TimeoutError:\n    print('Timeout')\n```\n\n#### Register services and wait for connection: (Peripheral, Server)\n\n```py\n_ENV_SENSE_UUID = bluetooth.UUID(0x181A)\n_ENV_SENSE_TEMP_UUID = bluetooth.UUID(0x2A6E)\n_GENERIC_THERMOMETER = const(768)\n\n_ADV_INTERVAL_US = const(250000)\n\ntemp_service = aioble.Service(_ENV_SENSE_UUID)\ntemp_char = aioble.Characteristic(temp_service, _ENV_SENSE_TEMP_UUID, read=True, notify=True)\n\naioble.register_services(temp_service)\n\nwhile True:\n    connection = await aioble.advertise(\n            _ADV_INTERVAL_US,\n            name=\"temp-sense\",\n            services=[_ENV_SENSE_UUID],\n            appearance=_GENERIC_THERMOMETER,\n            manufacturer=(0xabcd, b\"1234\"),\n        )\n    print(\"Connection from\", device)\n```\n\n#### Update characteristic value: (Server)\n\n```py\n# Write the local value.\ntemp_char.write(b'data')\n```\n\n```py\n# Write the local value and notify/indicate subscribers.\ntemp_char.write(b'data', send_update=True)\n```\n\n#### Send notifications: (Server)\n\n```py\n# Notify with the current value.\ntemp_char.notify(connection)\n```\n\n```py\n# Notify with a custom value.\ntemp_char.notify(connection, b'optional data')\n```\n\n#### Send indications: (Server)\n\n```py\n# Indicate with current value.\nawait temp_char.indicate(connection, timeout_ms=2000)\n```\n\n```py\n# Indicate with custom value.\nawait temp_char.indicate(connection, b'optional data', timeout_ms=2000)\n```\n\nThis will raise `GattError` if the indication is not acknowledged.\n\n#### Wait for a write from the client: (Server)\n\n```py\n# Normal characteristic, returns the connection that did the write.\nconnection = await char.written(timeout_ms=2000)\n```\n\n```py\n# Characteristic with capture enabled, also returns the value.\nchar = Characteristic(..., capture=True)\nconnection, data = await char.written(timeout_ms=2000)\n```\n\n#### Query the value of a characteristic: (Client)\n\n```py\ntemp_service = await connection.service(_ENV_SENSE_UUID)\ntemp_char = await temp_service.characteristic(_ENV_SENSE_TEMP_UUID)\n\ndata = await temp_char.read(timeout_ms=1000)\n```\n\n#### Wait for a notification/indication: (Client)\n\n```py\n# Notification\ndata = await temp_char.notified(timeout_ms=1000)\n```\n\n```py\n# Indication\ndata = await temp_char.indicated(timeout_ms=1000)\n```\n\n#### Subscribe to a characteristic: (Client)\n\n```py\n# Subscribe for notification.\nawait temp_char.subscribe(notify=True)\nwhile True:\n    data = await temp_char.notified()\n```\n\n```py\n# Subscribe for indication.\nawait temp_char.subscribe(indicate=True)\nwhile True:\n    data = await temp_char.indicated()\n```\n\n#### Open L2CAP channels: (Listener)\n\n```py\nchannel = await connection.l2cap_accept(_L2CAP_PSN, _L2CAP_MTU)\nbuf = bytearray(64)\nn = channel.recvinto(buf)\nchannel.send(b'response')\n```\n\n#### Open L2CAP channels: (Initiator)\n\n```py\nchannel = await connection.l2cap_connect(_L2CAP_PSN, _L2CAP_MTU)\nchannel.send(b'request')\nbuf = bytearray(64)\nn = channel.recvinto(buf)\n```\n\n\nExamples\n--------\n\nSee the `examples` directory for some example applications.\n\n* temp_sensor.py: Temperature sensor peripheral.\n* temp_client.py: Connects to the temp sensor.\n* l2cap_file_server.py: Simple file server peripheral. (WIP)\n* l2cap_file_client.py: Client for the file server. (WIP)\n\nTests\n-----\n\nThe `multitests` directory provides tests that can be run with MicroPython's `run-multitests.py` script. These are based on the existing `multi_bluetooth` tests that are in the main repo.\n"
}