From 35725aa381d187c9cbbd4cdd8c684f98927e8bec Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Fri, 20 Sep 2024 11:13:04 +0100 Subject: [PATCH] check current playing disc --- lib/mqtt.py | 66 +++++++++++++++++++++++++++++++++++++++++------------ main.py | 22 +++++++++++++----- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/lib/mqtt.py b/lib/mqtt.py index 66e9a38..9458cf3 100644 --- a/lib/mqtt.py +++ b/lib/mqtt.py @@ -1,17 +1,18 @@ import paho.mqtt.client as mqtt +import paho.mqtt.subscribe as subscribe import json -def create_client(broker:str, port:int, username:str, password:str)-> mqtt: - """_summary_ +def create_client(broker: str, port: int, username: str, password: str) -> mqtt.Client: + """Create an MQTT client and connect it to the broker Args: - broker (str): _description_ - port (int): _description_ - username (str): _description_ - password (str): _description_ + broker (str): MQTT broker address + port (int): MQTT broker port + username (str): Username for MQTT broker + password (str): Password for MQTT broker Returns: - mqtt: _description_ + mqtt.Client: Connected MQTT client instance """ # Create a new MQTT client instance client = mqtt.Client() @@ -24,11 +25,11 @@ def create_client(broker:str, port:int, username:str, password:str)-> mqtt: return client -def create_config(client:mqtt)->None: +def create_config(client: mqtt.Client) -> None: """Create Home Assistant discovery topics Args: - client (mqtt): MQTT Client + client (mqtt.Client): MQTT Client """ # Device-specific information for multiple sensors node_id = "floppy_player" # Unique device ID @@ -70,24 +71,59 @@ def create_config(client:mqtt)->None: client.publish(discovery_topic_disc, json.dumps(disc_config), retain=True) client.publish(discovery_topic_status, json.dumps(status_config), retain=True) -def update_disc(client:mqtt, disc_message:dict)->None: + +def check_current_disc(client: mqtt.Client) -> str: + """Check the current loaded disc by subscribing to the retained message on the state topic. + + Args: + client (mqtt.Client): MQTT Client + + Returns: + str: Current object at current_disc/state + """ + def on_message(client, userdata, message): + """Callback function to handle received MQTT messages.""" + userdata['message'] = message.payload.decode() + + # Create a dictionary to store the message + userdata = {'message': None} + + # Set the user data and the on_message callback + client.user_data_set(userdata) + client.on_message = on_message + + # Subscribe to the topic + client.subscribe("homeassistant/sensor/floppy_player/current_disc/state") + + # Run the loop manually until we receive a message + timeout = 5 # Timeout after 5 seconds + while userdata['message'] is None and timeout > 0: + client.loop(timeout=0.1) # Process network events for a short time + timeout -= 0.1 + + # Check if we received the message + if userdata['message'] is None: + raise TimeoutError("No retained message was found.") + + return userdata['message'] + + +def update_disc(client: mqtt.Client, disc_message: dict) -> None: """Update current disc. Args: - client (mqtt): MQTT Client + client (mqtt.Client): MQTT Client disc_message (dict): Current disc information """ client.publish("homeassistant/sensor/floppy_player/current_disc/state", json.dumps(disc_message), retain=True) print(f"Published current disc: {disc_message}") - -def control_player(client:mqtt, state:str)->None: +def control_player(client: mqtt.Client, state: str) -> None: """Control the player Args: - client (mqtt): MQTT Client + client (mqtt.Client): MQTT Client state (str): Player State """ client.publish("homeassistant/sensor/floppy_player/status/state", state, retain=True) print(f"Published status: {state}") - \ No newline at end of file diff --git a/main.py b/main.py index d60015d..c0c01f4 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,7 @@ import os import sys import json from dotenv import load_dotenv -from lib.mqtt import create_client, update_disc, control_player, create_config +from lib.mqtt import create_client, update_disc, control_player, create_config, check_current_disc # Load the .env file load_dotenv() @@ -27,16 +27,26 @@ if len(sys.argv) > 1: try: # Convert the JSON string into a dictionary - disc_data = json.loads(json_str) - # Pass the parsed data to the update_disc function - update_disc(client, disc_data) + disc_data = json.loads(json_str.replace("'",'"')) + # Check if disc is the same as last inserted + if (disc_data == json.loads(check_current_disc(client))): + # If disc is the same, PLAY + control_player(client, "PLAY") + else: + # Pass the parsed data to the update_disc function + control_player(client, "PLAY") + update_disc(client, disc_data) except json.JSONDecodeError as e: try: if json_str == "EJECT": - control_player(client, "EJECT") - update_disc(client, {"type": "album", "id": "EJECT"}) + # PAUSE the current playing item + control_player(client, "PAUSE") elif json_str == "PLAY": + # PLAY the current playing item control_player(client, "PLAY") + elif json_str == "PAUSE": + # PAUSE the current playing item + control_player(client, "PAUSE") else: print(f"Can't process {json_str}") except Exception: