mcculw/enums.py
class ErrorCode(IntEnum):
    # System error code
    NOERRORS = 0  # No error occurred
    BADBOARD = 1  # Invalid board number specified
    DEADDIGITALDEV = 2  # Digital I/O device is not responding
    DEADCOUNTERDEV = 3  # Counter I/O device is not responding
    DEADDADEV = 4  # D/A is not responding
    DEADADDEV = 5  # A/D is not responding
    NOTDIGITALCONF = 6  # Specified board does not have digital I/O
    NOTCOUNTERCONF = 7  # Specified board does not have a counter
    NOTDACONF = 8  # Specified board is does not have D/A
    NOTADCONF = 9  # Specified board does not have A/D
    NOTMUXCONF = 10  # Specified board does not have thermocouple inputs
    BADPORTNUM = 11  # Invalid port number specified
    BADCOUNTERDEVNUM = 12  # Invalid counter device
    BADDADEVNUM = 13  # Invalid D/A device
    BADSAMPLEMODE = 14  # Invalid sampling mode option specified
    BADINT = 15  # Board configured for invalid interrupt level
    BADADCHAN = 16  # Invalid A/D channel Specified
    BADCOUNT = 17  # Invalid count specified
    BADCNTRCONFIG = 18  # invalid counter configuration specified
    BADDAVAL = 19  # Invalid D/A output value specified
    BADDACHAN = 20  # Invalid D/A channel specified
    ALREADYACTIVE = 22  # A background process is already in progress
    PAGEOVERRUN = 23  # DMA transfer crossed page boundary, may have gaps in data
    BADRATE = 24  # Inavlid sampling rate specified
    COMPATMODE = 25  # Board switches set for "compatible" mode
    TRIGSTATE = 26  # Incorrect intial trigger state D0 must=TTL low)
    ADSTATUSHUNG = 27  # A/D is not responding
    TOOFEW = 28  # Too few samples before trigger occurred
    OVERRUN = 29  # Data lost due to overrun, rate too high
    BADRANGE = 30  # Invalid range specified
    NOPROGGAIN = 31  # Board does not have programmable gain
    BADFILENAME = 32  # Not a legal DOS filename
    DISKISFULL = 33  # Couldn't complete, disk is full
    COMPATWARN = 34  # Board is in compatible mode, so DMA will be used
    BADPOINTER = 35  # Invalid pointer (NULL)
    TOOMANYGAINS = 36  # Too many gains
    RATEWARNING = 37  # Rate may be too high for interrupt I/O
    CONVERTDMA = 38  # CONVERTDATA cannot be used with DMA I/O
    DTCONNECTERR = 39  # Board doesn't have DT Connect
    FORECONTINUOUS = 40  # CONTINUOUS can only be used with BACKGROUND
    BADBOARDTYPE = 41  # This function can not be used with this board
    WRONGDIGCONFIG = 42  # Digital I/O is configured incorrectly
    NOTCONFIGURABLE = 43  # Digital port is not configurable
    BADPORTCONFIG = 44  # Invalid port configuration specified
    BADFIRSTPOINT = 45  # First point argument is not valid
    ENDOFFILE = 46  # Attempted to read past end of file
    NOT8254CTR = 47  # This board does not have an 8254 counter
    NOT9513CTR = 48  # This board does not have a 9513 counter
    BADTRIGTYPE = 49  # Invalid trigger type
    BADTRIGVALUE = 50  # Invalid trigger value
    BADOPTION = 52  # Invalid option specified for this function
    BADPRETRIGCOUNT = 53  # Invalid pre-trigger count sepcified
    BADDIVIDER = 55  # Invalid fout divider value
    BADSOURCE = 56  # Invalid source value
    BADCOMPARE = 57  # Invalid compare value
    BADTIMEOFDAY = 58  # Invalid time of day value
    BADGATEINTERVAL = 59  # Invalid gate interval value
    BADGATECNTRL = 60  # Invalid gate control value
    BADCOUNTEREDGE = 61  # Invalid counter edge value
    BADSPCLGATE = 62  # Invalid special gate value
    BADRELOAD = 63  # Invalid reload value
    BADRECYCLEFLAG = 64  # Invalid recycle flag value
    BADBCDFLAG = 65  # Invalid BCD flag value
    BADDIRECTION = 66  # Invalid count direction value
    BADOUTCONTROL = 67  # Invalid output control value
    BADBITNUMBER = 68  # Invalid bit number
    NONEENABLED = 69  # None of the counter channels are enabled
    BADCTRCONTROL = 70  # Element of control array not ENABLED/DISABLED
    BADEXPCHAN = 71  # Invalid EXP channel
    WRONGADRANGE = 72  # Wrong A/D range selected for cbtherm
    OUTOFRANGE = 73  # Temperature input is out of range
    BADTEMPSCALE = 74  # Invalid temperate scale
    BADERRCODE = 75  # Invalid error code specified
    NOQUEUE = 76  # Specified board does not have chan/gain queue
    CONTINUOUSCOUNT = 77  # CONTINUOUS can not be used with this count value
    UNDERRUN = 78  # D/A FIFO hit empty while doing output
    BADMEMMODE = 79  # Invalid memory mode specified
    FREQOVERRUN = 80  # Measured frequency too high for gating interval
    NOCJCCHAN = 81  # Board does not have CJC chan configured
    BADCHIPNUM = 82  # Invalid chip number used with c_9513_init
    DIGNOTENABLED = 83  # Digital I/O not enabled
    CONVERT16BITS = 84  # CONVERT option not allowed with 16 bit A/D
    NOMEMBOARD = 85  # EXTMEMORY option requires memory board
    DTACTIVE = 86  # Memory I/O while DT Active
    NOTMEMCONF = 87  # Specified board is not a memory board
    ODDCHAN = 88  # First chan in queue can not be odd
    CTRNOINIT = 89  # Counter was not initialized
    NOT8536CTR = 90  # Specified counter is not an 8536
    FREERUNNING = 91  # A/D sampling is not timed
    INTERRUPTED = 92  # Operation interrupted with CTRL-C
    NOSELECTORS = 93  # Selector could not be allocated
    NOBURSTMODE = 94  # Burst mode is not supported on this board
    NOTWINDOWSFUNC = 95  # This function not available in Windows lib
    NOTSIMULCONF = 96  # Not configured for simultaneous update
    EVENODDMISMATCH = 97  # Even channel in odd slot in the queue
    M1RATEWARNING = 98  # DAS16/M1 sample rate too fast
    NOTRS485 = 99  # Board is not an RS-485 board
    NOTDOSFUNC = 100  # This function not avaliable in DOS
    RANGEMISMATCH = 101  # Unipolar and Bipolar can not be used together in A/D que
    CLOCKTOOSLOW = 102  # Sample rate too fast for clock jumper setting
    BADCALFACTORS = 103  # Cal factors were out of expected range of values
    BADCONFIGTYPE = 104  # Invalid configuration type information requested
    BADCONFIGITEM = 105  # Invalid configuration item specified
    NOPCMCIABOARD = 106  # Can't acces PCMCIA board
    NOBACKGROUND = 107  # Board does not support background I/O
    STRINGTOOSHORT = 108  # String passed to get_board_name is to short
    CONVERTEXTMEM = 109  # Convert data option not allowed with external memory
    BADEUADD = 110  # e_ToEngUnits addition error
    DAS16JRRATEWARNING = 111  # use 10 MHz clock for rates > 125KHz
    DAS08TOOLOWRATE = 112  # DAS08 rate set too low for AInScan warning
    AMBIGSENSORONGP = 114  # more than one sensor type defined for EXP-GP
    NOSENSORTYPEONGP = 115  # no sensor type defined for EXP-GP
    NOCONVERSIONNEEDED = 116  # 12 bit board without chan tags - converted in ISR
    NOEXTCONTINUOUS = 117  # External memory cannot be used in CONTINUOUS mode
    # a_convert_pretrig_data was called after failure in a_pretrig
    INVALIDPRETRIGCONVERT = 118
    BADCTRREG = 119  # bad arg to CLoad for 9513
    BADTRIGTHRESHOLD = 120  # Invalid trigger threshold specified in set_trigger
    BADPCMSLOTREF = 121  # No PCM card in specified slot
    AMBIGPCMSLOTREF = 122  # More than one CBI PCM card in slot
    BADSENSORTYPE = 123  # Bad sensor type selected in Instacal
    DELBOARDNOTEXIST = 124  # tried to delete board number which doesn't exist
    NOBOARDNAMEFILE = 125  # board name file not found
    CFGFILENOTFOUND = 126  # configuration file not found
    NOVDDINSTALLED = 127  # CBUL.386 device driver not installed
    NOWINDOWSMEMORY = 128  # No Windows memory available
    OUTOFDOSMEMORY = 129  # ISR data struct alloc failure
    OBSOLETEOPTION = 130  # Obsolete option for get_config/set_config
    NOPCMREGKEY = 131  # No registry entry for this PCMCIA board
    NOCBUL32SYS = 132  # CBUL32.SYS device driver is not loaded
    NODMAMEMORY = 133  # No DMA buffer available to device driver
    IRQNOTAVAILABLE = 134  # IRQ in being used by another device
    NOT7266CTR = 135  # This board does not have an LS7266 counter
    BADQUADRATURE = 136  # Invalid quadrature specified
    BADCOUNTMODE = 137  # Invalid counting mode specified
    BADENCODING = 138  # Invalid data encoding specified
    BADINDEXMODE = 139  # Invalid index mode specified
    BADINVERTINDEX = 140  # Invalid invert index specified
    BADFLAGPINS = 141  # Invalid flag pins specified
    NOCTRSTATUS = 142  # This board does not support c_status()
    NOGATEALLOWED = 143  # Gating and indexing not allowed simultaneously
    NOINDEXALLOWED = 144  # Indexing not allowed in non-quadratue mode
    OPENCONNECTION = 145  # Temperature input has open connection
    # Count must be integer multiple of packetsize for recycle mode.
    BMCONTINUOUSCOUNT = 146
    BADCALLBACKFUNC = 147  # Invalid pointer to callback function passed as arg
    MBUSINUSE = 148  # MetraBus in use
    MBUSNOCTLR = 149  # MetraBus I/O card has no configured controller card
    BADEVENTTYPE = 150  # Invalid event type specified for this board.
    ALREADYENABLED = 151  # An event handler has already been enabled for this event type
    BADEVENTSIZE = 152  # Invalid event count specified.
    CANTINSTALLEVENT = 153  # Unable to install event handler
    BADBUFFERSIZE = 154  # Buffer is too small for operation
    BADAIMODE = 155  # Invalid Analog Input Mode specified

    BADSIGNAL = 156
    BADCONNECTION = 157
    BADINDEX = 158
    NOCONNECTION = 159

    BADBURSTIOCOUNT = 160  # Count cannot be greater than FIFO size for BURSTIO scans
    DEADDEV = 161  # Device no longer responding
    BADCONFIGVAL = 162

    INVALIDACCESS = 163  # Invalid access or privilege for specified operation
    # Device unavailable at time of request. Please repeat operation.
    UNAVAILABLE = 164
    # Device is not ready to send data. Please repeat operation.
    NOTREADY = 165
    OWNERSHIPREFUSED = 166  # Current device owner refused to release device.
    OWNERSHIPFAILED = 167  # No response from current device owner,
    NETERROR = 168  # Network error.
    BITUSEDFORALARM = 169  # The specified bit is used for alarm.
    # One or more bits on the specified port are used for alarm.
    PORTUSEDFORALARM = 170
    PACEROVERRUN = 171  # Pacer overrun, external clock rate too fast.
    BADCHANTYPE = 172  # Invalid channel type specified
    BADTRIGSENSE = 173  # Invalid trigger sensitivity specified
    BADTRIGCHAN = 174  # Invalid trigger channel specified
    BADTRIGLEVEL = 175  # Invalid trigger level specified
    NOPRETRIGMODE = 176  # Pre-trigger mode is not supported for the specified trigger type
    BADDEBOUNCETIME = 177  # Invalid debounce time specified
    BADDEBOUNCETRIGMODE = 178  # Invalid debounce trigger mode specified
    BADMAPPEDCOUNTER = 179  # Invalid mapped counter specified
    # This function can not be used with the current mode of the specified
    # counter
    BADCOUNTERMODE = 180
    BADTCCHANMODE = 181  # Single-Ended mode can not be used for temperature input
    BADFREQUENCY = 182  # Invalid frequency specified.
    BADEVENTPARAM = 183  # Invalid event parameter specified.
    NONETIFC = 184  # No interface cards with specified PAN and channel.
    DEADNETIFC = 185
    NOREMOTEACK = 186
    INPUTTIMEOUT = 187
    # Number of Setpoints not equal to number of channels with setpoint flag
    # set
    MISMATCHSETPOINTCOUNT = 188
    INVALIDSETPOINTLEVEL = 189  # Setpoint Level is outside channel range
    INVALIDSETPOINTOUTPUTTYPE = 190  # Setpoint Output Type is invalid
    INVALIDSETPOINTOUTPUTVALUE = 191  # Setpoint Output Value is outside channel range
    INVALIDSETPOINTLIMITS = 192  # Setpoint Comparison limit B greater than Limit A
    STRINGTOOLONG = 193
    INVALIDLOGIN = 194
    SESSIONINUSE = 195
    NOEXTPOWER = 196  # External power is not connected.
    BADDUTYCYCLE = 197  # Invalid duty cycle specified.
    INVALIDPASSWORD = 198
    BADINITIALDELAY = 199  # Invalid initial delay specified
    # No TEDS sensor was detected on the specified channel.
    NOTEDSSENSOR = 1000
    # Connected TEDS sensor to the specified channel is not supported
    INVALIDTEDSSENSOR = 1001
    CALIBRATIONFAILED = 1002  # Calibration failed
    # The specified bit is used for terminal count stauts.
    BITUSEDFORTERMINALCOUNTSTATUS = 1003
    # One or more bits on the specified port are used for terminal count
    # stauts.
    PORTUSEDFORTERMINALCOUNTSTATUS = 1004
    BADEXCITATION = 1005  # Invalid excitation specified
    BADBRIDGETYPE = 1006  # Invalid bridge type specified
    BADLOADVAL = 1007  # Invalid load value specified
    BADTICKSIZE = 1008  # Invalid tick size specified
    MINSLOPEVALREACHED = 1009  # Minimum slope value reached
    MAXSLOPEVALREACHED = 1010  # Maximum slope value reached
    MINOFFSETVALREACHED = 1011  # Minimum offset value reached
    MAXOFFSETVALREACHED = 1012  # Maximum offset value reached
    BTHCONNECTIONFAILED = 1013  # Bluetooth connection failed
    INVALIDBTHFRAME = 1014  # Invalid Bluetooth frame
    BADTRIGEVENT = 1015  # Invalid trigger event specified
    NETCONNECTIONFAILED = 1016  # Network connection failed
    DATASOCKETCONNECTIONFAILED = 1017  # Data socket connection failed
    INVALIDNETFRAME = 1018  # Invalid Network frame
    NETTIMEOUT = 1019  # Network device did not respond within expected time
    NETDEVNOTFOUND = 1020  # Network device not found
    INVALIDCONNECTIONCODE = 1021  # Invalid connection code
    CONNECTIONCODEIGNORED = 1022  # Connection code ignored
    NETDEVINUSE = 1023  # Network device already in use
    NETDEVINUSEBYANOTHERPROC = 1024  # Network device already in use by another process
    SOCKETDISCONNECTED = 1025  # Socket Disconnected
    BOARDNUMINUSE = 1026  # Board Number already in use
    DEVALREADYCREATED = 1027  # Specified DAQ device already created
    BOARDNOTEXIST = 1028  # Tried to release a board which doesn't exist
    INVALIDNETHOST = 1029  # Invalid host specified
    INVALIDNETPORT = 1030  # Invalid port specified
    INVALIDIFC = 1031  # Invalid interface specified
    INVALIDAIINPUTMODE = 1032  # Invalid input mode specified
    AIINPUTMODENOTCONFIGURABLE = 1033  # Input mode not configurable
    INVALIDEXTPACEREDGE = 1034  # Invalid external pacer edge
    CMREXCEEDED = 1035  # Common-mode voltage range exceeded
    BADTRIGSRC = 1036  # Invalid trigger source

    # Internal errors returned by 16 bit library
    INTERNALERR = 200  # 200-299 Internal library error
    CANT_LOCK_DMA_BUF = 201  # DMA buffer could not be locked
    DMA_IN_USE = 202  # DMA already controlled by another VxD
    BAD_MEM_HANDLE = 203  # Invalid Windows memory handle
    NO_ENHANCED_MODE = 204  # Windows Enhance mode is not running
    MEMBOARDPROGERROR = 211  # Program error getting memory board source

    # Internal errors returned by 32 bit library
    INTERNAL32_ERR = 300  # 300-399 32 bit library internal errors
    # 32 bit - default buffer allocation when no user buffer used with file
    NO_MEMORY_FOR_BUFFER = 301
    WIN95_CANNOT_SETUP_ISR_DATA = 302  # 32 bit - failure on INIT_ISR_DATA IOCTL call
    WIN31_CANNOT_SETUP_ISR_DATA = 303  # 32 bit - failure on INIT_ISR_DATA IOCTL call
    CFG_FILE_READ_FAILURE = 304  # 32 bit - error reading board configuration file
    CFG_FILE_WRITE_FAILURE = 305  # 32 bit - error writing board configuration file
    CREATE_BOARD_FAILURE = 306  # 32 bit - failed to create board
    DEVELOPMENT_OPTION = 307  # 32 bit - Config Option item used in development only
    CFGFILE_CANT_OPEN = 308  # 32 bit - cannot open configuration file.
    CFGFILE_BAD_ID = 309  # 32 bit - incorrect file id.
    CFGFILE_BAD_REV = 310  # 32 bit - incorrect file version.
    CFGFILE_NOINSERT = 311  # ;
    CFGFILE_NOREPLACE = 312  # ;
    BIT_NOT_ZERO = 313  # ;
    BIT_NOT_ONE = 314  # ;
    BAD_CTRL_REG = 315  # No control register at this location.
    BAD_OUTP_REG = 316  # No output register at this location.
    BAD_RDBK_REG = 317  # No read back register at this location.
    NO_CTRL_REG = 318  # No control register on this board.
    NO_OUTP_REG = 319  # No control register on this board.
    NO_RDBK_REG = 320  # No control register on this board.
    CTRL_REG_FAIL = 321  # internal ctrl reg test failed.
    OUTP_REG_FAIL = 322  # internal output reg test failed.
    RDBK_REG_FAIL = 323  # internal read back reg test failed.
    FUNCTION_NOT_IMPLEMENTED = 324
    BAD_RTD_CONVERSION = 325  # Overflow in RTD calculation
    NO_PCI_BIOS = 326  # PCI BIOS not present in the PC
    BAD_PCI_INDEX = 327  # Invalid PCI board index passed to PCI BIOS
    NO_PCI_BOARD = 328  # Specified PCI board not detected
    PCI_ASSIGN_FAILED = 329  # PCI resource assignment failed
    PCI_NO_ADDRESS = 330  # No PCI address returned
    PCI_NO_IRQ = 331  # No PCI IRQ returned
    CANT_INIT_ISR_INFO = 332  # IOCTL call failed on VDD_API_INIT_ISR_INFO
    CANT_PASS_USER_BUFFER = 333  # IOCTL call failed on VDD_API_PASS_USER_BUFFER
    CANT_INSTALL_INT = 334  # IOCTL call failed on VDD_API_INSTALL_INT
    CANT_UNINSTALL_INT = 335  # IOCTL call failed on VDD_API_UNINSTALL_INT
    CANT_START_DMA = 336  # IOCTL call failed on VDD_API_START_DMA
    CANT_GET_STATUS = 337  # IOCTL call failed on VDD_API_GET_STATUS
    CANT_GET_PRINT_PORT = 338  # IOCTL call failed on VDD_API_GET_PRINT_PORT
    CANT_MAP_PCM_CIS = 339  # IOCTL call failed on VDD_API_MAP_PCM_CIS
    CANT_GET_PCM_CFG = 340  # IOCTL call failed on VDD_API_GET_PCM_CFG
    CANT_GET_PCM_CCSR = 341  # IOCTL call failed on VDD_API_GET_PCM_CCSR
    CANT_GET_PCI_INFO = 342  # IOCTL call failed on VDD_API_GET_PCI_INFO
    NO_USB_BOARD = 343  # Specified USB board not detected
    NOMOREFILES = 344  # No more files in the directory
    BADFILENUMBER = 345  # Invalid file number
    INVALIDSTRUCTSIZE = 346  # Invalid structure size
    LOSSOFDATA = 347  # EOF marker not found, possible loss of data
    INVALIDBINARYFILE = 348  # File is not a valid MCC binary file
    INVALIDDELIMITER = 349  # Invlid delimiter specified for CSV file
    NO_BTH_BOARD = 350  # Specified Bluetooth board not detected
    NO_NET_BOARD = 351  # Specified Network board not detected

    # DOS errors are remapped by adding DOS_ERR_OFFSET to them */
    DOS_ERR_OFFSET = 500
    # These are the commonly occurring remapped DOS error codes
    DOSBADFUNC = 501
    DOSFILENOTFOUND = 502
    DOSPATHNOTFOUND = 503
    DOSNOHANDLES = 504
    DOSACCESSDENIED = 505
    DOSINVALIDHANDLE = 506
    DOSNOMEMORY = 507
    DOSBADDRIVE = 515
    DOSTOOMANYFILES = 518
    DOSWRITEPROTECT = 519
    DOSDRIVENOTREADY = 521
    DOSSEEKERROR = 525
    DOSWRITEFAULT = 529
    DOSREADFAULT = 530
    DOSGENERALFAULT = 531  # Windows internal error codes
    WIN_CANNOT_ENABLE_INT = 603
    WIN_CANNOT_DISABLE_INT = 605
    WIN_CANT_PAGE_LOCK_BUFFER = 606
    NO_PCM_CARD = 630
