#!/usr/bin/env python3
import struct
import serial
import time
import csv
import math
import matplotlib.pyplot as plt
import os

"""""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """''
======================================================================
                    Listas de Entidades BSMP
        A posição da entidade na lista corresponde ao seu ID BSMP
======================================================================
""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""
# common_list
from .constants.common_list import (
    list_ps_models,
    list_common_vars,
    list_curv,
    list_func,
    list_op_mode,
    list_sig_gen_types,
    list_parameters,
)

# fbp_const_list
from .constants.fbp_const_list import (
    list_fbp_soft_interlocks,
    list_fbp_hard_interlocks,
    list_fbp_dclink_hard_interlocks,
)

# fac_const_list
from .constants.fac_const_list import (
    list_fac_acdc_soft_interlocks,
    list_fac_acdc_hard_interlocks,
    list_fac_acdc_iib_is_interlocks,
    list_fac_acdc_iib_is_alarms,
    list_fac_acdc_iib_cmd_interlocks,
    list_fac_acdc_iib_cmd_alarms,
    list_fac_dcdc_soft_interlocks,
    list_fac_dcdc_hard_interlocks,
    list_fac_dcdc_iib_interlocks,
    list_fac_dcdc_iib_alarms,
    list_fac_2s_acdc_soft_interlocks,
    list_fac_2s_acdc_hard_interlocks,
    list_fac_2s_acdc_iib_is_interlocks,
    list_fac_2s_acdc_iib_cmd_interlocks,
    list_fac_2s_acdc_iib_is_alarms,
    list_fac_2s_acdc_iib_cmd_alarms,
    list_fac_2s_dcdc_soft_interlocks,
    list_fac_2s_dcdc_hard_interlocks,
    list_fac_2s_dcdc_iib_interlocks,
    list_fac_2s_dcdc_iib_alarms,
    list_fac_2p4s_dcdc_soft_interlocks,
    list_fac_2p4s_dcdc_hard_interlocks,
    list_fac_2p4s_dcdc_iib_interlocks,
    list_fac_2p4s_dcdc_iib_alarms,
    list_fac_dcdc_ema_soft_interlocks,
    list_fac_dcdc_ema_hard_interlocks,
    list_fac_dcdc_ema_iib_interlocks,
    list_fac_dcdc_ema_iib_alarms,
    list_fac_2p_acdc_imas_soft_interlocks,
    list_fac_2p_acdc_imas_hard_interlocks,
    list_fac_2p_dcdc_imas_soft_interlocks,
    list_fac_2p_dcdc_imas_hard_interlocks,
)

# fap_const_list
from .constants.fap_const_list import (
    list_fap_soft_interlocks,
    list_fap_hard_interlocks,
    list_fap_iib_interlocks,
    list_fap_iib_alarms,
    list_fap_4p_soft_interlocks,
    list_fap_4p_hard_interlocks,
    list_fap_4p_iib_interlocks,
    list_fap_4p_iib_alarms,
    list_fap_2p2s_soft_interlocks,
    list_fap_2p2s_hard_interlocks,
    list_fap_225A_soft_interlocks,
    list_fap_225A_hard_interlocks,
)

UDC_FIRMWARE_VERSION = "0.42 2021-05-06"

type_format = {
    "uint8_t": "BBHBB",
    "uint16_t": "BBHHB",
    "uint32_t": "BBHIB",
    "float": "BBHfB",
}

bytes_format = {"Uint16": "H", "Uint32": "L", "Uint64": "Q", "float": "f"}

type_size = {"uint8_t": 6, "uint16_t": 7, "uint32_t": 9, "float": 9}

num_blocks_curves_fbp = [4, 4, 4]
num_blocks_curves_fax = [16, 16, 16]
size_curve_block = [1024, 1024, 1024]

ufm_offset = {
    "serial": 0,
    "calibdate": 4,
    "variant": 9,
    "rburden": 10,
    "calibtemp": 12,
    "vin_gain": 14,
    "vin_offset": 16,
    "iin_gain": 18,
    "iin_offset": 20,
    "vref_p": 22,
    "vref_n": 24,
    "gnd": 26,
}

hradc_variant = ["HRADC-FBP", "HRADC-FAX-A",
                 "HRADC-FAX-B", "HRADC-FAX-C", "HRADC-FAX-D"]

hradc_input_types = [
    "GND",
    "Vref_bipolar_p",
    "Vref_bipolar_n",
    "Temp",
    "Vin_bipolar_p",
    "Vin_bipolar_n",
    "Iin_bipolar_p",
    "Iin_bipolar_n",
]

NUM_MAX_COEFFS_DSP = 12
num_dsp_classes = 7
num_dsp_modules = [4, 4, 4, 6, 8, 4, 2, 2]
num_coeffs_dsp_modules = [0, 1, 1, 4, 8, 16, 2]
dsp_classes_names = [
    "DSP_Error",
    "DSP_SRLim",
    "DSP_LPF",
    "DSP_PI",
    "DSP_IIR_2P2Z",
    "DSP_IIR_3P3Z",
    "DSP_VdcLink_FeedForward",
    "DSP_Vect_Product",
]


