diff --git a/main.py b/main.py index 5696b58..85a6616 100644 --- a/main.py +++ b/main.py @@ -19,6 +19,7 @@ from dbus_next import Variant, Message, MessageType bus = None agent_instance = None +pairing_task = None # --- Bluetooth constants and agent --- BLUEZ_SERVICE = 'org.bluez' @@ -156,28 +157,37 @@ async def manage_bluetooth(): await asyncio.sleep(3600) +async def enable_pairing(): + """Enable pairing for 120 seconds. This task can be cancelled and restarted.""" + adapter_obj = await get_adapter() + if not adapter_obj: + logging.error('Bluetooth adapter not found') + return + + adapter_props = adapter_obj.get_interface('org.freedesktop.DBus.Properties') + try: + await adapter_props.call_set(ADAPTER_IFACE, 'Discoverable', Variant('b', True)) + await adapter_props.call_set(ADAPTER_IFACE, 'Pairable', Variant('b', True)) + logging.info('Adapter is discoverable and pairable for 120 seconds') + + await asyncio.sleep(120) + + logging.info('Pairing timeout reached. Making adapter non-discoverable.') + await adapter_props.call_set(ADAPTER_IFACE, 'Discoverable', Variant('b', False)) + except asyncio.CancelledError: + logging.info('Pairing timer cancelled, likely by a new pair request.') + raise + except Exception as e: + logging.error(f"Failed to manage pairing state: {e}") + async def process_bluetooth_command(topic, text): + global pairing_task logging.info('Bluetooth command: %s', text) if text == "pair": - logging.info('Starting pairing process by making adapter discoverable') - adapter_obj = await get_adapter() - if not adapter_obj: - logging.error('Bluetooth adapter not found') - return - - adapter_props = adapter_obj.get_interface('org.freedesktop.DBus.Properties') - - try: - await adapter_props.call_set(ADAPTER_IFACE, 'Discoverable', Variant('b', True)) - await adapter_props.call_set(ADAPTER_IFACE, 'Pairable', Variant('b', True)) - logging.info('Adapter is discoverable and pairable for 120 seconds') - - await asyncio.sleep(120) - - await adapter_props.call_set(ADAPTER_IFACE, 'Discoverable', Variant('b', False)) - logging.info('Adapter is no longer discoverable') - except Exception as e: - logging.error(f"Failed to set adapter properties: {e}") + if pairing_task and not pairing_task.done(): + logging.info('A pairing process is already active. Cancelling it to restart the timer.') + pairing_task.cancel() + pairing_task = asyncio.create_task(enable_pairing()) async def process_mqtt(message): text = message.payload.decode()