mcculw/enums.py
class EventType(IntFlag):
    ON_SCAN_ERROR = 0x0001
    ON_EXTERNAL_INTERRUPT = 0x0002
    ON_PRETRIGGER = 0x0004
    ON_DATA_AVAILABLE = 0x0008
    ON_END_OF_AI_SCAN = 0x0010
    ON_END_OF_AO_SCAN = 0x0020
    ON_CHANGE_DI = 0x0040
    # Since we can have only one input scan running at a time created this
    # constant with the same value as ON_END_OF_AI_SCAN
    ON_END_OF_INPUT_SCAN = 0x0010
    # Since we can have only one output scan running at a time created this
    # constant with the same value as ON_END_OF_AO_SCAN
    ON_END_OF_OUTPUT_SCAN = 0x0020
    ALL_AI_EVENT_TYPES = 0x001d
    ALL_AO_EVENT_TYPES = 0x0021
    ALL_EVENT_TYPES = 0xffff
mcculw/device_info/ao_info.py
class AoInfo:
    """Provides analog output information for the device with the specified
    board number.

    NOTE: This class is primarily used to provide hardware information for the
    library examples and may change some hardware configuration values. It is
    recommended that values provided by this class be hard-coded in production
    code.

    Parameters
    ----------
    board_num : int
        The board number associated with the device when created with
        :func:`.create_daq_device` or configured with Instacal.
    """
    def __init__(self, board_num):
        self._board_num = board_num

    @property
    def board_num(self):
        return self._board_num

    @property
    def num_chans(self):
        return ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                             BoardInfo.NUMDACHANS)

    @property
    def is_supported(self):
        return self.num_chans > 0

    @property
    def resolution(self):
        return ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                             BoardInfo.DACRES)

    @property
    def supports_scan(self):
        return ScanOptions.CONTINUOUS in self.supported_scan_options

    @property
    def supported_scan_options(self):
        try:
            scan_options_supported = ScanOptions(ul.get_config(
                InfoType.BOARDINFO, self._board_num, 0,
                BoardInfo.DACSCANOPTIONS))
        except ULError:
            scan_options_supported = ScanOptions(0)

        return scan_options_supported

    @property
    def supported_ranges(self):
        result = []
        # Check if the range is ignored by passing a bogus range in
        try:
            ul.a_out(self._board_num, 0, -5, 0)
            range_ignored = True
        except ULError as e:
            if (e.errorcode == ErrorCode.NETDEVINUSE or
                    e.errorcode == ErrorCode.NETDEVINUSEBYANOTHERPROC):
                raise
            range_ignored = False

        if range_ignored:
            # Try and get the range configured in InstaCal
            try:
                curr_range = ULRange(ul.get_config(InfoType.BOARDINFO,
                                                   self._board_num, 0,
                                                   BoardInfo.DACRANGE))
                result.append(curr_range)
            except ULError as e:
                if (e.errorcode == ErrorCode.NETDEVINUSE or
                        e.errorcode == ErrorCode.NETDEVINUSEBYANOTHERPROC):
                    raise
        else:
            for dac_range in ULRange:
                try:
                    ul.a_out(self._board_num, 0, dac_range, 0)
                    result.append(dac_range)
                except ULError as e:
                    if (e.errorcode == ErrorCode.NETDEVINUSE or
                            e.errorcode == ErrorCode.NETDEVINUSEBYANOTHERPROC):
                        raise

        return result

    @property
    def supports_v_out(self):
        ranges_supported = self.supported_ranges
        v_out_supported = False
        if ranges_supported:
            try:
                ul.v_out(self._board_num, 0, ranges_supported[0], 0)
                v_out_supported = True
            except ULError:
                v_out_supported = False
        return v_out_supported
