from sdm_modbus import meter


class TAC4300_CT(meter.Meter):

    def __init__(self, *args, **kwargs):
        self.model = "TAC4300-CT"
        self.baud = 9600

        super().__init__(*args, **kwargs)

        self.registers = {
            "l1_voltage": (0x0000, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Voltage", "V", 1, 1),
            "l2_voltage": (0x0002, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Voltage", "V", 1, 1),
            "l3_voltage": (0x0004, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Voltage", "V", 1, 1),
            "l1_current": (0x0006, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Current", "A", 1, 1),
            "l2_current": (0x0008, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Current", "A", 1, 1),
            "l3_current": (0x000a, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Current", "A", 1, 1),
            "l1_power_active": (0x000c, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Power (Active)", "W", 1, 1),
            "l2_power_active": (0x000e, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Power (Active)", "W", 1, 1),
            "l3_power_active": (0x0010, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Power (Active)", "W", 1, 1),
            "l1_power_reactive": (0x0012, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Power (Reactive)", "VAr", 1, 1),
            "l2_power_reactive": (0x0014, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Power (Reactive)", "VAr", 1, 1),
            "l3_power_reactive": (0x0016, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Power (Reactive)", "VAr", 1, 1),
            "l1_power_apparent": (0x0018, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Power (Apparent)", "VA", 1, 1),
            "l2_power_apparent": (0x001A, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Power (Apparent)", "VA", 1, 1),
            "l3_power_apparent": (0x001C, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Power (Apparent)", "VA", 1, 1),
            "l1_power_factor": (0x001e, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Power Factor", "", 1, 1),
            "l2_power_factor": (0x0020, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Power Factor", "", 1, 1),
            "l3_power_factor": (0x0022, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Power Factor", "", 1, 1),
            "l1_phase_angle": (0x0024, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Phase Angle", "°", 1, 1),
            "l2_phase_angle": (0x0026, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Phase Angle", "°", 1, 1),
            "l3_phase_angle": (0x0028, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Phase Angle", "°", 1, 1),
            "l12_voltage": (0x002a, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1-L2 Voltage", "V", 3, 1),
            "l23_voltage": (0x002c, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2-L3 Voltage", "V", 3, 1),
            "l31_voltage": (0x002e, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3-L1 Voltage", "V", 3, 1),
            "frequency": (0x0030, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Frequency", "Hz", 1, 1),
            "total_power_active": (0x0032, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Power (Active)", "W", 1, 1),
            "total_power_reactive": (0x0034, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Power (Reactive)", "VAr", 1, 1),
            "total_power_apparent": (0x0036, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Power (Apparent)", "VA", 1, 1),
            "total_power_factor": (0x0038, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Power Factor", "", 1, 1),
            "total_phase_angle": (0x003a, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Phase Angle", "°", 1, 1),
            "total_line_current": (0x003c, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Line Current", "A", 1, 1),
            "voltage_ln": (0x003e, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L-N Voltage", "V", 1, 1),
            "voltage_ll": (0x0040, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L-L Voltage", "V", 3, 1),
            "current_ln": (0x0042, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L-N Current", "A", 1, 1),
            "neutral_current": (0x0044, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Neutral Current", "A", 3, 1),
            "l1_load_type": (0x004e, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Load Type", "", 1, 1),
            "l2_load_type": (0x0050, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Load Type", "", 1, 1),
            "l3_load_type": (0x0052, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Load Type", "", 1, 1),
            "total_load_type": (0x0054, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Load Type", "", 1, 1),
            "l1n_voltage_thd": (0x007c, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1-N Voltage THD", "%", 3, 1),
            "l2n_voltage_thd": (0x007e, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2-N Voltage THD", "%", 3, 1),
            "l3n_voltage_thd": (0x0080, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3-N Voltage THD", "%", 3, 1),
            "l1_current_thd": (0x0082, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Current THD", "%", 3, 1),
            "l2_current_thd": (0x0084, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Current THD", "%", 3, 1),
            "l3_current_thd": (0x0086, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Current THD", "%", 3, 1),
            "voltage_ln_thd": (0x0088, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L-N Voltage THD", "%", 3, 1),
            "current_thd": (0x008a, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Current THD", "%", 3, 1),
            "total_demand_power_active": (0x008c, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Demand Power (Apparent)", "VA", 2, 1),
            "total_demand_power_reactive": (0x008e, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Demand Power (Apparent)", "VA", 2, 1),
            "total_demand_power_apparent": (0x0090, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Demand Power (Apparent)", "VA", 2, 1),
            "l1_demand_current": (0x0092, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Demand Current", "A", 3, 1),
            "l2_demand_current": (0x0094, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Demand Current", "A", 3, 1),
            "l3_demand_current": (0x0096, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Demand Current", "A", 3, 1),
            "neutral_demand_current": (0x0098, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Neutral Demand Current", "A", 2, 1),
            "import_demand_power_active": (0x009a, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Import Demand Power (Active)", "W", 2, 1),
            "export_demand_power_active": (0x009c, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Export Demand Power (Active)", "W", 2, 1),
            "maximum_demand_power_active": (0x00a2, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Maximum Total System Power Demand (Active)", "W", 2, 1),
            "maximum_demand_power_reactive": (0x00a4, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Maximum Total System Power Demand (Reactive)", "VAr", 2, 1),
            "maximum_demand_power_apparent": (0x00a6, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Maximum Total System Power Demand (Apparent)", "VA", 2, 1),
            "maximum_l1_demand_current": (0x00a8, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Maximum L1 Demand Current", "A", 3, 1),
            "maximum_l2_demand_current": (0x00aa, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Maximum L2 Demand Current", "A", 3, 1),
            "maximum_l3_demand_current": (0x00ac, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Maximum L3 Demand Current", "A", 3, 1),
            "maximum_neutral_demand_current": (0x00ae, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Maximum Neutral Demand Current", "A", 2, 1),
            "maximum_import_demand_power_active": (0x00b0, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Maximum Import Demand Power (Active)", "W", 2, 1),
            "maximum_export_demand_power_active": (0x00b2, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Maximum Export Demand Power (Active)", "W", 2, 1),
            "import_energy_active": (0x0500, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Imported Energy (Active)", "kWh", 1, 1),
            "export_energy_active": (0x0502, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Exported Energy (Active)", "kWh", 1, 1),
            "total_energy_active": (0x0504, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Energy (Active)", "kWh", 4, 1),
            "import_energy_reactive": (0x0508, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Imported Energy (Reactive)", "kVArh", 1, 1),
            "export_energy_reactive": (0x050a, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Exported Energy (Reactive)", "kVArh", 1, 1),
            "total_energy_reactive": (0x050c, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Energy (Reactive)", "kVArh", 4, 1),
            "total_energy_apparent": (0x0510, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "Total Energy (Apparent)", "kVAh", 2, 1),
            "l1_import_energy_active": (0x0514, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Import Energy (Active)", "kWh", 4, 1),
            "l2_import_energy_active": (0x0516, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Import Energy (Active)", "kWh", 4, 1),
            "l3_import_energy_active": (0x0518, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Import Energy (Active)", "kWh", 4, 1),
            "l1_export_energy_active": (0x051a, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Export Energy (Active)", "kWh", 4, 1),
            "l2_export_energy_active": (0x051c, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Export Energy (Active)", "kWh", 4, 1),
            "l3_export_energy_active": (0x051e, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Export Energy (Active)", "kWh", 4, 1),
            "l1_energy_active": (0x0520, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Total Energy (Active)", "kWh", 4, 1),
            "l2_energy_active": (0x0522, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Total Energy (Active)", "kWh", 4, 1),
            "l3_energy_active": (0x0524, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Total Energy (Active)", "kWh", 4, 1),
            "l1_import_energy_reactive": (0x0526, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Import Energy (Reactive)", "kVArh", 4, 1),
            "l2_import_energy_reactive": (0x0528, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Import Energy (Reactive)", "kVArh", 4, 1),
            "l3_import_energy_reactive": (0x052a, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Import Energy (Reactive)", "kVArh", 4, 1),
            "l1_export_energy_reactive": (0x052c, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Export Energy (Reactive)", "kVArh", 4, 1),
            "l2_export_energy_reactive": (0x052e, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Export Energy (Reactive)", "kVArh", 4, 1),
            "l3_export_energy_reactive": (0x0530, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Export Energy (Reactive)", "kVArh", 4, 1),
            "l1_energy_reactive": (0x0532, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L1 Total Energy (Reactive)", "kVArh", 4, 1),
            "l2_energy_reactive": (0x0534, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L2 Total Energy (Reactive)", "kVArh", 4, 1),
            "l3_energy_reactive": (0x0536, 2, meter.registerType.INPUT, meter.registerDataType.FLOAT32, float, "L3 Total Energy (Reactive)", "kVArh", 4, 1),

            "kppa": (0x5000, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Key Parameter Programming Authorization (KPPA)", "", 1, 1),
            "system_type": (0x5001, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "System Type", [
                "1P2W", "3P3W", "3P4W", "1P3W"], 1, 1),
            "demand_period": (0x5002, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Demand Period", "s", 1, 1),
            "slide_time": (0x5003, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Slide Time", "s", 1, 1),
            "modbus_address": (0x505, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Modbus Address", "", 1, 1),
            "baud": (0x506, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Baud Rate", [
                1200, 2400, 4800, 9600, 19200, 38400], 1, 1),
            "network_parity_stop": (0x5007, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Network Parity Stop", [
                "N-1", "E-1", "O-1", "N-2"], 1, 1),
            "password": (0x5008, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Password", "s", 1, 1),
            "pulse_1_energy_type": (0x5009, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Pulse 1 Energy Type", [
                "import_active_energy", "total_active_energy", "export_active_energy", "import_reactive_energy", "total_reactive_energy", "export_reactive_energy"], 1, 1),
            "pulse_1_rate": (0x500A, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Pulse 1 Rate", [
                "0.001_kwh_imp", "0.01_kwh_imp", "0.1_kwh_imp", "1_kwh_imp", "10_kwh_imp", "100_kwh_imp"], 1, 1),
            "pulse_width": (0x500B, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Pulse 1 Width", "ms", 1, 1),
            "current_direction_corr": (0x500F, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Current Direction Correction", [
                "L1F_L2F_L3F", "L1R_L2F_L3F", "L1F_L2R_L3F", "L1R_L2R_L3F", "L1F_L2F_L3R", "L1R_L2F_L3R"], 1, 1),
            "pt1": (0x5012, 2, meter.registerType.HOLDING, meter.registerDataType.UINT32, int, "PT1", "V", 1, 1),
            "pt2": (0x5014, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "PT2", "V", 1, 1),
            "ct1": (0x5015, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "CT1", "A", 1, 1),
            "ct2": (0x5016, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "CT2 ", "A", 1, 1),
            "auto_scroll_disp": (0x5018, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Automatic Scroll Display Time", "s", 1, 1),
            "backlight_time": (0x5019, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Backlight Time", "min", 1, 1),
            "running_time": (0x503c, 2, meter.registerType.HOLDING, meter.registerDataType.UINT32, int, "Running Time", "min", 1, 1),
            "running_time_w_load": (0x503e, 2, meter.registerType.HOLDING, meter.registerDataType.UINT32, int, "Running Time With Load", "min", 1, 1),
            "reset_historical_data": (0x5600, 1, meter.registerType.HOLDING, meter.registerDataType.UINT16, int, "Reset Historical Data", "", 1, 1),
            "meter_code": (0x5601, 1, meter.registerType.HOLDING, meter.registerDataType.INT16, int, "Meter Code", "", 4, 1),
            "serial_number": (0x5602, 2, meter.registerType.HOLDING, meter.registerDataType.UINT32, int, "Serial Number", "", 4, 1),
            "software_version": (0x5604, 1, meter.registerType.HOLDING, meter.registerDataType.INT16, int, "Software Version Number", "", 4, 1),           
            "hardware_version": (0x5605, 1, meter.registerType.HOLDING, meter.registerDataType.INT16, int, "Hardware Version Number", "", 4, 1),
            "displayed_version": (0x5606, 1, meter.registerType.HOLDING, meter.registerDataType.INT16, int, "Displayed Version Number", "", 4, 1)

        }
