예제 #1
0
    def __init__(self, manager, resID, **kwargs):
        assert (isinstance(manager, labtronyx.InstrumentManager))

        super(r_Serial, self).__init__(manager, resID, **kwargs)

        # Ensure resource doesn't already exist
        if len(manager.plugin_manager.searchPluginInstances(pluginType='resource', interfaceName='Serial',
                                                            resID=resID)) > 0:
            raise labtronyx.InterfaceError("Resource already exists")

        try:
            self.instrument = serial.Serial(port=resID, timeout=0)

            self.logger.debug("Created Serial resource: %s", resID)

            # Serial port is immediately opened on object creation
            self.close()

        except (serial.SerialException, OSError) as e:
            if os.name == 'nt':
                # Windows implementation of PySerial does not set errno correctly
                import ctypes
                e.errno = ctypes.WinError().errno

            if e.errno in [errno.ENOENT, errno.EACCES, errno.EBUSY]:
                raise labtronyx.ResourceUnavailable('Serial resource error: %s' % resID)

            else:
                raise labtronyx.InterfaceError('Serial interface error [%i]: %s' % (e.errno, e.message))
예제 #2
0
    def __init__(self, manager, resID, **kwargs):
        assert (isinstance(manager, labtronyx.InstrumentManager))

        super(r_VISA, self).__init__(manager, resID, **kwargs)

        # Ensure dependency was resolved correctly
        if not isinstance(self.interface, i_VISA):
            raise labtronyx.InterfaceError("VISA Interface is not enabled")

        # Ensure resource doesn't already exist
        if len(
                manager.plugin_manager.searchPluginInstances(
                    pluginType='resource', interfaceName='VISA',
                    resID=resID)) > 0:
            raise labtronyx.InterfaceError("Resource already exists")

        try:
            self.instrument = self.interface.resource_manager.open_resource(
                resID)

            self.logger.debug("Created VISA resource: %s", resID)

            # Instance variables
            self._identity = []
            self._conf = {  # Default configuration
                'read_termination': '\r',
                'write_termination': '\r\n',
                'timeout': 2000
            }
            self._resourceType = self.RES_TYPES.get(
                self.instrument.interface_type, 'VISA')

            # Instrument is created in the open state, but we do not want to lock the VISA instrument
            self.close()

            # Set a flag to initialize the resource when it is used
            self.ready = False

        # except AttributeError:
        #     raise labtronyx.ResourceUnavailable('Invalid VISA Resource Identifier: %s' % resID)

        except visa.VisaIOError as e:
            if e.abbreviation in [
                    "VI_ERROR_RSRC_BUSY", "VI_ERROR_RSRC_NFOUND",
                    "VI_ERROR_TMO", "VI_ERROR_INV_RSRC_NAME"
            ]:  # Returned by TekVISA

                raise labtronyx.ResourceUnavailable('VISA Resource Error: %s' %
                                                    e.abbreviation)

            else:
                raise labtronyx.InterfaceError('VISA Interface Error: %s' %
                                               e.abbreviation)
예제 #3
0
 def read_raw(self, size=None):
     """
     Read Binary-encoded data from the instrument.
     
     No termination characters are stripped.
     
     :param size:    Number of bytes to read
     :type size:     int
     :returns:       bytes
     :raises:        ResourceNotOpen
     """
     try:
         ret = bytes()
         
         if size is None:
             size = self.instrument.inWaiting()
         
         ret += self.instrument.read(size)
         if len(ret) != len(size):
             raise labtronyx.InterfaceTimeout("Timeout before requested bytes could be read")
             
         return ret
     
     except SerialException as e:
         if e == serial.portNotOpenError:
             raise labtronyx.ResourceNotOpen()
         else:
             raise labtronyx.InterfaceError(e.strerror)
예제 #4
0
    def read(self, termination=None):
        """
        Read string data from the instrument.
        
        Reading stops when the device stops sending, or the termination 
        characters sequence was detected.
        
        All line-ending characters are stripped from the end of the string.

        :raises:        ResourceNotOpen
        """
        try:
            ret = ''
            
            if termination is None:
                bytes_waiting = self.instrument.inWaiting()
                ret += self.instrument.read(bytes_waiting)
            
            else:
                ret += self.instrument.read(1)
                while ret[-1] != self.termination[-1] or self.instrument.inWaiting() == 0:
                    ret += self.instrument.read(1)
                ret = ret[:-len(self.termination)]
        
            return ret
        
        except SerialException as e:
            if e == serial.portNotOpenError:
                raise labtronyx.ResourceNotOpen()
            else:
                raise labtronyx.InterfaceError(e.strerror)
