def read_analog_input_regs_cn0414(global_data: Dict[str, Any],
                                  address: List[int],
                                  registers_number: int = 50,
                                  debug: bool = False) -> List[int]:
    """Read analog input registers.

    Read analog input registers from CN0414 with function code 4.

    Args:
        instrument: Instrument object created by minimalmodbus
        delay: Delay between MODBUS commands
        address: MODBUS register start address
        registers_number: Number of MODBUS register read (default value = 50)
        debug: If True will print registers description and value
            in a colored table (default value = False)

    Returns:
        Return a list of registers values

    """
    register_address = utilities.generate_register_address(address)
    sleep(global_data["DELAY"])
    registers = global_data["INSTRUMENT"].read_registers(register_address,
                                                         registers_number,
                                                         functioncode=4)

    if debug:
        print(Fore.LIGHTMAGENTA_EX + '\nAnalog input registers at',
              Fore.YELLOW + 'MODBUS address ' + str(address[1]))
        labels = [
            Fore.YELLOW + 'Channel 1 MSW', Fore.YELLOW + 'Channel 1 LSW',
            Fore.YELLOW + 'Channel 2 MSW', Fore.YELLOW + 'Channel 2 LSW',
            Fore.YELLOW + 'Channel 3 MSW', Fore.YELLOW + 'Channel 3 LSW',
            Fore.YELLOW + 'Channel 4 MSW', Fore.YELLOW + 'Channel 4 LSW',
            Fore.YELLOW + 'Channel 5 MSW', Fore.YELLOW + 'Channel 5 LSW',
            Fore.YELLOW + 'Channel 6 MSW', Fore.YELLOW + 'Channel 6 LSW',
            Fore.YELLOW + 'Channel 7 MSW', Fore.YELLOW + 'Channel 7 LSW',
            Fore.YELLOW + 'Channel 8 MSW', Fore.YELLOW + 'Channel 8 LSW',
            Fore.YELLOW + 'Channel 1 OWD', Fore.YELLOW + 'Channel 2 OWD',
            Fore.YELLOW + 'Channel 3 OWD', Fore.YELLOW + 'Channel 4 OWD',
            Fore.YELLOW + 'HART IN 01', Fore.YELLOW + 'HART IN 02',
            Fore.YELLOW + 'HART IN 03', Fore.YELLOW + 'HART IN 04',
            Fore.YELLOW + 'HART IN 05', Fore.YELLOW + 'HART IN 06',
            Fore.YELLOW + 'HART IN 07', Fore.YELLOW + 'HART IN 08',
            Fore.YELLOW + 'HART IN 09', Fore.YELLOW + 'HART IN 10',
            Fore.YELLOW + 'HART IN 11', Fore.YELLOW + 'HART IN 12',
            Fore.YELLOW + 'HART IN 13', Fore.YELLOW + 'HART IN 14',
            Fore.YELLOW + 'HART IN 15', Fore.YELLOW + 'HART IN 16',
            Fore.YELLOW + 'HART IN 17', Fore.YELLOW + 'HART IN 18',
            Fore.YELLOW + 'HART IN 19', Fore.YELLOW + 'HART IN 20',
            Fore.YELLOW + 'HART IN 21', Fore.YELLOW + 'HART IN 22',
            Fore.YELLOW + 'HART IN 23', Fore.YELLOW + 'HART IN 24',
            Fore.YELLOW + 'HART IN 25', Fore.YELLOW + 'HART IN 26',
            Fore.YELLOW + 'HART IN 27', Fore.YELLOW + 'HART IN 28',
            Fore.YELLOW + 'HART IN 29', Fore.YELLOW + 'HART IN 30'
        ]
        utilities.print_table(register_address, registers_number, labels,
                              registers)
    return registers
def set_dac_output(global_data: Dict[str, Any], channel: int) -> None:
    """Request device CS address and register value.

    Args:
        global_data: Dictionary with global variables
        channel: Channel number

    Returns:
        Return requested device address and register value

    """
    cs_addr = request_dac_cs(global_data)

    detected_range = global_data["INSTRUMENT"].read_register(
        utilities.generate_register_address(
            [global_data["MODBUS_ADDRESS"], cs_addr, 0]))

    if detected_range in range(4):
        ranges = ['0V to 5V', '0V to 10V', '-5V to 5V', '-10V to 10V']
        print(Fore.CYAN + "Enter a voltage value in [V] from range",
              Fore.YELLOW + str(ranges[detected_range]),
              Fore.CYAN + "or press ENTER to set",
              Fore.YELLOW + "0V: ",
              end='')
        input_data = input()
        if input_data == "":
            voltage_value = 0.0
        else:
            voltage_value = float(input_data.split()[0])
        write_voltage(global_data,
                      [global_data["MODBUS_ADDRESS"], cs_addr, channel],
                      voltage_value, detected_range)
    else:
        ranges = ['4mA to 20mA', '0mA to 20mA', '0mA to 24mA']
        print(Fore.CYAN + "Enter a current value in [mA] from range",
              Fore.CYAN + str(ranges[detected_range - 4]),
              Fore.CYAN + "or press ENTER to set",
              Fore.YELLOW + "0mA: ",
              end='')
        input_data = input()
        if input_data == "":
            current_value = 0.0
        else:
            current_value = float(input_data.split()[0]) / 1000
        write_current(global_data,
                      [global_data["MODBUS_ADDRESS"], cs_addr, channel],
                      current_value, detected_range - 4)
