import asyncio
import os
from datetime import datetime
from unittest import TestCase

from goodwe.et import ET
from goodwe.exceptions import RequestRejectedException, RequestFailedException
from goodwe.inverter import OperationMode
from goodwe.modbus import ILLEGAL_DATA_ADDRESS
from goodwe.protocol import ModbusRtuReadCommand, ProtocolCommand, ProtocolResponse


class EtMock(TestCase, ET):

    def __init__(self, methodName="runTest"):
        TestCase.__init__(self, methodName)
        ET.__init__(self, "localhost", 8899)
        self.sensor_map = {s.id_: s for s in self.sensors()}
        self._mock_responses = {}
        self._list_of_requests = []

    def mock_response(self, command: ProtocolCommand, filename: str):
        self._mock_responses[command] = filename

    async def _read_from_socket(self, command: ProtocolCommand) -> ProtocolResponse:
        """Mock UDP communication"""
        root_dir = os.path.dirname(os.path.abspath(__file__))
        filename = self._mock_responses.get(command)
        if filename is not None:
            if ILLEGAL_DATA_ADDRESS == filename:
                raise RequestRejectedException(ILLEGAL_DATA_ADDRESS)
            if "NO RESPONSE" == filename:
                raise RequestFailedException()
            with open(root_dir + "/sample/et/" + filename, "r") as f:
                response = bytes.fromhex(f.read())
                if not command.validator(response):
                    raise RequestFailedException
                return ProtocolResponse(response, command)
        else:
            self.request = command.request
            self._list_of_requests.append(command.request)
            return ProtocolResponse(
                bytes.fromhex("aa55f700010203040506070809"), command
            )

    def assertSensor(self, sensor_name, expected_value, expected_unit, data):
        self.assertEqual(expected_value, data.get(sensor_name))
        sensor = self.sensor_map.get(sensor_name)
        self.assertEqual(expected_unit, sensor.unit)
        self.sensor_map.pop(sensor_name)

    @classmethod
    def setUpClass(cls):
        cls.loop = asyncio.get_event_loop()