class SerialDRS(object):

    ser = serial.Serial()

    def __init__(self):
        # self.ser=serial.Serial()
        self.master_add = "\x00"
        self.slave_add = "\x01"
        self.b_cast_add = "\xFF"
        self.com_write_var = "\x20"
        self.write_float_size_payload = "\x00\x05"
        self.write_double_size_payload = "\x00\x03"
        self.com_read_var = "\x10\x00\x01"
        self.com_request_curve = "\x40"
        self.com_send_wfm_ref = "\x41"
        self.com_function = "\x50"
        self.dp_module_max_coeff = 16

        print(
            "\n pyDRS - compatible UDC firmware version: " + UDC_FIRMWARE_VERSION + "\n"
        )

    """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """''
    ======================================================================
                    Funções Internas da Classe
    ======================================================================
    """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""
    # Converte float para hexadecimal

    def float_to_hex(self, value):
        hex_value = struct.pack("f", value)
        return hex_value.decode("ISO-8859-1")

    # Converte lista de float  para hexadecimal
    def float_list_to_hex(self, value_list):
        hex_list = b""
        for value in value_list:
            hex_list = hex_list + struct.pack("f", value)
        return hex_list.decode("ISO-8859-1")

    def format_list_size(self, in_list, max_size):
        out_list = in_list[0:max_size]
        if max_size > len(in_list):
            for i in range(max_size - len(in_list)):
                out_list.append(0)
        return out_list

    # Converte double para hexadecimal
    def double_to_hex(self, value):
        hex_value = struct.pack("H", value)
        return hex_value.decode("ISO-8859-1")

    # Converte unsigned int para hexadecimal
    def uint32_to_hex(self, value):
        hex_value = struct.pack("I", value)
        return hex_value.decode("ISO-8859-1")

    # Converte indice para hexadecimal
    def index_to_hex(self, value):
        hex_value = struct.pack("B", value)
        return hex_value.decode("ISO-8859-1")

    # Converte payload_size para hexadecimal
    def size_to_hex(self, value):
        hex_value = struct.pack(">H", value)
        return hex_value.decode("ISO-8859-1")

    # Função Checksum
    def checksum(self, packet):
        b = bytearray(packet.encode("ISO-8859-1"))
        csum = (256 - sum(b)) % 256
        hcsum = struct.pack("B", csum)
        send_msg = packet + hcsum.decode(encoding="ISO-8859-1")
        return send_msg

    # Função de leitura de variável
    def read_var(self, var_id):
        send_msg = self.checksum(self.slave_add + self.com_read_var + var_id)
        self.ser.reset_input_buffer()
        self.ser.write(send_msg.encode("ISO-8859-1"))

    def is_open(self):
        return self.ser.isOpen()

    """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """''
    ======================================================================
                Métodos de Chamada de Entidades Funções BSMP
            O retorno do método são os bytes de retorno da mensagem
    ======================================================================
    """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""

    def turn_on(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("turn_on"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def turn_off(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("turn_off"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def open_loop(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("open_loop"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def closed_loop(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("closed_loop"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def reset_interlocks(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("reset_interlocks"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def read_ps_status(self):
        self.read_var(self.index_to_hex(list_common_vars.index("ps_status")))
        reply_msg = self.ser.read(7)
        val = struct.unpack("BBHHB", reply_msg)
        status = {}
        status["state"] = list_op_mode[(val[3] & 0b0000000000001111)]
        status["open_loop"] = (val[3] & 0b0000000000010000) >> 4
        status["interface"] = (val[3] & 0b0000000001100000) >> 5
        status["active"] = (val[3] & 0b0000000010000000) >> 7
        status["model"] = list_ps_models[(val[3] & 0b0001111100000000) >> 8]
        status["unlocked"] = (val[3] & 0b0010000000000000) >> 13
        # print(status)
        return status

    def set_ps_name(self, ps_name):
        if type(ps_name) == str:
            for n in range(len(ps_name)):
                self.set_param("PS_Name", n, float(ord(ps_name[n])))
            for i in range(n + 1, 64):
                self.set_param("PS_Name", i, float(ord(" ")))

    def get_ps_name(self):
        ps_name = ""
        for n in range(64):
            ps_name = ps_name + chr(int(self.get_param("PS_Name", n)))
            if ps_name[-3:] == "   ":
                ps_name = ps_name[: n - 2]
                break
        return ps_name

    def set_slowref(self, setpoint):
        payload_size = self.size_to_hex(1 + 4)  # Payload: ID + iSlowRef
        hex_setpoint = self.float_to_hex(setpoint)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_slowref"))
            + hex_setpoint
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def set_slowref_fbp(self, iRef1=0, iRef2=0, iRef3=0, iRef4=0):
        payload_size = self.size_to_hex(1 + 4 * 4)  # Payload: ID + 4*iRef
        hex_iRef1 = self.float_to_hex(iRef1)
        hex_iRef2 = self.float_to_hex(iRef2)
        hex_iRef3 = self.float_to_hex(iRef3)
        hex_iRef4 = self.float_to_hex(iRef4)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_slowref_fbp"))
            + hex_iRef1
            + hex_iRef2
            + hex_iRef3
            + hex_iRef4
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def set_slowref_readback_mon(self, setpoint):
        payload_size = self.size_to_hex(1 + 4)  # Payload: ID + iSlowRef
        hex_setpoint = self.float_to_hex(setpoint)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_slowref_readback_mon"))
            + hex_setpoint
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        reply_msg = self.ser.read(9)
        val = struct.unpack("BBHfB", reply_msg)
        return val[3]

    def set_slowref_fbp_readback_mon(self, iRef1=0, iRef2=0, iRef3=0, iRef4=0):
        payload_size = self.size_to_hex(1 + 4 * 4)  # Payload: ID + 4*iRef
        hex_iRef1 = self.float_to_hex(iRef1)
        hex_iRef2 = self.float_to_hex(iRef2)
        hex_iRef3 = self.float_to_hex(iRef3)
        hex_iRef4 = self.float_to_hex(iRef4)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_slowref_fbp_readback_mon"))
            + hex_iRef1
            + hex_iRef2
            + hex_iRef3
            + hex_iRef4
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        reply_msg = self.ser.read(21)
        if len(reply_msg) == 6:
            return reply_msg
        else:
            val = struct.unpack("BBHffffB", reply_msg)
            return [val[3], val[4], val[5], val[6]]

    def set_slowref_readback_ref(self, setpoint):
        payload_size = self.size_to_hex(1 + 4)  # Payload: ID + iSlowRef
        hex_setpoint = self.float_to_hex(setpoint)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_slowref_readback_ref"))
            + hex_setpoint
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        reply_msg = self.ser.read(9)
        val = struct.unpack("BBHfB", reply_msg)
        return val[3]

    def set_slowref_fbp_readback_ref(self, iRef1=0, iRef2=0, iRef3=0, iRef4=0):
        payload_size = self.size_to_hex(1 + 4 * 4)  # Payload: ID + 4*iRef
        hex_iRef1 = self.float_to_hex(iRef1)
        hex_iRef2 = self.float_to_hex(iRef2)
        hex_iRef3 = self.float_to_hex(iRef3)
        hex_iRef4 = self.float_to_hex(iRef4)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_slowref_fbp_readback_ref"))
            + hex_iRef1
            + hex_iRef2
            + hex_iRef3
            + hex_iRef4
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        reply_msg = self.ser.read(21)
        if len(reply_msg) == 6:
            return reply_msg
        else:
            val = struct.unpack("BBHffffB", reply_msg)
            return [val[3], val[4], val[5], val[6]]

    def set_param(self, param_id, n, value):
        payload_size = self.size_to_hex(
            1 + 2 + 2 + 4
        )  # Payload: ID + param id + [n] + value
        if type(param_id) == str:
            hex_id = self.double_to_hex(list_parameters.index(param_id))
        if type(param_id) == int:
            hex_id = self.double_to_hex(param_id)
        hex_n = self.double_to_hex(n)
        hex_value = self.float_to_hex(value)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_param"))
            + hex_id
            + hex_n
            + hex_value
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        reply_msg = self.ser.read(6)
        if reply_msg[4] == 8:
            print("Invalid parameter")
        return reply_msg

    def get_param(self, param_id, n=0):
        # Payload: ID + param id + [n]
        payload_size = self.size_to_hex(1 + 2 + 2)
        if type(param_id) == str:
            hex_id = self.double_to_hex(list_parameters.index(param_id))
        if type(param_id) == int:
            hex_id = self.double_to_hex(param_id)
        hex_n = self.double_to_hex(n)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("get_param"))
            + hex_id
            + hex_n
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.reset_input_buffer()
        self.ser.write(send_msg.encode("ISO-8859-1"))
        reply_msg = self.ser.read(9)
        if len(reply_msg) == 9:
            val = struct.unpack("BBHfB", reply_msg)
            return val[3]
        else:
            # print('Invalid parameter')
            return float("nan")

    def save_param_eeprom(self, param_id, n=0, type_memory=2):
        payload_size = self.size_to_hex(
            1 + 2 + 2 + 2
        )  # Payload: ID + param id + [n] + memory type
        if type(param_id) == str:
            hex_id = self.double_to_hex(list_parameters.index(param_id))
        if type(param_id) == int:
            hex_id = self.double_to_hex(param_id)
        hex_n = self.double_to_hex(n)
        hex_type = self.double_to_hex(type_memory)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("save_param_eeprom"))
            + hex_id
            + hex_n
            + hex_type
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        reply_msg = self.ser.read(6)
        if reply_msg[4] == 8:
            print("Invalid parameter")
        return reply_msg

    def load_param_eeprom(self, param_id, n=0, type_memory=2):
        payload_size = self.size_to_hex(
            1 + 2 + 2 + 2
        )  # Payload: ID + param id + [n] + memory type
        if type(param_id) == str:
            hex_id = self.double_to_hex(list_parameters.index(param_id))
        if type(param_id) == int:
            hex_id = self.double_to_hex(param_id)
        hex_n = self.double_to_hex(n)
        hex_type = self.double_to_hex(type_memory)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("load_param_eeprom"))
            + hex_id
            + hex_n
            + hex_type
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        reply_msg = self.ser.read(6)
        if reply_msg[4] == 8:
            print("Invalid parameter")
        return reply_msg

    def save_param_bank(self, type_memory=2):
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID + memory type
        hex_type = self.double_to_hex(type_memory)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("save_param_bank"))
            + hex_type
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def load_param_bank(self, type_memory=2):
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID + memory type
        hex_type = self.double_to_hex(type_memory)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("load_param_bank"))
            + hex_type
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def set_param_bank(self, param_file):
        fbp_param_list = []
        with open(param_file, newline="") as f:
            reader = csv.reader(f)
            for row in reader:
                fbp_param_list.append(row)

        for param in fbp_param_list:
            if str(param[0]) == "PS_Name":
                print(str(param[0]) + "[0]: " + str(param[1]))
                print(self.set_ps_name(str(param[1])))
            else:
                for n in range(64):
                    try:
                        print(str(param[0]) + "[" + str(n) +
                              "]: " + str(param[n + 1]))
                        print(self.set_param(
                            str(param[0]), n, float(param[n + 1])))
                    except:
                        break
        # self.save_param_bank()

    def get_param_bank(
        self, list_param=list_parameters, timeout=0.5, print_modules=True
    ):
        timeout_old = self.ser.timeout
        # self.ser.timeout = 0.05
        param_bank = []

        for param_name in list_param:

            param_row = [param_name]

            for n in range(64):
                if param_name == "PS_Name":

                    p = self.get_ps_name()
                    param_row.append(p)
                    # if(print_modules):
                    # print('PS_Name: ' + p)
                    self.ser.timeout = timeout
                    break

                else:
                    p = self.get_param(param_name, n)
                    if math.isnan(p):
                        break
                    param_row.append(p)
                    # if(print_modules):
                    # print(param_name + "[" + str(n) + "]: " + str(p))

            if print_modules:
                print(param_row)

            param_bank.append(param_row)

        self.ser.timeout = timeout_old

        return param_bank

    def store_param_bank_csv(self, bank):
        filename = input("Digite o nome do arquivo: ")
        with open(filename + ".csv", "w", newline="") as f:
            writer = csv.writer(f, delimiter=",")
            for param_row in bank:
                writer.writerow(param_row)

    def enable_onboard_eeprom(self):
        self.set_param("Enable_Onboard_EEPROM", 0, 0)
        self.save_param_eeprom("Enable_Onboard_EEPROM", 0, 2)

    def disable_onboard_eeprom(self):
        self.set_param("Enable_Onboard_EEPROM", 0, 1)
        self.save_param_eeprom("Enable_Onboard_EEPROM", 0, 2)

    def set_dsp_coeffs(
        self, dsp_class, dsp_id, coeffs_list=[
            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    ):
        coeffs_list_full = self.format_list_size(
            coeffs_list, NUM_MAX_COEFFS_DSP)
        payload_size = self.size_to_hex(1 + 2 + 2 + 4 * NUM_MAX_COEFFS_DSP)
        hex_dsp_class = self.double_to_hex(dsp_class)
        hex_dsp_id = self.double_to_hex(dsp_id)
        hex_coeffs = self.float_list_to_hex(coeffs_list_full)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_dsp_coeffs"))
            + hex_dsp_class
            + hex_dsp_id
            + hex_coeffs
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def get_dsp_coeff(self, dsp_class, dsp_id, coeff):
        payload_size = self.size_to_hex(1 + 2 + 2 + 2)
        hex_dsp_class = self.double_to_hex(dsp_class)
        hex_dsp_id = self.double_to_hex(dsp_id)
        hex_coeff = self.double_to_hex(coeff)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("get_dsp_coeff"))
            + hex_dsp_class
            + hex_dsp_id
            + hex_coeff
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.reset_input_buffer()
        self.ser.write(send_msg.encode("ISO-8859-1"))
        reply_msg = self.ser.read(9)
        # print(reply_msg)
        val = struct.unpack("BBHfB", reply_msg)
        return val[3]

    def save_dsp_coeffs_eeprom(self, dsp_class, dsp_id, type_memory=2):
        payload_size = self.size_to_hex(1 + 2 + 2 + 2)
        hex_dsp_class = self.double_to_hex(dsp_class)
        hex_dsp_id = self.double_to_hex(dsp_id)
        hex_type = self.double_to_hex(type_memory)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("save_dsp_coeffs_eeprom"))
            + hex_dsp_class
            + hex_dsp_id
            + hex_type
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def load_dsp_coeffs_eeprom(self, dsp_class, dsp_id, type_memory=2):
        payload_size = self.size_to_hex(1 + 2 + 2 + 2)
        hex_dsp_class = self.double_to_hex(dsp_class)
        hex_dsp_id = self.double_to_hex(dsp_id)
        hex_type = self.double_to_hex(type_memory)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("load_dsp_coeffs_eeprom"))
            + hex_dsp_class
            + hex_dsp_id
            + hex_type
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def save_dsp_modules_eeprom(self, type_memory=2):
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID + memory type
        hex_type = self.double_to_hex(type_memory)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("save_dsp_modules_eeprom"))
            + hex_type
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def load_dsp_modules_eeprom(self, type_memory=2):
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID + memory type
        hex_type = self.double_to_hex(type_memory)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("load_dsp_modules_eeprom"))
            + hex_type
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def reset_udc(self):
        reply = input(
            "\nEste comando realiza o reset do firmware da placa UDC, e por isso, so e executado caso a fonte esteja desligada. \nCaso deseje apenas resetar interlocks, utilize o comando reset_interlocks(). \n\nTem certeza que deseja prosseguir? [Y/N]: "
        )
        if reply == "Y" or reply == "y":
            payload_size = self.size_to_hex(1)  # Payload: ID
            send_packet = (
                self.com_function
                + payload_size
                + self.index_to_hex(list_func.index("reset_udc"))
            )
            send_msg = self.checksum(self.slave_add + send_packet)
            self.ser.write(send_msg.encode("ISO-8859-1"))

    def run_bsmp_func(self, id_func, print_msg=0):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = self.com_function + \
            payload_size + self.index_to_hex(id_func)
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        reply_msg = self.ser.read(6)
        if print_msg:
            print(reply_msg)
        return reply_msg

    def run_bsmp_func_all_ps(
        self, p_func, add_list, arg=None, delay=0.5, print_reply=1
    ):
        old_add = self.get_slave_add()
        for add in add_list:
            self.set_slave_add(add)
            if arg is None:
                r = p_func()
            else:
                r = p_func(arg)
            if print_reply:
                print("\n Add " + str(add))
                print(r)
            time.sleep(delay)
        self.set_slave_add(old_add)

    def cfg_source_scope(self, p_source):
        payload_size = self.size_to_hex(1 + 4)  # Payload: ID + p_source
        hex_op_mode = self.uint32_to_hex(p_source)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("cfg_source_scope"))
            + hex_op_mode
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def cfg_freq_scope(self, freq):
        payload_size = self.size_to_hex(1 + 4)  # Payload: ID + freq
        hex_op_mode = self.float_to_hex(freq)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("cfg_freq_scope"))
            + hex_op_mode
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def cfg_duration_scope(self, duration):
        payload_size = self.size_to_hex(1 + 4)  # Payload: ID + duration
        hex_op_mode = self.float_to_hex(duration)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("cfg_duration_scope"))
            + hex_op_mode
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def enable_scope(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("enable_scope"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def disable_scope(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("disable_scope"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def get_scope_vars(self):
        print("\n### Scope Variables ###\n")
        print("Frequency: " + str((round(self.read_bsmp_variable(25, "float"), 3))))
        print("Duration: " + str((round(self.read_bsmp_variable(26, "float"), 3))))
        print(
            "Source Data: " +
            str((round(self.read_bsmp_variable(27, "uint32_t"), 3)))
        )

    def sync_pulse(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("sync_pulse"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def select_op_mode(self, op_mode):
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID + enable
        hex_op_mode = self.double_to_hex(list_op_mode.index(op_mode))
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("select_op_mode"))
            + hex_op_mode
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def set_serial_termination(self, term_enable):
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID + enable
        hex_enable = self.double_to_hex(term_enable)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_serial_termination"))
            + hex_enable
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def set_command_interface(self, interface):
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID + enable
        hex_interface = self.double_to_hex(interface)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_command_interface"))
            + hex_interface
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def unlock_udc(self, password):
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID + password
        hex_password = self.double_to_hex(password)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("unlock_udc"))
            + hex_password
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def lock_udc(self, password):
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID + password
        hex_password = self.double_to_hex(password)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("lock_udc"))
            + hex_password
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def reset_counters(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("reset_counters"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def cfg_siggen(
        self, sig_type, num_cycles, freq, amplitude, offset, aux0, aux1, aux2, aux3
    ):
        payload_size = self.size_to_hex(1 + 2 + 2 + 4 + 4 + 4 + 4 * 4)
        hex_sig_type = self.double_to_hex(list_sig_gen_types.index(sig_type))
        hex_num_cycles = self.double_to_hex(num_cycles)
        hex_freq = self.float_to_hex(freq)
        hex_amplitude = self.float_to_hex(amplitude)
        hex_offset = self.float_to_hex(offset)
        hex_aux0 = self.float_to_hex(aux0)
        hex_aux1 = self.float_to_hex(aux1)
        hex_aux2 = self.float_to_hex(aux2)
        hex_aux3 = self.float_to_hex(aux3)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("cfg_siggen"))
            + hex_sig_type
            + hex_num_cycles
            + hex_freq
            + hex_amplitude
            + hex_offset
            + hex_aux0
            + hex_aux1
            + hex_aux2
            + hex_aux3
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def set_siggen(self, freq, amplitude, offset):
        payload_size = self.size_to_hex(1 + 4 + 4 + 4)
        hex_freq = self.float_to_hex(freq)
        hex_amplitude = self.float_to_hex(amplitude)
        hex_offset = self.float_to_hex(offset)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("set_siggen"))
            + hex_freq
            + hex_amplitude
            + hex_offset
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def enable_siggen(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("enable_siggen"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def disable_siggen(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("disable_siggen"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def cfg_wfmref(self, idx, sync_mode, frequency, gain=1, offset=0):
        payload_size = self.size_to_hex(
            1 + 2 + 2 + 4 + 4 + 4
        )  # Payload: ID + idx + sync_mode + frequency + gain + offset
        hex_idx = self.double_to_hex(idx)
        hex_mode = self.double_to_hex(sync_mode)
        hex_freq = self.float_to_hex(frequency)
        hex_gain = self.float_to_hex(gain)
        hex_offset = self.float_to_hex(offset)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("cfg_wfmref"))
            + hex_idx
            + hex_mode
            + hex_freq
            + hex_gain
            + hex_offset
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def select_wfmref(self, idx):
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID + idx
        hex_idx = self.double_to_hex(idx)
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("select_wfmref"))
            + hex_idx
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def reset_wfmref(self):
        payload_size = self.size_to_hex(1)  # Payload: ID
        send_packet = (
            self.com_function
            + payload_size
            + self.index_to_hex(list_func.index("reset_wfmref"))
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(6)

    def get_wfmref_vars(self, curve_id):
        print("\n### WfmRef " + str(curve_id) + " Variables ###\n")
        print(
            "Length: "
            + str(
                (
                    round(self.read_bsmp_variable(
                        20 + curve_id * 3, "uint32_t"), 3)
                    - round(self.read_bsmp_variable(19 +
                                                    curve_id * 3, "uint32_t"), 3)
                )
                / 2
                + 1
            )
        )
        print(
            "Index: "
            + str(
                (
                    round(self.read_bsmp_variable(
                        21 + curve_id * 3, "uint32_t"), 3)
                    - round(self.read_bsmp_variable(19 +
                                                    curve_id * 3, "uint32_t"), 3)
                )
                / 2
                + 1
            )
        )
        print(
            "WfmRef Selected: " +
            str(round(self.read_bsmp_variable(14, "uint16_t"), 3))
        )
        print("Sync Mode: " + str(round(self.read_bsmp_variable(15, "uint16_t"), 3)))
        print(
            "Frequency: " +
            str(round(self.read_bsmp_variable(16, "float"), 3)) + " Hz"
        )
        print("Gain: " + str(round(self.read_bsmp_variable(17, "float"), 3)))
        print("Offset: " + str(round(self.read_bsmp_variable(18, "float"), 3)))

    def read_csv_file(self, filename, type="float"):
        csv_list = []
        with open(filename, newline="") as f:
            reader = csv.reader(f)
            for row in reader:
                if type == "float":
                    row_converted = float(row[0])
                elif type == "string" or type == "str":
                    row_converted = str(row[0])
                csv_list.append(row_converted)
        print("Length of list: " + str(len(csv_list)) + "\n")
        return csv_list

    """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """''
    ======================================================================
                Métodos de Leitura de Valores das Variáveis BSMP
    O retorno do método são os valores double/float da respectiva variavel
    ======================================================================
    """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""

    def read_bsmp_variable(self, id_var, type_var, print_msg=0):
        self.read_var(self.index_to_hex(id_var))
        reply_msg = self.ser.read(type_size[type_var])
        if print_msg:
            print(reply_msg)
        val = struct.unpack(type_format[type_var], reply_msg)
        return val[3]

    def read_bsmp_variable_gen(self, id_var, size_bytes, print_msg=0):
        self.read_var(self.index_to_hex(id_var))
        reply_msg = self.ser.read(size_bytes + 5)
        if print_msg:
            print(reply_msg)
        return reply_msg

    def read_udc_arm_version(self):
        self.read_var(self.index_to_hex(3))
        reply_msg = self.ser.read(133)
        val = struct.unpack("16s", reply_msg[4:20])
        return val[0].decode("utf-8")

    def read_udc_c28_version(self):
        self.read_var(self.index_to_hex(3))
        reply_msg = self.ser.read(133)
        val = struct.unpack("16s", reply_msg[20:36])
        return val[0].decode("utf-8")

    def read_udc_version(self):
        print("\n ARM: " + self.read_udc_arm_version())
        print(" C28: " + self.read_udc_c28_version())

    def read_ps_model(self):
        reply_msg = self.read_ps_model()
        return list_ps_models[reply_msg[3]]

    """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """''
    ======================================================================
                Métodos de Escrita de Valores das Variáveis BSMP
            O retorno do método são os bytes de retorno da mensagem
    ======================================================================
    """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""

    def Write_sigGen_Freq(self, float_value):
        hex_float = self.float_to_hex(float_value)
        send_packet = (
            self.com_write_var
            + self.write_float_size_payload
            + self.index_to_hex(list_common_vars.index("sigGen_Freq"))
            + hex_float
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(5)

    def Write_sigGen_Amplitude(self, float_value):
        hex_float = self.float_to_hex(float_value)
        send_packet = (
            self.com_write_var
            + self.write_float_size_payload
            + self.index_to_hex(list_common_vars.index("sigGen_Amplitude"))
            + hex_float
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(5)

    def Write_sigGen_Offset(self, float_value):
        hex_float = self.float_to_hex(float_value)
        send_packet = (
            self.com_write_var
            + self.write_float_size_payload
            + self.index_to_hex(list_common_vars.index("sigGen_Offset"))
            + hex_float
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(5)

    def Write_sigGen_Aux(self, float_value):
        hex_float = self.float_to_hex(float_value)
        send_packet = (
            self.com_write_var
            + self.write_float_size_payload
            + self.index_to_hex(list_common_vars.index("sigGen_Aux"))
            + hex_float
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(5)

    def Write_dp_ID(self, double_value):
        hex_double = self.double_to_hex(double_value)
        send_packet = (
            self.com_write_var
            + self.write_double_size_payload
            + self.index_to_hex(list_common_vars.index("dp_ID"))
            + hex_double
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(5)

    def Write_dp_Class(self, double_value):
        hex_double = self.double_to_hex(double_value)
        send_packet = (
            self.com_write_var
            + self.write_double_size_payload
            + self.index_to_hex(list_common_vars.index("dp_Class"))
            + hex_double
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(5)

    def Write_dp_Coeffs(self, list_float):

        hex_float_list = []
        # list_full = list_float[:]

        # while(len(list_full) < self.dp_module_max_coeff):
        #    list_full.append(0)

        list_full = [0 for i in range(self.dp_module_max_coeff)]
        list_full[: len(list_float)] = list_float[:]

        for float_value in list_full:
            hex_float = self.float_to_hex(float(float_value))
            hex_float_list.append(hex_float)
        str_float_list = "".join(hex_float_list)
        payload_size = self.size_to_hex(
            1 + 4 * self.dp_module_max_coeff
        )  # Payload: ID + 16floats
        send_packet = (
            self.com_write_var
            + payload_size
            + self.index_to_hex(list_common_vars.index("dp_Coeffs"))
            + str_float_list
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(5)

    """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """''
    ======================================================================
                     Métodos de Escrita de Curvas BSMP
            O retorno do método são os bytes de retorno da mensagem
    ======================================================================
    """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""

    def send_wfmref_curve(self, block_idx, data):
        block_hex = struct.pack(">H", block_idx).decode("ISO-8859-1")
        val = []
        for k in range(0, len(data)):
            val.append(self.float_to_hex(float(data[k])))
        payload_size = struct.pack(
            ">H", (len(val) * 4) + 3).decode("ISO-8859-1")
        curva_hex = "".join(val)
        send_packet = (
            self.com_send_wfm_ref
            + payload_size
            + self.index_to_hex(list_curv.index("wfmRef_Curve"))
            + block_hex
            + curva_hex
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(5)

    def recv_wfmref_curve(self, block_idx):
        block_hex = struct.pack(">H", block_idx).decode("ISO-8859-1")
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID+Block_index
        send_packet = (
            self.com_request_curve
            + payload_size
            + self.index_to_hex(list_curv.index("wfmRef_Curve"))
            + block_hex
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        recv_msg = self.ser.read(
            1 + 1 + 2 + 1 + 2 + 8192 + 1
        )  # Address+Command+Size+ID+Block_idx+data+checksum
        val = []
        for k in range(7, len(recv_msg) - 1, 4):
            val.append(struct.unpack("f", recv_msg[k: k + 4]))
        return val

    def recv_samples_buffer(self):
        block_hex = struct.pack(">H", 0).decode("ISO-8859-1")
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID+Block_index
        send_packet = (
            self.com_request_curve
            + payload_size
            + self.index_to_hex(list_curv.index("samplesBuffer"))
            + block_hex
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        recv_msg = self.ser.read(
            1 + 1 + 2 + 1 + 2 + 16384 + 1
        )  # Address+Command+Size+ID+Block_idx+data+checksum
        val = []
        try:
            for k in range(7, len(recv_msg) - 1, 4):
                val.extend(struct.unpack("f", recv_msg[k: k + 4]))
        except:
            pass
        return val

    def send_full_wfmref_curve(self, block_idx, data):
        block_hex = struct.pack(">H", block_idx).decode("ISO-8859-1")
        val = []
        for k in range(0, len(data)):
            val.append(self.float_to_hex(float(data[k])))
        payload_size = struct.pack(
            ">H", (len(val) * 4) + 3).decode("ISO-8859-1")
        curva_hex = "".join(val)
        send_packet = (
            self.com_send_wfm_ref
            + payload_size
            + self.index_to_hex(list_curv.index("fullwfmRef_Curve"))
            + block_hex
            + curva_hex
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(5)

    def recv_full_wfmref_curve(self, block_idx):
        block_hex = struct.pack(">H", block_idx).decode("ISO-8859-1")
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID+Block_index
        send_packet = (
            self.com_request_curve
            + payload_size
            + self.index_to_hex(list_curv.index("fullwfmRef_Curve"))
            + block_hex
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        recv_msg = self.ser.read(
            1 + 1 + 2 + 1 + 2 + 16384 + 1
        )  # Address+Command+Size+ID+Block_idx+data+checksum
        val = []
        for k in range(7, len(recv_msg) - 1, 4):
            val.append(struct.unpack("f", recv_msg[k: k + 4]))
        return val

    def recv_samples_buffer_blocks(self, block_idx):
        block_hex = struct.pack(">H", block_idx).decode("ISO-8859-1")
        payload_size = self.size_to_hex(1 + 2)  # Payload: ID+Block_index
        send_packet = (
            self.com_request_curve
            + payload_size
            + self.index_to_hex(list_curv.index("samplesBuffer_blocks"))
            + block_hex
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        # t0 = time.time()
        self.ser.write(send_msg.encode("ISO-8859-1"))
        recv_msg = self.ser.read(
            1 + 1 + 2 + 1 + 2 + 1024 + 1
        )  # Address+Command+Size+ID+Block_idx+data+checksum
        # print(time.time()-t0)
        # print(recv_msg)
        val = []
        for k in range(7, len(recv_msg) - 1, 4):
            val.extend(struct.unpack("f", recv_msg[k: k + 4]))
        return val

    def recv_samples_buffer_allblocks(self):
        buff = []
        # self.DisableSamplesBuffer()
        for i in range(0, 16):
            # t0 = time.time()
            buff.extend(self.recv_samples_buffer_blocks(i))
            # print(time.time()-t0)
        # self.EnableSamplesBuffer()
        return buff

    def read_curve_block(self, curve_id, block_id):
        block_hex = struct.pack(">H", block_id).decode("ISO-8859-1")
        payload_size = self.size_to_hex(1 + 2)  # Payload: curve_id + block_id
        send_packet = (
            self.com_request_curve
            + payload_size
            + self.index_to_hex(curve_id)
            + block_hex
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        # t0 = time.time()
        self.ser.reset_input_buffer()
        self.ser.write(send_msg.encode("ISO-8859-1"))
        recv_msg = self.ser.read(
            1 + 1 + 2 + 1 + 2 + size_curve_block[curve_id] + 1
        )  # Address+Command+Size+ID+Block_idx+data+checksum
        # print(time.time()-t0)
        # print(recv_msg)
        val = []
        for k in range(7, len(recv_msg) - 1, 4):
            val.extend(struct.unpack("f", recv_msg[k: k + 4]))
        return val

    def write_curve_block(self, curve_id, block_id, data):
        block_hex = struct.pack(">H", block_id).decode("ISO-8859-1")
        val = []
        for k in range(0, len(data)):
            val.append(self.float_to_hex(float(data[k])))
        payload_size = struct.pack(
            ">H", (len(val) * 4) + 3).decode("ISO-8859-1")
        curva_hex = "".join(val)
        send_packet = (
            self.com_send_wfm_ref
            + payload_size
            + self.index_to_hex(curve_id)
            + block_hex
            + curva_hex
        )
        send_msg = self.checksum(self.slave_add + send_packet)
        self.ser.write(send_msg.encode("ISO-8859-1"))
        return self.ser.read(5)

    def write_wfmref(self, curve, data):
        # curve = list_curv.index('wfmref')
        block_size = int(size_curve_block[curve] / 4)
        print(block_size)

        blocks = [data[x: x + block_size]
                  for x in range(0, len(data), block_size)]

        ps_status = self.read_ps_status()

        wfmref_selected = self.read_bsmp_variable(14, "uint16_t")

        if (wfmref_selected == curve) and (
            ps_status["state"] == "RmpWfm" or ps_status["state"] == "MigWfm"
        ):
            print(
                "\n The specified curve ID is currently selected and PS is on "
                + ps_status["state"]
                + " state. Choose a different curve ID to proceed.\n"
            )

        else:
            for block_id in range(len(blocks)):
                self.write_curve_block(curve, block_id, blocks[block_id])
                print(blocks[block_id])

    def read_buf_samples_ctom(self):
        buf = []
        curve_id = list_curv.index("buf_samples_ctom")

        ps_status = self.read_ps_status()
        if ps_status["model"] == "FBP":
            for i in range(num_blocks_curves_fbp[curve_id]):
                buf.extend(self.read_curve_block(curve_id, i))
        else:
            for i in range(num_blocks_curves_fax[curve_id]):
                buf.extend(self.read_curve_block(curve_id, i))

        return buf

    """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """''
    ======================================================================
                            Funções Serial
    ======================================================================
    """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""

    def connect(self, port="COM2", baud=115200):
        try:
            SerialDRS.ser = serial.Serial(
                port, baud, timeout=1
            )  # port format should be 'COM'+number
            return True
        except:
            return False

    def disconnect(self):
        if self.ser.isOpen():
            try:
                self.ser.close()
                return True
            except:
                return False

    def set_slave_add(self, address):
        self.slave_add = struct.pack("B", address).decode("ISO-8859-1")

    def get_slave_add(self):
        return struct.unpack("B", self.slave_add.encode())[0]

    """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """''
    ======================================================================
                      Funções auxiliares
    ======================================================================
    """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" ""

    def read_vars_common(self, print_all=False):

        loop_state = ["Closed Loop", "Open Loop"]

        ps_status = self.read_ps_status()
        if ps_status["open_loop"] == 0:
            if (
                (ps_status["model"] == "FAC_ACDC")
                or (ps_status["model"] == "FAC_2S_ACDC")
                or (ps_status["model"] == "FAC_2P4S_ACDC")
            ):
                setpoint_unit = " V"
            else:
                setpoint_unit = " A"
        else:
            setpoint_unit = " %"

        print("\nPS Model: " + ps_status["model"])
        print("State: " + ps_status["state"])
        print("Loop State: " + loop_state[ps_status["open_loop"]])

        print(
            "\nSetpoint: "
            + str(round(self.read_bsmp_variable(1, "float"), 3))
            + setpoint_unit
        )
        print(
            "Reference: "
            + str(round(self.read_bsmp_variable(2, "float"), 3))
            + setpoint_unit
        )

        if print_all:
            print(self.read_ps_status())

            print(
                "\nCounter set_slowref: "
                + str(round(self.read_bsmp_variable(4, "uint32_t"), 3))
            )
            print(
                "Counter sync pulse: "
                + str(round(self.read_bsmp_variable(5, "uint32_t"), 3))
            )

            self.get_siggen_vars()
            self.get_wfmref_vars(0)
            self.get_wfmref_vars(1)
            self.get_scope_vars()

    def decode_interlocks(self, reg_interlocks, list_interlocks):
        active_interlocks = []

        for i in range(32):
            if reg_interlocks & (1 << i):
                active_interlocks.append(list_interlocks[i])
                print("\t" + list_interlocks[i])
        return active_interlocks

    def read_vars_fbp(self, n=1, dt=0.5):

        try:
            for i in range(n):

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fbp_soft_interlocks)
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fbp_hard_interlocks)

                print(
                    "\nLoad Current: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " A"
                )
                print(
                    "Load Voltage: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " V"
                )
                print(
                    "Load Resistance: "
                    + str(
                        abs(
                            round(
                                self.read_bsmp_variable(34, "float")
                                / self.read_bsmp_variable(33, "float"),
                                3,
                            )
                        )
                    )
                    + " Ohm"
                )
                print(
                    "Load Power: "
                    + str(
                        abs(
                            round(
                                self.read_bsmp_variable(34, "float")
                                * self.read_bsmp_variable(33, "float"),
                                3,
                            )
                        )
                    )
                    + " W"
                )
                print(
                    "DC-Link Voltage: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " V"
                )
                print(
                    "Heat-Sink Temp: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " °C"
                )
                print(
                    "Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                    + " %"
                )

                time.sleep(dt)

        except:
            pass

    def read_vars_fbp_dclink(self, n=1, dt=0.5):

        try:
            for i in range(n):

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("\nHard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fbp_dclink_hard_interlocks)

                print(
                    "\nModules status: "
                    + str(round(self.read_bsmp_variable(33, "uint32_t"), 3))
                )
                print(
                    "DC-Link Voltage: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " V"
                )
                print(
                    "PS1 Voltage: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " V"
                )
                print(
                    "PS2 Voltage: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " V"
                )
                print(
                    "PS3 Voltage: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                    + " V"
                )
                print(
                    "Dig Pot Tap: "
                    + str(round(self.read_bsmp_variable(38, "uint8_t"), 3))
                )

                time.sleep(dt)

        except:
            pass

    def read_vars_fac_acdc(self, n=1, dt=0.5, iib=1):

        # try:
        for i in range(n):

            print(
                "\n--- Measurement #"
                + str(i + 1)
                + " ------------------------------------------\n"
            )
            self.read_vars_common()

            soft_itlks = self.read_bsmp_variable(31, "uint32_t")
            print("\nSoft Interlocks: " + str(soft_itlks))
            if soft_itlks:
                self.decode_interlocks(
                    soft_itlks, list_fac_acdc_soft_interlocks)
                print("")

            hard_itlks = self.read_bsmp_variable(32, "uint32_t")
            print("Hard Interlocks: " + str(hard_itlks))
            if hard_itlks:
                self.decode_interlocks(
                    hard_itlks, list_fac_acdc_hard_interlocks)

            iib_is_itlks = self.read_bsmp_variable(45, "uint32_t")
            print("\nIIB IS Interlocks: " + str(iib_is_itlks))
            if iib_is_itlks:
                self.decode_interlocks(
                    iib_is_itlks, list_fac_acdc_iib_is_interlocks)

            iib_is_alarms = self.read_bsmp_variable(46, "uint32_t")
            print("IIB IS Alarms: " + str(iib_is_alarms))
            if iib_is_alarms:
                self.decode_interlocks(
                    iib_is_alarms, list_fac_acdc_iib_is_alarms)

            iib_cmd_itlks = self.read_bsmp_variable(57, "uint32_t")
            print("\nIIB Cmd Interlocks: " + str(iib_cmd_itlks))
            if iib_cmd_itlks:
                self.decode_interlocks(
                    iib_cmd_itlks, list_fac_acdc_iib_cmd_interlocks)

            iib_cmd_alarms = self.read_bsmp_variable(58, "uint32_t")
            print("IIB Cmd Alarms: " + str(iib_cmd_alarms))
            if iib_cmd_alarms:
                self.decode_interlocks(
                    iib_cmd_alarms, list_fac_acdc_iib_cmd_alarms)

            print(
                "\nCapBank Voltage: "
                + str(round(self.read_bsmp_variable(33, "float"), 3))
                + " V"
            )
            print(
                "Rectifier Current: "
                + str(round(self.read_bsmp_variable(34, "float"), 3))
                + " A"
            )

            print(
                "Duty-Cycle: "
                + str(round(self.read_bsmp_variable(35, "float"), 3))
                + " %"
            )

            if iib:
                print(
                    "\nIIB IS Input Current: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " A"
                )
                print(
                    "IIB IS Input Voltage: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                    + " V"
                )
                print(
                    "IIB IS IGBT Temp: "
                    + str(round(self.read_bsmp_variable(38, "float"), 3))
                    + " °C"
                )
                print(
                    "IIB IS Driver Voltage: "
                    + str(round(self.read_bsmp_variable(39, "float"), 3))
                    + " V"
                )
                print(
                    "IIB IS Driver Current: "
                    + str(round(self.read_bsmp_variable(40, "float"), 3))
                    + " A"
                )
                print(
                    "IIB IS Inductor Temp: "
                    + str(round(self.read_bsmp_variable(41, "float"), 3))
                    + " °C"
                )
                print(
                    "IIB IS Heat-Sink Temp: "
                    + str(round(self.read_bsmp_variable(42, "float"), 3))
                    + " °C"
                )
                print(
                    "IIB IS Board Temp: "
                    + str(round(self.read_bsmp_variable(43, "float"), 3))
                    + " °C"
                )
                print(
                    "IIB IS Board RH: "
                    + str(round(self.read_bsmp_variable(44, "float"), 3))
                    + " %"
                )
                print(
                    "IIB IS Interlocks: "
                    + str(round(self.read_bsmp_variable(45, "uint32_t"), 3))
                )
                print(
                    "IIB IS Alarms: "
                    + str(round(self.read_bsmp_variable(46, "uint32_t"), 3))
                )

                print(
                    "\nIIB Cmd Load Voltage: "
                    + str(round(self.read_bsmp_variable(47, "float"), 3))
                    + " V"
                )
                print(
                    "IIB Cmd CapBank Voltage: "
                    + str(round(self.read_bsmp_variable(48, "float"), 3))
                    + " V"
                )
                print(
                    "IIB Cmd Rectifier Inductor Temp: "
                    + str(round(self.read_bsmp_variable(49, "float"), 3))
                    + " °C"
                )
                print(
                    "IIB Cmd Rectifier Heat-Sink Temp: "
                    + str(round(self.read_bsmp_variable(50, "float"), 3))
                    + " °C"
                )
                print(
                    "IIB Cmd External Boards Voltage: "
                    + str(round(self.read_bsmp_variable(51, "float"), 3))
                    + " V"
                )
                print(
                    "IIB Cmd Auxiliary Board Current: "
                    + str(round(self.read_bsmp_variable(52, "float"), 3))
                    + " A"
                )
                print(
                    "IIB Cmd IDB Board Current: "
                    + str(round(self.read_bsmp_variable(53, "float"), 3))
                    + " A"
                )
                print(
                    "IIB Cmd Ground Leakage Current: "
                    + str(round(self.read_bsmp_variable(54, "float"), 3))
                    + " A"
                )
                print(
                    "IIB Cmd Board Temp: "
                    + str(round(self.read_bsmp_variable(55, "float"), 3))
                    + " °C"
                )
                print(
                    "IIB Cmd Board RH: "
                    + str(round(self.read_bsmp_variable(56, "float"), 3))
                    + " %"
                )
                print(
                    "IIB Cmd Interlocks: "
                    + str(round(self.read_bsmp_variable(57, "uint32_t"), 3))
                )
                print(
                    "IIB Cmd Alarms: "
                    + str(round(self.read_bsmp_variable(58, "uint32_t"), 3))
                )

            time.sleep(dt)

        # except:
        #    pass

    def read_vars_fac_dcdc(self, n=1, dt=0.5, iib=1):

        try:
            for i in range(n):

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                print(
                    "\nSync Pulse Counter: "
                    + str(round(self.read_bsmp_variable(5, "uint32_t"), 3))
                )
                print(
                    "WfmRef Index: "
                    + str(
                        (
                            round(self.read_bsmp_variable(20, "uint32_t"), 3)
                            - round(self.read_bsmp_variable(18, "uint32_t"), 3)
                        )
                        / 2
                        + 1
                    )
                )

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fac_dcdc_soft_interlocks)
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fac_dcdc_hard_interlocks)

                iib_itlks = self.read_bsmp_variable(51, "uint32_t")
                print("\nIIB Interlocks: " + str(iib_itlks))
                if iib_itlks:
                    self.decode_interlocks(
                        iib_itlks, list_fac_dcdc_iib_interlocks)

                iib_alarms = self.read_bsmp_variable(52, "uint32_t")
                print("IIB Alarms: " + str(iib_alarms))
                if iib_alarms:
                    self.decode_interlocks(
                        iib_alarms, list_fac_dcdc_iib_alarms)

                print(
                    "\nLoad Current: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " A"
                )
                print(
                    "Load Current DCCT 1: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )
                print(
                    "Load Current DCCT 2: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " A"
                )

                print(
                    "\nCapBank Voltage: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " V"
                )

                print(
                    "\nDuty-Cycle: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                    + " %"
                )

                if iib:
                    print(
                        "\nIIB CapBank Voltage: "
                        + str(round(self.read_bsmp_variable(38, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Input Current: "
                        + str(round(self.read_bsmp_variable(39, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Output Current: "
                        + str(round(self.read_bsmp_variable(40, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB IGBT Leg 1 Temp: "
                        + str(round(self.read_bsmp_variable(41, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IGBT Leg 2 Temp: "
                        + str(round(self.read_bsmp_variable(42, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Inductor Temp: "
                        + str(round(self.read_bsmp_variable(43, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Heat-Sink Temp: "
                        + str(round(self.read_bsmp_variable(44, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Driver Voltage: "
                        + str(round(self.read_bsmp_variable(45, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Driver Current 1: "
                        + str(round(self.read_bsmp_variable(46, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Driver Current 2: "
                        + str(round(self.read_bsmp_variable(47, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Ground Leakage Current: "
                        + str(round(self.read_bsmp_variable(48, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Board Temp: "
                        + str(round(self.read_bsmp_variable(49, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Board RH: "
                        + str(round(self.read_bsmp_variable(50, "float"), 3))
                        + " %"
                    )
                    print(
                        "IIB Interlocks: "
                        + str(round(self.read_bsmp_variable(51, "uint32_t"), 3))
                    )
                    print(
                        "IIB Alarms: "
                        + str(round(self.read_bsmp_variable(52, "uint32_t"), 3))
                    )

                time.sleep(dt)

        except:
            pass

    def read_vars_fac_dcdc_ema(self, n=1, dt=0.5, iib=0):

        try:
            for i in range(n):

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fac_dcdc_ema_soft_interlocks
                    )
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fac_dcdc_ema_hard_interlocks
                    )

                iib_itlks = self.read_bsmp_variable(49, "uint32_t")
                print("IIB Interlocks: " + str(iib_itlks))
                if iib_itlks:
                    self.decode_interlocks(
                        iib_itlks, list_fac_dcdc_ema_iib_interlocks)

                iib_alarms = self.read_bsmp_variable(50, "uint32_t")
                print("IIB Alarms: " + str(iib_alarms))
                if iib_alarms:
                    self.decode_interlocks(
                        iib_alarms, list_fac_dcdc_ema_iib_alarms)

                print(
                    "\nLoad Current: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                )
                print(
                    "DC-Link Voltage: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                )
                print(
                    "\nDuty-Cycle: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                )

                if iib:
                    print(
                        "\nIIB Input Voltage: "
                        + str(round(self.read_bsmp_variable(36, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Input Current: "
                        + str(round(self.read_bsmp_variable(37, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Output Current: "
                        + str(round(self.read_bsmp_variable(38, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB IGBT 1 Temp: "
                        + str(round(self.read_bsmp_variable(39, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IGBT 2 Temp: "
                        + str(round(self.read_bsmp_variable(40, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Inductor Temp: "
                        + str(round(self.read_bsmp_variable(41, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Heat-Sink Temp: "
                        + str(round(self.read_bsmp_variable(42, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Driver Voltage: "
                        + str(round(self.read_bsmp_variable(43, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Driver Current 1: "
                        + str(round(self.read_bsmp_variable(44, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Driver Current 2: "
                        + str(round(self.read_bsmp_variable(45, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Ground Leakage Current: "
                        + str(round(self.read_bsmp_variable(46, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Board Temp: "
                        + str(round(self.read_bsmp_variable(47, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Board RH: "
                        + str(round(self.read_bsmp_variable(48, "float"), 3))
                        + " %"
                    )
                    print(
                        "IIB Interlocks: "
                        + str(round(self.read_bsmp_variable(49, "uint32_t"), 3))
                    )
                    print(
                        "IIB Alarms: "
                        + str(round(self.read_bsmp_variable(50, "uint32_t"), 3))
                    )

                time.sleep(dt)

        except:
            pass

    def read_vars_fac_2s_acdc(self, n=1, add_mod_a=2, dt=0.5, iib=0):

        old_add = self.get_slave_add()

        try:
            for i in range(n):

                self.set_slave_add(add_mod_a)

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                print("\n *** MODULE A ***")

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fac_2s_acdc_soft_interlocks)
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fac_2s_acdc_hard_interlocks)

                iib_is_itlks = self.read_bsmp_variable(45, "uint32_t")
                print("\nIIB IS Interlocks: " + str(iib_is_itlks))
                if iib_is_itlks:
                    self.decode_interlocks(
                        iib_is_itlks, list_fac_2s_acdc_iib_is_interlocks
                    )

                iib_is_alarms = self.read_bsmp_variable(46, "uint32_t")
                print("IIB IS Alarms: " + str(iib_is_alarms))
                if iib_is_alarms:
                    self.decode_interlocks(
                        iib_is_alarms, list_fac_2s_acdc_iib_is_alarms
                    )

                iib_cmd_itlks = self.read_bsmp_variable(57, "uint32_t")
                print("\nIIB Cmd Interlocks: " + str(iib_cmd_itlks))
                if iib_cmd_itlks:
                    self.decode_interlocks(
                        iib_cmd_itlks, list_fac_2s_acdc_iib_cmd_interlocks
                    )

                iib_cmd_alarms = self.read_bsmp_variable(58, "uint32_t")
                print("IIB Cmd Alarms: " + str(iib_cmd_alarms))
                if iib_cmd_alarms:
                    self.decode_interlocks(
                        iib_cmd_alarms, list_fac_2s_acdc_iib_cmd_alarms
                    )

                print(
                    "\nCapBank Voltage: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " V"
                )
                print(
                    "Rectifier Current: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )
                print(
                    "Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " %"
                )

                if iib:
                    print(
                        "\nIIB IS Input Current: "
                        + str(round(self.read_bsmp_variable(36, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB IS Input Voltage: "
                        + str(round(self.read_bsmp_variable(37, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB IS IGBT Temp: "
                        + str(round(self.read_bsmp_variable(38, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IS Driver Voltage: "
                        + str(round(self.read_bsmp_variable(39, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB IS Driver Current: "
                        + str(round(self.read_bsmp_variable(40, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB IS Inductor Temp: "
                        + str(round(self.read_bsmp_variable(41, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IS Heat-Sink Temp: "
                        + str(round(self.read_bsmp_variable(42, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IS Board Temp: "
                        + str(round(self.read_bsmp_variable(43, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IS Board RH: "
                        + str(round(self.read_bsmp_variable(44, "float"), 3))
                        + " %"
                    )
                    print(
                        "IIB IS Interlocks: "
                        + str(round(self.read_bsmp_variable(45, "uint32_t"), 3))
                    )
                    print(
                        "IIB IS Alarms: "
                        + str(round(self.read_bsmp_variable(46, "uint32_t"), 3))
                    )

                    print(
                        "\nIIB Cmd Load Voltage: "
                        + str(round(self.read_bsmp_variable(47, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Cmd CapBank Voltage: "
                        + str(round(self.read_bsmp_variable(48, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Cmd Rectifier Inductor Temp: "
                        + str(round(self.read_bsmp_variable(49, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Cmd Rectifier Heat-Sink Temp: "
                        + str(round(self.read_bsmp_variable(50, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Cmd External Boards Voltage: "
                        + str(round(self.read_bsmp_variable(51, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Cmd Auxiliary Board Current: "
                        + str(round(self.read_bsmp_variable(52, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Cmd IDB Board Current: "
                        + str(round(self.read_bsmp_variable(53, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Cmd Ground Leakage Current: "
                        + str(round(self.read_bsmp_variable(54, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Cmd Board Temp: "
                        + str(round(self.read_bsmp_variable(55, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Cmd Board RH: "
                        + str(round(self.read_bsmp_variable(56, "float"), 3))
                        + " %"
                    )
                    print(
                        "IIB Cmd Interlocks: "
                        + str(round(self.read_bsmp_variable(57, "uint32_t"), 3))
                    )
                    print(
                        "IIB Cmd Alarms: "
                        + str(round(self.read_bsmp_variable(58, "uint32_t"), 3))
                    )

                self.set_slave_add(add_mod_a + 1)

                print("\n *** MODULE B ***")

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fac_2s_acdc_soft_interlocks)
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fac_2s_acdc_hard_interlocks)

                iib_is_itlks = self.read_bsmp_variable(45, "uint32_t")
                print("\nIIB IS Interlocks: " + str(iib_is_itlks))
                if iib_is_itlks:
                    self.decode_interlocks(
                        iib_is_itlks, list_fac_2s_acdc_iib_is_interlocks
                    )

                iib_is_alarms = self.read_bsmp_variable(46, "uint32_t")
                print("IIB IS Alarms: " + str(iib_is_alarms))
                if iib_is_alarms:
                    self.decode_interlocks(
                        iib_is_alarms, list_fac_2s_acdc_iib_is_alarms
                    )

                iib_cmd_itlks = self.read_bsmp_variable(57, "uint32_t")
                print("\nIIB Cmd Interlocks: " + str(iib_cmd_itlks))
                if iib_cmd_itlks:
                    self.decode_interlocks(
                        iib_cmd_itlks, list_fac_2s_acdc_iib_cmd_interlocks
                    )

                iib_cmd_alarms = self.read_bsmp_variable(58, "uint32_t")
                print("IIB Cmd Alarms: " + str(iib_cmd_alarms))
                if iib_cmd_alarms:
                    self.decode_interlocks(
                        iib_cmd_alarms, list_fac_2s_acdc_iib_cmd_alarms
                    )

                print(
                    "\nCapBank Voltage: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " V"
                )
                print(
                    "Rectifier Current: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )
                print(
                    "Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " %"
                )

                if iib:
                    print(
                        "\nIIB IS Input Current: "
                        + str(round(self.read_bsmp_variable(36, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB IS Input Voltage: "
                        + str(round(self.read_bsmp_variable(37, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB IS IGBT Temp: "
                        + str(round(self.read_bsmp_variable(38, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IS Driver Voltage: "
                        + str(round(self.read_bsmp_variable(39, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB IS Driver Current: "
                        + str(round(self.read_bsmp_variable(40, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB IS Inductor Temp: "
                        + str(round(self.read_bsmp_variable(41, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IS Heat-Sink Temp: "
                        + str(round(self.read_bsmp_variable(42, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IS Board Temp: "
                        + str(round(self.read_bsmp_variable(43, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IS Board RH: "
                        + str(round(self.read_bsmp_variable(44, "float"), 3))
                        + " %"
                    )
                    print(
                        "IIB IS Interlocks: "
                        + str(round(self.read_bsmp_variable(45, "uint32_t"), 3))
                    )
                    print(
                        "IIB IS Alarms: "
                        + str(round(self.read_bsmp_variable(46, "uint32_t"), 3))
                    )

                    print(
                        "\nIIB Cmd Load Voltage: "
                        + str(round(self.read_bsmp_variable(47, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Cmd CapBank Voltage: "
                        + str(round(self.read_bsmp_variable(48, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Cmd Rectifier Inductor Temp: "
                        + str(round(self.read_bsmp_variable(49, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Cmd Rectifier Heat-Sink Temp: "
                        + str(round(self.read_bsmp_variable(50, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Cmd External Boards Voltage: "
                        + str(round(self.read_bsmp_variable(51, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Cmd Auxiliary Board Current: "
                        + str(round(self.read_bsmp_variable(52, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Cmd IDB Board Current: "
                        + str(round(self.read_bsmp_variable(53, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Cmd Ground Leakage Current: "
                        + str(round(self.read_bsmp_variable(54, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Cmd Board Temp: "
                        + str(round(self.read_bsmp_variable(55, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Cmd Board RH: "
                        + str(round(self.read_bsmp_variable(56, "float"), 3))
                        + " %"
                    )
                    print(
                        "IIB Cmd Interlocks: "
                        + str(round(self.read_bsmp_variable(57, "uint32_t"), 3))
                    )
                    print(
                        "IIB Cmd Alarms: "
                        + str(round(self.read_bsmp_variable(58, "uint32_t"), 3))
                    )

                time.sleep(dt)

            self.set_slave_add(old_add)
        except:
            self.set_slave_add(old_add)

    def read_vars_fac_2s_dcdc(self, n=1, com_add=1, dt=0.5, iib=0):

        old_add = self.get_slave_add()
        iib_offset = 14 * (iib - 1)

        try:
            for i in range(n):

                self.set_slave_add(com_add)

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )

                self.read_vars_common()

                print(
                    "\nSync Pulse Counter: "
                    + str(round(self.read_bsmp_variable(5, "uint32_t"), 3))
                )

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fac_2s_dcdc_soft_interlocks)
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fac_2s_dcdc_hard_interlocks)

                print(
                    "\nLoad Current: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " A"
                )
                print(
                    "Load Current DCCT 1: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )
                print(
                    "Load Current DCCT 2: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " A"
                )

                print(
                    "\nCapBank Voltage 1: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " V"
                )
                print(
                    "CapBank Voltage 2: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                    + " V"
                )

                print(
                    "\nDuty-Cycle 1: "
                    + str(round(self.read_bsmp_variable(38, "float"), 3))
                    + " %"
                )
                print(
                    "Duty-Cycle 2: "
                    + str(round(self.read_bsmp_variable(39, "float"), 3))
                    + " %"
                )

                if iib:
                    print(
                        "\nIIB CapBank Voltage: "
                        + str(
                            round(self.read_bsmp_variable(
                                40 + iib_offset, "float"), 3)
                        )
                        + " V"
                    )
                    print(
                        "IIB Input Current: "
                        + str(
                            round(self.read_bsmp_variable(
                                41 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB Output Current: "
                        + str(
                            round(self.read_bsmp_variable(
                                42 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB IGBT Leg 1 Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                43 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB IGBT Leg 2 Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                44 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB Inductor Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                45 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB Heat-Sink Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                46 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB Driver Voltage: "
                        + str(
                            round(self.read_bsmp_variable(
                                47 + iib_offset, "float"), 3)
                        )
                        + " V"
                    )
                    print(
                        "IIB Driver Current 1: "
                        + str(
                            round(self.read_bsmp_variable(
                                48 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB Driver Current 2: "
                        + str(
                            round(self.read_bsmp_variable(
                                49 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB Board Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                50 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB Board RH: "
                        + str(
                            round(self.read_bsmp_variable(
                                51 + iib_offset, "float"), 3)
                        )
                        + " %"
                    )

                    iib_itlks = self.read_bsmp_variable(
                        52 + iib_offset, "uint32_t")
                    print("\nIIB Interlocks: " + str(iib_itlks))
                    if iib_itlks:
                        self.decode_interlocks(
                            iib_itlks, list_fac_2s_dcdc_iib_interlocks
                        )

                    iib_alarms = self.read_bsmp_variable(
                        53 + iib_offset, "uint32_t")
                    print("IIB Alarms: " + str(iib_alarms))
                    if iib_alarms:
                        self.decode_interlocks(
                            iib_alarms, list_fac_2s_dcdc_iib_alarms)

                time.sleep(dt)

            self.set_slave_add(old_add)
        except:
            self.set_slave_add(old_add)

    def read_vars_fac_2p4s_acdc(self, n=1, add_mod_a=1, dt=0.5, iib=0):
        self.read_vars_fac_2s_acdc(n, add_mod_a, dt, iib)

    def read_vars_fac_2p4s_dcdc(self, n=1, com_add=1, dt=0.5, iib=0):

        old_add = self.get_slave_add()

        try:
            for i in range(n):

                self.set_slave_add(com_add)

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )

                self.read_vars_common()

                print(
                    "\nSync Pulse Counter: "
                    + str(round(self.read_bsmp_variable(5, "uint32_t"), 3))
                )

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fac_2p4s_dcdc_soft_interlocks
                    )
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fac_2p4s_dcdc_hard_interlocks
                    )

                print(
                    "\nLoad Current: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                )
                print(
                    "Load Current DCCT 1: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                )
                print(
                    "Load Current DCCT 2: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                )

                print(
                    "\nArm Current 1: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                )
                print(
                    "Arm Current 2: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                )

                print(
                    "\nCapBank Voltage 1: "
                    + str(round(self.read_bsmp_variable(38, "float"), 3))
                )
                print(
                    "CapBank Voltage 2: "
                    + str(round(self.read_bsmp_variable(39, "float"), 3))
                )
                print(
                    "CapBank Voltage 3: "
                    + str(round(self.read_bsmp_variable(40, "float"), 3))
                )
                print(
                    "CapBank Voltage 4: "
                    + str(round(self.read_bsmp_variable(41, "float"), 3))
                )
                print(
                    "CapBank Voltage 5: "
                    + str(round(self.read_bsmp_variable(42, "float"), 3))
                )
                print(
                    "CapBank Voltage 6: "
                    + str(round(self.read_bsmp_variable(43, "float"), 3))
                )
                print(
                    "CapBank Voltage 7: "
                    + str(round(self.read_bsmp_variable(44, "float"), 3))
                )
                print(
                    "CapBank Voltage 8: "
                    + str(round(self.read_bsmp_variable(45, "float"), 3))
                )

                print(
                    "\nDuty-Cycle 1: "
                    + str(round(self.read_bsmp_variable(46, "float"), 3))
                )
                print(
                    "Duty-Cycle 2: "
                    + str(round(self.read_bsmp_variable(47, "float"), 3))
                )
                print(
                    "Duty-Cycle 3: "
                    + str(round(self.read_bsmp_variable(48, "float"), 3))
                )
                print(
                    "Duty-Cycle 4: "
                    + str(round(self.read_bsmp_variable(49, "float"), 3))
                )
                print(
                    "Duty-Cycle 5: "
                    + str(round(self.read_bsmp_variable(50, "float"), 3))
                )
                print(
                    "Duty-Cycle 6: "
                    + str(round(self.read_bsmp_variable(51, "float"), 3))
                )
                print(
                    "Duty-Cycle 7: "
                    + str(round(self.read_bsmp_variable(52, "float"), 3))
                )
                print(
                    "Duty-Cycle 8: "
                    + str(round(self.read_bsmp_variable(53, "float"), 3))
                )

                if iib:

                    print(
                        "\nIIB CapBank Voltage: "
                        + str(round(self.read_bsmp_variable(54, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Input Current: "
                        + str(round(self.read_bsmp_variable(55, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Output Current: "
                        + str(round(self.read_bsmp_variable(56, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB IGBT Leg 1 Temp: "
                        + str(round(self.read_bsmp_variable(57, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IGBT Leg 2 Temp: "
                        + str(round(self.read_bsmp_variable(58, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Inductor Temp: "
                        + str(round(self.read_bsmp_variable(59, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Heat-Sink Temp: "
                        + str(round(self.read_bsmp_variable(60, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Driver Voltage: "
                        + str(round(self.read_bsmp_variable(61, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Driver Current 1: "
                        + str(round(self.read_bsmp_variable(62, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Driver Current 2: "
                        + str(round(self.read_bsmp_variable(63, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Board Temp: "
                        + str(round(self.read_bsmp_variable(64, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Board RH: "
                        + str(round(self.read_bsmp_variable(65, "float"), 3))
                        + " %"
                    )

                    iib_itlks = self.read_bsmp_variable(66, "uint32_t")
                    print("\nIIB Interlocks: " + str(iib_itlks))
                    if iib_itlks:
                        self.decode_interlocks(
                            iib_itlks, list_fac_2p4s_dcdc_iib_interlocks
                        )

                    iib_alarms = self.read_bsmp_variable(67, "uint32_t")
                    print("IIB Alarms: " + str(iib_alarms))
                    if iib_alarms:
                        self.decode_interlocks(
                            iib_alarms, list_fac_2p4s_dcdc_iib_alarms
                        )

                    print(
                        "\nIIB CapBank Voltage: "
                        + str(round(self.read_bsmp_variable(68, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Input Current: "
                        + str(round(self.read_bsmp_variable(69, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Output Current: "
                        + str(round(self.read_bsmp_variable(70, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB IGBT Leg 1 Temp: "
                        + str(round(self.read_bsmp_variable(71, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IGBT Leg 2 Temp: "
                        + str(round(self.read_bsmp_variable(72, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Inductor Temp: "
                        + str(round(self.read_bsmp_variable(73, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Heat-Sink Temp: "
                        + str(round(self.read_bsmp_variable(74, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Driver Voltage: "
                        + str(round(self.read_bsmp_variable(75, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Driver Current 1: "
                        + str(round(self.read_bsmp_variable(76, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Driver Current 2: "
                        + str(round(self.read_bsmp_variable(77, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Board Temp: "
                        + str(round(self.read_bsmp_variable(78, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Board RH: "
                        + str(round(self.read_bsmp_variable(79, "float"), 3))
                        + " %"
                    )

                    iib_itlks = self.read_bsmp_variable(80, "uint32_t")
                    print("\nIIB Interlocks: " + str(iib_itlks))
                    if iib_itlks:
                        self.decode_interlocks(
                            iib_itlks, list_fac_2p4s_dcdc_iib_interlocks
                        )

                    iib_alarms = self.read_bsmp_variable(81, "uint32_t")
                    print("IIB Alarms: " + str(iib_alarms))
                    if iib_alarms:
                        self.decode_interlocks(
                            iib_alarms, list_fac_2p4s_dcdc_iib_alarms
                        )

                time.sleep(dt)

            self.set_slave_add(old_add)
        except:
            self.set_slave_add(old_add)

    def read_vars_fap(self, n=1, com_add=1, dt=0.5, iib=1):

        old_add = self.get_slave_add()

        try:
            for i in range(n):

                self.set_slave_add(com_add)

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fap_soft_interlocks)
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fap_hard_interlocks)

                iib_itlks = self.read_bsmp_variable(56, "uint32_t")
                print("\nIIB Interlocks: " + str(iib_itlks))
                if iib_itlks:
                    self.decode_interlocks(iib_itlks, list_fap_iib_interlocks)

                iib_alarms = self.read_bsmp_variable(57, "uint32_t")
                print("\nIIB Alarms: " + str(iib_alarms))
                if iib_alarms:
                    self.decode_interlocks(iib_alarms, list_fap_iib_alarms)

                iload = self.read_bsmp_variable(33, "float")

                print("\nLoad Current: " + str(round(iload, 3)) + " A")
                print(
                    "Load Current DCCT 1: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )
                print(
                    "Load Current DCCT 2: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " A"
                )

                if not iload == 0:
                    print(
                        "\nLoad Resistance: "
                        + str(
                            abs(round(self.read_bsmp_variable(
                                43, "float") / iload, 3))
                        )
                        + " Ohm"
                    )
                else:
                    print("\nLoad Resistance: 0 Ohm")
                print(
                    "Load Power: "
                    + str(
                        abs(
                            round(
                                self.read_bsmp_variable(43, "float")
                                * self.read_bsmp_variable(33, "float"),
                                3,
                            )
                        )
                    )
                    + " W"
                )

                print(
                    "\nDC-Link Voltage: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " V"
                )
                print(
                    "\nIGBT 1 Current: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 2 Current: "
                    + str(round(self.read_bsmp_variable(38, "float"), 3))
                    + " A"
                )
                print(
                    "\nIGBT 1 Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(39, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 2 Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(40, "float"), 3))
                    + " %"
                )
                print(
                    "Differential Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(41, "float"), 3))
                    + " %"
                )

                if iib:
                    print(
                        "\nIIB Input Voltage: "
                        + str(round(self.read_bsmp_variable(42, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Output Voltage: "
                        + str(round(self.read_bsmp_variable(43, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB IGBT 1 Current: "
                        + str(round(self.read_bsmp_variable(44, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB IGBT 2 Current: "
                        + str(round(self.read_bsmp_variable(45, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB IGBT 1 Temp: "
                        + str(round(self.read_bsmp_variable(46, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB IGBT 2 Temp: "
                        + str(round(self.read_bsmp_variable(47, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Driver Voltage: "
                        + str(round(self.read_bsmp_variable(48, "float"), 3))
                        + " V"
                    )
                    print(
                        "IIB Driver Current 1: "
                        + str(round(self.read_bsmp_variable(49, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Driver Current 2: "
                        + str(round(self.read_bsmp_variable(50, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Inductor Temp: "
                        + str(round(self.read_bsmp_variable(51, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Heat-Sink Temp: "
                        + str(round(self.read_bsmp_variable(52, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Ground Leakage Current: "
                        + str(round(self.read_bsmp_variable(53, "float"), 3))
                        + " A"
                    )
                    print(
                        "IIB Board Temp: "
                        + str(round(self.read_bsmp_variable(54, "float"), 3))
                        + " °C"
                    )
                    print(
                        "IIB Board RH: "
                        + str(round(self.read_bsmp_variable(55, "float"), 3))
                        + " %"
                    )
                    print(
                        "IIB Interlocks: "
                        + str(round(self.read_bsmp_variable(56, "uint32_t"), 3))
                    )
                    print(
                        "IIB Alarms: "
                        + str(round(self.read_bsmp_variable(57, "uint32_t"), 3))
                    )
                time.sleep(dt)

            self.set_slave_add(old_add)
        except:
            self.set_slave_add(old_add)

    def read_vars_fap_4p(self, n=1, com_add=1, dt=0.5, iib=0):

        old_add = self.get_slave_add()
        iib_offset = 16 * (iib - 1)

        try:
            for i in range(n):

                self.set_slave_add(com_add)

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fap_4p_soft_interlocks)
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fap_4p_hard_interlocks)

                for j in range(4):
                    iib_itlks = self.read_bsmp_variable(
                        72 + j * 16, "uint32_t")
                    print("\nIIB " + str(j + 1) +
                          " Interlocks: " + str(iib_itlks))
                    if iib_itlks:
                        self.decode_interlocks(
                            iib_itlks, list_fap_4p_iib_interlocks)

                    iib_alarms = self.read_bsmp_variable(
                        73 + j * 16, "uint32_t")
                    print("IIB " + str(j + 1) + " Alarms: " + str(iib_alarms))
                    if iib_alarms:
                        self.decode_interlocks(
                            iib_alarms, list_fap_4p_iib_alarms)

                print(
                    "\n Mean Load Current: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " A"
                )
                print(
                    "Load Current 1: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )
                print(
                    "Load Current 2: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " A"
                )

                print(
                    "Load Voltage: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " V"
                )

                print(
                    "\nIGBT 1 Current Mod 1: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 2 Current Mod 1: "
                    + str(round(self.read_bsmp_variable(38, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 1 Current Mod 2: "
                    + str(round(self.read_bsmp_variable(39, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 2 Current Mod 2: "
                    + str(round(self.read_bsmp_variable(40, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 1 Current Mod 3: "
                    + str(round(self.read_bsmp_variable(41, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 2 Current Mod 3: "
                    + str(round(self.read_bsmp_variable(42, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 1 Current Mod 4: "
                    + str(round(self.read_bsmp_variable(43, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 2 Current Mod 4: "
                    + str(round(self.read_bsmp_variable(44, "float"), 3))
                    + " A"
                )

                print(
                    "\nDC-Link Voltage Mod 1: "
                    + str(round(self.read_bsmp_variable(45, "float"), 3))
                    + " V"
                )
                print(
                    "DC-Link Voltage Mod 2: "
                    + str(round(self.read_bsmp_variable(46, "float"), 3))
                    + " V"
                )
                print(
                    "DC-Link Voltage Mod 3: "
                    + str(round(self.read_bsmp_variable(47, "float"), 3))
                    + " V"
                )
                print(
                    "DC-Link Voltage Mod 4: "
                    + str(round(self.read_bsmp_variable(48, "float"), 3))
                    + " V"
                )

                print(
                    "\nMean Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(49, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 1 Duty-Cycle Mod 1: "
                    + str(round(self.read_bsmp_variable(50, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 2 Duty-Cycle Mod 1: "
                    + str(round(self.read_bsmp_variable(51, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 1 Duty-Cycle Mod 2: "
                    + str(round(self.read_bsmp_variable(52, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 2 Duty-Cycle Mod 2: "
                    + str(round(self.read_bsmp_variable(53, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 1 Duty-Cycle Mod 3: "
                    + str(round(self.read_bsmp_variable(54, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 2 Duty-Cycle Mod 3: "
                    + str(round(self.read_bsmp_variable(55, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 1 Duty-Cycle Mod 4: "
                    + str(round(self.read_bsmp_variable(56, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 2 Duty-Cycle Mod 4: "
                    + str(round(self.read_bsmp_variable(57, "float"), 3))
                    + " %"
                )

                if not iib == 0:
                    print(
                        "\nIIB "
                        + str(iib)
                        + " Input Voltage: "
                        + str(
                            round(self.read_bsmp_variable(
                                58 + iib_offset, "float"), 3)
                        )
                        + " V"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Output Voltage: "
                        + str(
                            round(self.read_bsmp_variable(
                                59 + iib_offset, "float"), 3)
                        )
                        + " V"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " IGBT 1 Current: "
                        + str(
                            round(self.read_bsmp_variable(
                                60 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " IGBT 2 Current: "
                        + str(
                            round(self.read_bsmp_variable(
                                61 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " IGBT 1 Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                62 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " IGBT 2 Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                63 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Driver Voltage: "
                        + str(
                            round(self.read_bsmp_variable(
                                64 + iib_offset, "float"), 3)
                        )
                        + " V"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Driver Current 1: "
                        + str(
                            round(self.read_bsmp_variable(
                                65 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Driver Current 2: "
                        + str(
                            round(self.read_bsmp_variable(
                                66 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Inductor Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                67 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Heat-Sink Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                68 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Ground Leakage Current: "
                        + str(
                            round(self.read_bsmp_variable(
                                69 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Board Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                70 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Board RH: "
                        + str(
                            round(self.read_bsmp_variable(
                                71 + iib_offset, "float"), 3)
                        )
                        + " %"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Interlocks: "
                        + str(
                            round(
                                self.read_bsmp_variable(
                                    72 + iib_offset, "uint32_t"), 3
                            )
                        )
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Alarms: "
                        + str(
                            round(
                                self.read_bsmp_variable(
                                    73 + iib_offset, "uint32_t"), 3
                            )
                        )
                    )

                time.sleep(dt)

            self.set_slave_add(old_add)

        except Exception as e:
            print(e)
            self.set_slave_add(old_add)

    def read_vars_fap_2p2s(self, n=1, com_add=1, dt=0.5, iib=0):

        old_add = self.get_slave_add()
        iib_offset = 16 * (iib - 1)

        try:
            for i in range(n):

                self.set_slave_add(com_add)

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fap_2p2s_soft_interlocks)
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fap_2p2s_hard_interlocks)

                for j in range(4):
                    iib_itlks = self.read_bsmp_variable(
                        78 + j * 16, "uint32_t")
                    print("\nIIB " + str(j + 1) +
                          " Interlocks: " + str(iib_itlks))
                    if iib_itlks:
                        self.decode_interlocks(
                            iib_itlks, list_fap_4p_iib_interlocks)

                    iib_alarms = self.read_bsmp_variable(
                        79 + j * 16, "uint32_t")
                    print("IIB " + str(j + 1) + " Alarms: " + str(iib_alarms))
                    if iib_alarms:
                        self.decode_interlocks(
                            iib_alarms, list_fap_4p_iib_alarms)

                print(
                    "\nMean Load Current: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " A"
                )
                print(
                    "Load Current 1: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )
                print(
                    "Load Current 2: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " A"
                )

                print(
                    "\nArm Current 1: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " A"
                )
                print(
                    "Arm Current 2: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                    + " A"
                )

                print(
                    "\nIGBT 1 Current Mod 1: "
                    + str(round(self.read_bsmp_variable(38, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 2 Current Mod 1: "
                    + str(round(self.read_bsmp_variable(39, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 1 Current Mod 2: "
                    + str(round(self.read_bsmp_variable(40, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 2 Current Mod 2: "
                    + str(round(self.read_bsmp_variable(41, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 1 Current Mod 3: "
                    + str(round(self.read_bsmp_variable(42, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 2 Current Mod 3: "
                    + str(round(self.read_bsmp_variable(43, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 1 Current Mod 4: "
                    + str(round(self.read_bsmp_variable(44, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 2 Current Mod 4: "
                    + str(round(self.read_bsmp_variable(45, "float"), 3))
                    + " A"
                )

                print(
                    "\nDC-Link Voltage Mod 1: "
                    + str(round(self.read_bsmp_variable(50, "float"), 3))
                    + " V"
                )
                print(
                    "DC-Link Voltage Mod 2: "
                    + str(round(self.read_bsmp_variable(51, "float"), 3))
                    + " V"
                )
                print(
                    "DC-Link Voltage Mod 3: "
                    + str(round(self.read_bsmp_variable(52, "float"), 3))
                    + " V"
                )
                print(
                    "DC-Link Voltage Mod 4: "
                    + str(round(self.read_bsmp_variable(53, "float"), 3))
                    + " V"
                )

                print(
                    "\nMean Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(54, "float"), 3))
                    + " %"
                )
                print(
                    "Differential Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(55, "float"), 3))
                    + " %"
                )
                print(
                    "\nIGBT 1 Duty-Cycle Mod 1: "
                    + str(round(self.read_bsmp_variable(56, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 2 Duty-Cycle Mod 1: "
                    + str(round(self.read_bsmp_variable(57, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 1 Duty-Cycle Mod 2: "
                    + str(round(self.read_bsmp_variable(58, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 2 Duty-Cycle Mod 2: "
                    + str(round(self.read_bsmp_variable(59, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 1 Duty-Cycle Mod 3: "
                    + str(round(self.read_bsmp_variable(60, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 2 Duty-Cycle Mod 3: "
                    + str(round(self.read_bsmp_variable(61, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 1 Duty-Cycle Mod 4: "
                    + str(round(self.read_bsmp_variable(62, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 2 Duty-Cycle Mod 4: "
                    + str(round(self.read_bsmp_variable(63, "float"), 3))
                    + " %"
                )

                if not iib == 0:
                    print(
                        "\nIIB "
                        + str(iib)
                        + " Input Voltage: "
                        + str(
                            round(self.read_bsmp_variable(
                                64 + iib_offset, "float"), 3)
                        )
                        + " V"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Output Voltage: "
                        + str(
                            round(self.read_bsmp_variable(
                                65 + iib_offset, "float"), 3)
                        )
                        + " V"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " IGBT 1 Current: "
                        + str(
                            round(self.read_bsmp_variable(
                                66 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " IGBT 2 Current: "
                        + str(
                            round(self.read_bsmp_variable(
                                67 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " IGBT 1 Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                68 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " IGBT 2 Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                69 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Driver Voltage: "
                        + str(
                            round(self.read_bsmp_variable(
                                70 + iib_offset, "float"), 3)
                        )
                        + " V"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Driver Current 1: "
                        + str(
                            round(self.read_bsmp_variable(
                                71 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Driver Current 2: "
                        + str(
                            round(self.read_bsmp_variable(
                                72 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Inductor Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                73 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Heat-Sink Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                74 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Ground Leakage Current: "
                        + str(
                            round(self.read_bsmp_variable(
                                75 + iib_offset, "float"), 3)
                        )
                        + " A"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Board Temp: "
                        + str(
                            round(self.read_bsmp_variable(
                                76 + iib_offset, "float"), 3)
                        )
                        + " °C"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Board RH: "
                        + str(
                            round(self.read_bsmp_variable(
                                77 + iib_offset, "float"), 3)
                        )
                        + " %"
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Interlocks: "
                        + str(
                            round(
                                self.read_bsmp_variable(
                                    78 + iib_offset, "uint32_t"), 3
                            )
                        )
                    )
                    print(
                        "IIB "
                        + str(iib)
                        + " Alarms: "
                        + str(
                            round(
                                self.read_bsmp_variable(
                                    79 + iib_offset, "uint32_t"), 3
                            )
                        )
                    )

                time.sleep(dt)

            self.set_slave_add(old_add)

        except Exception as e:
            print(e)
            self.set_slave_add(old_add)

    def read_vars_fap_225A(self, n=1, com_add=1, dt=0.5):

        old_add = self.get_slave_add()

        try:
            for i in range(n):

                self.set_slave_add(com_add)

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fap_225A_soft_interlocks)
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fap_225A_hard_interlocks)

                print(
                    "\nLoad Current: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " A"
                )
                print(
                    "\nIGBT 1 Current: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )
                print(
                    "IGBT 2 Current: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " A"
                )
                print(
                    "\nIGBT 1 Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " %"
                )
                print(
                    "IGBT 2 Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                    + " %"
                )
                print(
                    "Differential Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(38, "float"), 3))
                    + " %"
                )

                time.sleep(dt)

            self.set_slave_add(old_add)
        except:
            self.set_slave_add(old_add)

    def read_vars_fbp_2s_ufjf(self, n=1, com_add=1, dt=0.5):

        old_add = self.get_slave_add()

        try:
            for i in range(n):

                self.set_slave_add(com_add)

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fbp_soft_interlocks)
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fbp_hard_interlocks)

                print(
                    "\nLoad Current: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " A"
                )
                print(
                    "Load Error: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )

                print(
                    "\nMod 1 Load Voltage: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " V"
                )
                print(
                    "Mod 3 Load Voltage: "
                    + str(round(self.read_bsmp_variable(40, "float"), 3))
                    + " V"
                )

                # print("\nMod 1 DC-Link Voltage: " + str(round(self.read_bsmp_variable(29,'float'),3)) + " V")
                # print("Mod 1 Temperature: " + str(round(self.read_bsmp_variable(31,'float'),3)) + " °C")

                # print("\nMod 3 DC-Link Voltage: " + str(round(self.read_bsmp_variable(33,'float'),3)) + " V")
                # print("Mod 3 Temperature: " + str(round(self.read_bsmp_variable(35,'float'),3)) + " °C")

                print(
                    "\nMod 1 Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(32, "float"), 3))
                    + " %"
                )
                print(
                    "Mod 3 Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " %"
                )

                time.sleep(dt)

            self.set_slave_add(old_add)
        except:
            self.set_slave_add(old_add)

    def read_vars_fac_2p_acdc_imas(self, n=1, add_mod_a=2, dt=0.5, iib=0):

        old_add = self.get_slave_add()

        try:
            for i in range(n):

                self.set_slave_add(add_mod_a)

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.read_vars_common()

                print("\n *** MODULE A ***")

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fac_2p_acdc_imas_soft_interlocks
                    )
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fac_2p_acdc_imas_hard_interlocks
                    )

                print(
                    "\nCapBank Voltage: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " V"
                )
                print(
                    "Rectifier Current: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )
                print(
                    "Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " %"
                )

                self.set_slave_add(add_mod_a + 1)

                print("\n *** MODULE B ***")

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fac_2p_acdc_imas_soft_interlocks
                    )
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fac_2p_acdc_imas_hard_interlocks
                    )

                print(
                    "\nCapBank Voltage: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " V"
                )
                print(
                    "Rectifier Current: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )
                print(
                    "Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " %"
                )

                time.sleep(dt)

            self.set_slave_add(old_add)
        except:
            self.set_slave_add(old_add)
            raise

    def read_vars_fac_2p_dcdc_imas(self, n=1, com_add=1, dt=0.5, iib=0):

        old_add = self.get_slave_add()

        try:
            for i in range(n):

                self.set_slave_add(com_add)

                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )

                self.read_vars_common()

                print(
                    "\nSync Pulse Counter: "
                    + str(round(self.read_bsmp_variable(5, "uint32_t"), 3))
                )

                soft_itlks = self.read_bsmp_variable(31, "uint32_t")
                print("\nSoft Interlocks: " + str(soft_itlks))
                if soft_itlks:
                    self.decode_interlocks(
                        soft_itlks, list_fac_2p_dcdc_imas_soft_interlocks
                    )
                    print("")

                hard_itlks = self.read_bsmp_variable(32, "uint32_t")
                print("Hard Interlocks: " + str(hard_itlks))
                if hard_itlks:
                    self.decode_interlocks(
                        hard_itlks, list_fac_2p_dcdc_imas_hard_interlocks
                    )

                print(
                    "\nLoad Current: "
                    + str(round(self.read_bsmp_variable(33, "float"), 3))
                    + " A"
                )
                print(
                    "Load Current Error: "
                    + str(round(self.read_bsmp_variable(34, "float"), 3))
                    + " A"
                )

                print(
                    "\nArm 1 Current: "
                    + str(round(self.read_bsmp_variable(35, "float"), 3))
                    + " A"
                )
                print(
                    "Arm 2 Current: "
                    + str(round(self.read_bsmp_variable(36, "float"), 3))
                    + " A"
                )
                print(
                    "Arms Current Diff: "
                    + str(round(self.read_bsmp_variable(37, "float"), 3))
                    + " A"
                )

                print(
                    "\nCapBank Voltage 1: "
                    + str(round(self.read_bsmp_variable(38, "float"), 3))
                    + " V"
                )
                print(
                    "CapBank Voltage 2: "
                    + str(round(self.read_bsmp_variable(39, "float"), 3))
                    + " V"
                )

                print(
                    "\nDuty-Cycle 1: "
                    + str(round(self.read_bsmp_variable(40, "float"), 3))
                    + " %"
                )
                print(
                    "Duty-Cycle 2: "
                    + str(round(self.read_bsmp_variable(41, "float"), 3))
                    + " %"
                )
                print(
                    "Differential Duty-Cycle: "
                    + str(round(self.read_bsmp_variable(42, "float"), 3))
                    + " %"
                )

                time.sleep(dt)

            self.set_slave_add(old_add)
        except:
            self.set_slave_add(old_add)
            raise

    def check_param_bank(self, param_file):
        fbp_param_list = []

        max_sampling_freq = 600000
        c28_sysclk = 150e6

        with open(param_file, newline="") as f:
            reader = csv.reader(f)
            for row in reader:
                fbp_param_list.append(row)

        for param in fbp_param_list:
            if str(param[0]) == "Num_PS_Modules" and param[1] > 4:
                print(
                    "Invalid " + str(param[0]) + ": " +
                    str(param[1]) + ". Maximum is 4"
                )

            elif str(param[0]) == "Freq_ISR_Controller" and param[1] > 6000000:
                print(
                    "Invalid " + str(param[0]) + ": " +
                    str(param[1]) + ". Maximum is 4"
                )

            else:
                for n in range(64):
                    try:
                        print(str(param[0]) + "[" + str(n) +
                              "]: " + str(param[n + 1]))
                        print(self.set_param(
                            str(param[0]), n, float(param[n + 1])))
                    except:
                        break

    def get_default_ramp_waveform(
        self, interval=500, nrpts=4000, ti=None, fi=None, forms=None
    ):
        from siriuspy.magnet.util import get_default_ramp_waveform

        return get_default_ramp_waveform(interval, nrpts, ti, fi, forms)

    def save_ramp_waveform(self, ramp):
        filename = input("Digite o nome do arquivo: ")
        with open(filename + ".csv", "w", newline="") as f:
            writer = csv.writer(f, delimiter=";")
            writer.writerow(ramp)

    def save_ramp_waveform_col(self, ramp):
        filename = input("Digite o nome do arquivo: ")
        with open(filename + ".csv", "w", newline="") as f:
            writer = csv.writer(f)
            for val in ramp:
                writer.writerow([val])

    def read_vars_fac_n(self, n=1, dt=0.5):
        old_add = self.get_slave_add()
        try:
            for i in range(n):
                print(
                    "\n--- Measurement #"
                    + str(i + 1)
                    + " ------------------------------------------\n"
                )
                self.set_slave_add(1)
                self.read_vars_fac_dcdc()
                print("\n-----------------------\n")
                self.set_slave_add(2)
                self.read_vars_fac_acdc()
                time.sleep(dt)
            self.set_slave_add(old_add)
        except:
            self.set_slave_add(old_add)

    def get_step_buffer_fbp_ufjf(self, net1, net2, i_0, i_f, dly):
        self.set_param("Analog_Var_Max", 4, net1)
        self.set_param("Analog_Var_Max", 5, net2)
        self.set_slowref(i_0)
        time.sleep(0.5)
        self.enable_buf_samples()
        time.sleep(dly)
        self.set_slowref(i_f)
        self.disable_buf_samples()
        buf = self.read_buf_samples_ctom()
        buf1 = buf[0:4096:2]
        buf2 = buf[1:4096:2]
        fig = plt.figure()
        ax1 = fig.add_subplot(2, 1, 1)
        ax2 = fig.add_subplot(2, 1, 2)
        ax1.plot(buf1)
        ax1.grid()
        ax2.plot(buf2)
        ax2.grid()
        fig.show()
        return [buf1, buf2]

    def set_buf_samples_freq(self, fs):
        self.set_param("Freq_TimeSlicer", 1, fs)
        self.save_param_eeprom("Freq_TimeSlicer", 1)
        self.reset_udc()

    def calc_pi(self, r_load, l_load, f_bw, v_dclink, send_drs=0, dsp_id=0):
        kp = 2 * 3.1415 * f_bw * l_load / v_dclink
        ki = kp * r_load / l_load
        print("\n  Kp = " + str(kp))
        print("  Ki = " + str(ki) + "\n")
        if send_drs:
            self.set_dsp_coeffs(3, dsp_id, [kp, ki, 0.95, -0.95])
        return [kp, ki]

    def config_dsp_modules_drs_fap_tests(self):
        kp_load = 0
        ki_load = 20.95
        kp_share = 0.000032117
        ki_share = 0.0012

        drs.set_dsp_coeffs(3, 0, [kp_load, ki_load, 0.6, 0])
        drs.set_dsp_coeffs(3, 1, [kp_share, ki_share, 0.0015, -0.0015])
        drs.save_dsp_modules_eeprom()

    def set_prbs_sampling_freq(self, freq, type_memory):
        self.set_param("Freq_TimeSlicer", 0, freq)
        self.set_param("Freq_TimeSlicer", 1, freq)
        self.save_param_bank(type_memory)

    def get_dsp_modules_bank(
        self, list_dsp_classes=[1, 2, 3, 4, 5, 6], print_modules=1
    ):
        dsp_modules_bank = []
        for dsp_class in list_dsp_classes:
            for dsp_id in range(num_dsp_modules[dsp_class]):
                dsp_module = [dsp_classes_names[dsp_class], dsp_class, dsp_id]
                for dsp_coeff in range(num_coeffs_dsp_modules[dsp_class]):
                    try:
                        coeff = self.get_dsp_coeff(
                            dsp_class, dsp_id, dsp_coeff)
                        if dsp_class == 3 and dsp_coeff == 1:
                            coeff *= self.get_param("Freq_ISR_Controller", 0)
                        dsp_module.append(coeff)
                    except:
                        dsp_module.append("nan")
                dsp_modules_bank.append(dsp_module)
                if print_modules:
                    print(dsp_module)

        return dsp_modules_bank

    def store_dsp_modules_bank_csv(self, bank):
        filename = input("Digite o nome do arquivo: ")
        with open(filename + ".csv", "w", newline="") as f:
            writer = csv.writer(f, delimiter=",")
            for dsp_module in bank:
                writer.writerow(dsp_module)

    def set_dsp_modules_bank(self, dsp_modules_file, save_eeprom=0):
        dsp_modules_row = []
        with open(dsp_modules_file, newline="") as f:
            reader = csv.reader(f)

            for dsp_module in reader:
                if not dsp_module == []:
                    if not dsp_module[0][0] == "#":
                        list_coeffs = []

                        for coeff in dsp_module[
                            3: 3 + num_coeffs_dsp_modules[int(dsp_module[1])]
                        ]:
                            list_coeffs.append(float(coeff))

                        print(
                            str(int(dsp_module[1]))
                            + " "
                            + str(int(dsp_module[2]))
                            + " "
                            + str(list_coeffs)
                        )
                        self.set_dsp_coeffs(
                            int(dsp_module[1]), int(dsp_module[2]), list_coeffs
                        )

        if save_eeprom:
            self.save_dsp_modules_eeprom()
        else:
            print(
                "\n *** Aviso: Os coeficientes configurados não foram salvos na memória EEPROM. Caso deseje salvar, utilize o argumento save_eeprom = 1"
            )

    def select_param_bank(self, cfg_dsp_modules=0):

        add = int(
            input(
                "\n Digite o endereco serial atual do controlador a ser configurado: "
            )
        )

        old_add = self.get_slave_add()
        self.set_slave_add(add)

        areas = ["IA", "LA", "PA"]
        ps_models = ["fbp", "fbp_dclink", "fap",
                     "fap_4p", "fap_2p4s", "fac", "fac_2s"]
        ps_folders = [
            "fbp",
            "fbp_dclink",
            "fap",
            "fap",
        ]
        la_fap = [
            "TB-Fam:PS-B",
            "TS-01:PS-QF1A",
            "TS-01:PS-QF1B",
            "TS-02:PS-QD2",
            "TS-02:PS-QF2",
            "TS-03:PS-QF3",
            "TS-04:PS-QD4A",
            "TS-04:PS-QD4B",
            "TS-04:PS-QF4",
        ]

        print("\n Selecione area: \n")
        print("   0: Sala de racks")
        print("   1: Linhas de transporte")
        print("   2: Sala de fontes\n")
        area = int(input(" Digite o numero correspondente: "))

        if area == 0:
            sector = input("\n Digite o setor da sala de racks [1 a 20]: ")

            if int(sector) < 10:
                sector = "0" + sector

            rack = input(
                "\n Escolha o rack em que a fonte se encontra [1/2/3]: ")

            # if (rack != '1') and (rack != '2'):
            if not ((rack == "1") or (rack == "2") or (sector == "09" and rack == "3")):
                print(" \n *** RACK INEXISTENTE ***\n")
                return

            print("\n Escolha o tipo de fonte: \n")
            print("   0: FBP")
            print("   1: FBP-DCLink\n")
            ps_model = int(input(" Digite o numero correspondente: "))

            if ps_model == 0:
                crate = "_crate_" + input(
                    "\n Digite a posicao do bastidor, de cima para baixo. Leve em conta os bastidores que ainda nao foram instalados : "
                )

            elif ps_model == 1:
                crate = ""

            else:
                print(" \n *** TIPO DE FONTE INEXISTENTE ***\n")
                return

            file_dir = "../ps_parameters/IA-" + \
                sector + "/" + ps_models[ps_model] + "/"

            file_name = (
                "parameters_"
                + ps_models[ps_model]
                + "_IA-"
                + sector
                + "RaPS0"
                + rack
                + crate
                + ".csv"
            )

            file_path = file_dir + file_name

            print("\n Banco de parametros a ser utilizado: " + file_path)

        elif area == 1:

            print("\n Escolha o tipo de fonte: \n")
            print("   0: FBP")
            print("   1: FBP-DCLink")
            print("   2: FAP\n")

            ps_model = int(input(" Digite o numero correspondente: "))

            if ps_model == 0 or ps_model == 1:

                crate = input(
                    "\n Digite a posicao do bastidor, de cima para baixo. Leve em conta os bastidores que ainda nao foram instalados : "
                )
                ps_name = "_LA-RaPS06_crate_" + crate

                file_dir = "../ps_parameters/LA/" + ps_models[ps_model] + "/"
                file_name = "parameters_" + \
                    ps_models[ps_model] + ps_name + ".csv"
                file_path = file_dir + file_name

            elif ps_model == 2:

                ps_list = []

                file_dir = "../ps_parameters/LA/fap/"
                for entry in os.listdir(file_dir):
                    if os.path.isfile(os.path.join(file_dir, entry)):
                        ps_list.append(entry)

                print("\n ### Lista de fontes FAP da linha de transporte ### \n")

                for idx, ps in enumerate(ps_list):
                    print("   " + str(idx) + ": " + ps)

                ps_idx = int(
                    input("\n Escolha o índice da fonte correspondente: "))

                file_path = file_dir + ps_list[ps_idx]

            else:
                print(" \n *** TIPO DE FONTE INEXISTENTE ***\n")
                return

            print("\n Banco de parametros a ser utilizado: " + file_path)

        elif area == 2:
            print("\n Escolha o tipo de fonte: \n")
            print("   0: FAC")
            print("   1: FAP\n")

            ps_model = int(input(" Digite o numero correspondente: "))

            if ps_model == 0:

                ps_list = []

                file_dir = "../ps_parameters/PA/fac/"
                for entry in os.listdir(file_dir):
                    if os.path.isfile(os.path.join(file_dir, entry)):
                        ps_list.append(entry)

                print(
                    "\n ### Lista de bastidores de controle FAC da sala de fontes ### \n"
                )

                for idx, ps in enumerate(ps_list):
                    print(" ", idx, ": ", ps)

                ps_idx = int(
                    input("\n Escolha o índice da fonte correspondente: "))

                file_path = file_dir + ps_list[ps_idx]

            elif ps_model == 1:

                ps_list = []

                file_dir = "../ps_parameters/PA/fap/"
                for entry in os.listdir(file_dir):
                    if os.path.isfile(os.path.join(file_dir, entry)):
                        ps_list.append(entry)

                print(
                    "\n ### Lista de bastidores de controle FAP da sala de fontes ### \n"
                )

                for idx, ps in enumerate(ps_list):
                    print(" ", idx, ": ", ps)

                ps_idx = int(
                    input("\n Escolha o índice da fonte correspondente: "))

                file_path = file_dir + ps_list[ps_idx]

            else:
                print(" \n *** TIPO DE FONTE INEXISTENTE ***\n")
                return

            print("\n Banco de parametros a ser utilizado: " + file_path)

        else:
            print(" \n *** SALA INEXISTENTE ***\n")
            return

        r = input("\n Tem certeza que deseja prosseguir? [Y/N]: ")

        if (r != "Y") and (r != "y"):
            print(" \n *** OPERAÇÃO CANCELADA ***\n")
            return
        self.set_slave_add(add)

        if ps_model == 0 and cfg_dsp_modules == 1:
            print("\n Enviando parametros de controle para controlador ...")

            dsp_file_dir = (
                "../dsp_parameters/IA-" + sector +
                "/" + ps_models[ps_model] + "/"
            )

            dsp_file_name = (
                "dsp_parameters_"
                + ps_models[ps_model]
                + "_IA-"
                + sector
                + "RaPS0"
                + rack
                + crate
                + ".csv"
            )

            dsp_file_path = dsp_file_dir + dsp_file_name

            self.set_dsp_modules_bank(dsp_file_path)

            print("\n Gravando parametros de controle na memoria ...")
            time.sleep(1)
            self.save_dsp_modules_eeprom()

        print("\n Enviando parametros de operacao para controlador ...\n")
        time.sleep(1)
        self.set_param_bank(file_path)
        print("\n Gravando parametros de operacao na memoria EEPROM onboard ...")
        self.save_param_bank(2)
        time.sleep(5)

        print("\n Resetando UDC ...")
        self.reset_udc()
        time.sleep(2)

        print(
            "\n Pronto! Não se esqueça de utilizar o novo endereço serial para se comunicar com esta fonte! :)\n"
        )

        self.set_slave_add(old_add)

    def get_siggen_vars(self):
        print("\n### SigGen Variables ###\n")
        print("Enable: " + str((round(self.read_bsmp_variable(6, "uint16_t"), 3))))
        print(
            "Type: "
            + list_sig_gen_types[int(round(self.read_bsmp_variable(7, "uint16_t"), 3))]
        )
        print("Num Cycles: " + str(round(self.read_bsmp_variable(8, "uint16_t"), 3)))
        print("Index: " + str(round(self.read_bsmp_variable(9, "float"), 3)))
        print("Frequency: " + str(round(self.read_bsmp_variable(10, "float"), 3)))
        print("Amplitude: " + str(round(self.read_bsmp_variable(11, "float"), 3)))
        print("Offset: " + str(round(self.read_bsmp_variable(12, "float"), 3)))

        self.read_var(self.index_to_hex(13))
        reply_msg = self.ser.read(21)
        val = struct.unpack("BBHffffB", reply_msg)

        print("Aux Param 0: " + str(val[3]))
        print("Aux Param 1: " + str(val[4]))
        print("Aux Param 2: " + str(val[5]))
        print("Aux Param 3: " + str(val[6]))

    def firmware_initialization(self):
        print("\n ### Inicialização de firmware ### \n")

        print("\n Lendo status...")
        print(self.read_ps_status())

        print("\n Lendo versão de firmware...")
        self.read_udc_version()

        print("\n Desbloqueando UDC...")
        print(self.unlock_udc(0xFFFF))

        print("\n Habilitando EEPROM onboard...")
        self.enable_onboard_eeprom()

        print("\n Alterando senha...")
        print(self.set_param("Password", 0, 0xCAFE))
        print(self.save_param_eeprom("Password", 0, 2))

        print("\n Configurando banco de parâmetros...")
        self.select_param_bank()

        print("\n ### Fim da inicialização de firmware ### \n")

    def cfg_hensys_ps_model(self):

        list_files = [
            "fbp_dclink/parameters_fbp_dclink_hensys.csv",
            "fac/parameters_fac_acdc_hensys.csv",
            "fac/parameters_fac_dcdc_hensys.csv",
            "fac/parameters_fac_2s_acdc_hensys.csv",
            "fac/parameters_fac_2s_dcdc_hensys.csv",
            "fac/parameters_fac_2p4s_acdc_hensys.csv",
            "fac/parameters_fac_2p4s_dcdc_hensys.csv",
            "fap/parameters_fap_hensys.csv",
            "fap/parameters_fap_2p2s_hensys.csv",
            "fap/parameters_fap_4p_hensys.csv",
        ]

        print("\n Desbloqueando UDC ...")
        print(self.unlock_udc(0xCAFE))

        print("\n *** Escolha o modelo de fonte a ser configurado ***\n")
        print(" 0: FBP-DClink")
        print(" 1: FAC-ACDC")
        print(" 2: FAC-DCDC")
        print(" 3: FAC-2S-ACDC")
        print(" 4: FAC-2S-DCDC")
        print(" 5: FAC-2P4S-ACDC")
        print(" 6: FAC-2P4S-DCDC")
        print(" 7: FAP")
        print(" 8: FAP-2P2S")
        print(" 9: FAP-4P")

        model_idx = int(input("\n Digite o índice correspondente: "))
        file_path = "../ps_parameters/development/" + list_files[model_idx]

        print("\n Banco de parametros a ser utilizado: " + file_path)

        r = input("\n Tem certeza que deseja prosseguir? [Y/N]: ")

        if (r != "Y") and (r != "y"):
            print(" \n *** OPERAÇÃO CANCELADA ***\n")
            return

        print("\n Enviando parametros de operacao para controlador ...\n")
        time.sleep(1)
        self.set_param_bank(file_path)

        print("\n Gravando parametros de operacao na memoria EEPROM onboard ...")
        self.save_param_bank(2)
        time.sleep(5)

        print("\n Resetando UDC ...")
        self.reset_udc()
        time.sleep(2)

        print(
            "\n Pronto! Nao se esqueca de utilizar o novo endereco serial para se comunicar com esta fonte! :)\n"
        )

    def test_bid_board(self, password):

        r = input(
            "\n Antes de iniciar, certifique-se que o bastidor foi energizado sem a placa BID.\n Para prosseguir, conecte a placa BID a ser testada e pressione qualquer tecla... "
        )

        print("\n Desbloqueando UDC ...")
        print(self.unlock_udc(password))

        print("\n Carregando banco de parametros da memoria onboard ...")
        print(self.load_param_bank(type_memory=2))

        print("\n Banco de parametros da memoria onboard:\n")

        max_param = list_parameters.index("Scope_Source")
        param_bank_onboard = []

        for param in list_parameters[0:max_param]:
            val = self.get_param(param, 0)
            print(param + ":", val)
            param_bank_onboard.append(val)

        print("\n Salvando banco de parametros na memoria offboard ...")
        print(self.save_param_bank(type_memory=1))

        time.sleep(5)

        print("\n Resetando UDC ...")
        self.reset_udc()

        time.sleep(3)

        self.read_ps_status()

        print("\n Desbloqueando UDC ...")
        print(self.unlock_udc(password))

        print("\n Carregando banco de parametros da memoria offboard ...")
        print(self.load_param_bank(type_memory=1))

        self.read_ps_status()

        print("\n Verificando banco de parametros offboard apos reset ... \n")
        try:
            param_bank_offboard = []

            for param in list_parameters[0:max_param]:
                val = self.get_param(param, 0)
                print(param, val)
                param_bank_offboard.append(val)

            if param_bank_onboard == param_bank_offboard:
                print("\n Placa BID aprovada!\n")
            else:
                print("\n Placa BID reprovada!\n")

        except:
            print(" Placa BID reprovada!\n")

    def upload_parameters_bid(self, password):
        print("\n Desbloqueando UDC ...")
        print(self.unlock_udc(password))

        print("\n Carregando banco de parametros da memoria offboard ...")
        print(self.load_param_bank(type_memory=1))
        time.sleep(1)

        print("\n Salvando banco de parametros na memoria onboard ...")
        print(self.save_param_bank(type_memory=2))
        time.sleep(5)

        print("\n Carregando coeficientes de controle da memoria offboard ...")
        print(self.load_dsp_modules_eeprom(type_memory=1))
        time.sleep(1)

        print("\n Salvando coeficientes de controle na memoria onboard ...\n")
        print(self.save_dsp_modules_eeprom(type_memory=2))

    def download_parameters_bid(self, password):
        print("\n Desbloqueando UDC ...")
        print(self.unlock_udc(password))

        print("\n Carregando banco de parametros da memoria onboard ...")
        print(self.load_param_bank(type_memory=2))
        time.sleep(1)

        print("\n Salvando banco de parametros na memoria offboard ...")
        print(self.save_param_bank(type_memory=1))
        time.sleep(5)

        print("\n Carregando coeficientes de controle da memoria onboard ...")
        print(self.load_dsp_modules_eeprom(type_memory=2))
        time.sleep(1)

        print("\n Salvando coeficientes de controle na memoria offboard ...")
        print(self.save_dsp_modules_eeprom(type_memory=1))
