""" Service Explorer ---------------- An example showing how to access and print out the services, characteristics and descriptors of a connected GATT server. Created on 2019-03-25 by hbldh """ import argparse import asyncio import logging from bleak import BleakClient, BleakScanner logger = logging.getLogger(__name__) async def main(args: argparse.Namespace): logger.info("starting scan...") if args.address: device = await BleakScanner.find_device_by_address( args.address, cb=dict(use_bdaddr=args.macos_use_bdaddr) ) if device is None: logger.error("could not find device with address '%s'", args.address) return else: device = await BleakScanner.find_device_by_name( args.name, cb=dict(use_bdaddr=args.macos_use_bdaddr) ) if device is None: logger.error("could not find device with name '%s'", args.name) return logger.info("connecting to device...") async with BleakClient( device, services=args.services, ) as client: logger.info("connected") for service in client.services: logger.info("[Service] %s", service) for char in service.characteristics: if "read" in char.properties: try: value = await client.read_gatt_char(char.uuid) extra = f", Value: {value}" except Exception as e: extra = f", Error: {e}" else: extra = "" if "write-without-response" in char.properties: extra += f", Max write w/o rsp size: {char.max_write_without_response_size}" logger.info( " [Characteristic] %s (%s)%s", char, ",".join(char.properties), extra, ) for descriptor in char.descriptors: try: value = await client.read_gatt_descriptor(descriptor.handle) logger.info(" [Descriptor] %s, Value: %r", descriptor, value) except Exception as e: logger.error(" [Descriptor] %s, Error: %s", descriptor, e) logger.info("disconnecting...") logger.info("disconnected") if __name__ == "__main__": parser = argparse.ArgumentParser() device_group = parser.add_mutually_exclusive_group(required=True) device_group.add_argument( "--name", metavar="", help="the name of the bluetooth device to connect to", ) device_group.add_argument( "--address", metavar="
", help="the address of the bluetooth device to connect to", ) parser.add_argument( "--macos-use-bdaddr", action="store_true", help="when true use Bluetooth address instead of UUID on macOS", ) parser.add_argument( "--services", nargs="+", metavar="", help="if provided, only enumerate matching service(s)", ) parser.add_argument( "-d", "--debug", action="store_true", help="sets the log level to debug", ) args = parser.parse_args() log_level = logging.DEBUG if args.debug else logging.INFO logging.basicConfig( level=log_level, format="%(asctime)-15s %(name)-8s %(levelname)s: %(message)s", ) asyncio.run(main(args))