mcculw/ul.py
class ULError(Exception):
    def __init__(self, errorcode):
    def __str__(self):
def a_chan_input_mode(board_num, channel, input_mode):
def a_in(board_num, channel, ul_range):
def a_in_32(board_num, channel, ul_range, options=0):
def a_in_scan(
        board_num, low_chan, high_chan, num_points, rate, ul_range, memhandle,
        options):
def a_input_mode(board_num, input_mode):
def a_load_queue(board_num, chan_list, gain_list, count):
def a_out(board_num, channel, ul_range, data_value):
def a_out_scan(board_num, low_chan, high_chan, num_points, rate, ul_range, memhandle, options):
def a_pretrig(board_num, low_chan, high_chan, pretrig_count, total_count, rate,
              ul_range, memhandle, options):
def a_convert_pretrig_data(board_num, pretrig_count, total_count, data, chan_tags = None):
def a_trig(board_num, channel, trig_type, trig_value, ul_range):
def a_calibrate_data(board_num, num_points, range, data):
def c_clear(board_num, counter_num):
def c_config_scan(board_num, counter_num, mode, debounce_time, debounce_mode,
                  edge_detection, tick_size, mapped_channel):
def c_in(board_num, counter_num):
def c_in_32(board_num, counter_num):
def c_in_64(board_num, counter_num):
def c_in_scan(board_num, first_ctr, last_ctr, count, rate, memhandle, options):
def c_load(board_num, reg_num, load_value):
def c_load_32(board_num, reg_num, load_value):
def c_load_64(board_num, reg_num, load_value):
def c_8254_config(board_num, counter_num, config):
def create_daq_device(board_num, descriptor):
def daq_in_scan(board_num, chan_list, chan_type_list, gain_list, chan_count,
                rate, pretrig_count, total_count, memhandle, options):
