From 240fe2f39d951fdb49efeb502020de6138eabd84 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Tue, 30 Dec 2025 23:20:51 +0000 Subject: [PATCH] feat: Add MQTT commands for music playback control Co-authored-by: aider (gemini/gemini-2.5-pro) --- main.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/main.py b/main.py index 26364ab..d7a9285 100644 --- a/main.py +++ b/main.py @@ -25,6 +25,7 @@ pairing_task = None BLUEZ_SERVICE = 'org.bluez' ADAPTER_IFACE = 'org.bluez.Adapter1' DEVICE_IFACE = 'org.bluez.Device1' +MEDIA_PLAYER_IFACE = 'org.bluez.MediaPlayer1' AGENT_IFACE = 'org.bluez.Agent1' AGENT_MANAGER_IFACE = 'org.bluez.AgentManager1' AGENT_PATH = '/io/bluetooth_speaker/agent' @@ -205,6 +206,34 @@ async def disconnect_connected_device(): logging.info("No connected device found to disconnect.") +async def send_media_command(command): + """Finds a media player and sends a command to it.""" + logging.info(f"Attempting to send media command: {command}") + introspection = await bus.introspect(BLUEZ_SERVICE, '/') + manager_obj = bus.get_proxy_object(BLUEZ_SERVICE, '/', introspection) + manager_iface = manager_obj.get_interface('org.freedesktop.DBus.ObjectManager') + managed_objects = await manager_iface.call_get_managed_objects() + + for path, ifaces in managed_objects.items(): + if MEDIA_PLAYER_IFACE in ifaces: + logging.info(f"Found media player: {path}. Sending command '{command}'...") + try: + player_introspection = await bus.introspect(BLUEZ_SERVICE, path) + player_obj = bus.get_proxy_object(BLUEZ_SERVICE, path, player_introspection) + player_iface = player_obj.get_interface(MEDIA_PLAYER_IFACE) + + method_name = f'call_{command}' + dbus_method = getattr(player_iface, method_name) + await dbus_method() + + logging.info(f"Successfully sent command '{command}' to {path}") + return # Assume only one media player is active + except Exception as e: + logging.error(f"Failed to send media command to {path}: {e}") + + logging.warning("No active media player found to send command to.") + + async def process_bluetooth_command(topic, text): global pairing_task logging.info('Bluetooth command: %s', text) @@ -215,6 +244,9 @@ async def process_bluetooth_command(topic, text): pairing_task = asyncio.create_task(enable_pairing()) elif text == "kick": await disconnect_connected_device() + elif text in ["play", "pause", "next", "prev"]: + command = "previous" if text == "prev" else text + await send_media_command(command) async def process_mqtt(message): text = message.payload.decode()