# 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 serial
from .baseio import BaseIO
from ..helpers import get_kwargs
        self._serial_baud = get_kwargs(kwargs, "serial_baud")
        self._records = get_kwargs(kwargs, "records")

    def send_and_receive(self, *args, **kwargs) -> dict:
        # self._port.send_and_receive(
        #    command=command,
        #    full_command=full_command,
        #    protocol=self._protocol,
        #    command_defn=self._protocol.get_command_defn(command),

        full_command = get_kwargs(kwargs, "full_command")
        # print(full_command)
        # "VEDTEXT"
        responses = b""
        log.debug(
            f"port {self._serial_port}, baudrate {self._serial_baud}, records {self._records}"
        )

        if full_command == "VEDTEXT":
            # Just grab _records from the serial port
            try:
                with serial.serial_for_url(self._serial_port, self._serial_baud) as s:
                    # log.debug(f"Executing command via serialio...")
                    s.timeout = 1
                    # s.write_timeout = 1
                    # s.flushInput()
                    # s.flushOutput()
                    # s.write(full_command)
                    # time.sleep(0.1)  # give serial port time to receive the data
                    for _ in range(self._records):

# 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/vserialio.py
import logging
import serial
from .baseio import BaseIO
from ..helpers import get_kwargs

        self._serial_baud = get_kwargs(kwargs, "serial_baud")
        self._records = get_kwargs(kwargs, "records")

    def send_and_receive(self, *args, **kwargs) -> dict:
        # self._port.send_and_receive(
        #    command=command,
        #    full_command=full_command,
        #    protocol=self._protocol,
        #    command_defn=self._protocol.get_command_defn(command),

        full_command = get_kwargs(kwargs, "full_command")
        # print(full_command)
        # "VEDTEXT"
        responses = b""
        log.debug(
            f"port {self._serial_port}, baudrate {self._serial_baud}, records {self._records}"
        )

        if full_command == "VEDTEXT":
            # Just grab _records from the serial port
            try:
                with serial.serial_for_url(self._serial_port, self._serial_baud) as s:
                    # log.debug(f"Executing command via serialio...")
                    s.timeout = 1
                    # s.write_timeout = 1
                    # s.flushInput()
                    # s.flushOutput()
                    # s.write(full_command)
                    # time.sleep(0.1)  # give serial port time to receive the data
                    for _ in range(self._records):

                        response_line = s.read_until(b"\n")