def daq_out_scan(board_num, chan_list, chan_type_list, gain_list, chan_count,
                 rate, count, memhandle, options):
def daq_set_setpoints(board_num, limit_a_list, limit_b_list, setpoint_flags_list,
                      setpoint_output_list, output_1_list, output_2_list,
                      output_mask_1_list, output_mask_2_list, setpoint_count):
def daq_set_trigger(board_num, trig_source, trig_sense, trig_chan, chan_type,
                    gain, level, variance, trig_event):
def d_bit_in(board_num, port_type, bit_num):
def d_bit_out(board_num, port_type, bit_num, bit_value):
def d_clear_alarm(board_num, port_type, mask):
def d_config_bit(board_num, port_type, bit_num, direction):
def d_config_port(board_num, port_type, direction):
def device_login(board_num, user_name, password):
def device_logout(board_num):
def d_in(board_num, port_type):
def d_in_32(board_num, port_type):
def d_in_array(board_num, low_port, high_port, data_array=None):
def d_in_scan(board_num, port_type, count, rate, memhandle, options):
def disable_event(board_num, event_type):
def d_out(board_num, port_type, data_value):
def d_out_32(board_num, port_type, data_value):
def d_out_array(board_num, low_port, high_port, data_list):
def d_out_scan(board_num, port_type, count, rate, memhandle, options):
def enable_event(board_num, event_type, event_param, callback_func, c_user_data):
def flash_led(board_num):
def from_eng_units(board_num, ul_range, eng_units_value):
def get_board_name(board_num):
def get_board_number(descriptor):
def get_config(info_type, board_num, dev_num, config_item):
def get_config_string(info_type, board_num, dev_num, config_item, max_config_len):
def get_daq_device_inventory(interface_type, number_of_devices=100):
def get_err_msg(error_code):
def get_status(board_num, function_type):
def get_net_device_descriptor(host, port, timeout):
def get_tc_values(board_num, chan_list, chan_type_list, chan_count, memhandle, first_point,
                  count, scale, data_array=None):
def ignore_instacal():
def pulse_out_start(board_num, timer_num, frequency, duty_cycle, pulse_count=0, initial_delay=0,
                    idle_state=TimerIdleState.LOW, options=PulseOutOptions.NONE):
