import json as js
import logging
import paho.mqtt.publish as publish
import paho.mqtt.subscribe as subscribe
import paho.mqtt.client as mqttc

import time

from .baseio import BaseIO
from ..helpers import get_kwargs

log = logging.getLogger("MqttIO")


class MqttIO(BaseIO):
    def __init__(self, *args, **kwargs) -> None:
        # self._serial_port = device_path
        # self._serial_baud = serial_baud
        self.mqtt_broker = get_kwargs(kwargs, "mqtt_broker", "localhost")
        self.mqtt_port = get_kwargs(kwargs, "mqtt_port", 1883)
        self.mqtt_user = get_kwargs(kwargs, "mqtt_user")
        self.mqtt_pass = get_kwargs(kwargs, "mqtt_pass")
        self.client_id = get_kwargs(kwargs, "client_id")
        log.info(
            f"__init__: client_id: {self.client_id},  mqtt_broker: {self.mqtt_broker}, port: {self.mqtt_port}, user: {self.mqtt_user}, pass: {self.mqtt_pass}"
        )
        self._msg = None

    def sub_cb(self, client, userdata, message):
        log.debug(f"Mqttio sub_cb got msg, topic: {message.topic}, payload: {message.payload}")
        self._msg = message

    def send_and_receive(self, *args, **kwargs) -> dict:
        full_command = get_kwargs(kwargs, "full_command")
        command = get_kwargs(kwargs, "command")
        client_id = self.client_id

        wait_time = 5
        response_line = None
        command_topic = f"{client_id}/command"
        result_topic = f"{client_id}/result"
        # print(self.mqtt_broker)
        # Create mqtt client
        # Client(client_id="", clean_session=True, userdata=None, protocol=MQTTv311, transport="tcp")
        mqtt_client = mqttc.Client()
        # mqtt_client.on_connect = on_connect

        if self.mqtt_user is not None and self.mqtt_pass is not None:
            # auth = {"username": self.mqtt_user, "password": self.mqtt_pass}
            log.info(f"Using mqtt authentication, username: {self.mqtt_user}, password: [supplied]")
            mqtt_client.username_pw_set(self.mqtt_user, password=self.mqtt_pass)
        else:
            log.debug("No mqtt authentication used")
            # auth = None

        # connect(host, port=1883, keepalive=60, bind_address="")
        mqtt_client.connect(self.mqtt_broker, port=self.mqtt_port)

        payload = full_command
        _payload = "{'command': '%s', 'full_command': %s}" % (command, full_command)
        print(_payload)

        log.debug(f"Publishing {payload} to topic: {command_topic}")

        # publish(topic, payload=None, qos=0, retain=False)
        mqtt_client.publish(command_topic, payload=payload)

        mqtt_client.on_message = self.sub_cb
        mqtt_client.subscribe(result_topic)
        mqtt_client.loop_start()
        time.sleep(wait_time)
        mqtt_client.loop_stop(force=False)

        if self._msg is None:
            # Didnt get a result
            return {
                "ERROR": [
                    f"Mqtt result message not received on topic {result_topic} after {wait_time}sec",
                    "",
                ]
            }
        else:
            msg_topic = self._msg.topic
            msg_payload = self._msg.payload.decode("unicode_escape")
            log.debug(
                f"mqtt raw response on {self._msg.topic} was: {self._msg.payload}, payload type: {type(self._msg.payload)}"
            )
            # msg_payload = self._msg.payload
            self._msg = None
            log.debug(f"mqtt response on {msg_topic} was: {msg_payload}")
            return msg_payload

@@ -1,12 +1,28 @@
+import binascii%0A
 import json 
@@ -42,16 +42,62 @@
 logging%0A
+import time%0A%0Aimport paho.mqtt.client as mqttc%0A
 import p
@@ -168,81 +168,8 @@
 ibe%0A
-import paho.mqtt.client as mqttc%0A%0Aimport time%0A%0Afrom .baseio import BaseIO
 %0Afro
@@ -197,16 +197,43 @@
 t_kwargs
+%0Afrom .baseio import BaseIO
 %0A%0Alog = 
@@ -795,17 +795,16 @@
 ent_id%7D,
- 
  mqtt_br
@@ -2130,74 +2130,8 @@
 ne%0A%0A
-        # connect(host, port=1883, keepalive=60, bind_address=%22%22)%0A
     
@@ -2202,26 +2202,47 @@
         
-payload = 
+command_hex = binascii.hexlify(
 full_com
@@ -2245,16 +2245,17 @@
 _command
+)
 %0A       
@@ -2255,17 +2255,16 @@
         
-_
 payload 
@@ -2269,89 +2269,93 @@
 d = 
+%7B
 %22
-%7B'
 command
-': '%25s', 'full_command': %25s%7D%22 %25 (command, full_command)%0A        print(_
+%22: command, %22command_hex%22: command_hex.decode()%7D%0A        payload = js.dumps(
 payl
@@ -2434,68 +2434,8 @@
 %22)%0A%0A
-        # publish(topic, payload=None, qos=0, retain=False)%0A
     
@@ -3026,64 +3026,176 @@
     
-msg_payload = self._msg.payload.decode(%22unicode_escape%22)
+# decode the payload%0A            # payload should be a json dumped byte string%0A            # payload: b'%7B%22command_hex%22: %22515049beac0d%22, %22result%22: %22%22, %22command%22: %22QPI%22%7D'
 %0A   
@@ -3370,39 +3370,350 @@
   # 
-msg_payload = self._msg.payload
+Return the byte-string to a dict%0A            payload_dict = js.loads(self._msg.payload)%0A            # Get 'results', and convert back to bytes%0A            result = binascii.unhexlify(payload_dict%5B%22result%22%5D)%0A            # TODO: Currently ignoring this - might want to update return types at some point%0A            cmd = payload_dict%5B%22command%22%5D
 %0A   
@@ -3795,25 +3795,38 @@
 ic%7D 
-was: %7Bmsg_payload
+for command %7Bcmd%7D was: %7Bresult
 %7D%22)%0A
@@ -3848,16 +3848,11 @@
 urn 
-msg_payload
+result
 %0A

Update mqttio to use hexlify and json dumps