# 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

# import paho.mqtt.publish as publish
# import paho.mqtt.subscribe as subscribe


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 = self.mqtt_broker.port
        self.mqtt_user = self.mqtt_broker.username
        self.mqtt_pass = self.mqtt_broker.password
        # 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:

# 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


# import paho.mqtt.publish as publish
# import paho.mqtt.subscribe as subscribe


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 = self.mqtt_broker.port
        self.mqtt_user = self.mqtt_broker.username
        self.mqtt_pass = self.mqtt_broker.password
        # 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")