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
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
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))
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