From 586c89579c3dc618ef486962f3a8bf121367acf5 Mon Sep 17 00:00:00 2001 From: Karl Hudgell Date: Fri, 20 Sep 2024 14:13:21 +0100 Subject: [PATCH] rework for string logic --- lib/mqtt.py | 150 ++++++++++++++++++++++++++++++++++++++++++---------- main.py | 2 +- 2 files changed, 124 insertions(+), 28 deletions(-) diff --git a/lib/mqtt.py b/lib/mqtt.py index 2f8892e..54eda42 100644 --- a/lib/mqtt.py +++ b/lib/mqtt.py @@ -2,6 +2,7 @@ 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.Client: """Create an MQTT client and connect it to the broker @@ -13,7 +14,7 @@ def create_client(broker: str, port: int, username: str, password: str) -> mqtt. Returns: mqtt.Client: Connected MQTT client instance - """ + """ # Create a new MQTT client instance client = mqtt.Client() @@ -22,21 +23,37 @@ def create_client(broker: str, port: int, username: str, password: str) -> mqtt. # Connect to the MQTT broker client.connect(broker, port, 60) - + return client + def create_config(client: mqtt.Client) -> None: """Create Home Assistant discovery topics Args: client (mqtt.Client): MQTT Client - """ + """ # Device-specific information for multiple sensors node_id = "floppy_player" # Unique device ID # Define discovery and state topics for each sensor discovery_topic_disc = f"homeassistant/sensor/floppy_player/current_disc/config" - current_disc_state_topic_disc = f"homeassistant/sensor/floppy_player/current_disc/state" + discovery_topic_disc_type = ( + f"homeassistant/sensor/floppy_player/current_disc_type/config" + ) + discovery_topic_disc_id = ( + f"homeassistant/sensor/floppy_player/current_disc_id/config" + ) + + current_disc_state_topic_disc = ( + f"homeassistant/sensor/floppy_player/current_disc/state" + ) + current_disc_type_state_topic_disc = ( + f"homeassistant/sensor/floppy_player/current_disc_type/state" + ) + current_disc_id_state_topic_disc = ( + f"homeassistant/sensor/floppy_player/current_disc_id/state" + ) discovery_topic_status = f"homeassistant/sensor/floppy_player/status/config" state_topic_status = f"homeassistant/sensor/floppy_player/status/state" @@ -51,8 +68,34 @@ def create_config(client: mqtt.Client) -> None: "identifiers": [node_id], "name": "Floppy Player", "model": "v1", - "manufacturer": "Karl" - } + "manufacturer": "Karl", + }, + } + + current_disc_type_state_config = { + "name": "Current Disc Type", + "state_topic": current_disc_type_state_topic_disc, + "value_template": "{{ value }}", # Textual value + "unique_id": f"{node_id}_current_disc_type", + "device": { + "identifiers": [node_id], + "name": "Floppy Player", + "model": "v1", + "manufacturer": "Karl", + }, + } + + current_disc_id_state_config = { + "name": "Current Disc Id", + "state_topic": current_disc_id_state_topic_disc, + "value_template": "{{ value }}", # Textual value + "unique_id": f"{node_id}_current_disc_id", + "device": { + "identifiers": [node_id], + "name": "Floppy Player", + "model": "v1", + "manufacturer": "Karl", + }, } # Sensor 2: status (another text-based sensor) @@ -65,47 +108,83 @@ def create_config(client: mqtt.Client) -> None: "identifiers": [node_id], "name": "Floppy Player", "model": "v1", - "manufacturer": "Karl" - } + "manufacturer": "Karl", + }, } client.publish(discovery_topic_disc, json.dumps(current_disc_config), retain=True) + client.publish( + discovery_topic_disc_type, + json.dumps(current_disc_type_state_config), + retain=True, + ) + client.publish( + discovery_topic_disc_id, json.dumps(current_disc_id_state_config), retain=True + ) + client.publish(discovery_topic_status, json.dumps(status_config), retain=True) -def check_current_disc(client: mqtt.Client) -> str: - """Check the current loaded disc by subscribing to the retained message on the state topic. +def check_current_disc(client: mqtt.Client) -> dict: + """Check the current loaded disc, disc type, and disc ID by subscribing to the retained messages on the state topics. Args: client (mqtt.Client): MQTT Client Returns: - str: Current object at current_disc/state - """ + dict: A dictionary containing the current disc, disc type, and disc ID. + """ + 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} + topic = message.topic + userdata[topic] = message.payload.decode() + + # Create a dictionary to store the messages + userdata = { + "homeassistant/sensor/floppy_player/current_disc/state": None, + "homeassistant/sensor/floppy_player/current_disc_type/state": None, + "homeassistant/sensor/floppy_player/current_disc_id/state": 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") + # Subscribe to the topics + current_disc_state_topic_disc = ( + "homeassistant/sensor/floppy_player/current_disc/state" + ) + current_disc_type_state_topic_disc = ( + "homeassistant/sensor/floppy_player/current_disc_type/state" + ) + current_disc_id_state_topic_disc = ( + "homeassistant/sensor/floppy_player/current_disc_id/state" + ) - # Run the loop manually until we receive a message + topics = [ + current_disc_state_topic_disc, + current_disc_type_state_topic_disc, + current_disc_id_state_topic_disc, + ] + for topic in topics: + client.subscribe(topic) + + # Run the loop manually until we receive all messages or timeout timeout = 5 # Timeout after 5 seconds - while userdata['message'] is None and timeout > 0: + while any(value is None for value in userdata.values()) 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.") + # Check if we received all messages + if any(value is None for value in userdata.values()): + raise TimeoutError("Some retained messages were not found.") - return userdata['message'] + # Return the relevant messages + return { + "name": userdata[current_disc_state_topic_disc], + "type": userdata[current_disc_type_state_topic_disc], + "id": userdata[current_disc_id_state_topic_disc], + } def update_disc(client: mqtt.Client, disc_message: dict) -> None: @@ -115,15 +194,32 @@ def update_disc(client: mqtt.Client, disc_message: dict) -> None: 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) + client.publish( + "homeassistant/sensor/floppy_player/current_disc/state", + disc_message[1], + retain=True, + ) + client.publish( + "homeassistant/sensor/floppy_player/current_disc_type/state", + disc_message[2], + retain=True, + ) + client.publish( + "homeassistant/sensor/floppy_player/current_disc_id/state", + disc_message[3], + retain=True, + ) print(f"Published current disc: {disc_message}") + def control_player(client: mqtt.Client, state: str) -> None: """Control the player Args: client (mqtt.Client): MQTT Client state (str): Player State - """ - client.publish("homeassistant/sensor/floppy_player/status/state", state, retain=True) + """ + client.publish( + "homeassistant/sensor/floppy_player/status/state", state, retain=True + ) print(f"Published status: {state}") diff --git a/main.py b/main.py index 38019cc..d4cd223 100644 --- a/main.py +++ b/main.py @@ -29,7 +29,7 @@ if len(sys.argv) > 1: disc_data = input_str.split(":") if disc_data[0] == "ytmusic": disc_object = { - "Name":disc_data[1], + "name":disc_data[1], "type":disc_data[2], "id":disc_data[3] }