def monitor_start(self, monitor_append=False): """ Start a monitoring process on the PV channel. Parameters ---------- monitor_apppend : bool, optional The choice of storing all updated values in a list, or simply overwriting the value attribute each time. This will change the :attr:`.monitor_append` attribute """ if not self.isinitialized: if self.isconnected: self.get_data(self.control, -1.0, self.count) pyca.flush_io() else: self.do_initialize = True self.connect() self.wait_ready() if self.ismonitored: if monitor_append == self.monitor_append: return if monitor_append: self.monitor_clear() self.monitor_append = monitor_append return self.monitor_append = monitor_append self.monitor_clear() self.monitor() pyca.flush_io()
def _linkEPICSPV(self): ''' Connect PVs to monitoring changes: runPv, failUDPv, failLDPv, nshotsPv, evrDlyPv ''' ppPvs = [ self.runPv, self.failUDPv, self.failLDPv, self.nshotsPv, self.evrDlyPv ] self._connectEPICSPV() if None in ppPvs: self.ims_on = False return False self._pr_log('Connecting EPICS Monitors -----') evtmask = pyca.DBE_VALUE # monitor run status self.runPv.monitor_cb = self._runPvCallback self.runPv.monitor(evtmask) # monitor upper bounds status self.failUDPv.monitor_cb = self._failUDPvCallback self.failUDPv.monitor(evtmask) # monitor lower bounds status self.failLDPv.monitor_cb = self._failLDPvCallback self.failLDPv.monitor(evtmask) # monitor number of shots self.nshotsPv.monitor_cb = self._nshotsPvCallback self.nshotsPv.monitor(evtmask) # monitor EVR delay value self.evrDlyPv.monitor_cb = self._evrDlyPvCallback self.evrDlyPv.monitor(evtmask) self.ims_on = True pyca.flush_io() return True
def some_thread_thing(pvname): pyca.attach_context() pv = setup_pv(pvname) pv.get_data(False, -1.0) pyca.flush_io() assert pv.getevt_cb.wait(timeout=1) assert isinstance(pv.data['value'], tuple)
def getSelection(self, selected, deselected): try: row = selected.indexes()[0].row() ioc = self.model.data(self.model.index(row, MyModel.IOCNAME), QtCore.Qt.EditRole).value() host = self.model.data(self.model.index(row, MyModel.HOST), QtCore.Qt.EditRole).value() if ioc == self.currentIOC: return self.disconnectPVs() self.currentIOC = ioc self.ui.IOCname.setText(ioc) base = utils.getBaseName(ioc) self.currentBase = base if base != None: self.dopv(base + ":HEARTBEAT", self.ui.heartbeat, "%d") self.dopv(base + ":TOD", self.ui.tod, "%s") self.dopv(base + ":STARTTOD", self.ui.boottime, "%s") pyca.flush_io() d = utils.netconfig(host) try: self.ui.location.setText(d['location']) except: self.ui.location.setText("") try: self.ui.description.setText(d['description']) except: self.ui.description.setText("") except: pass
def test_subscribe(pvname): logger.debug('test_subscribe %s', pvname) pv = setup_pv(pvname) ev = threading.Event() def mon_cb(exception=None): logger.debug('monitor_cb in %s, exception=%s', pvname, exception) if exception is None: ev.set() pv.monitor_cb = mon_cb pv.subscribe_channel(pyca.DBE_VALUE | pyca.DBE_LOG | pyca.DBE_ALARM, False) # Repeat the put/get test without the get pv.get_data(False, -1.0) pyca.flush_io() assert pv.getevt_cb.wait(timeout=1) old_value = pv.data['value'] pv_type = type(old_value) logger.debug('%s is of type %s', pvname, pv_type) if pv_type in (int, long, float): new_value = old_value + 1 elif pv_type == str: new_value = "putmon" elif pv_type == tuple: new_value = tuple([1] * len(old_value)) logger.debug('caput %s %s', pvname, new_value) ev.clear() pv.put_data(new_value, 1.0) assert ev.wait(timeout=1) recv_value = pv.data['value'] assert recv_value == new_value
def __connection_handler(self, isconnected): """ Called by Channel Access when connection state changes """ self.isconnected = isconnected if isconnected: self.__con_sem.set() else: self.__con_sem.clear() if self.do_initialize: self.get_data(self.control, -1.0, self.count) pyca.flush_io() if self.count is None: try: self.count = super(Pv, self).count() except: pass for (id, cb) in self.con_cbs.items(): try: cb(isconnected) except Exception: logprint("Exception in connection callback for {}:".format(self.name)) traceback.print_exc()
def connect(self): Pv.connect(self, timeout=1.0) self.connected = True # self.monitor_cb = self.changed evtmask = pyca.DBE_VALUE | pyca.DBE_LOG | pyca.DBE_ALARM self.monitor(evtmask) pyca.flush_io()
def _disconnectPv(self, pv): if pv != None: try: pv.disconnect() pyca.flush_io() except: pass return None
def _ensure_monitored(self): """ Make sure PV has been initialized and monitored """ self.get() if not self.ismonitored: self.monitor() pyca.flush_io()
def __getevt_callback(pv, e=None): if pv.handler: pv.handler(pv, e) if e is None: pv._Pv__getevt_handler(e) pv.getevt_cb = None pv.monitor(pyca.DBE_VALUE) pyca.flush_io()
def monitor_start(self): """ start monitoring for the Pv, new values are added to the `values` list """ evtmask = pyca.DBE_VALUE | pyca.DBE_LOG | pyca.DBE_ALARM self.monitor(evtmask, ctrl=False) self.ismonitored = True pyca.flush_io() # self.values=[] if (is_debug_on()): logprint("start monitoring for %s" % self.name)
def set_naverage(self,nimage,timeout=300) : """ Set number of images for averaging """ try: self.__navgimage_pv.put(nimage,timeout) pyca.flush_io() except pyca.pyexc, e: print "ERROR: Failed to set naverage:",e raise
def get_naverage(self,timeout=300) : """ Get number of images for average """ try: self.__navgimage_pv.get(timeout=timeout) pyca.flush_io() return self.__navgimage_pv.value except pyca.pyexc, e: print "ERROR: Failed to get naverage:",e raise
def energy(self, timeout=1.0): """ Get gas detector energy (mJ) """ try: self.__energy_pv.get(timeout=timeout) pyca.flush_io() return self.__energy_pv.value except pyca.pyexc, e: print "ERROR: Failed to get gas-detector energy:", e raise
def close(self): self.__logger.info("Close shutter") if self.isClose(): self.__logger.info("shutter already closed") else: self.__logger.info("Set %s to %0.1f" % (self.__ctrl.name, self.__close_val)) self.__state_change.clear() self.__ctrl.put(self.__close_val) pyca.flush_io()
def open(self): self.__logger.info("Open shutter") if self.isOpen(): self.__logger.info("shuttter already opened") else: self.__logger.info("Set %s to %0.1f" % (self.__ctrl.name, self.__open_val)) self.__state_change.clear() self.__ctrl.put(self.__open_val) pyca.flush_io()
def apply(self, idx): d = self.getObj(idx) pvd = self.pvdict[idx] for s in param.params.pobj.setflds: for f in s: fm = param.params.pobj.fldmap[f] if fm['readonly']: continue if fm['writezero']: try: v = d[f] # PV value except: continue v2 = self.getCfg(idx, f) # Configured value # # Write a value if: # 1. It's not derived (the value isn't None), and either # 2a. It's a change, or # 2b. It's a "must write" value. # if v2 != None and (not param.equal(v, v2) or fm['mustwrite']): try: z = fm['enum'][0] except: z = 0 try: pv = pvd[f] if param.params.debug: print("Put %s to %s" % (str(z), pv.name)) else: pv.put(z, timeout=-1.0) except: pass pyca.flush_io() for f in s: fm = param.params.pobj.fldmap[f] if fm['readonly']: continue try: v = d[f] # PV value except: continue v2 = self.getCfg(idx, f) # Configured value if v2 != None and (not param.equal(v, v2) or fm['mustwrite']): try: pv = pvd[f] if param.params.debug: print("Put %s to %s" % (str(v2), pv.name)) else: pv.put(v2, timeout=-1.0) except: pass pyca.flush_io()
def mv(self,position,timeout=-1.0) : """ Move motor to position """ self.__logger.info("%s Move motor to %0.6f"%(self.__basepv,position)) try: self.__val.put(position,timeout) pyca.flush_io() self.__motion_done.clear() except pyca.pyexc, e: self.__logger.error("%s Failed to move motor"%self.__basepv) raise
def monitor_start(self, monitor_append=False): """ start monitoring for the Pv, new values are added to the `values` list """ if (self.ismonitored and self.monitor_append == monitor_append): return if (self.ismonitored and self.monitor_append != monitor_append): self.monitor_stop() self.monitor_append = monitor_append evtmask = pyca.DBE_VALUE | pyca.DBE_LOG | pyca.DBE_ALARM self.monitor(evtmask, ctrl=False) self.ismonitored = True pyca.flush_io() self.values = [] if (is_debug_on()): logprint("start monitoring for %s" % self.name)
def __getevt_handler(self, e=None): """ Called when data is requested over the Channel """ if e == None: self.isinitialized = True self.do_initialize = False self.getevt_cb = None if self.do_monitor: self.monitor(pyca.DBE_VALUE | pyca.DBE_LOG | pyca.DBE_ALARM, self.control, self.count) pyca.flush_io() self.__init_sem.set()
def mvr(self,nudge,timeout=-1.0) : """ Nudge motor position by value nudge """ self.__logger.info("%s Nudge motor by %0.6f"%(self.__basepv,nudge)) try: self.__twv.put(nudge,timeout) self.__twf.put(1,timeout) pyca.flush_io() self.__motion_done.clear() except pyca.pyexc, e: self.__logger.error("%s Failed to nudge motor"%self.__basepv) raise
def update_follower(self, exception=None): print "Update follower" print self.__pvmonitor.name, "updated" # Get monitor value print "Getting", self.__pvmonitor.name, "latest value" self.__pvmonitor.get() # Calculate new value for follower new_value = self.__follower_func(self.__pvmonitor.value) # Set new value for follower print self.__pvfollower.name, new_value self.__pvfollower.put(new_value) pyca.flush_io()
def put(self, value, timeout=None) : """ EPICS PUT - Set EPICS PV and wait until complete or timeout """ # Put EPICS data super(epics_PV,self).put_data(value,-1.0) pyca.flush_io() # Wait for EPICS call to complete self.__put_done.clear() self.__put_done.wait(timeout) if not self.__put_done.isSet(): self.__logger.warning("%s EPICS PUT timedout after %d seconds"%(self.name,timeout)) raise
def __start_monitors(self): """ Start EPICS monitors of rbv PV to continously update shutter state """ self.__logger.debug("Starting monitor for %s" % self.__rbv.name) # Connect to monitor callbacks self.__rbv.monitor_cb = self.__rbv_cb # Start monitor pvevt = pyca.DBE_ALARM | pyca.DBE_LOG | pyca.DBE_VALUE self.__rbv.monitor(pvevt) pyca.flush_io() # Wait 1 second for monitoring to start time.sleep(1.0)
def put(self, value, timeout = DEFAULT_TIMEOUT, **kw): """ Set the PV value If the PV has not been previously connected, this will automatically attempt to use :meth:`.connect`. Parameters ---------- value : float, int, str or array Desired PV value timeout : float or None, optional Time to wait for put to be completed. If None, no timeout is used Returns ------- value : float, int, str, or array The value given to the PV TODO : Add a put_complete which confirms the success of the function """ if DEBUG != 0: logprint("caput %s in %s\n" % (value, self.name)) if timeout: try: tmo = float(timeout) except ValueError: tmo = DEFAULT_TIMEOUT else: tmo = -1.0 if not self.isinitialized: if self.isconnected: self.get_data(self.control, -1.0, self.count) pyca.flush_io() else: self.do_initialize = True self.connect() self.wait_ready(DEFAULT_TIMEOUT * 2) with utils.TimeoutSem(self.__pyca_sem, tmo): self.put_data(value, tmo) return value
def get(self, ctrl=False, timeout=None) : """ EPICS GET - waits for EPICS to return data or will timeout """ self.__logger.debug("%s EPICS GET"%self.name) # Get EPICS data super(epics_PV,self).get(ctrl,-1.0) pyca.flush_io() # Wait for EPICS call to complete self.__get_done.clear() self.__get_done.wait(timeout) if not self.__get_done.isSet(): self.__logger.warning("%s EPICS GET timedout after %d seconds"%(self.name,timeout)) raise
def set(self, value): """ Set FEL Energy """ self.__logger.info("Set FEL Energy to %f" % value) # Check current value self.__ctrl.get(timeout=1.0) pyca.flush_io() if self.__ctrl.value == value: self.__logger.info("FEL already at %f" % value) self.__done.set() else: self.__done.clear() self.__ctrl.put(value) pyca.flush_io()
def test_get_data(pvname): logger.debug('test_get_data %s', pvname) pv = setup_pv(pvname) # get time vars pv.get_data(False, -1.0) pyca.flush_io() assert pv.getevt_cb.wait(timeout=1) pv.getevt_cb.reset() # get ctrl vars pv.get_data(True, -1.0) pyca.flush_io() assert pv.getevt_cb.wait(timeout=1) # check that the data has all the keys all_keys = ('status', 'value', 'secs', 'nsec') for key in all_keys: assert key in pv.data # check that value is not None assert pv.data['value'] is not None
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 start_dropshot_counting(self, threshold=0.0): """ Monitor gasdet energy value and count number of dropped shots, defined as number of below threshold readings """ # Set threshold self.__threshold = threshold # Set up monitor call back for gas-detector energy reading self.__energy_pv.monitor_cb = self.__energy_cb print "Counting dropshot [thereshold=", self.__threshold, "]" # Reset internal dropped shot counter and start monitoring self.__dropped_shot = 0 pvevt = pyca.DBE_ALARM | pyca.DBE_LOG | pyca.DBE_VALUE self.__energy_pv.monitor(pvevt) pyca.flush_io()
def connected_cb(self, isconnected): """ Callback to run whenever the connection state of our pv changes. :param isconnected: True if we are connected, False otherwise. :type isconnected: bool """ self.connected = isconnected self.send_connection_state(isconnected) if isconnected: self.epics_type = self.pv.type() self.count = self.pv.count or 1 # Get the control info for the PV. self.pv.get_data(True, -1.0, self.count) pyca.flush_io() if self.epics_type == "DBF_ENUM": self.pv.get_enum_strings(-1.0) if not self.pv.ismonitored: self.pv.monitor() self.python_type = type_map.get(self.epics_type) if self.python_type is None: raise Exception("Unsupported EPICS type {0} for pv {1}".format( self.epics_type, self.pv.name))