def pulse_out_stop(board_num, timer_num):
def release_daq_device(board_num):
def scaled_win_array_to_buf(data_array, memhandle, first_point, count):
def scaled_win_buf_alloc(num_points):
def scaled_win_buf_to_array(memhandle, data_array, first_point, count):
def set_config(info_type, board_num, dev_num, config_item, config_val):
def set_config_string(info_type, board_num, dev_num, config_item, config_val):
def set_trigger(board_num, trig_type, low_threshold, high_threshold):
def stop_background(board_num, function_type):
def teds_read(board_num, channel, count, data_array=None, options=0):
def timer_out_start(board_num, timer_num, frequency):
def timer_out_stop(board_num, timer_num):
def t_in(board_num, channel, scale, options=TInOptions.FILTER):
def t_in_scan(board_num, low_chan, high_chan, scale, options=0, data_array=None):
def to_eng_units(board_num, ul_range, data_value):
def to_eng_units_32(board_num, ul_range, data_value):
def v_in(board_num, channel, ul_range, options=0):
def v_in_32(board_num, channel, ul_range, options=0):
def v_out(board_num, channel, ul_range, data_value, options=0):
def win_array_to_buf(data_array, memhandle, first_point, count):
def win_array_to_buf_32(data_array, memhandle, first_point, count):
def win_buf_alloc(num_points):
def win_buf_alloc_32(num_points):
def win_buf_alloc_64(num_points):
def win_buf_free(memhandle):
def win_buf_to_array(memhandle, data_array, first_point, count):
def win_buf_to_array_32(memhandle, data_array, first_point, count):
def win_buf_to_array_64(memhandle, data_array, first_point, count):
def in_byte(board_num, port_num):
def out_byte(board_num, port_num, port_value):
def in_word(board_num, port_num):
def out_word(board_num, port_num, port_value):
def load_config(config_file_name):
def save_config(config_file_name):
def _to_ctypes_array(list_, datatype):
def _check_err(errcode):
_ERRSTRLEN = 256
_BOARDNAMELEN = 64
mcculw/enums.py
class BoardInfo(IntEnum):
    BASEADR = 0  # Base Address
    BOARDTYPE = 1  # Board Type (0x101 - 0x7FFF)
    INTLEVEL = 2  # Interrupt level
    DMACHAN = 3  # DMA channel
    INITIALIZED = 4  # TRUE or FALSE
    CLOCK = 5  # Clock freq (1, 10 or bus)
    RANGE = 6  # Switch selectable range
    NUMADCHANS = 7  # Number of A/D channels
    USESEXPS = 8  # Supports expansion boards TRUE/FALSE
    DINUMDEVS = 9  # Number of digital devices
    DIDEVNUM = 10  # Index into digital information
    CINUMDEVS = 11  # Number of counter devices
    CIDEVNUM = 12  # Index into counter information
    NUMDACHANS = 13  # Number of D/A channels
    WAITSTATE = 14  # Wait state enabled TRUE/FALSE
    NUMIOPORTS = 15  # I/O address space used by board
    PARENTBOARD = 16  # Board number of parent board
    DTBOARD = 17  # Board number of connected DT board
    NUMEXPS = 18  # Number of EXP boards installed

    # NEW CONFIG ITEMS for 32 bit library
    NOITEM = 99  # NO-OP return no data and returns DEVELOPMENT_OPTION error code
    DACSAMPLEHOLD = 100  # DAC sample and hold jumper state
    DIOENABLE = 101  # DIO enable
    CTR0SRC = 104  # CTR 0 source
    CTR1SRC = 105  # CTR 1 source
    CTR2SRC = 106  # CTR 2 source
    PACERCTR0SRC = 107  # cer CTR 0 source
    DAC0VREF = 108  # DAC 0 voltage reference
    DAC1VREF = 109  # DAC 1 voltage reference
    INTP2LEVEL = 110  # P2 interrupt for CTR10 and CTR20HD
    WAITSTATEP2 = 111  # Wait state 2
    ADPOLARITY = 112  # DAS1600 Polarity state(UNI/BI)
    TRIGEDGE = 113  # DAS1600 trigger edge(RISING/FALLING)
    DACRANGE = 114  # DAC Range (DevNo is channel)
    DACUPDATE = 115  # DAC Update (INDIVIDUAL/SIMULTANEOUS) (DevNo)
    DACINSTALLED = 116  # DAC Installed
    ADCFG = 117  # AD Config (SE/DIFF) (DevNo)
    ADINPUTMODE = 118  # AD Input Mode (Voltage/Current)
    DACPOLARITY = 119  # DAC Startup state (UNI/BI)
    TEMPMODE = 120  # DAS-TEMP Mode (NORMAL/CALIBRATE)
    TEMPREJFREQ = 121  # DAS-TEMP reject frequency
    DISOFILTER = 122  # DISO48 line filter (EN/DIS) (DevNo)
    INT32SRC = 123  # INT32 Intr Src
    INT32PRIORITY = 124  # INT32 Intr Priority
    MEMSIZE = 125  # MEGA-FIFO module size
    MEMCOUNT = 126  # MEGA-FIFO # of modules
    PRNPORT = 127  # PPIO series printer port
    PRNDELAY = 128  # PPIO series printer port delay
    PPIODIO = 129  # PPIO digital line I/O state
    CTR3SRC = 130  # CTR 3 source
    CTR4SRC = 131  # CTR 4 source
    CTR5SRC = 132  # CTR 5 source
    CTRINTSRC = 133  # PCM-D24/CTR3 interrupt source
    CTRLINKING = 134  # PCM-D24/CTR3 ctr linking
    SBX0BOARDNUM = 135  # SBX #0 board number
    SBX0ADDRESS = 136  # SBX #0 address
    SBX0DMACHAN = 137  # SBX #0 DMA channel
    SBX0INTLEVEL0 = 138  # SBX #0 Int Level 0
    SBX0INTLEVEL1 = 139  # SBX #0 Int Level 1
    SBX1BOARDNUM = 140  # SBX #0 board number
    SBX1ADDRESS = 141  # SBX #0 address
    SBX1DMACHAN = 142  # SBX #0 DMA channel
    SBX1INTLEVEL0 = 143  # SBX #0 Int Level 0
    SBX1INTLEVEL1 = 144  # SBX #0 Int Level 1
    SBXBUSWIDTH = 145  # SBX Bus width
    CALFACTOR1 = 146  # DAS08/Jr Cal factor
    CALFACTOR2 = 147  # DAS08/Jr Cal factor
    DACTRIG = 148  # PCI-DAS1602 Dac trig edge
    CHANCFG = 149  # 801/802 chan config (devno =ch)
    PROTOCOL = 150  # 422 protocol
    COMADDR2 = 151  # dual 422 2nd address
    CTSRTS1 = 152  # dual 422 cts/rts1
    CTSRTS2 = 153  # dual 422 cts/rts2
    CTRLLINES = 154  # pcm com 422 ctrl lines
    WAITSTATEP1 = 155  # Wait state P1
    INTP1LEVEL = 156  # P1 interrupt for CTR10 and CTR20HD
    CTR6SRC = 157  # CTR 6 source
    CTR7SRC = 158  # CTR 7 source
    CTR8SRC = 159  # CTR 8 source
    CTR9SRC = 160  # CTR 9 source
    CTR10SRC = 161  # CTR 10 source
    CTR11SRC = 162  # CTR 11 source
    CTR12SRC = 163  # CTR 12 source
    CTR13SRC = 164  # CTR 13 source
    CTR14SRC = 165  # CTR 14 source
    TCGLOBALAVG = 166  # DASTC global average
    TCCJCSTATE = 167  # DASTC CJC State(=ON or OFF)
    TCCHANRANGE = 168  # DASTC Channel Gain
    TCCHANTYPE = 169  # Deprecated, use CHANTCTYPE /* DASTC Channel thermocouple type */
    FWVERSION = 170  # Firmware Version
    PHACFG = 180  # Quad PhaseA config (devNo =ch)
    PHBCFG = 190  # Quad PhaseB config (devNo =ch)
    INDEXCFG = 200  # Quad Index Ref config (devNo =ch)
    SLOTNUM = 201  # PCI/PCM card slot number
    AIWAVETYPE = 202  # analog input wave type (for demo board)
    PWRUPSTATE = 203  # DDA06 pwr up state jumper
    IRQCONNECT = 204  # DAS08 pin6 to 24 jumper
    TRIGPOLARITY = 205  # PCM DAS16xx Trig Polarity
    CTLRNUM = 206  # MetraBus controller board number
    PWRJMPR = 207  # MetraBus controller board Pwr jumper
    NUMTEMPCHANS = 208  # Number of Temperature channels
    ADTRIGSRC = 209  # A/D trigger source
    BNCSRC = 210  # BNC source
    BNCTHRESHOLD = 211  # BNC Threshold 2.5V or 0.0V
    BURSTMODE = 212  # Board supports BURSTMODE scans
    DITHERON = 213
    SERIALNUM = 214  # User Serial Number for HID boards
    DACUPDATEMODE = 215  # Update immediately or upon AOUPDATE command
    DACUPDATECMD = 216  # Issue D/A UPDATE command
    DACRESTORE = 217  # Restore last value written or reset to ground
    DACSTARTUP = DACRESTORE
    ACCOUPLED = 218  # A/D AC(=1) or DC(=0) coupling
    ADTRIGCOUNT = 219  # Number of samples to acquire per trigger
    ADFIFOSIZE = 220
    ADSOURCE = 221
    CALOUTPUT = 222  # CAL output pin setting
    SRCADPACER = 223  # Source A/D Pacer output
    MFGSERIALNUM = 224  # Manufacturers 8-byte serial number
    PCIREVID = 225  # Revision Number stored in PCI header
    BOARDTEMP = 226  # Internal board temperature. Could be used as CJC.
    EXTCLKTYPE = 227  # Free-running/Continuous or Gated/Synchronized
    RELAYLOGIC = 228  # ActiveLow = 1, ActiveHigh = 0
    OPENRELAYLEVEL = 229  # DefaultLow = 0, DefaultHigh = 1
    DIALARMMASK = 230  # ON_CHANGE_DIG_INPUT alarm event mask
    DEFAULTIP = 231
    CURRENTIP = 232
    DHCPENABLED = 233
    CURRENTPORT = 234
    TEMPSENSORTYPE = 235
    TEMPCONNECTIONTYPE = 236
    TEMPEXCITATION = 237
    TEMPCHANGAIN = 238
    OWNERNAME = 239
    OWNERIP = 240
    TBASERES = 241
    TEMPCALIBRATE = 242
    CURRENTGATEWAYIP = 243
    DEFAULTGATEWAYIP = 244
    CURRENTSUBNET = 245
    DEFAULTSUBNET = 246
    NETIOTIMEOUT = 247
    NETMINPORT = 248
    ADCHANAIMODE = 249
    DACFORCESENSE = 250
    SYNCMODE = 251  # master = 0, slave =1
    ADCPACEROUT = 252  # Enable/Disable A/D Pacer output
    DACPACEROUT = 253
    CALTABLETYPE = 254
    DIDEBOUNCESTATE = 255
    DIDEBOUNCETIME = 256
    BUSNUM = 257
    PANID = 258
    RFCHANNEL = 259
    POWERLEVEL = 260
    RSS = 261
    NODEID = 262
    DEVNOTES = 263
    PROGRAMDEV = 264
    INTEDGE = 265
    RFCHANENERGY = 266
    ADCCALIBRATE = 267
    ADCCALSTEPS = 268
    TEMPCALSTEPS = 269
    ADCSETTLETIME = 270
    WEBSERVERENABLE = 271
    FACTORYID = 272
    HTTPPORT = 273
    HIDELOGINDLG = 274
    ACTUALDAQSCANRATE = 275
    USBQUERY = 276
    DACXFERPRIMECOUNT = 277
    EXTPOWERSTATE = 278
    CHANBWMODE = 279
    TEMPSCALE = 280
    CALDACVREF = 281
    DACCALVOLT = 282
    USERADCSETTLETIME = 283
    DACTRIGCOUNT = 284
    ADTIMINGMODE = 285
    RTDCHANTYPE = 286  # Deprecated use CHANRTDTYPE
    TERMINALCOUNTSTATUSENABLE = 287
    ATRIGCALIBRATE = 288
    ADEXCITATION = 289  # Deprecated use EXCITATION
    ADBRIDGETYPE = 290  # Deprecated use CHANBRIDGETYPE
    ADRES = 291
    DACRES = 292
    CALTIMEOUT = 293
    ADLOADCALCOEFS = 294
    DACLOADCALCOEFS = 295
    CLOCKTIME = 296
    BUTTONSTATE = 297
    INTERFACEPATH = 298
    DACCALIBRATE = 299
    ATRIGRANGE = 300
    LEDPATTERN = 301
    ADCAVGCOUNT = 302  # ADC Averaging sample count
    DEVINST = 303  # retrieves DEVINST values to be used by CM_Device_Id etc...
    DIFILTERTIME = 304
    DISTATERETENTION = 305
    ADXFERMODE = 306
    CTRTRIGCOUNT = 307
    DAQITRIGCOUNT = 308

    HASEXTINFO = 309  # Indicates if devices has extended info
    NUMIODEVS = 310  # Number of IO devices
    IODEVTYPE = 311  # Type of IO device
    ADNUMCHANMODES = 312  # Number of channel modes
    ADCHANMODE = 313  # Channel mode
    ADNUMDIFFRANGES = 314  # Number of differncial ranges supported by devide
    ADDIFFRANGE = 315
    ADNUMSERANGES = 316  # Number of Single-Ended ranges supported by devide
    ADSERANGE = 317
    ADNUMTRIGTYPES = 318
    ADTRIGTYPE = 319
    ADMAXRATE = 320
    ADMAXTHROUGHPUT = 321
    ADMAXBURSTRATE = 322
    ADMAXBURSTTHROUGHPUT = 323
    ADHASPACER = 324
    ADCHANTYPES = 325
    ADSCANOPTIONS = 326
    ADMAXSEQUEUELENGTH = 327
    ADMAXDIFFQUEUELENGTH = 328
    ADQUEUETYPES = 329
    ADQUEUELIMITS = 330

    DACHASPACER = 331
    DACSCANOPTIONS = 332
    DACFIFOSIZE = 333
    DACNUMRANGES = 334  # Number of ranges supported by dac devide
    DACDEVRANGE = 335  # DACRANGE is already defined
    DACNUMTRIGTYPES = 336
    DACTRIGTYPE = 337
    DAQAMISUPPORTED = 338

    DISCONNECT = 340
    NETCONNECTCODE = 341

    CONNECTED = 342

    DITRIGCOUNT = 343  # Number of digital input samples to acquire per trigger
    DOTRIGCOUNT = 344  # Number of digital output samples to generate per trigger
    PATTERNTRIGPORT = 345

    CHANTCTYPE = 347  # Channel thermocouple type
    EXTINPACEREDGE = 348
    EXTOUTPACEREDGE = 349
    INPUTPACEROUT = 350  # Enable/Disable input Pacer output
    OUTPUTPACEROUT = 351  # Enable/Disable output Pacer output
    TEMPAVG = 352
    EXCITATION = 353
    CHANBRIDGETYPE = 354
    ADCHANTYPE = 355
    CHANRTDTYPE = 356
    # Unique identifier of DAQ device. Serial Number (USB devices), MAC
    # address (Ethernet devices)
    DEVUNIQUEID = 357
    USERDEVID = 358
    DEVVERSION = 359
    TERMCOUNTSTATBIT = 360
    DETECTOPENTC = 361
    ADDATARATE = 362
    DEVSERIALNUM = 363
    DEVMACADDR = 364
    USERDEVIDNUM = 365  # User device ID for HID devices
    NETBIOSNAME = 366
    DISCANOPTIONS = 367
    DOSCANOPTIONS = 368
    CTRSCANOPTIONS = 369
    DAQISCANOPTIONS = 370
    DAQOSCANOPTIONS = 371
    DEVCLASS = 372
    ADAIMODE = 373
    DEVIPADDR = 374
    DACDISABLERESTORE = 375

    DAQINUMCHANTYPES = 376
    DAQICHANTYPE = 377
    DAQONUMCHANTYPES = 378
    DAQOCHANTYPE = 379
    BICTRZACTIVEMODE = 380