class GW10K_ET_Test(EtMock):

    def __init__(self, methodName="runTest"):
        EtMock.__init__(self, methodName)
        self.mock_response(
            self._READ_DEVICE_VERSION_INFO, "GW10K-ET_device_info_fw617.hex"
        )
        self.mock_response(self._READ_RUNNING_DATA, "GW10K-ET_running_data.hex")
        self.mock_response(self._READ_METER_DATA, "GW10K-ET_meter_data.hex")
        self.mock_response(self._READ_BATTERY_INFO, "GW10K-ET_battery_info.hex")
        self.mock_response(ModbusRtuReadCommand(0xF7, 47547, 6), ILLEGAL_DATA_ADDRESS)
        self.mock_response(ModbusRtuReadCommand(0xF7, 47589, 6), ILLEGAL_DATA_ADDRESS)
        self.mock_response(ModbusRtuReadCommand(0xF7, 47515, 4), "eco_mode_v1.hex")

    def test_GW10K_ET_device_info(self):
        self.loop.run_until_complete(self.read_device_info())
        self.assertEqual("GW10K-ET", self.model_name)
        self.assertEqual("9010KETU000W0000", self.serial_number)
        self.assertEqual(10000, self.rated_power)
        self.assertEqual(1, self.modbus_version)
        self.assertEqual(254, self.ac_output_type)
        self.assertEqual(6, self.dsp1_version)
        self.assertEqual(6, self.dsp2_version)
        self.assertEqual(152, self.dsp_svn_version)
        self.assertEqual(17, self.arm_version)
        self.assertEqual(192, self.arm_svn_version)
        self.assertEqual("04029-06-S11", self.firmware)
        self.assertEqual("02041-17-S00", self.arm_firmware)

    def test_GW10K_ET_runtime_data(self):
        # Reset sensors
        self.loop.run_until_complete(self.read_device_info())
        self.sensor_map = {s.id_: s for s in self.sensors()}

        data = self.loop.run_until_complete(self.read_runtime_data())
        self.assertEqual(145, len(data))

        self.assertEqual(36015, self.sensor_map.get("meter_e_total_exp").offset)

        # for sensor in self.sensors():
        #   print(f"self.assertSensor('{sensor.id_}', {data[sensor.id_]}, '{self.sensor_map.get(sensor.id_).unit}', data)")

        self.assertSensor(
            "timestamp",
            datetime.strptime("2021-08-22 11:11:12", "%Y-%m-%d %H:%M:%S"),
            "",
            data,
        )
        self.assertSensor("vpv1", 332.6, "V", data)
        self.assertSensor("ipv1", 5.1, "A", data)
        self.assertSensor("ppv1", 1695, "W", data)
        self.assertSensor("vpv2", 332.6, "V", data)
        self.assertSensor("ipv2", 5.3, "A", data)
        self.assertSensor("ppv2", 1761, "W", data)
        self.assertSensor("ppv", 3456, "W", data)
        self.assertSensor("pv1_mode", 2, "", data)
        self.assertSensor(
            "pv1_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("pv2_mode", 2, "", data)
        self.assertSensor(
            "pv2_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("vgrid", 239.3, "V", data)
        self.assertSensor("igrid", 1.5, "A", data)
        self.assertSensor("fgrid", 49.99, "Hz", data)
        self.assertSensor("pgrid", 336, "W", data)
        self.assertSensor("vgrid2", 241.5, "V", data)
        self.assertSensor("igrid2", 1.3, "A", data)
        self.assertSensor("fgrid2", 49.99, "Hz", data)
        self.assertSensor("pgrid2", 287, "W", data)
        self.assertSensor("vgrid3", 241.1, "V", data)
        self.assertSensor("igrid3", 1.1, "A", data)
        self.assertSensor("fgrid3", 49.99, "Hz", data)
        self.assertSensor("pgrid3", 206, "W", data)
        self.assertSensor("grid_mode", 1, "", data)
        self.assertSensor("grid_mode_label", "Connected to grid", "", data)
        self.assertSensor("total_inverter_power", 831, "W", data)
        self.assertSensor("active_power", -3, "W", data)
        self.assertSensor("grid_in_out", 0, "", data)
        self.assertSensor("grid_in_out_label", "Idle", "", data)
        self.assertSensor("reactive_power", 0, "var", data)
        self.assertSensor("apparent_power", 0, "VA", data)
        self.assertSensor("backup_v1", 239.0, "V", data)
        self.assertSensor("backup_i1", 0.6, "A", data)
        self.assertSensor("backup_f1", 49.98, "Hz", data)
        self.assertSensor("load_mode1", 1, "", data)
        self.assertSensor("backup_p1", 107, "W", data)
        self.assertSensor("backup_v2", 241.3, "V", data)
        self.assertSensor("backup_i2", 0.9, "A", data)
        self.assertSensor("backup_f2", 50.0, "Hz", data)
        self.assertSensor("load_mode2", 1, "", data)
        self.assertSensor("backup_p2", 189, "W", data)
        self.assertSensor("backup_v3", 241.2, "V", data)
        self.assertSensor("backup_i3", 0.2, "A", data)
        self.assertSensor("backup_f3", 49.99, "Hz", data)
        self.assertSensor("load_mode3", 1, "", data)
        self.assertSensor("backup_p3", 0, "W", data)
        self.assertSensor("load_p1", 224, "W", data)
        self.assertSensor("load_p2", 80, "W", data)
        self.assertSensor("load_p3", 233, "W", data)
        self.assertSensor("load_ptotal", 522, "W", data)
        self.assertSensor("backup_ptotal", 312, "W", data)
        self.assertSensor("ups_load", 4, "%", data)
        self.assertSensor("temperature_air", 51.0, "C", data)
        self.assertSensor("temperature_module", 0, "C", data)
        self.assertSensor("temperature", 58.7, "C", data)
        self.assertSensor("function_bit", 0, "", data)
        self.assertSensor("bus_voltage", 803.6, "V", data)
        self.assertSensor("nbus_voltage", 401.8, "V", data)
        self.assertSensor("vbattery1", 254.2, "V", data)
        self.assertSensor("ibattery1", -9.8, "A", data)
        self.assertSensor("pbattery1", -2512, "W", data)
        self.assertSensor("battery_mode", 3, "", data)
        self.assertSensor("battery_mode_label", "Charge", "", data)
        self.assertSensor("warning_code", 0, "", data)
        self.assertSensor("safety_country", 32, "", data)
        self.assertSensor("safety_country_label", "50Hz 230Vac Default", "", data)
        self.assertSensor("work_mode", 1, "", data)
        self.assertSensor("work_mode_label", "Normal (On-Grid)", "", data)
        self.assertSensor("operation_mode", 0, "", data)
        self.assertSensor("error_codes", 0, "", data)
        self.assertSensor("errors", "", "", data)
        self.assertSensor("e_total", 6085.3, "kWh", data)
        self.assertSensor("e_day", 12.5, "kWh", data)
        self.assertSensor("e_total_exp", 4718.6, "kWh", data)
        self.assertSensor("h_total", 9246, "h", data)
        self.assertSensor("e_day_exp", 9.8, "kWh", data)
        self.assertSensor("e_total_imp", 58.0, "kWh", data)
        self.assertSensor("e_day_imp", 0, "kWh", data)
        self.assertSensor("e_load_total", 8820.2, "kWh", data)
        self.assertSensor("e_load_day", 11.6, "kWh", data)
        self.assertSensor("e_bat_charge_total", 2758.1, "kWh", data)
        self.assertSensor("e_bat_charge_day", 5.3, "kWh", data)
        self.assertSensor("e_bat_discharge_total", 2442.1, "kWh", data)
        self.assertSensor("e_bat_discharge_day", 2.9, "kWh", data)
        self.assertSensor("diagnose_result", 117442560, "", data)
        self.assertSensor(
            "diagnose_result_label",
            "Self-use load light, Export power limit set, PF value set, Real power limit set",
            "",
            data,
        )
        self.assertSensor("house_consumption", 947, "W", data)
        self.assertSensor("battery_bms", 255, "", data)
        self.assertSensor("battery_index", 256, "", data)
        self.assertSensor("battery_status", 1, "", data)
        self.assertSensor("battery_temperature", 35.0, "C", data)
        self.assertSensor("battery_charge_limit", 25, "A", data)
        self.assertSensor("battery_discharge_limit", 25, "A", data)
        self.assertSensor("battery_error_l", 0, "", data),
        self.assertSensor("battery_soc", 68, "%", data)
        self.assertSensor("battery_soh", 99, "%", data)
        self.assertSensor("battery_modules", 5, "", data)
        self.assertSensor("battery_warning_l", 0, "", data)
        self.assertSensor("battery_protocol", 257, "", data)
        self.assertSensor("battery_error_h", 0, "", data)
        self.assertSensor("battery_error", "", "", data)
        self.assertSensor("battery_warning_h", 0, "", data)
        self.assertSensor("battery_warning", "", "", data)
        self.assertSensor("battery_sw_version", 0, "", data)
        self.assertSensor("battery_hw_version", 0, "", data)
        self.assertSensor("battery_max_cell_temp_id", 0, "", data)
        self.assertSensor("battery_min_cell_temp_id", 0, "", data)
        self.assertSensor("battery_max_cell_voltage_id", 0, "", data)
        self.assertSensor("battery_min_cell_voltage_id", 0, "", data)
        self.assertSensor("battery_max_cell_temp", 0, "C", data)
        self.assertSensor("battery_min_cell_temp", 0, "C", data)
        self.assertSensor("battery_max_cell_voltage", 0, "V", data)
        self.assertSensor("battery_min_cell_voltage", 0, "V", data)
        self.assertSensor("commode", 1, "", data)
        self.assertSensor("rssi", 35, "", data)
        self.assertSensor("manufacture_code", 10, "", data)
        self.assertSensor("meter_test_status", 0, "", data)
        self.assertSensor("meter_comm_status", 1, "", data)
        self.assertSensor("active_power1", -57, "W", data)
        self.assertSensor("active_power2", -46, "W", data)
        self.assertSensor("active_power3", -6, "W", data)
        self.assertSensor("active_power_total", -110, "W", data)
        self.assertSensor("reactive_power_total", 1336, "var", data)
        self.assertSensor("meter_power_factor1", -0.145, "", data)
        self.assertSensor("meter_power_factor2", -0.124, "", data)
        self.assertSensor("meter_power_factor3", -0.014, "", data)
        self.assertSensor("meter_power_factor", -0.08, "", data)
        self.assertSensor("meter_freq", 50.05, "Hz", data)
        self.assertSensor("meter_e_total_exp", 10.514, "kWh", data)
        self.assertSensor("meter_e_total_imp", 3254.462, "kWh", data)
        self.assertSensor("meter_active_power1", -57, "W", data)
        self.assertSensor("meter_active_power2", -46, "W", data)
        self.assertSensor("meter_active_power3", -6, "W", data)
        self.assertSensor("meter_active_power_total", -110, "W", data)
        self.assertSensor("meter_reactive_power1", 364, "var", data)
        self.assertSensor("meter_reactive_power2", 357, "var", data)
        self.assertSensor("meter_reactive_power3", 614, "var", data)
        self.assertSensor("meter_reactive_power_total", 1336, "var", data)
        self.assertSensor("meter_apparent_power1", -402, "VA", data)
        self.assertSensor("meter_apparent_power2", -372, "VA", data)
        self.assertSensor("meter_apparent_power3", -627, "VA", data)
        self.assertSensor("meter_apparent_power_total", -1403, "VA", data)
        self.assertSensor("meter_type", 1, "", data)
        self.assertSensor("meter_sw_version", 3, "", data)

        self.assertFalse(
            self.sensor_map, f"Some sensors were not tested {self.sensor_map}"
        )

    def test_GW10K_ET_setting(self):
        self.assertEqual(69, len(self.settings()))
        settings = {s.id_: s for s in self.settings()}
        self.assertEqual("Timestamp", type(settings.get("time")).__name__)
        self.assertEqual("EcoModeV1", type(settings.get("eco_mode_1")).__name__)

    def test_GW10K_ET_read_setting(self):
        self.loop.run_until_complete(self.read_setting("work_mode"))
        self.assertEqual("f703b798000136c7", self.request.hex())

        self.loop.run_until_complete(self.read_setting("grid_export_limit"))
        self.assertEqual("f703b996000155ec", self.request.hex())

        self.loop.run_until_complete(self.read_setting("time"))
        self.assertEqual("f703b090000337b0", self.request.hex())

        self.loop.run_until_complete(self.read_setting("modbus_47000"))
        self.assertEqual("f703b798000136c7", self.request.hex())

    def test_GW10K_ET_write_setting(self):
        self.loop.run_until_complete(self.write_setting("grid_export_limit", 100))
        self.assertEqual("f706b996006459c7", self.request.hex())

        self.loop.run_until_complete(self.write_setting("modbus_47510", 100))
        self.assertEqual("f706b996006459c7", self.request.hex())

        self.loop.run_until_complete(
            self.write_setting("time", datetime(2022, 1, 4, 18, 30, 25))
        )
        self.assertEqual("f710b090000306160104121e19a961", self.request.hex())

    def test_get_grid_export_limit(self):
        self.loop.run_until_complete(self.get_grid_export_limit())
        self.assertEqual("f703b996000155ec", self.request.hex())

    def test_set_grid_export_limit(self):
        self.loop.run_until_complete(self.set_grid_export_limit(100))
        self.assertEqual("f706b996006459c7", self.request.hex())

    def test_get_operation_modes(self):
        self.loop.run_until_complete(self.read_device_info())
        self.assertEqual(
            (
                OperationMode.GENERAL,
                OperationMode.OFF_GRID,
                OperationMode.BACKUP,
                OperationMode.ECO,
            ),
            self.loop.run_until_complete(self.get_operation_modes(False)),
        )
        self.assertEqual(
            (
                OperationMode.GENERAL,
                OperationMode.OFF_GRID,
                OperationMode.BACKUP,
                OperationMode.ECO,
                OperationMode.ECO_CHARGE,
                OperationMode.ECO_DISCHARGE,
            ),
            self.loop.run_until_complete(self.get_operation_modes(True)),
        )

    # def test_get_operation_mode(self):
    #    self.loop.run_until_complete(self.get_operation_mode())
    #    self.assertEqual('f703b798000136c7', self.request.hex())

    #    def test_set_operation_mode(self):
    #        self.loop.run_until_complete(self.set_operation_mode(1))
    #        self.assertEqual('f706b7980001fac7', self.request.hex())

    def test_set_operation_mode_ECO_CHARGE(self):
        self.loop.run_until_complete(self.read_device_info())
        self.loop.run_until_complete(
            self.set_operation_mode(OperationMode.ECO_CHARGE, eco_mode_power=40)
        )
        self.assertEqual(
            "f710b99b0004080000173bffd8ff7f1343", self._list_of_requests[-9].hex()
        )
        self.loop.run_until_complete(
            self.set_operation_mode(
                OperationMode.ECO_CHARGE, eco_mode_power=40, eco_mode_soc=80
            )
        )
        self.assertEqual(
            "f710b99b0004080000173bffd8ff7f1343", self._list_of_requests[-9].hex()
        )

    def test_set_operation_mode_DISCHARGE(self):
        self.loop.run_until_complete(self.read_device_info())
        self.loop.run_until_complete(
            self.set_operation_mode(OperationMode.ECO_DISCHARGE, eco_mode_power=50)
        )
        self.assertEqual(
            "f710b99b0004080000173b0032ff7f02a3", self._list_of_requests[-9].hex()
        )

    def test_get_ems_mode(self):
        self.loop.run_until_complete(self.get_ems_mode())
        self.assertEqual("f703b9970001042c", self.request.hex())

    def test_get_ongrid_battery_dod(self):
        self.loop.run_until_complete(self.get_ongrid_battery_dod())
        self.assertEqual("f703b12c00017669", self.request.hex())

    def test_set_ongrid_battery_dod(self):
        self.loop.run_until_complete(self.set_ongrid_battery_dod(80))
        self.assertEqual("f706b12c00147ba6", self.request.hex())


class GW10K_ET_fw819_Test(EtMock):

    def __init__(self, methodName="runTest"):
        EtMock.__init__(self, methodName)
        self.mock_response(
            self._READ_DEVICE_VERSION_INFO, "GW10K-ET_device_info_fw819.hex"
        )
        self.mock_response(ModbusRtuReadCommand(0xF7, 47547, 6), "eco_mode_v2.hex")
        self.mock_response(ModbusRtuReadCommand(0xF7, 47589, 6), ILLEGAL_DATA_ADDRESS)
        asyncio.get_event_loop().run_until_complete(self.read_device_info())

    def test_GW10K_ET_fw819_device_info(self):
        self.assertEqual("0GW10K-ET", self.model_name)
        self.assertEqual("9010KETU00000000", self.serial_number)
        self.assertEqual(10000, self.rated_power)
        self.assertEqual(1, self.modbus_version)
        self.assertEqual(254, self.ac_output_type)
        self.assertEqual(8, self.dsp1_version)
        self.assertEqual(8, self.dsp2_version)
        self.assertEqual(159, self.dsp_svn_version)
        self.assertEqual(19, self.arm_version)
        self.assertEqual(207, self.arm_svn_version)
        self.assertEqual("04029-08-S11", self.firmware)
        self.assertEqual("02041-19-S00", self.arm_firmware)

    def test_GW10K_ET_settings_fw819(self):
        self.assertEqual(76, len(self.settings()))
        settings = {s.id_: s for s in self.settings()}
        self.assertEqual("EcoModeV2", type(settings.get("eco_mode_1")).__name__)
        self.assertEqual(None, settings.get("peak_shaving_mode"))

    def test_set_operation_mode_ECO_CHARGE(self):
        self.loop.run_until_complete(
            self.set_operation_mode(
                OperationMode.ECO_CHARGE, eco_mode_power=40, eco_mode_soc=80
            )
        )
        self.assertEqual(
            "f710b9bb00060c0000173bff7fffd80050000002cc",
            self._list_of_requests[-9].hex(),
        )
        self.loop.run_until_complete(
            self.set_operation_mode(OperationMode.ECO_CHARGE, eco_mode_power=40)
        )
        self.assertEqual(
            "f710b9bb00060c0000173bff7fffd8006400004302",
            self._list_of_requests[-9].hex(),
        )

    def test_set_operation_mode_ECO_DISCHARGE(self):
        self.loop.run_until_complete(
            self.set_operation_mode(OperationMode.ECO_DISCHARGE, eco_mode_power=50)
        )
        self.assertEqual(
            "f710b9bb00060c0000173bff7f0032006400004eda",
            self._list_of_requests[-9].hex(),
        )


class GW10K_ET_fw1023_Test(EtMock):

    def __init__(self, methodName="runTest"):
        EtMock.__init__(self, methodName)
        self.mock_response(
            self._READ_DEVICE_VERSION_INFO, "GW10K-ET_device_info_fw1023.hex"
        )
        self.mock_response(self._READ_RUNNING_DATA, "GW10K-ET_running_data_fw1023.hex")
        asyncio.get_event_loop().run_until_complete(self.read_device_info())

    def test_GW10K_ET_fw1023_device_info(self):
        self.assertEqual("GW10K-ET", self.model_name)
        self.assertEqual("9010KETU000W0000", self.serial_number)
        self.assertEqual(10000, self.rated_power)
        self.assertEqual(2, self.modbus_version)
        self.assertEqual(254, self.ac_output_type)
        self.assertEqual(10, self.dsp1_version)
        self.assertEqual(10, self.dsp2_version)
        self.assertEqual(167, self.dsp_svn_version)
        self.assertEqual(23, self.arm_version)
        self.assertEqual(237, self.arm_svn_version)
        self.assertEqual("04029-10-S11", self.firmware)
        self.assertEqual("02041-23-S00", self.arm_firmware)

    def test_GW10K_ET_setting_fw1023(self):
        self.assertEqual(84, len(self.settings()))
        settings = {s.id_: s for s in self.settings()}
        self.assertEqual(
            "PeakShavingMode", type(settings.get("peak_shaving_mode")).__name__
        )

    def test_GW10K_ET_runtime_data_fw1023(self):
        # Reset sensors
        self.loop.run_until_complete(self.read_device_info())
        self.sensor_map = {s.id_: s for s in self.sensors()}

        data = self.loop.run_until_complete(self.read_runtime_data())
        self.assertEqual(145, len(data))

        self.assertSensor(
            "timestamp",
            datetime.strptime("2024-05-11 00:03:34", "%Y-%m-%d %H:%M:%S"),
            "",
            data,
        )
        self.assertSensor("vpv1", 0.0, "V", data)
        self.assertSensor("ipv1", 0.0, "A", data)
        self.assertSensor("ppv1", 0, "W", data)
        self.assertSensor("vpv2", 0.0, "V", data)
        self.assertSensor("ipv2", 0.0, "A", data)
        self.assertSensor("ppv2", 0, "W", data)
        self.assertSensor("ppv", 0, "W", data)
        self.assertSensor("pv2_mode", 0, "", data)
        self.assertSensor("pv2_mode_label", "PV panels not connected", "", data)
        self.assertSensor("pv1_mode", 0, "", data)
        self.assertSensor("pv1_mode_label", "PV panels not connected", "", data)
        self.assertSensor("vgrid", 244.4, "V", data)
        self.assertSensor("igrid", 2.0, "A", data)
        self.assertSensor("fgrid", 49.92, "Hz", data)
        self.assertSensor("pgrid", 435, "W", data)
        self.assertSensor("vgrid2", 244.3, "V", data)
        self.assertSensor("igrid2", 1.2, "A", data)
        self.assertSensor("fgrid2", 49.92, "Hz", data)
        self.assertSensor("pgrid2", 241, "W", data)
        self.assertSensor("vgrid3", 244.9, "V", data)
        self.assertSensor("igrid3", 0.8, "A", data)
        self.assertSensor("fgrid3", 49.92, "Hz", data)
        self.assertSensor("pgrid3", 132, "W", data)
        self.assertSensor("grid_mode", 1, "", data)
        self.assertSensor("grid_mode_label", "Connected to grid", "", data)
        self.assertSensor("total_inverter_power", 812, "W", data)
        self.assertSensor("active_power", -11, "W", data)
        self.assertSensor("grid_in_out", 0, "", data)
        self.assertSensor("grid_in_out_label", "Idle", "", data)
        self.assertSensor("reactive_power", 0, "var", data)
        self.assertSensor("apparent_power", 0, "VA", data)
        self.assertSensor("backup_v1", 244.2, "V", data)
        self.assertSensor("backup_i1", 1.3, "A", data)
        self.assertSensor("backup_f1", 49.92, "Hz", data)
        self.assertSensor("load_mode1", 1, "", data)
        self.assertSensor("backup_p1", 217, "W", data)
        self.assertSensor("backup_v2", 243.8, "V", data)
        self.assertSensor("backup_i2", 0.6, "A", data)
        self.assertSensor("backup_f2", 49.92, "Hz", data)
        self.assertSensor("load_mode2", 1, "", data)
        self.assertSensor("backup_p2", 114, "W", data)
        self.assertSensor("backup_v3", 244.7, "V", data)
        self.assertSensor("backup_i3", 0.3, "A", data)
        self.assertSensor("backup_f3", 49.92, "Hz", data)
        self.assertSensor("load_mode3", 1, "", data)
        self.assertSensor("backup_p3", 5, "W", data)
        self.assertSensor("load_p1", 129, "W", data)
        self.assertSensor("load_p2", 108, "W", data)
        self.assertSensor("load_p3", 247, "W", data)
        self.assertSensor("backup_ptotal", 321, "W", data)
        self.assertSensor("load_ptotal", 502, "W", data)
        self.assertSensor("ups_load", 5, "%", data)
        self.assertSensor("temperature_air", 36.4, "C", data)
        self.assertSensor("temperature_module", 0.0, "C", data)
        self.assertSensor("temperature", 32.5, "C", data)
        self.assertSensor("function_bit", 16384, "", data)
        self.assertSensor("bus_voltage", 790.7, "V", data)
        self.assertSensor("nbus_voltage", 395.1, "V", data)
        self.assertSensor("vbattery1", 397.1, "V", data)
        self.assertSensor("ibattery1", 2.0, "A", data)
        self.assertSensor("pbattery1", 820, "W", data)
        self.assertSensor("battery_mode", 2, "", data)
        self.assertSensor("battery_mode_label", "Discharge", "", data)
        self.assertSensor("warning_code", 0, "", data)
        self.assertSensor("safety_country", 32, "", data)
        self.assertSensor("safety_country_label", "50Hz 230Vac Default", "", data)
        self.assertSensor("work_mode", 1, "", data)
        self.assertSensor("work_mode_label", "Normal (On-Grid)", "", data)
        self.assertSensor("operation_mode", 0, "", data)
        self.assertSensor("error_codes", 0, "", data)
        self.assertSensor("errors", "", "", data)
        self.assertSensor("e_total", 30630.9, "kWh", data)
        self.assertSensor("e_day", 0, "kWh", data)
        self.assertSensor("e_total_exp", 27208.5, "kWh", data)
        self.assertSensor("h_total", 33055, "h", data)
        self.assertSensor("e_day_exp", 0, "kWh", data)
        self.assertSensor("e_total_imp", 70.3, "kWh", data)
        self.assertSensor("e_day_imp", 0, "kWh", data)
        self.assertSensor("e_load_total", 35366.4, "kWh", data)
        self.assertSensor("e_load_day", 0, "kWh", data)
        self.assertSensor("e_bat_charge_total", 9884.3, "kWh", data)
        self.assertSensor("e_bat_charge_day", 0, "kWh", data)
        self.assertSensor("e_bat_discharge_total", 8642.2, "kWh", data)
        self.assertSensor("e_bat_discharge_day", 0.1, "kWh", data)
        self.assertSensor("diagnose_result", 33554496, "", data)
        self.assertSensor(
            "diagnose_result_label", "Discharge Driver On, PF value set", "", data
        )
        self.assertSensor("house_consumption", 831, "W", data)
        self.assertSensor("commode", 515, "", data)
        self.assertSensor("rssi", 1029, "", data)
        self.assertSensor("manufacture_code", 1543, "", data)


class GW6000_EH_Test(EtMock):

    def __init__(self, methodName="runTest"):
        EtMock.__init__(self, methodName)
        self.mock_response(self._READ_RUNNING_DATA, "GW6000_EH_running_data.hex")
        self.mock_response(self._READ_DEVICE_VERSION_INFO, "GW6000_EH_device_info.hex")

    def test_GW6000_EH_device_info(self):
        self.loop.run_until_complete(self.read_device_info())
        self.assertEqual("GW6000-EH", self.model_name)
        self.assertEqual("00000EHU00000000", self.serial_number)
        self.assertEqual(6000, self.rated_power)
        self.assertEqual(0, self.modbus_version)
        self.assertEqual(254, self.ac_output_type)
        self.assertEqual(3, self.dsp1_version)
        self.assertEqual(3, self.dsp2_version)
        self.assertEqual(325, self.dsp_svn_version)
        self.assertEqual(16, self.arm_version)
        self.assertEqual(188, self.arm_svn_version)
        self.assertEqual("04034-03-S10", self.firmware)
        self.assertEqual("02041-16-S00", self.arm_firmware)

    def test_GW6000_EH_runtime_data(self):
        self.loop.run_until_complete(self.read_device_info())
        data = self.loop.run_until_complete(self.read_runtime_data())
        self.assertEqual(89, len(data))

        self.assertSensor("vpv1", 330.3, "V", data)
        self.assertSensor("ipv1", 2.6, "A", data)
        self.assertSensor("ppv1", 857, "W", data)
        self.assertSensor("vpv2", 329.6, "V", data)
        self.assertSensor("ipv2", 2.1, "A", data)
        self.assertSensor("ppv2", 691, "W", data)
        self.assertSensor("ppv", 1548, "W", data)
        self.assertSensor("pv1_mode", 2, "", data)
        self.assertSensor(
            "pv1_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("pv2_mode", 2, "", data)
        self.assertSensor(
            "pv2_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("vgrid", 236.6, "V", data)
        self.assertSensor("igrid", 6.6, "A", data)
        self.assertSensor("fgrid", 49.97, "Hz", data)
        self.assertSensor("pgrid", 1561, "W", data)
        self.assertSensor("grid_mode", 1, "", data)
        self.assertSensor("grid_mode_label", "Connected to grid", "", data)
        self.assertSensor("total_inverter_power", 1561, "W", data)
        self.assertSensor("active_power", -164, "W", data)
        self.assertSensor("grid_in_out", 2, "", data)
        self.assertSensor("grid_in_out_label", "Importing", "", data)
        self.assertSensor("reactive_power", -1, "var", data)
        self.assertSensor("apparent_power", -1, "VA", data)
        self.assertSensor("backup_v1", 0.0, "V", data)
        self.assertSensor("backup_i1", 0.0, "A", data)
        self.assertSensor("backup_f1", 0.0, "Hz", data)
        self.assertSensor("load_mode1", 0, "", data)
        self.assertSensor("backup_p1", 0, "W", data)
        self.assertSensor("load_p1", 1724, "W", data)
        self.assertSensor("load_ptotal", 1725, "W", data)
        self.assertSensor("backup_ptotal", 0, "W", data)
        self.assertSensor("ups_load", 0, "%", data)
        self.assertSensor("temperature_air", 60.4, "C", data)
        self.assertSensor("temperature_module", None, "C", data)
        self.assertSensor("temperature", 38.6, "C", data)
        self.assertSensor("function_bit", 256, "", data)
        self.assertSensor("bus_voltage", 380.6, "V", data)
        self.assertSensor("nbus_voltage", 0, "V", data)
        self.assertSensor("vbattery1", 0.0, "V", data)
        self.assertSensor("ibattery1", 0.1, "A", data)
        self.assertSensor("pbattery1", 0, "W", data)
        self.assertSensor("battery_mode", 0, "", data)
        self.assertSensor("battery_mode_label", "No battery", "", data)
        self.assertSensor("warning_code", 0, "", data)
        self.assertSensor("safety_country", 3, "", data)
        self.assertSensor("safety_country_label", "ES-A", "", data)
        self.assertSensor("work_mode", 1, "", data)
        self.assertSensor("work_mode_label", "Normal (On-Grid)", "", data)
        self.assertSensor("operation_mode", 0, "", data)
        self.assertSensor("error_codes", 0, "", data)
        self.assertSensor("errors", "", "", data)
        self.assertSensor("e_total", 59.4, "kWh", data)
        self.assertSensor("e_day", 22.0, "kWh", data)
        self.assertSensor("e_total_exp", 58.6, "kWh", data)
        self.assertSensor("h_total", 33, "h", data)
        self.assertSensor("e_day_exp", 21.6, "kWh", data)
        self.assertSensor("e_total_imp", 0, "kWh", data)
        self.assertSensor("e_day_imp", 0, "kWh", data)
        self.assertSensor("e_load_total", 70.1, "kWh", data)
        self.assertSensor("e_load_day", 27.1, "kWh", data)
        self.assertSensor("e_bat_charge_total", 0, "kWh", data)
        self.assertSensor("e_bat_charge_day", 0, "kWh", data)
        self.assertSensor("e_bat_discharge_total", 0, "kWh", data)
        self.assertSensor("e_bat_discharge_day", 0, "kWh", data)
        self.assertSensor("diagnose_result", 117983303, "", data)
        self.assertSensor(
            "diagnose_result_label",
            "Battery voltage low, Battery SOC low, Battery SOC in back, Discharge Driver On, Self-use load light, Battery Disconnected, Self-use off, Export power limit set, PF value set, Real power limit set",
            "",
            data,
        )
        self.assertSensor("house_consumption", 1712, "W", data)


class GEH10_1U_10_Test(EtMock):

    def __init__(self, methodName="runTest"):
        EtMock.__init__(self, methodName)
        self.mock_response(self._READ_RUNNING_DATA, "GEH10-1U-10_running_data.hex")
        self.mock_response(
            self._READ_DEVICE_VERSION_INFO, "GEH10-1U-10_device_info.hex"
        )

    def test_GEH10_1U_10_device_info(self):
        self.loop.run_until_complete(self.read_device_info())
        self.assertEqual("00000HSB00000000", self.serial_number)

    def test_GEH10_1U_10_runtime_data(self):
        # Reset sensors
        self.loop.run_until_complete(self.read_device_info())
        self.sensor_map = {s.id_: s for s in self.sensors()}

        data = self.loop.run_until_complete(self.read_runtime_data())
        self.assertEqual(125, len(data))

        self.assertSensor(
            "timestamp",
            datetime.strptime("2023-01-26 11:34:07", "%Y-%m-%d %H:%M:%S"),
            "",
            data,
        )
        self.assertSensor("vpv1", 242.3, "V", data)
        self.assertSensor("ipv1", 11.5, "A", data)
        self.assertSensor("ppv1", 2777, "W", data)
        self.assertSensor("vpv2", 213.5, "V", data)
        self.assertSensor("ipv2", 11.5, "A", data)
        self.assertSensor("ppv2", 2455, "W", data)
        self.assertSensor("vpv3", 333.3, "V", data)
        self.assertSensor("ipv3", 11.0, "A", data)
        self.assertSensor("ppv3", 3640, "W", data)
        self.assertSensor("vpv4", 184.5, "V", data)
        self.assertSensor("ipv4", 10.4, "A", data)
        self.assertSensor("ppv4", 1915, "W", data)
        self.assertSensor("ppv", 10787, "W", data)
        self.assertSensor("pv4_mode", 2, "", data)
        self.assertSensor(
            "pv4_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("pv3_mode", 2, "", data)
        self.assertSensor(
            "pv3_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("pv2_mode", 2, "", data)
        self.assertSensor(
            "pv2_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("pv1_mode", 2, "", data)
        self.assertSensor(
            "pv1_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("vgrid", 242.9, "V", data)
        self.assertSensor("igrid", 36.5, "A", data)
        self.assertSensor("fgrid", 49.98, "Hz", data)
        self.assertSensor("pgrid", 8710, "W", data)
        self.assertSensor("grid_mode", 1, "", data)
        self.assertSensor("grid_mode_label", "Connected to grid", "", data)
        self.assertSensor("total_inverter_power", 8710, "W", data)
        self.assertSensor("active_power", 4277, "W", data)
        self.assertSensor("grid_in_out", 1, "", data)
        self.assertSensor("grid_in_out_label", "Exporting", "", data)
        self.assertSensor("reactive_power", -1650, "var", data)
        self.assertSensor("apparent_power", 8865, "VA", data)
        self.assertSensor("backup_v1", 240.0, "V", data)
        self.assertSensor("backup_i1", 0.7, "A", data)
        self.assertSensor("backup_f1", 49.98, "Hz", data)
        self.assertSensor("load_mode1", 1, "", data)
        self.assertSensor("backup_p1", 77, "W", data)
        self.assertSensor("load_p1", 4356, "W", data)
        self.assertSensor("backup_ptotal", 77, "W", data)
        self.assertSensor("load_ptotal", 4356, "W", data)
        self.assertSensor("ups_load", 1, "%", data)
        self.assertSensor("temperature_air", 0.0, "C", data)
        self.assertSensor("temperature_module", -10.0, "C", data)
        self.assertSensor("temperature", 67.0, "C", data)
        self.assertSensor("function_bit", 257, "", data)
        self.assertSensor("bus_voltage", 458.4, "V", data)
        self.assertSensor("nbus_voltage", 0, "V", data)
        self.assertSensor("vbattery1", 406.1, "V", data)
        self.assertSensor("ibattery1", -3.8, "A", data)
        self.assertSensor("pbattery1", -1566, "W", data)
        self.assertSensor("battery_mode", 3, "", data)
        self.assertSensor("battery_mode_label", "Charge", "", data)
        self.assertSensor("warning_code", 0, "", data)
        self.assertSensor("safety_country", 9, "", data)
        self.assertSensor("safety_country_label", "Australia A", "", data)
        self.assertSensor("work_mode", 1, "", data)
        self.assertSensor("work_mode_label", "Normal (On-Grid)", "", data)
        self.assertSensor("operation_mode", 0, "", data)
        self.assertSensor("error_codes", 0, "", data)
        self.assertSensor("errors", "", "", data)
        self.assertSensor("e_total", 10225.8, "kWh", data)
        self.assertSensor("e_day", 23.1, "kWh", data)
        self.assertSensor("e_total_exp", 10273.3, "kWh", data)
        self.assertSensor("h_total", 3256, "h", data)
        self.assertSensor("e_day_exp", 16.6, "kWh", data)
        self.assertSensor("e_total_imp", 0, "kWh", data)
        self.assertSensor("e_day_imp", 0, "kWh", data)
        self.assertSensor("e_load_total", 4393.9, "kWh", data)
        self.assertSensor("e_load_day", 10.7, "kWh", data)
        self.assertSensor("e_bat_charge_total", 141.9, "kWh", data)
        self.assertSensor("e_bat_charge_day", 9.6, "kWh", data)
        self.assertSensor("e_bat_discharge_total", 117.5, "kWh", data)
        self.assertSensor("e_bat_discharge_day", 2.6, "kWh", data)
        self.assertSensor("diagnose_result", 33556864, "", data)
        self.assertSensor(
            "diagnose_result_label",
            "BMS: Discharge current low, APP: Discharge current too low, Self-use load light, PF value set",
            "",
            data,
        )
        self.assertSensor("house_consumption", 4944, "W", data)
        self.assertSensor("battery_bms", 515, "", data)
        self.assertSensor("battery_index", 1029, "", data)
        self.assertSensor("battery_status", 1543, "", data)
        self.assertSensor("battery_temperature", 0.0, "C", data)
        self.assertSensor("battery_charge_limit", 0, "A", data)
        self.assertSensor("battery_discharge_limit", 0, "A", data)
        self.assertSensor("battery_error_l", 0, "", data)
        self.assertSensor("battery_soc", 0, "%", data)
        self.assertSensor("battery_soh", 0, "%", data)
        self.assertSensor("battery_modules", 0, "", data)
        self.assertSensor("battery_warning_l", 0, "", data)
        self.assertSensor("battery_protocol", 0, "", data)
        self.assertSensor("battery_error_h", 0, "", data)
        self.assertSensor("battery_error", "", "", data)
        self.assertSensor("battery_warning_h", 0, "", data)
        self.assertSensor("battery_warning", "", "", data)
        self.assertSensor("battery_sw_version", 0, "", data)
        self.assertSensor("battery_hw_version", 0, "", data)
        self.assertSensor("battery_max_cell_temp_id", 0, "", data)
        self.assertSensor("battery_min_cell_temp_id", 0, "", data)
        self.assertSensor("battery_max_cell_voltage_id", 0, "", data)
        self.assertSensor("battery_min_cell_voltage_id", 0, "", data)
        self.assertSensor("battery_max_cell_temp", 0.0, "C", data)
        self.assertSensor("battery_min_cell_temp", 0.0, "C", data)
        self.assertSensor("battery_max_cell_voltage", 0.0, "V", data)
        self.assertSensor("battery_min_cell_voltage", 0.0, "V", data)
        self.assertSensor("commode", 515, "", data)
        self.assertSensor("rssi", 1029, "", data)
        self.assertSensor("manufacture_code", 1543, "", data)
        self.assertSensor("meter_test_status", 0, "", data)
        self.assertSensor("meter_comm_status", 0, "", data)
        self.assertSensor("active_power1", 0, "W", data)
        self.assertSensor("active_power_total", 0, "W", data)
        self.assertSensor("reactive_power_total", 0, "var", data)
        self.assertSensor("meter_power_factor1", 0.0, "", data)
        self.assertSensor("meter_power_factor", 0.0, "", data)
        self.assertSensor("meter_freq", 0.0, "Hz", data)
        self.assertSensor("meter_e_total_exp", 0.0, "kWh", data)
        self.assertSensor("meter_e_total_imp", 0.0, "kWh", data)
        self.assertSensor("meter_active_power1", 0, "W", data)
        self.assertSensor("meter_active_power_total", 0, "W", data)
        self.assertSensor("meter_reactive_power1", 0, "var", data)
        self.assertSensor("meter_reactive_power_total", 0, "var", data)
        self.assertSensor("meter_apparent_power1", 0, "VA", data)
        self.assertSensor("meter_apparent_power_total", 0, "VA", data)
        self.assertSensor("meter_type", 0, "", data)
        self.assertSensor("meter_sw_version", 0, "", data)

        self.assertFalse(
            self.sensor_map, f"Some sensors were not tested {self.sensor_map}"
        )


class GW6000_ES_20_Test(EtMock):

    def __init__(self, methodName="runTest"):
        EtMock.__init__(self, methodName)
        self.mock_response(
            self._READ_DEVICE_VERSION_INFO, "GW6000-ES-20_device_info.hex"
        )

    def test_GW6000_ES_20_device_info(self):
        self.loop.run_until_complete(self.read_device_info())
        self.assertEqual("GW6000ES20", self.model_name)
        self.assertEqual("56000ESN00AW0000", self.serial_number)
        self.assertEqual(6050, self.rated_power)
        self.assertEqual(121, self.modbus_version)
        self.assertEqual(0, self.ac_output_type)
        self.assertEqual(2, self.dsp1_version)
        self.assertEqual(2, self.dsp2_version)
        self.assertEqual(3527, self.dsp_svn_version)
        self.assertEqual(5, self.arm_version)
        self.assertEqual(264, self.arm_svn_version)
        self.assertEqual("ffffffffffffffffffffffff", self.firmware)
        self.assertEqual("02020-05-S01", self.arm_firmware)


class GW25K_ET_Test(EtMock):

    def __init__(self, methodName="runTest"):
        EtMock.__init__(self, methodName)
        self.mock_response(self._READ_DEVICE_VERSION_INFO, "GW25K-ET_device_info.hex")
        self.mock_response(self._READ_RUNNING_DATA, "GW25K-ET_running_data.hex")
        self.mock_response(self._READ_METER_DATA_EXTENDED2, ILLEGAL_DATA_ADDRESS)
        self.mock_response(self._READ_METER_DATA_EXTENDED, "GW25K-ET_meter_data.hex")
        self.mock_response(self._READ_BATTERY_INFO, "GW25K-ET_battery_info.hex")
        self.mock_response(self._READ_MPPT_DATA, "GW25K-ET_mppt_data.hex")
        self.mock_response(
            self._READ_BATTERY2_INFO_EXTENDED, "GW25K-ET_battery2_info_extended.hex"
        )

    def test_GW25K_ET_device_info(self):
        self.loop.run_until_complete(self.read_device_info())
        self.assertEqual("", self.model_name)
        self.assertEqual("9025KETT00000000", self.serial_number)
        self.assertEqual(25000, self.rated_power)
        self.assertEqual(0, self.modbus_version)
        self.assertEqual(1, self.ac_output_type)
        self.assertEqual(6, self.dsp1_version)
        self.assertEqual(6, self.dsp2_version)
        self.assertEqual(6017, self.dsp_svn_version)
        self.assertEqual(8, self.arm_version)
        self.assertEqual(362, self.arm_svn_version)
        self.assertEqual("04062-", self.firmware)
        self.assertEqual("02020-08-S01", self.arm_firmware)

    def test_GW25K_ET_runtime_data(self):
        # Reset sensors
        self.loop.run_until_complete(self.read_device_info())

        data = self.loop.run_until_complete(self.read_runtime_data())
        self.assertEqual(242, len(data))

        self.sensor_map = {s.id_: s for s in self.sensors()}

        # self.assertEqual(36104, self.sensor_map.get("meter_e_total_exp").offset)

        self.assertSensor(
            "timestamp",
            datetime.strptime("2023-12-03 14:07:07", "%Y-%m-%d %H:%M:%S"),
            "",
            data,
        )
        self.assertSensor("vpv1", 737.9, "V", data)
        self.assertSensor("ipv1", 1.4, "A", data)
        self.assertSensor("ppv1", 1033, "W", data)
        self.assertSensor("vpv2", 737.9, "V", data)
        self.assertSensor("ipv2", 0.0, "A", data)
        self.assertSensor("ppv2", 981, "W", data)
        self.assertSensor("vpv3", 755.4, "V", data)
        self.assertSensor("ipv3", 1.3, "A", data)
        self.assertSensor("ppv3", 0, "W", data)
        self.assertSensor("vpv4", 755.4, "V", data)
        self.assertSensor("ipv4", 0.0, "A", data)
        self.assertSensor("ppv4", 0, "W", data)
        self.assertSensor("ppv", 2014, "W", data)
        self.assertSensor("pv4_mode", 0, "", data)
        self.assertSensor("pv4_mode_label", "PV panels not connected", "", data)
        self.assertSensor("pv3_mode", 0, "", data)
        self.assertSensor("pv3_mode_label", "PV panels not connected", "", data)
        self.assertSensor("pv2_mode", 2, "", data)
        self.assertSensor(
            "pv2_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("pv1_mode", 2, "", data)
        self.assertSensor(
            "pv1_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("vgrid", 230.9, "V", data)
        self.assertSensor("igrid", 2.9, "A", data)
        self.assertSensor("fgrid", 49.95, "Hz", data)
        self.assertSensor("pgrid", 589, "W", data)
        self.assertSensor("vgrid2", 231.0, "V", data)
        self.assertSensor("igrid2", 2.7, "A", data)
        self.assertSensor("fgrid2", 49.97, "Hz", data)
        self.assertSensor("pgrid2", 553, "W", data)
        self.assertSensor("vgrid3", 230.4, "V", data)
        self.assertSensor("igrid3", 4.2, "A", data)
        self.assertSensor("fgrid3", 49.97, "Hz", data)
        self.assertSensor("pgrid3", 803, "W", data)
        self.assertSensor("grid_mode", 1, "", data)
        self.assertSensor("grid_mode_label", "Connected to grid", "", data)
        self.assertSensor("total_inverter_power", 1945, "W", data)
        self.assertSensor("active_power", 1511, "W", data)
        self.assertSensor("grid_in_out", 1, "", data)
        self.assertSensor("grid_in_out_label", "Exporting", "", data)
        self.assertSensor("reactive_power", 1239, "var", data)
        self.assertSensor("apparent_power", 2259, "VA", data)
        self.assertSensor("backup_v1", 229.5, "V", data)
        self.assertSensor("backup_i1", 3.0, "A", data)
        self.assertSensor("backup_f1", 49.95, "Hz", data)
        self.assertSensor("load_mode1", 0, "", data)
        self.assertSensor("backup_p1", 52, "W", data)
        self.assertSensor("backup_v2", 230.0, "V", data)
        self.assertSensor("backup_i2", 1.8, "A", data)
        self.assertSensor("backup_f2", 49.97, "Hz", data)
        self.assertSensor("load_mode2", 0, "", data)
        self.assertSensor("backup_p2", 15, "W", data)
        self.assertSensor("backup_v3", 229.4, "V", data)
        self.assertSensor("backup_i3", 3.2, "A", data)
        self.assertSensor("backup_f3", 49.97, "Hz", data)
        self.assertSensor("load_mode3", 0, "", data)
        self.assertSensor("backup_p3", 344, "W", data)
        self.assertSensor("load_p1", 44, "W", data)
        self.assertSensor("load_p2", 16, "W", data)
        self.assertSensor("load_p3", 339, "W", data)
        self.assertSensor("backup_ptotal", 408, "W", data)
        self.assertSensor("load_ptotal", 26, "W", data)
        self.assertSensor("ups_load", 7, "%", data)
        self.assertSensor("temperature_air", 46.2, "C", data)
        self.assertSensor("temperature_module", 0.0, "C", data)
        self.assertSensor("temperature", 43.0, "C", data)
        self.assertSensor("function_bit", 0, "", data)
        self.assertSensor("bus_voltage", 773.3, "V", data)
        self.assertSensor("nbus_voltage", 386.6, "V", data)
        self.assertSensor("vbattery1", 215.2, "V", data)
        self.assertSensor("ibattery1", 0.0, "A", data)
        self.assertSensor("pbattery1", 0, "W", data)
        self.assertSensor("battery_mode", 2, "", data)
        self.assertSensor("battery_mode_label", "Discharge", "", data)
        self.assertSensor("warning_code", 0, "", data)
        self.assertSensor("safety_country", 32, "", data)
        self.assertSensor("safety_country_label", "50Hz 230Vac Default", "", data)
        self.assertSensor("work_mode", 1, "", data)
        self.assertSensor("work_mode_label", "Normal (On-Grid)", "", data)
        self.assertSensor("operation_mode", 0, "", data)
        self.assertSensor("error_codes", 0, "", data)
        self.assertSensor("errors", "", "", data)
        self.assertSensor("e_total", 160.3, "kWh", data)
        self.assertSensor("e_day", 14.7, "kWh", data)
        self.assertSensor("e_total_exp", 137.7, "kWh", data)
        self.assertSensor("h_total", 388, "h", data)
        self.assertSensor("e_day_exp", 2.9, "kWh", data)
        self.assertSensor("e_total_imp", 14.8, "kWh", data)
        self.assertSensor("e_day_imp", 1.0, "kWh", data)
        self.assertSensor("e_load_total", 17.2, "kWh", data)
        self.assertSensor("e_load_day", 0.2, "kWh", data)
        self.assertSensor("e_bat_charge_total", 91.3, "kWh", data)
        self.assertSensor("e_bat_charge_day", 11.0, "kWh", data)
        self.assertSensor("e_bat_discharge_total", 69.6, "kWh", data)
        self.assertSensor("e_bat_discharge_day", 0, "kWh", data)
        self.assertSensor("diagnose_result", 33816960, "", data)
        self.assertSensor(
            "diagnose_result_label",
            "BMS: Discharge current low, APP: Discharge current too low, BMS: Charge disabled, PF value set",
            "",
            data,
        )
        self.assertSensor("house_consumption", 503, "W", data)
        self.assertSensor("battery_bms", 255, "", data)
        self.assertSensor("battery_index", 311, "", data)
        self.assertSensor("battery_status", 1, "", data)
        self.assertSensor("battery_temperature", 23.0, "C", data)
        self.assertSensor("battery_charge_limit", 0, "A", data)
        self.assertSensor("battery_discharge_limit", 40, "A", data)
        self.assertSensor("battery_error_l", 0, "", data)
        self.assertSensor("battery_soc", 100, "%", data)
        self.assertSensor("battery_soh", 100, "%", data)
        self.assertSensor("battery_modules", 4, "", data)
        self.assertSensor("battery_warning_l", 0, "", data)
        self.assertSensor("battery_protocol", 261, "", data)
        self.assertSensor("battery_error_h", 0, "", data)
        self.assertSensor("battery_error", "", "", data)
        self.assertSensor("battery_warning_h", 0, "", data)
        self.assertSensor("battery_warning", "", "", data)
        self.assertSensor("battery_sw_version", 790, "", data)
        self.assertSensor("battery_hw_version", 0, "", data)
        self.assertSensor("battery_max_cell_temp_id", 0, "", data)
        self.assertSensor("battery_min_cell_temp_id", 0, "", data)
        self.assertSensor("battery_max_cell_voltage_id", 0, "", data)
        self.assertSensor("battery_min_cell_voltage_id", 0, "", data)
        self.assertSensor("battery_max_cell_temp", 0.0, "C", data)
        self.assertSensor("battery_min_cell_temp", 0.0, "C", data)
        self.assertSensor("battery_max_cell_voltage", 0.0, "V", data)
        self.assertSensor("battery_min_cell_voltage", 0.0, "V", data)
        self.assertSensor("battery2_status", 515, "", data)
        self.assertSensor("battery2_temperature", 102.9, "C", data)
        self.assertSensor("battery2_charge_limit", 1543, "A", data)
        self.assertSensor("battery2_discharge_limit", 0, "A", data)
        self.assertSensor("battery2_error_l", 0, "", data)
        self.assertSensor("battery2_soc", 0, "%", data)
        self.assertSensor("battery2_soh", 0, "%", data)
        self.assertSensor("battery2_modules", 0, "", data)
        self.assertSensor("battery2_warning_l", 0, "", data)
        self.assertSensor("battery2_protocol", 0, "", data)
        self.assertSensor("battery2_error_h", 0, "", data)
        self.assertSensor("battery2_error", "", "", data)
        self.assertSensor("battery2_warning_h", 0, "", data)
        self.assertSensor("battery2_warning", "", "", data)
        self.assertSensor("battery2_sw_version", 0, "", data)
        self.assertSensor("battery2_hw_version", 0, "", data)
        self.assertSensor("battery2_max_cell_temp_id", 0, "", data)
        self.assertSensor("battery2_min_cell_temp_id", 0, "", data)
        self.assertSensor("battery2_max_cell_voltage_id", 0, "", data)
        self.assertSensor("battery2_min_cell_voltage_id", 0, "", data)
        self.assertSensor("battery2_max_cell_temp", 0.0, "C", data)
        self.assertSensor("battery2_min_cell_temp", 0.0, "C", data)
        self.assertSensor("battery2_max_cell_voltage", 0.0, "V", data)
        self.assertSensor("battery2_min_cell_voltage", 0.0, "V", data)
        self.assertSensor("commode", 2, "", data)
        self.assertSensor("rssi", 100, "", data)
        self.assertSensor("manufacture_code", 10, "", data)
        self.assertSensor("meter_test_status", 273, "", data)
        self.assertSensor("meter_comm_status", 1, "", data)
        self.assertSensor("active_power1", -208, "W", data)
        self.assertSensor("active_power2", -166, "W", data)
        self.assertSensor("active_power3", -114, "W", data)
        self.assertSensor("active_power_total", -489, "W", data)
        self.assertSensor("reactive_power_total", 1197, "var", data)
        self.assertSensor("meter_power_factor1", 24.236, "", data)
        self.assertSensor("meter_power_factor2", 32.336, "", data)
        self.assertSensor("meter_power_factor3", -28.2, "", data)
        self.assertSensor("meter_power_factor", 31.136, "", data)
        self.assertSensor("meter_freq", 49.99, "Hz", data)
        self.assertSensor("meter_e_total_exp", 0.0, "kWh", data)
        self.assertSensor("meter_e_total_imp", 0.0, "kWh", data)
        self.assertSensor("meter_active_power1", -208, "W", data)
        self.assertSensor("meter_active_power2", -166, "W", data)
        self.assertSensor("meter_active_power3", -114, "W", data)
        self.assertSensor("meter_active_power_total", -489, "W", data)
        self.assertSensor("meter_reactive_power1", 421, "var", data)
        self.assertSensor("meter_reactive_power2", 440, "var", data)
        self.assertSensor("meter_reactive_power3", 335, "var", data)
        self.assertSensor("meter_reactive_power_total", 1197, "var", data)
        self.assertSensor("meter_apparent_power1", -511, "VA", data)
        self.assertSensor("meter_apparent_power2", -509, "VA", data)
        self.assertSensor("meter_apparent_power3", -448, "VA", data)
        self.assertSensor("meter_apparent_power_total", -1470, "VA", data)
        self.assertSensor("meter_type", 2, "", data)
        self.assertSensor("meter_sw_version", 5, "", data)
        self.assertSensor("meter2_active_power", 0, "W", data)
        self.assertSensor("meter2_e_total_exp", 0.0, "kWh", data)
        self.assertSensor("meter2_e_total_imp", 0.0, "kWh", data)
        self.assertSensor("meter2_comm_status", 0, "", data)
        self.assertSensor("meter_voltage1", 229.0, "V", data)
        self.assertSensor("meter_voltage2", 229.6, "V", data)
        self.assertSensor("meter_voltage3", 228.8, "V", data)
        self.assertSensor("meter_current1", 2.2, "A", data)
        self.assertSensor("meter_current2", 2.2, "A", data)
        self.assertSensor("meter_current3", 1.9, "A", data)
        self.assertSensor("ppv_total", 529, "W", data)
        self.assertSensor("pv_channel", 2, "", data)
        self.assertSensor("vpv5", 0.0, "V", data)
        self.assertSensor("ipv5", 0.0, "A", data)
        self.assertSensor("vpv6", 0.0, "V", data)
        self.assertSensor("ipv6", 0.0, "A", data)
        self.assertSensor("vpv7", 0.0, "V", data)
        self.assertSensor("ipv7", 0.0, "A", data)
        self.assertSensor("vpv8", 0.0, "V", data)
        self.assertSensor("ipv8", 0.0, "A", data)
        self.assertSensor("vpv9", 0.0, "V", data)
        self.assertSensor("ipv9", 0.0, "A", data)
        self.assertSensor("vpv10", 0.0, "V", data)
        self.assertSensor("ipv10", 0.0, "A", data)
        self.assertSensor("vpv11", 0.0, "V", data)
        self.assertSensor("ipv11", 0.0, "A", data)
        self.assertSensor("vpv12", 0.0, "V", data)
        self.assertSensor("ipv12", 0.0, "A", data)
        self.assertSensor("vpv13", 0.0, "V", data)
        self.assertSensor("ipv13", 0.0, "A", data)
        self.assertSensor("vpv14", 0.0, "V", data)
        self.assertSensor("ipv14", 0.0, "A", data)
        self.assertSensor("vpv15", 0.0, "V", data)
        self.assertSensor("ipv15", 0.0, "A", data)
        self.assertSensor("vpv16", 0.0, "V", data)
        self.assertSensor("ipv16", 0.0, "A", data)
        self.assertSensor("pmppt1", 232, "W", data)
        self.assertSensor("pmppt2", 299, "W", data)
        self.assertSensor("pmppt3", 0, "W", data)
        self.assertSensor("pmppt4", 0, "W", data)
        self.assertSensor("pmppt5", 0, "W", data)
        self.assertSensor("pmppt6", 0, "W", data)
        self.assertSensor("pmppt7", 0, "W", data)
        self.assertSensor("pmppt8", 0, "W", data)
        self.assertSensor("imppt1", 0.3, "A", data)
        self.assertSensor("imppt2", 0.4, "A", data)
        self.assertSensor("imppt3", 0, "A", data)
        self.assertSensor("imppt4", 0, "A", data)
        self.assertSensor("imppt5", 0, "A", data)
        self.assertSensor("imppt6", 0, "A", data)
        self.assertSensor("imppt7", 0, "A", data)
        self.assertSensor("imppt8", 0, "A", data)
        self.assertSensor("reactive_power1", 0, "var", data)
        self.assertSensor("reactive_power2", 0, "var", data)
        self.assertSensor("reactive_power3", 0, "var", data)
        self.assertSensor("apparent_power1", 0, "VA", data)
        self.assertSensor("apparent_power2", 0, "VA", data)
        self.assertSensor("apparent_power3", 0, "VA", data)
        self.assertSensor("vbattery2", 417.8, "V", data)
        self.assertSensor("ibattery2", -3.0, "A", data)
        self.assertSensor("pbattery2", -1254, "W", data)
        self.assertSensor("battery2_mode", 3, "", data)
        self.assertSensor("battery2_mode_label", "Charge", "", data)

        self.assertFalse(
            self.sensor_map, f"Some sensors were not tested {self.sensor_map}"
        )


class GW29K9_ET_Test(EtMock):

    def __init__(self, methodName="runTest"):
        EtMock.__init__(self, methodName)
        self.mock_response(self._READ_DEVICE_VERSION_INFO, "GW29K9-ET_device_info.hex")
        self.mock_response(self._READ_RUNNING_DATA, "GW29K9-ET_running_data.hex")
        self.mock_response(self._READ_METER_DATA_EXTENDED2, ILLEGAL_DATA_ADDRESS)
        self.mock_response(self._READ_METER_DATA_EXTENDED, "GW29K9-ET_meter_data.hex")
        self.mock_response(self._READ_BATTERY_INFO, "GW29K9-ET_battery_info.hex")
        self.mock_response(self._READ_BATTERY2_INFO, "GW29K9-ET_battery2_info.hex")
        self.mock_response(self._READ_MPPT_DATA, "GW29K9-ET_mppt_data.hex")
        self.mock_response(
            self._READ_BATTERY2_INFO_EXTENDED, "GW29K9-ET_battery2_info_extended.hex"
        )

    def test_GW29K9_ET_device_info(self):
        self.loop.run_until_complete(self.read_device_info())
        self.assertEqual("", self.model_name)
        self.assertEqual("929K9ETT00CW0000", self.serial_number)
        self.assertEqual(29900, self.rated_power)
        self.assertEqual(0, self.modbus_version)
        self.assertEqual(1, self.ac_output_type)
        self.assertEqual(2, self.dsp1_version)
        self.assertEqual(2, self.dsp2_version)
        self.assertEqual(79, self.dsp_svn_version)
        self.assertEqual(3, self.arm_version)
        self.assertEqual(67, self.arm_svn_version)
        self.assertEqual("04062-", self.firmware)
        self.assertEqual("02020-03-S01", self.arm_firmware)

    def test_GW29K9_ET_runtime_data(self):
        # Reset sensors
        self.loop.run_until_complete(self.read_device_info())

        self.sensor_map = {s.id_: s for s in self.sensors()}

        data = self.loop.run_until_complete(self.read_runtime_data())
        self.assertEqual(216, len(data))

        self.sensor_map = {s.id_: s for s in self.sensors()}

        self.assertSensor(
            "timestamp",
            datetime.strptime("2024-01-17 14:49:14", "%Y-%m-%d %H:%M:%S"),
            "",
            data,
        )
        self.assertSensor("vpv1", 682.9, "V", data)
        self.assertSensor("ipv1", 1.5, "A", data)
        self.assertSensor("ppv1", 478, "W", data)
        self.assertSensor("vpv2", 682.9, "V", data)
        self.assertSensor("ipv2", 0.0, "A", data)
        self.assertSensor("ppv2", 679, "W", data)
        self.assertSensor("vpv3", 577.3, "V", data)
        self.assertSensor("ipv3", 1.8, "A", data)
        self.assertSensor("ppv3", 390, "W", data)
        self.assertSensor("vpv4", 577.3, "V", data)
        self.assertSensor("ipv4", 0.0, "A", data)
        self.assertSensor("ppv4", 0, "W", data)
        self.assertSensor("ppv", 1547, "W", data)
        self.assertSensor("pv4_mode", 0, "", data)
        self.assertSensor("pv4_mode_label", "PV panels not connected", "", data)
        self.assertSensor("pv3_mode", 2, "", data)
        self.assertSensor(
            "pv3_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("pv2_mode", 2, "", data)
        self.assertSensor(
            "pv2_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("pv1_mode", 2, "", data)
        self.assertSensor(
            "pv1_mode_label", "PV panels connected, producing power", "", data
        )
        self.assertSensor("vgrid", 231.3, "V", data)
        self.assertSensor("igrid", 2.9, "A", data)
        self.assertSensor("fgrid", 49.99, "Hz", data)
        self.assertSensor("pgrid", 583, "W", data)
        self.assertSensor("vgrid2", 232.9, "V", data)
        self.assertSensor("igrid2", 2.7, "A", data)
        self.assertSensor("fgrid2", 49.99, "Hz", data)
        self.assertSensor("pgrid2", 565, "W", data)
        self.assertSensor("vgrid3", 233.6, "V", data)
        self.assertSensor("igrid3", 2.9, "A", data)
        self.assertSensor("fgrid3", 49.97, "Hz", data)
        self.assertSensor("pgrid3", 587, "W", data)
        self.assertSensor("grid_mode", 1, "", data)
        self.assertSensor("grid_mode_label", "Connected to grid", "", data)
        self.assertSensor("total_inverter_power", 1735, "W", data)
        self.assertSensor("active_power", -5403, "W", data)
        self.assertSensor("grid_in_out", 2, "", data)
        self.assertSensor("grid_in_out_label", "Importing", "", data)
        self.assertSensor("reactive_power", 307, "var", data)
        self.assertSensor("apparent_power", 1975, "VA", data)
        self.assertSensor("backup_v1", 229.9, "V", data)
        self.assertSensor("backup_i1", 0.7, "A", data)
        self.assertSensor("backup_f1", 49.98, "Hz", data)
        self.assertSensor("load_mode1", 0, "", data)
        self.assertSensor("backup_p1", 21, "W", data)
        self.assertSensor("backup_v2", 231.5, "V", data)
        self.assertSensor("backup_i2", 0.7, "A", data)
        self.assertSensor("backup_f2", 50.0, "Hz", data)
        self.assertSensor("load_mode2", 0, "", data)
        self.assertSensor("backup_p2", 5, "W", data)
        self.assertSensor("backup_v3", 232.9, "V", data)
        self.assertSensor("backup_i3", 0.6, "A", data)
        self.assertSensor("backup_f3", 49.97, "Hz", data)
        self.assertSensor("load_mode3", 0, "", data)
        self.assertSensor("backup_p3", 37, "W", data)
        self.assertSensor("load_p1", 647, "W", data)
        self.assertSensor("load_p2", 640, "W", data)
        self.assertSensor("load_p3", 651, "W", data)
        self.assertSensor("backup_ptotal", 66, "W", data)
        self.assertSensor("load_ptotal", 7072, "W", data)
        self.assertSensor("ups_load", 1, "%", data)
        self.assertSensor("temperature_air", 24.1, "C", data)
        self.assertSensor("temperature_module", 0.0, "C", data)
        self.assertSensor("temperature", 20.5, "C", data)
        self.assertSensor("function_bit", 0, "", data)
        self.assertSensor("bus_voltage", 760.4, "V", data)
        self.assertSensor("nbus_voltage", 380.2, "V", data)
        self.assertSensor("vbattery1", 0.0, "V", data)
        self.assertSensor("ibattery1", -0.1, "A", data)
        self.assertSensor("pbattery1", 0, "W", data)
        self.assertSensor("battery_mode", 0, "", data)
        self.assertSensor("battery_mode_label", "No battery", "", data)
        self.assertSensor("warning_code", 0, "", data)
        self.assertSensor("safety_country", 32, "", data)
        self.assertSensor("safety_country_label", "50Hz 230Vac Default", "", data)
        self.assertSensor("work_mode", 1, "", data)
        self.assertSensor("work_mode_label", "Normal (On-Grid)", "", data)
        self.assertSensor("operation_mode", 0, "", data)
        self.assertSensor("error_codes", 0, "", data)
        self.assertSensor("errors", "", "", data)
        self.assertSensor("e_total", 4562.3, "kWh", data)
        self.assertSensor("e_day", 0.9, "kWh", data)
        self.assertSensor("e_total_exp", 4489.7, "kWh", data)
        self.assertSensor("h_total", 1175, "h", data)
        self.assertSensor("e_day_exp", 1.2, "kWh", data)
        self.assertSensor("e_total_imp", 8.7, "kWh", data)
        self.assertSensor("e_day_imp", 0, "kWh", data)
        self.assertSensor("e_load_total", 10742.2, "kWh", data)
        self.assertSensor("e_load_day", 43.8, "kWh", data)
        self.assertSensor("e_bat_charge_total", 0, "kWh", data)
        self.assertSensor("e_bat_charge_day", 0, "kWh", data)
        self.assertSensor("e_bat_discharge_total", 0, "kWh", data)
        self.assertSensor("e_bat_discharge_day", 0, "kWh", data)
        self.assertSensor("diagnose_result", 33816782, "", data)
        self.assertSensor(
            "diagnose_result_label",
            "Battery SOC low, Battery SOC in back, BMS: Discharge disabled, "
            "Discharge Driver On, BMS: Discharge current low, BMS: Charge disabled, PF value set",
            "",
            data,
        )
        self.assertSensor("house_consumption", 6950, "W", data)
        self.assertSensor("commode", 0, "", data)
        self.assertSensor("rssi", 100, "", data)
        self.assertSensor("manufacture_code", 10, "", data)
        self.assertSensor("meter_test_status", 0, "", data)
        self.assertSensor("meter_comm_status", 1, "", data)
        self.assertSensor("active_power1", -599, "W", data)
        self.assertSensor("active_power2", -567, "W", data)
        self.assertSensor("active_power3", -2911, "W", data)
        self.assertSensor("active_power_total", -4077, "W", data)
        self.assertSensor("reactive_power_total", 2831, "var", data)
        self.assertSensor("meter_power_factor1", -6.38, "", data)
        self.assertSensor("meter_power_factor2", -4.95, "", data)
        self.assertSensor("meter_power_factor3", -9.17, "", data)
        self.assertSensor("meter_power_factor", -7.46, "", data)
        self.assertSensor("meter_freq", 49.99, "Hz", data)
        self.assertSensor("meter_e_total_exp", 0.0, "kWh", data)
        self.assertSensor("meter_e_total_imp", 0.0, "kWh", data)
        self.assertSensor("meter_active_power1", -599, "W", data)
        self.assertSensor("meter_active_power2", -567, "W", data)
        self.assertSensor("meter_active_power3", -2911, "W", data)
        self.assertSensor("meter_active_power_total", -4077, "W", data)
        self.assertSensor("meter_reactive_power1", 647, "var", data)
        self.assertSensor("meter_reactive_power2", 1105, "var", data)
        self.assertSensor("meter_reactive_power3", 1077, "var", data)
        self.assertSensor("meter_reactive_power_total", 2831, "var", data)
        self.assertSensor("meter_apparent_power1", -1076, "VA", data)
        self.assertSensor("meter_apparent_power2", -1414, "VA", data)
        self.assertSensor("meter_apparent_power3", -3175, "VA", data)
        self.assertSensor("meter_apparent_power_total", -5667, "VA", data)
        self.assertSensor("meter_type", 2, "", data)
        self.assertSensor("meter_sw_version", 0, "", data)
        self.assertSensor("meter2_active_power", 0, "W", data)
        self.assertSensor("meter2_e_total_exp", 0.0, "kWh", data)
        self.assertSensor("meter2_e_total_imp", 0.0, "kWh", data)
        self.assertSensor("meter2_comm_status", 0, "", data)
        self.assertSensor("meter_voltage1", 231.1, "V", data)
        self.assertSensor("meter_voltage2", 233.2, "V", data)
        self.assertSensor("meter_voltage3", 232.6, "V", data)
        self.assertSensor("meter_current1", 4.6, "A", data)
        self.assertSensor("meter_current2", 6.0, "A", data)
        self.assertSensor("meter_current3", 13.6, "A", data)
        self.assertSensor("battery2_status", 0, "", data)
        self.assertSensor("battery2_temperature", 0.0, "C", data)
        self.assertSensor("battery2_charge_limit", 0, "A", data)
        self.assertSensor("battery2_discharge_limit", 0, "A", data)
        self.assertSensor("battery2_error_l", 4096, "", data)
        self.assertSensor("battery2_soc", 0, "%", data)
        self.assertSensor("battery2_soh", 0, "%", data)
        self.assertSensor("battery2_modules", 6, "", data)
        self.assertSensor("battery2_warning_l", 0, "", data)
        self.assertSensor("battery2_protocol", 288, "", data)
        self.assertSensor("battery2_error_h", 0, "", data)
        self.assertSensor("battery2_error", "", "", data)
        self.assertSensor("battery2_warning_h", 0, "", data)
        self.assertSensor("battery2_warning", "", "", data)
        self.assertSensor("battery2_sw_version", 0, "", data)
        self.assertSensor("battery2_hw_version", 0, "", data)
        self.assertSensor("battery2_max_cell_temp_id", 0, "", data)
        self.assertSensor("battery2_min_cell_temp_id", 0, "", data)
        self.assertSensor("battery2_max_cell_voltage_id", 0, "", data)
        self.assertSensor("battery2_min_cell_voltage_id", 0, "", data)
        self.assertSensor("battery2_max_cell_temp", 0.0, "C", data)
        self.assertSensor("battery2_min_cell_temp", 0.0, "C", data)
        self.assertSensor("battery2_max_cell_voltage", 0.0, "V", data)
        self.assertSensor("battery2_min_cell_voltage", 0.0, "V", data)
        self.assertSensor("ppv_total", 1565, "W", data)
        self.assertSensor("pv_channel", 3, "", data)
        self.assertSensor("vpv5", 301.5, "V", data)
        self.assertSensor("ipv5", 2.0, "A", data)
        self.assertSensor("vpv6", 301.5, "V", data)
        self.assertSensor("ipv6", 0.0, "A", data)
        self.assertSensor("vpv7", 0.0, "V", data)
        self.assertSensor("ipv7", 0.0, "A", data)
        self.assertSensor("vpv8", 0.0, "V", data)
        self.assertSensor("ipv8", 0.0, "A", data)
        self.assertSensor("vpv9", 0.0, "V", data)
        self.assertSensor("ipv9", 0.0, "A", data)
        self.assertSensor("vpv10", 0.0, "V", data)
        self.assertSensor("ipv10", 0.0, "A", data)
        self.assertSensor("vpv11", 0.0, "V", data)
        self.assertSensor("ipv11", 0.0, "A", data)
        self.assertSensor("vpv12", 0.0, "V", data)
        self.assertSensor("ipv12", 0.0, "A", data)
        self.assertSensor("vpv13", 0.0, "V", data)
        self.assertSensor("ipv13", 0.0, "A", data)
        self.assertSensor("vpv14", 0.0, "V", data)
        self.assertSensor("ipv14", 0.0, "A", data)
        self.assertSensor("vpv15", 0.0, "V", data)
        self.assertSensor("ipv15", 0.0, "A", data)
        self.assertSensor("vpv16", 0.0, "V", data)
        self.assertSensor("ipv16", 0.0, "A", data)
        self.assertSensor("pmppt1", 471, "W", data)
        self.assertSensor("pmppt2", 729, "W", data)
        self.assertSensor("pmppt3", 365, "W", data)
        self.assertSensor("pmppt4", 0, "W", data)
        self.assertSensor("pmppt5", 0, "W", data)
        self.assertSensor("pmppt6", 0, "W", data)
        self.assertSensor("pmppt7", 0, "W", data)
        self.assertSensor("pmppt8", 0, "W", data)
        self.assertSensor("imppt1", 0.7, "A", data)
        self.assertSensor("imppt2", 1.3, "A", data)
        self.assertSensor("imppt3", 1.3, "A", data)
        self.assertSensor("imppt4", 0.0, "A", data)
        self.assertSensor("imppt5", 0.0, "A", data)
        self.assertSensor("imppt6", 0.0, "A", data)
        self.assertSensor("imppt7", 0.0, "A", data)
        self.assertSensor("imppt8", 0.0, "A", data)
        self.assertSensor("reactive_power1", 0, "var", data)
        self.assertSensor("reactive_power2", 0, "var", data)
        self.assertSensor("reactive_power3", 0, "var", data)
        self.assertSensor("apparent_power1", 0, "VA", data)
        self.assertSensor("apparent_power2", 0, "VA", data)
        self.assertSensor("apparent_power3", 0, "VA", data)
        self.assertSensor("vbattery2", 417.8, "V", data)
        self.assertSensor("ibattery2", -3.0, "A", data)
        self.assertSensor("pbattery2", -1254, "W", data)
        self.assertSensor("battery2_mode", 3, "", data)
        self.assertSensor("battery2_mode_label", "Charge", "", data)

        self.assertFalse(
            self.sensor_map, f"Some sensors were not tested {self.sensor_map}"
        )


class GW5K_BT_Test(EtMock):

    def __init__(self, methodName="runTest"):
        EtMock.__init__(self, methodName)
        self.mock_response(self._READ_DEVICE_VERSION_INFO, "GW5K-BT_device_info.hex")
        self.mock_response(ModbusRtuReadCommand(0xF7, 47547, 6), "NO RESPONSE")

    def test_GW5K_BT_device_info(self):
        self.loop.run_until_complete(self.read_device_info())
        self.assertEqual("GW5K-BT", self.model_name)
        self.assertEqual("95000BTU203W0000", self.serial_number)
        self.assertEqual(5000, self.rated_power)
        self.assertEqual(0, self.modbus_version)
        self.assertEqual(254, self.ac_output_type)
        self.assertEqual(3, self.dsp1_version)
        self.assertEqual(3, self.dsp2_version)
        self.assertEqual(124, self.dsp_svn_version)
        self.assertEqual(11, self.arm_version)
        self.assertEqual(147, self.arm_svn_version)
        self.assertEqual("04029-03-S10", self.firmware)
        self.assertEqual("02041-11-S00", self.arm_firmware)