예제 #5
0
    def write(self, data):
        """
        Send ASCII-encoded data to the instrument. Includes termination character.
        
        Raises exception if the resource is not open
        
        :param data:    Data to send
        :type data:     str
        :raises:        ResourceNotOpen
        :raises:        InterfaceTimeout
        :raises:        InterfaceError
        """
        try:
            self.logger.debug("Serial Write: %s", data)
            self.instrument.write(data + self.termination)
            
        except SerialException as e:
            if e == serial.portNotOpenError:
                raise labtronyx.ResourceNotOpen()

            elif e == serial.writeTimeoutError:
                raise labtronyx.InterfaceTimeout()

            else:
                raise labtronyx.InterfaceError(e.strerror)
예제 #6
0
    def query(self, data, delay=None):
        """
        Retrieve ASCII-encoded data from the device given a prompt.
        
        A combination of write(data) and read()
        
        :param data:        Data to send
        :type data:         str
        :param delay:       delay (in seconds) between write and read operations.
        :type delay:        float
        :returns:           str
        :raises:            labtronyx.ResourceNotOpen
        :raises:            labtronyx.InterfaceTimeout
        :raises:            labtronyx.InterfaceError
        """
        try:
            ret_data = self.instrument.query(data)

            self.logger.debug("VISA Query: %s returned: %s", data, ret_data)

            return ret_data

        except visa.InvalidSession:
            raise labtronyx.ResourceNotOpen

        except visa.VisaIOError as e:
            if e.abbreviation in ["VI_ERROR_TMO"]:
                raise labtronyx.InterfaceTimeout(e.description)
            else:
                raise labtronyx.InterfaceError(e.description)
예제 #7
0
    def enumerate(self):
        """
        Identify all devices known to the VISA driver and create resource objects for valid resources
        """
        if self.__resource_manager is None:
            raise labtronyx.InterfaceError("Interface not open")

        self.logger.debug("Enumerating VISA interface")

        try:
            new_res_list = [
                res for res in self.__resource_manager.list_resources()
                if res not in self.resources_by_id
            ]

            # Check for new resources
            for resID in new_res_list:
                try:
                    self.openResource(resID)

                except labtronyx.ResourceUnavailable:
                    pass

        except visa.VisaIOError as e:
            # Exception thrown when there are no resources
            self.logger.exception('VISA Exception during enumeration')
예제 #8
0
    def read(self, termination=None, encoding=None):
        """
        Read ASCII-formatted data from the instrument.
        
        Reading stops when the device stops sending, or the termination characters sequence was detected. All
        line-ending characters are stripped from the end of the string.
        
        :param termination: Line termination
        :type termination:  str
        :param encoding:    Encoding
        :type encoding:     str
        :return:            str
        :raises:            labtronyx.ResourceNotOpen
        :raises:            labtronyx.InterfaceTimeout
        :raises:            labtronyx.InterfaceError
        """
        try:
            data = self.instrument.read(termination, encoding)

            self.logger.debug("VISA Read: %s", data)

            return data

        except visa.InvalidSession:
            raise labtronyx.ResourceNotOpen()

        except visa.VisaIOError as e:
            if e.abbreviation in ["VI_ERROR_TMO"]:
                raise labtronyx.InterfaceTimeout(e.description)
            else:
                raise labtronyx.InterfaceError(e.description)
예제 #9
0
    def flush(self):
        """
        Flush the output buffer
        """
        try:
            return self.instrument.flush()

        except serial.SerialException as e:
            raise labtronyx.InterfaceError(e.strerror)
예제 #10
0
    def inWaiting(self):
        """
        Return the number of bytes in the receive buffer
        
        :returns:       int
        :raises:        InterfaceError
        """
        try:
            return self.instrument.inWaiting()

        except serial.SerialException as e:
            raise labtronyx.InterfaceError(e.strerror)
예제 #11
0
    def getResource(self, resID):
        """
        Attempt to open a Serial instrument. If successful, a serial resource is added to the list of known resources
        and the object is returned.

        :return:        object
        :raises:        ResourceUnavailable
        :raises:        InterfaceError
        """
        if resID in self.resources_by_id:
            raise labtronyx.InterfaceError("Resource instance already exists")

        try:
            instrument = serial.Serial(port=resID, timeout=0)

            res_obj = self.manager.plugin_manager.createPluginInstance(r_Serial.fqn, manager=self.manager,
                                                                       interface=self,
                                                                       resID=resID,
                                                                       instrument=instrument,
                                                                       logger=self.logger
                                                                       )

            # Signal new resource event
            self.manager._publishEvent(labtronyx.EventCodes.resource.created, res_obj.uuid)

            return res_obj

        except (serial.SerialException, OSError) as e:
            if os.name == 'nt':
                # Windows implementation of PySerial does not set errno correctly
                import ctypes
                e.errno = ctypes.WinError().errno

            if e.errno in [errno.ENOENT, errno.EACCES, errno.EBUSY]:
                raise labtronyx.ResourceUnavailable('Serial resource error: %s' % resID)

            else:
                raise labtronyx.InterfaceError('Serial interface error [%i]: %s' % (e.errno, e.message))
예제 #12
0
    def read_raw(self, size=None):
        """
        Read Binary-encoded data directly from the instrument.
        
        :param size:        Number of bytes to read
        :type size:         int
        :raises:            labtronyx.ResourceNotOpen
        :raises:            labtronyx.InterfaceTimeout
        :raises:            labtronyx.InterfaceError
        """
        ret = bytes()

        try:
            if type(self.instrument
                    ) == pyvisa.resources.serial.SerialInstrument:
                # There is a bug in PyVISA that forces a low-level call (hgrecco/pyvisa #93)
                with self.instrument.ignore_warning(
                        pyvisa.constants.VI_SUCCESS_MAX_CNT):
                    if size is None:
                        num_bytes = self.instrument.bytes_in_buffer
                        chunk, status = self.instrument.visalib.read(
                            self.instrument.session, num_bytes)
                        ret += chunk

                    else:
                        while len(ret) < size:
                            chunk, status = self.instrument.visalib.read(
                                self.instrument.session, size - len(ret))
                            ret += chunk

                return ret

            else:
                return self.instrument.read_raw()

        except visa.InvalidSession:
            raise labtronyx.ResourceNotOpen

        except visa.VisaIOError as e:
            if e.abbreviation in ["VI_ERROR_TMO"]:
                raise labtronyx.InterfaceTimeout(e.description)
            else:
                raise labtronyx.InterfaceError(e.description)
예제 #13
0
    def write_raw(self, data):
        """
        Send Binary-encoded data to the instrument without modification
        
        :param data:        Data to send
        :type data:         str
        :raises:            labtronyx.ResourceNotOpen
        :raises:            labtronyx.InterfaceError
        """
        try:
            self.instrument.write_raw(data)

            self.logger.debug("VISA Write: %s", data)

        except visa.InvalidSession:
            raise labtronyx.ResourceNotOpen()

        except visa.VisaIOError as e:
            raise labtronyx.InterfaceError(e.description)
예제 #14
0
    def write(self, data):
        """
        Send ASCII-encoded data to the instrument. Termination character is appended automatically, according to
        `write_termination` property.
        
        :param data:        Data to send
        :type data:         str
        :raises:            labtronyx.ResourceNotOpen
        :raises:            labtronyx.InterfaceError
        """
        try:
            self.instrument.write(data)

            self.logger.debug("VISA Write: %s", data)

        except visa.InvalidSession:
            raise labtronyx.ResourceNotOpen()

        except visa.VisaIOError as e:
            raise labtronyx.InterfaceError(e.description)
예제 #15
0
    def write_raw(self, data):
        """
        Send Binary-encoded data to the instrument. Termination character is
        not included
        
        :param data:    Data to send
        :type data:     str
        :raises:        ResourceNotOpen
        :raises:        InterfaceTimeout
        :raises:        InterfaceError
        """
        try:
            self.instrument.write(data)
            
        except SerialException as e:
            if e == serial.portNotOpenError:
                raise labtronyx.ResourceNotOpen()

            elif e == serial.writeTimeoutError:
                raise labtronyx.InterfaceTimeout()

            else:
                raise labtronyx.InterfaceError(e.strerror)
예제 #16
0
    def prune(self):
        """
        Close any resources that are no longer known to the VISA interface
        """
        if self.__resource_manager is None:
            raise labtronyx.InterfaceError("Interface not open")

        try:
            # Get a fresh list of resources
            res_list = self.__resource_manager.list_resources()
        except visa.VisaIOError:
            # Exception thrown when there are no resources
            res_list = []

        for res_uuid, res_obj in self.resources.items():
            resID = res_obj.resID

            if resID not in res_list:
                res_obj.close()

                self.manager.plugin_manager.destroyPluginInstance(res_uuid)
                self.manager._publishEvent(
                    labtronyx.EventCodes.resource.destroyed, res_obj.uuid)