def read_analog_input_regs_cn0418(global_data: Dict[str, Any],
                                  address: List[int],
                                  registers_number: int = 30,
                                  debug: bool = False) -> List[int]:
    """Read analog input registers.

    Read analog input registers from CN0418 with function code 4.

    Args:
        global_data: Dictionary with global variables
        address: MODBUS register start address
        registers_number: Number of MODBUS register read (default value = 30)
        debug: If True will print registers description and value
            in a colored table (default value = False)

    Returns:
        Return a list of registers values

    """
    register_address = utilities.generate_register_address(address)
    registers = global_data["INSTRUMENT"].read_registers(register_address,
                                                         registers_number,
                                                         functioncode=4)
    sleep(global_data["DELAY"])
    if debug:
        print(Fore.LIGHTMAGENTA_EX + '\nAnalog input registers at',
              Fore.YELLOW + 'MODBUS address ' + str(address[1]))
        labels = [
            Fore.YELLOW + 'HART IN 01', Fore.YELLOW + 'HART IN 02',
            Fore.YELLOW + 'HART IN 03', Fore.YELLOW + 'HART IN 04',
            Fore.YELLOW + 'HART IN 05', Fore.YELLOW + 'HART IN 06',
            Fore.YELLOW + 'HART IN 07', Fore.YELLOW + 'HART IN 08',
            Fore.YELLOW + 'HART IN 09', Fore.YELLOW + 'HART IN 10',
            Fore.YELLOW + 'HART IN 11', Fore.YELLOW + 'HART IN 12',
            Fore.YELLOW + 'HART IN 13', Fore.YELLOW + 'HART IN 14',
            Fore.YELLOW + 'HART IN 15', Fore.YELLOW + 'HART IN 16',
            Fore.YELLOW + 'HART IN 17', Fore.YELLOW + 'HART IN 18',
            Fore.YELLOW + 'HART IN 19', Fore.YELLOW + 'HART IN 20',
            Fore.YELLOW + 'HART IN 21', Fore.YELLOW + 'HART IN 22',
            Fore.YELLOW + 'HART IN 23', Fore.YELLOW + 'HART IN 24',
            Fore.YELLOW + 'HART IN 25', Fore.YELLOW + 'HART IN 26',
            Fore.YELLOW + 'HART IN 27', Fore.YELLOW + 'HART IN 28',
            Fore.YELLOW + 'HART IN 29', Fore.YELLOW + 'HART IN 30'
        ]
        utilities.print_table(register_address, registers_number, labels,
                              registers)
    return registers
def read_output_holding_regs_cn0418(global_data: Dict[str, Any],
                                    address: List[int],
                                    registers_number: int = 10,
                                    debug: bool = False) -> List[int]:
    """Read output holding registers.

    Read output holding registers from CN0418 with function code 3.

    Args:
        global_data: Dictionary with global variables
        address: MODBUS register start address
        registers_number: Number of MODBUS register read (default value = 10)
        debug: If True will print registers description and value
            in a colored table (default value = False)

    Returns:
        Return a list of registers values

    """
    register_address = utilities.generate_register_address(address)
    sleep(global_data["DELAY"])
    registers = global_data["INSTRUMENT"].read_registers(register_address,
                                                         registers_number,
                                                         functioncode=3)
    if debug:
        print(Fore.LIGHTMAGENTA_EX + '\nAnalog input registers at',
              Fore.YELLOW + 'MODBUS address ' + str(address[1]))
        labels = [
            Fore.YELLOW + 'Channel 1 range', Fore.YELLOW + 'Channel 2 range',
            Fore.YELLOW + 'Channel 3 range', Fore.YELLOW + 'Channel 4 range',
            Fore.YELLOW + 'Channel 1', Fore.YELLOW + 'Channel 2',
            Fore.YELLOW + 'Channel 3', Fore.YELLOW + 'Channel 4',
            Fore.YELLOW + 'HART cmd 0', Fore.YELLOW + 'HART CH select'
        ]
        utilities.print_table(register_address, registers_number, labels,
                              registers)
    return registers
def read_output_holding_regs_cn0414(global_data: Dict[str, Any],
                                    address: List[int],
                                    registers_number: int = 7,
                                    debug: bool = False) -> List[int]:
    """Read output holding registers.

    Read output holding registers from CN0414 with function code 3.

    Args:
        instrument: Instrument object created by minimalmodbus
        delay: Delay between MODBUS commands
        address: MODBUS register start address
        registers_number: Number of MODBUS register read (default value = 7)
        debug: If True will print registers description and value
            in a colored table (default value = False)

    Returns:
        Return a list of registers values

    """
    register_address = utilities.generate_register_address(address)
    sleep(global_data["DELAY"])
    registers = global_data["INSTRUMENT"].read_registers(register_address,
                                                         registers_number,
                                                         functioncode=3)
    if debug:
        print(Fore.LIGHTMAGENTA_EX + '\nOutput holding registers at',
              Fore.YELLOW + 'MODBUS address ' + str(address[1]))
        labels = [
            Fore.YELLOW + 'ADC Output Code', Fore.YELLOW + 'ADC Filter',
            Fore.YELLOW + 'ADC Postfilter', Fore.YELLOW + 'ADC ODR',
            Fore.YELLOW + 'ADC OWD EN', Fore.YELLOW + 'HART cmd 0',
            Fore.YELLOW + 'HART CH select'
        ]
        utilities.print_table(register_address, registers_number, labels,
                              registers)
    return registers