mcculw/device_info/ctr_info.py
class CtrInfo:
    """Provides counter information for the device with the specified
    board number.

    NOTE: This class is primarily used to provide hardware information for the
    library examples and may change some hardware configuration values. It is
    recommended that values provided by this class be hard-coded in production
    code.

    Parameters
    ----------
    board_num : int
        The board number associated with the device when created with
        :func:`.create_daq_device` or configured with Instacal.
    """
    def __init__(self, board_num):
        self._board_num = board_num

    @property
    def num_chans(self):
        return ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                             BoardInfo.CINUMDEVS)

    @property
    def is_supported(self):
        return self.num_chans > 0

    @property
    def chan_info(self):
        chan_info_list = []
        for chan_index in range(self.num_chans):
            channel_info = CtrChanInfo(self._board_num, chan_index)
            chan_info_list.append(channel_info)
        return chan_info_list
mcculw/enums.py
class InfoType(IntEnum):
    GLOBALINFO = 1
    BOARDINFO = 2
    DIGITALINFO = 3
    COUNTERINFO = 4
    EXPANSIONINFO = 5
    MISCINFO = 6
    EXPINFOARRAY = 7
    MEMINFO = 8
mcculw/ul.py
class ULError(Exception):
    def __init__(self, errorcode):
        super(ULError, self).__init__()
        self.errorcode = errorcode
        self.message = get_err_msg(errorcode)

    def __str__(self):
        return "Error " + str(self.errorcode) + ": " + self.message
mcculw/enums.py
class ExpansionInfo(IntEnum):
    BOARDTYPE = 0  # Board type
    MUX_AD_CHAN1 = 1  # 0 - 7
    MUX_AD_CHAN2 = 2  # 0 - 7 or NOTUSED
    RANGE1 = 3  # Range (gain) of low 16 chans
    RANGE2 = 4  # Range (gain) of high 16 chans
    CJCCHAN = 5  # TYPE_8254_CTR or TYPE_9513_CTR
    THERMTYPE = 6  # TYPEJ, TYPEK, TYPET, TYPEE, TYPER, or TYPES
    NUMEXPCHANS = 7  # Number of expansion channels on board
    PARENTBOARD = 8  # Board number of parent A/D board
    SPARE0 = 9  # 16 words of misc options

    FIVEVOLTSOURCE = 100  # ICAL DATA - 5 volt source
    CHANCONFIG = 101  # exp Data - chan config 2/4 or 3-wire devNo=chan
    VSOURCE = 102  # ICAL DATA - voltage source
    VSELECT = 103  # ICAL Data - voltage select
    CHGAIN = 104  # exp Data - individual ch gain
    GND = 105  # ICAL DATA - exp grounding
    VADCHAN = 106  # ICAL DATA - Vexe A/D chan
    RESISTANCE = 107  # exp Data - resistance @0 (devNo =ch)
    FACGAIN = 108  # ICAL DATA - RTD factory gain
    CUSTOMGAIN = 109  # ICAL DATA - RTD custom gain
    CHCUSTOM = 110  # ICAL DATA - RTD custom gain setting
    IEXE = 111  # ICAL DATA - RTD Iexe
mcculw/device_info/daqi_info.py
class DaqiInfo:
    """Provides DAQ input information for the device with the specified
    board number.

    NOTE: This class is primarily used to provide hardware information for the
    library examples and may change some hardware configuration values. It is
    recommended that values provided by this class be hard-coded in production
    code.

    Parameters
    ----------
    board_num : int
        The board number associated with the device when created with
        :func:`.create_daq_device` or configured with Instacal.
    """
    def __init__(self, board_num):
        self._board_num = board_num

    @property
    def is_supported(self):
        daqi_supported = True
        try:
            ul.get_status(self._board_num, FunctionType.DAQIFUNCTION)
        except ul.ULError:
            daqi_supported = False
        return daqi_supported

    @property
    def supported_channel_types(self):
        chan_types = []

        if self.is_supported:
            count = ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                                  BoardInfo.DAQINUMCHANTYPES)

            for type_index in range(count):
                chan_type = ul.get_config(InfoType.BOARDINFO, self._board_num,
                                          type_index, BoardInfo.DAQICHANTYPE)
                chan_types.append(ChannelType(chan_type))

        return chan_types

    @property
    def supports_setpoints(self):
        setpoints_supported = False
        if self.is_supported:
            try:
                ul.daq_set_setpoints(self._board_num, [], [], [], [], [], [],
                                     [], [], 0)
                setpoints_supported = True
            except ULError:
                setpoints_supported = False

        return setpoints_supported
mcculw/device_info/ai_info.py
class AiInfo:
    """Provides analog input information for the device with the specified
    board number.

    NOTE: This class is primarily used to provide hardware information for the
    library examples and may change some hardware configuration values. It is
    recommended that values provided by this class be hard-coded in production
    code.

    Parameters
    ----------
    board_num : int
        The board number associated with the device when created with
        :func:`.create_daq_device` or configured with Instacal.
    """
    def __init__(self, board_num):
        self._board_num = board_num
        # Get the board type from UL
        self._board_type = ul.get_config(InfoType.BOARDINFO, self._board_num,
                                         0, BoardInfo.BOARDTYPE)

    @property
    def board_num(self):
        return self._board_num

    @property
    def num_chans(self):
        return ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                             BoardInfo.NUMADCHANS)

    @property
    def is_supported(self):
        return self.num_chans > 0

    @property
    def num_temp_chans(self):
        return ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                             BoardInfo.NUMTEMPCHANS)

    @property
    def temp_supported(self):
        return self.num_temp_chans > 0

    @property
    def resolution(self):
        return ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                             BoardInfo.ADRES)

    @property
    def supports_scan(self):
        scan_supported = True
        try:
            ul.get_status(self._board_num, FunctionType.AIFUNCTION)
        except ULError:
            scan_supported = False
        return scan_supported

    @property
    def supported_ranges(self):
        result = []

        # Check if the board has a switch-selectable, or only one, range
        hard_range = ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                                   BoardInfo.RANGE)

        if hard_range >= 0:
            result.append(ULRange(hard_range))
        else:
            for ai_range in ULRange:
                try:
                    if self.resolution <= 16:
                        ul.a_in(self._board_num, 0, ai_range)
                    else:
                        ul.a_in_32(self._board_num, 0, ai_range)
                    result.append(ai_range)
                except ULError as e:
                    if (e.errorcode == ErrorCode.NETDEVINUSE or
                            e.errorcode == ErrorCode.NETDEVINUSEBYANOTHERPROC):
                        raise

        return result

    @property
    def packet_size(self):
        """
        The hardware in the following table will return a packet size.
        This hardware must use an integer multiple of the packet size as
        the total_count for a_in_scan when using the
        :const:`~mcculw.enums.CONTINUOUS` option in
        :const:`~mcculw.enums.BLOCKIO` mode.

        For all other hardware, this method will return 1.

        ==========  ==========  ===========
        Hardware    Product Id  Packet Size
        ==========  ==========  ===========
        USB-1208LS  122         64
        USB-1208FS  130         31
        USB-1408FS  161         31
        USB-7204    240         31
        ==========  ==========  ===========
        """
        packet_size = 1
        if self._board_type == 122:
            packet_size = 64
        elif self._board_type in [130, 161, 240]:
            packet_size = 31

        return packet_size

    @property
    def supports_v_in(self):
        v_in_supported = True
        ai_ranges = self.supported_ranges
        if not ai_ranges:
            v_in_supported = False
        else:
            try:
                ul.v_in(self._board_num, 0, ai_ranges[0])
            except ULError:
                v_in_supported = False
        return v_in_supported

    @property
    def analog_trig_resolution(self):
        # PCI-DAS6030, 6031, 6032, 6033, 6052
        # USB-1602HS, 1602HS-2AO, 1604HS, 1604HS-2AO
        # PCI-2511, 2513, 2515, 2517, USB-2523, 2527, 2533, 2537
        # USB-1616HS, 1616HS-2, 1616HS-4, 1616HS-BNC
        trig_res_12_bit_types = [95, 96, 97, 98, 102, 165, 166, 167, 168, 177,
                                 178, 179, 180, 203, 204, 205, 213, 214, 215,
                                 216, 217]

        # PCI-DAS6040, 6070, 6071
        trig_res_8_bit_types = [101, 103, 104]

        trigger_resolution = 0
        if self._board_type in trig_res_12_bit_types:
            trigger_resolution = 12
        elif self._board_type in trig_res_8_bit_types:
            trigger_resolution = 8

        return trigger_resolution

    @property
    def analog_trig_range(self):
        # Get the analog trigger source
        try:
            trig_source = ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                                        BoardInfo.ADTRIGSRC)
        except ULError:
            trig_source = 0

        if self.analog_trig_resolution > 0 and trig_source <= 0:
            trigger_range = ULRange.BIP10VOLTS
        else:
            trigger_range = ULRange.UNKNOWN

        return trigger_range

    @property
    def supports_analog_trig(self):
        analog_trig_supported = True
        try:
            ul.set_trigger(self._board_num, TrigType.TRIG_ABOVE, 0, 0)
        except ULError:
            analog_trig_supported = False
        return analog_trig_supported

    @property
    def supported_scan_options(self):
        if self.supports_scan:
            scan_options_supported = ScanOptions(ul.get_config(
                InfoType.BOARDINFO, self._board_num, 0,
                BoardInfo.ADSCANOPTIONS))
        else:
            scan_options_supported = None
        return scan_options_supported

    @property
    def supports_gain_queue(self):
        gain_queue_supported = True
        try:
            ul.a_load_queue(self._board_num, [], [], 0)
        except ULError:
            gain_queue_supported = False
        return gain_queue_supported
mcculw/device_info/dio_info.py
class DioInfo:
    """Provides digital input/output information for the device with the
    specified board number.

    NOTE: This class is primarily used to provide hardware information for the
    library examples and may change some hardware configuration values. It is
    recommended that values provided by this class be hard-coded in production
    code.

    Parameters
    ----------
    board_num : int
        The board number associated with the device when created with
        :func:`.create_daq_device` or configured with Instacal.
    """
    def __init__(self, board_num):
        self._board_num = board_num

    @property
    def num_ports(self):
        try:
            port_count = ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                                       BoardInfo.DINUMDEVS)
        except ULError:
            port_count = 0

        return port_count

    @property
    def is_supported(self):
        return self.num_ports > 0

    @property
    def port_info(self):
        port_info_list = []
        for port_index in range(self.num_ports):
            port_info_list.append(PortInfo(self._board_num, port_index))
        return port_info_list
mcculw/device_info/daqo_info.py
class DaqoInfo:
    """Provides DAQ output information for the device with the specified
    board number.

    NOTE: This class is primarily used to provide hardware information for the
    library examples and may change some hardware configuration values. It is
    recommended that values provided by this class be hard-coded in production
    code.

    Parameters
    ----------
    board_num : int
        The board number associated with the device when created with
        :func:`.create_daq_device` or configured with Instacal.
    """
    def __init__(self, board_num):
        self._board_num = board_num

    @property
    def is_supported(self):
        daqo_supported = True
        try:
            ul.get_status(self._board_num, FunctionType.DAQOFUNCTION)
        except ULError:
            daqo_supported = False
        return daqo_supported

    @property
    def supported_channel_types(self):
        chan_types = []

        if self.is_supported:
            count = ul.get_config(InfoType.BOARDINFO, self._board_num, 0,
                                  BoardInfo.DAQONUMCHANTYPES)

            for type_index in range(count):
                chan_type = ul.get_config(InfoType.BOARDINFO, self._board_num,
                                          type_index, BoardInfo.DAQOCHANTYPE)
                chan_types.append(ChannelType(chan_type))

        return chan_types


Question: from builtins import *  # @UnusedWildImport
from mcculw import ul
from mcculw.ul import ULError
from mcculw.enums import (BoardInfo, InfoType, ErrorCode, EventType,
                          ExpansionInfo)
from .ai_info import AiInfo
from .ao_info import AoInfo
from .ctr_info import CtrInfo
from .daqi_info import DaqiInfo
from .daqo_info import DaqoInfo
from .dio_info import DioInfo

    NOTE: This class is primarily used to provide hardware information for the
    library examples and may change some hardware configuration values. It is
    recommended that values provided by this class be hard-coded in production
    code.

    Parameters
    ----------
    board_num : int
        The board number associated with the device when created with
        :func:`.create_daq_device` or configured with Instacal.
    """

    def __init__(self, board_num):
        self._board_num = board_num
        self._board_type = ul.get_config(InfoType.BOARDINFO, board_num, 0,
                                         BoardInfo.BOARDTYPE)
        if self._board_type == 0:
            raise ULError(ErrorCode.BADBOARD)

        self._ai_info = AiInfo(self._board_num)
        self._ao_info = AoInfo(self._board_num)
        self._ctr_info = CtrInfo(self._board_num)
        self._daqi_info = DaqiInfo(self._board_num)
        self._daqo_info = DaqoInfo(self._board_num)
        self._dio_info = DioInfo(self._board_num)

    @property
    def board_num(self):  # -> int
        return self._board_num

    @property
    def product_name(self):  # -> str
        return ul.get_board_name(self._board_num)

    @property
    def unique_id(self):  # -> str
        return ul.get_config_string(InfoType.BOARDINFO, self._board_num, 0,
                                    BoardInfo.DEVUNIQUEID, 32)

    @property
    def supports_analog_input(self):  # -> boolean
        return self._ai_info.is_supported

    @property
    def supports_temp_input(self):  # -> boolean
        return self._ai_info.temp_supported

    def get_ai_info(self):  # -> AiInfo
        return self._ai_info

    @property
    def supports_analog_output(self):  # -> boolean
        return self._ao_info.is_supported

    def get_ao_info(self):  # -> AoInfo
        return self._ao_info

    @property
    def supports_counters(self):  # -> boolean
        return self._ctr_info.is_supported

    def get_ctr_info(self):  # -> CtrInfo
        return self._ctr_info

    @property
    def supports_daq_input(self):  # -> boolean
        return self._daqi_info.is_supported

    def get_daqi_info(self):  # -> DaqiInfo
        return self._daqi_info

    @property
    def supports_daq_output(self):  # -> boolean
        return self._daqo_info.is_supported

    def get_daqo_info(self):  # -> DaqoInfo
        return self._daqo_info

    @property
    def supports_digital_io(self):  # -> boolean
        return self._dio_info.is_supported

    def get_dio_info(self):  # -> DioInfo
        return self._dio_info

    @property
    def supported_event_types(self):  # -> list[EventType]
        event_types = []

        for event_type in EventType:
            try:
                ul.disable_event(self._board_num, event_type)
                event_types.append(event_type)
            except ULError:
                pass

        return event_types

    @property
    def num_expansions(self):  # -> int
        return ul.get_config(InfoType.BOARDINFO, self.board_num, 0,
                             BoardInfo.NUMEXPS)

    @property
    def exp_info(self):  # -> list[ExpInfo]
        exp_info = []
        for expansion_num in range(self.num_expansions):
            exp_info.append(ExpInfo(self._board_num, expansion_num))
        return exp_info


class ExpInfo:
    def __init__(self, board_num, expansion_num):
        self._board_num = board_num
        self._expansion_num = expansion_num

    @property
    def board_type(self):
        return ul.get_config(InfoType.EXPANSIONINFO, self._board_num,

Answer:                              self._expansion_num, ExpansionInfo.BOARDTYPE)