Esempio n. 1
0
    def monitor(self,
                mask=pyca.DBE_VALUE | pyca.DBE_LOG | pyca.DBE_ALARM,
                ctrl=None,
                count=None):
        """
        Subscribe to monitor events from the PV channel

        Much of the functionality of this meth is wrapped in higher level
        utilities

        Parameters
        ----------
        mask : int
            Mask to select which monitor events to subscribe to using pyca
            variables including, pyca.DBE_VALUE for changes to PV value,
            pyca.DBE_ALARM, for changes in the alarm state, and pyca.DBE_LOG
            for anything else

        ctrl : bool, optional
            Choice to monitor the control or time value. By default,
            :attr:`.control` is used

        count : int, optional
            Subsection of waveform record to monitor. By default,
            :attr:`.count` is used

        See Also
        --------
        :meth:`.monitor_start`, :meth:`.monitor_stop`
        """
        if not self.isconnected:
            self.connect(DEFAULT_TIMEOUT)

        if not self.isconnected:
            raise pyca.pyexc("monitor: connection timedout for PV %s" %
                             self.name)

        if ctrl is None:
            ctrl = self.control

        if count is None:
            count = self.count

        self.subscribe_channel(mask, ctrl, count)

        # capv.get_data cannot be called inside a callback. Putting this
        # inside a try/except block lets us skip this step when it would
        # fail. Tons of code calls Pv.monitor inside a connection callback,
        # such as our built-in Pv.__getevt_handler.
        #
        # The purpose of this step is to initialize the .value when we call
        # .monitor() in an interactive session.
        try:
            self.get()
        except pyca.caexc:
            pass

        self.ismonitored = True
Esempio n. 2
0
File: Pv.py Progetto: slaclab/pyca
    def connect(self, timeout=None):
        """
        Create a connection to the PV through Channel Access

        If a timeout is specified, the function will wait for the connection
        state to report back as a success, raising an Exception upon failure.
        However, if no timeout is specified, no Exception will be raised, even
        upon a failed connection

        Parameters
        ----------
        timeout : float, optional
            The amount of time to wait for PV to make connection

        Returns
        -------
        isconnected : bool
            The connection state

        Raises
        ------
        pyca.pyexc
            If the user defined timeout is exceeded

        Note
        ----
        This function does not call pyca.flush_io
        """
        try:
            self.create_channel()

        except pyca.pyexc:
            logprint('Channel for PV {:} already exists'.format(self.name))
            return self.isconnected

        if timeout is not None:
            tmo = float(timeout)
            if tmo > 0:
                self.__con_sem.wait(tmo)
                if not self.__con_sem.isSet():
                    self.disconnect()
                    raise pyca.pyexc("connection timedout for PV %s" %
                                     self.name)

        return self.isconnected
Esempio n. 3
0
File: Pv.py Progetto: slaclab/pyca
    def wait_ready(self, timeout=None):
        """
        Wait for the PV to be initialized

        Parameters
        ----------
        timeout : float or None, optional
            Maximum time to wait to hear a response

        Raises
        ------
        pyca.pyexc
            If timeout is exceeded
        """
        pyca.flush_io()
        self.__init_sem.wait(timeout)
        if not self.__init_sem.isSet():
            raise pyca.pyexc("ready timedout for PV %s" % (self.name))
Esempio n. 4
0
File: Pv.py Progetto: slaclab/pyca
    def get(self, count=None, timeout=DEFAULT_TIMEOUT, as_string=False, **kw):
        """
        Get and return the value of the PV

        If the PV has not been previously connected, this will automatically
        attempt to use :meth:`.connect`. If you are expecting a waveform PV
        and want to choose to use a numpy array or not, set the attribute
        :attr:`.use_numpy`.

        Parameters
        ----------
        count : int, optional
            Maximum number of array elements to be return. By default uses
            :attr:`.count`

        ctrl : bool, optional
            Whether to get the control form information

        timeout : float or None, optional
            Time to wait for data to be returned. If None, no timeout is used

        as_string : bool , optional
            Return the value as a string type. For Enum PVs, the default
            behavior is to return the integer representing the current value.
            However, if as_string is set to True, this will return the
            associated string for the Enum

        Returns
        -------
        value : float, int, str
            Current value of the PV

        Raises
        ------
        pyca.pyexc
            If PV connection fails
        """
        if not count:
            count = self.count

        if timeout:
            try:
                tmo = float(timeout)
            except ValueError:
                tmo = DEFAULT_TIMEOUT
        else:
            tmo = -1.0

        try:
            ctrl = kw['ctrl']
            if ctrl is None:
                ctrl = False

        except KeyError:
            ctrl = self.control

        if DEBUG != 0:
            logprint("caget %s: " % self.name)

        if not self.isconnected and not self.connect(DEFAULT_TIMEOUT):
            raise pyca.pyexc("get: connection timedout for PV %s" % self.name)

        with utils.TimeoutSem(self.__pyca_sem, tmo):
            self.get_data(ctrl, tmo, count)

        if tmo > 0 and DEBUG != 0:
            logprint("got %s\n" % self.value.__str__())

        if as_string:
            if self.type() == 'DBF_ENUM':
                enums = self.get_enum_set(timeout=tmo)
                if len(enums) > self.value >= 0:
                    return enums[self.value]
                else:
                    raise IndexError('{:} is not a valid enumeration '
                                     'of {:}'.format(self.value, self.name))
            else:
                return str(self.value)

        return self.value