# 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/helpers.py
# def get_kwargs(kwargs, key, default=None):
#     if key not in kwargs or not kwargs[key]:
#         return default
#     return kwargs[key]


import logging
import os
import time
            import pdb
from .baseio import BaseIO
from ..helpers import get_kwargs
        self._device = device_path

    def send_and_receive(self, *args, **kwargs) -> dict:
        full_command = get_kwargs(kwargs, "full_command")
        response_line = bytes()
        usb0 = None
        try:
            usb0 = os.open(self._device, os.O_RDWR | os.O_NONBLOCK)
        except Exception as e:
            log.debug("USB open error: {}".format(e))
            return {"ERROR": ["USB open error: {}".format(e), ""]}
        # Send the command to the open usb connection
        to_send = full_command
        try:
            log.debug(f"length of to_send: {len(to_send)}")
        except:  # noqa: E722

            pdb.set_trace()
        if len(to_send) <= 8:
            # Send all at once
            log.debug("1 chunk send")
            time.sleep(0.35)
            os.write(usb0, to_send)
        elif len(to_send) > 8 and len(to_send) < 11:
            log.debug("2 chunk send")
            time.sleep(0.35)
            os.write(usb0, to_send[:5])
            time.sleep(0.35)
            os.write(usb0, to_send[5:])
        else:

# 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/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/hidrawio.py
import logging
import os
import time
            import pdb
from .baseio import BaseIO
from ..helpers import get_kwargs

        self._device = device_path

    def send_and_receive(self, *args, **kwargs) -> dict:
        full_command = get_kwargs(kwargs, "full_command")
        response_line = bytes()
        usb0 = None
        try:
            usb0 = os.open(self._device, os.O_RDWR | os.O_NONBLOCK)
        except Exception as e:
            log.debug("USB open error: {}".format(e))
            return {"ERROR": ["USB open error: {}".format(e), ""]}
        # Send the command to the open usb connection
        to_send = full_command
        try:
            log.debug(f"length of to_send: {len(to_send)}")
        except:  # noqa: E722

            pdb.set_trace()
        if len(to_send) <= 8:
            # Send all at once
            log.debug("1 chunk send")
            time.sleep(0.35)
            os.write(usb0, to_send)
        elif len(to_send) > 8 and len(to_send) < 11:
            log.debug("2 chunk send")
            time.sleep(0.35)
            os.write(usb0, to_send[:5])
            time.sleep(0.35)
            os.write(usb0, to_send[5:])
        else:

            while len(to_send) > 0: