# Path: mppsolar/helpers.py
# def get_kwargs(kwargs, key, default=None):
#     if key not in kwargs or not kwargs[key]:
#         return default
#     return kwargs[key]
# 
# Path: mppsolar/io/baseio.py
# class BaseIO(ABC):
#     @abstractmethod
#     def send_and_receive(self, *args, **kwargs) -> dict:
#         raise NotImplementedError
# 
#     def connect(self) -> None:
#         log.debug("connect not implemented")
#         return
# 
#     def disconnect(self) -> None:
#         log.debug("disconnect not implemented")
#         return
# 
#     def process_command(self, command, protocol):
#         # Band-aid solution, need to reduce what is sent
#         log.debug(f"Command {command}")
#         full_command = protocol.get_full_command(command)
# 
#         raw_response = self.send_and_receive(
#             command=command,
#             full_command=full_command,
#             protocol=protocol,
#             command_defn=protocol.get_command_defn(command),
#         )
#         log.debug(f"Send and Receive Response {raw_response}")
# 
#         # Handle errors
#         # Maybe there should a decode for ERRORs and WARNINGS...
#         # Some inverters return the command if the command is unknown:
#         if raw_response == full_command:
#             return {
#                 "ERROR": [
#                     f"Inverter returned the command string for {command} - the inverter didnt recognise this command",
#                     "",
#                 ]
#             }
#         # dict is returned on exception
# 
#         if isinstance(raw_response, dict):
#             return raw_response
# 
#         # Decode response
#         decoded_response = protocol.decode(raw_response, command)
#         log.info(f"Decoded response {decoded_response}")
# 
#         return decoded_response


import binascii
import json as js
import logging
import time
import paho.mqtt.client as mqttc
from ..helpers import get_kwargs
from .baseio import BaseIO

    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


# Path: mppsolar/helpers.py
# def get_kwargs(kwargs, key, default=None):
#     if key not in kwargs or not kwargs[key]:
#         return default
#     return kwargs[key]
# 
# Path: mppsolar/io/baseio.py
# class BaseIO(ABC):
#     @abstractmethod
#     def send_and_receive(self, *args, **kwargs) -> dict:
#         raise NotImplementedError
# 
#     def connect(self) -> None:
#         log.debug("connect not implemented")
#         return
# 
#     def disconnect(self) -> None:
#         log.debug("disconnect not implemented")
#         return
# 
#     def process_command(self, command, protocol):
#         # Band-aid solution, need to reduce what is sent
#         log.debug(f"Command {command}")
#         full_command = protocol.get_full_command(command)
# 
#         raw_response = self.send_and_receive(
#             command=command,
#             full_command=full_command,
#             protocol=protocol,
#             command_defn=protocol.get_command_defn(command),
#         )
#         log.debug(f"Send and Receive Response {raw_response}")
# 
#         # Handle errors
#         # Maybe there should a decode for ERRORs and WARNINGS...
#         # Some inverters return the command if the command is unknown:
#         if raw_response == full_command:
#             return {
#                 "ERROR": [
#                     f"Inverter returned the command string for {command} - the inverter didnt recognise this command",
#                     "",
#                 ]
#             }
#         # dict is returned on exception
# 
#         if isinstance(raw_response, dict):
#             return raw_response
# 
#         # Decode response
#         decoded_response = protocol.decode(raw_response, command)
#         log.info(f"Decoded response {decoded_response}")
# 
#         return decoded_response


# Path: mppsolar/io/mqttio.py
import binascii
import json as js
import logging
import time
import paho.mqtt.client as mqttc
from ..helpers import get_kwargs
from .baseio import BaseIO


    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


        mqtt_client.connect(self.mqtt_broker, port=self.mqtt_port)