def _initialise_channel(self, name): """Initialises the channel by creating a connection callback. Args: name (string): The name of the PV to connect to. """ def _block_connection_callback(epics_args, user_args): connection_state = epics_args[1] if connection_state == ca.CA_OP_CONN_UP: print ca.name(epics_args[0]), "UP" # First time through creates the monitor if ca.name(epics_args[0]) not in self.curr_values: self._create_monitor(user_args[0], ca.name(epics_args[0])) else: print ca.name(epics_args[0]), "DOWN" self.curr_lock.acquire() try: self.curr_values[ca.name(epics_args[0])] = ("*** disconnected", None) except: # Don't care, it is all about releasing the lock pass finally: # Must release lock self.curr_lock.release() chan = CaChannel() chan.setTimeout(EXISTS_TIMEOUT) print "initialising %s" % name try: chan.search_and_connect(name, _block_connection_callback, chan) chan.pend_event(PEND_EVENT_TIMEOUT) return chan except: print "Could not connect" return None
def connect_to_names_pv(self): """Connects amonitor to the block-server to get the names of the blocks. """ def _blocknames_callback(epics_args, user_args): names = json.loads(dehex_and_decompress(waveform_to_string(epics_args['pv_value']))) if self.block_names is None or names != self.block_names: self.block_names = names print "Updated" chan = CaChannel("BLOCKNAMES") chan.searchw("%s%s" % (self.prefix, "CS:BLOCKSERVER:BLOCKNAMES")) chan.add_masked_array_event( ca.DBR_CHAR, None, ca.DBE_VALUE | ca.DBE_ALARM, _blocknames_callback) chan.pend_event(PEND_EVENT_TIMEOUT)
class pv(): # Wrapper for associating CaChannel class to specific PV using its name def __init__(self, pvname): try: self.pv = CaChannel() self.pv.searchw(pvname) self.alarm_status = "n/a" # used to store severity provided by callback self.alarm_severity = "n/a" # used to store severity provided by callback except : raise Exception("****** PV not found - "+pvname+" ******") #return pv # Wrapper for putw() function - writing a value to PV and waiting for input records to scan (update their value) def write(self, *args): try: if len(args) == 2: # arguments: value, scan_time self.pv.putw(args[0]) time.sleep(args[1]) if len(args) == 3: # arguments: value, scan_time, type if args[2] == "STRING": self.pv.putw(args[0],ca.DBR_STRING) else: raise Exception("Type "+ str(args[3]) +" not recognized") time.sleep(args[1]) print("***W: Set PV "+self.pv.name()+" to "+str(args[0])) except: print("Could not set PV "+self.pv.name()+" to "+str(args[0])) # Similar to write() except it does not print output when successfully sets the value # Useful for setUp and tearDown methods def write_silent(self, *args): try: if len(args) == 2: # arguments: value, scan_time self.pv.putw(args[0]) time.sleep(args[1]) if len(args) == 3: # arguments: value, scan_time, type if args[2] == "STRING": self.pv.putw(args[0],ca.DBR_STRING) else: raise Exception("Type "+ str(args[3]) +" not recognized") time.sleep(args[1]) except: print("Could not set PV "+self.pv.name()+" to "+str(args[0])) # Wrapper for getw() def read(self, *args): if len(args) == 1: if args[0] == "STRING": val = self.pv.getw(ca.DBR_STRING) else: raise Exception("Type "+ str(args[3]) +" not recognized") print("***R: Read PV "+self.pv.name()+" value "+str(val)) return val else: val = self.pv.getw() print("***R: Read PV "+self.pv.name()+" value "+str(val)) return val # Wrapper for getw() with CALLBACK for alarm status/severity def read_alarm(self): self.pv.array_get_callback(ca.dbf_type_to_DBR_STS(self.pv.field_type()), None, Callback, self) self.pv.flush_io() for i in range(20): self.pv.pend_event() # Wrapper for name() def name(self): return self.pv.name()