# python import time import timeit import numpy as np import array import inspect import os import operator import platform import sys import PyCafe cafe = PyCafe.CyCafe() cyca = PyCafe.CyCa() ############################################################## # (1) Establishing connections to EPICS Process Variables (PVs) # (2) Simple single channel operations # (3) Waveforms and Arrays # (4) Multiple scalar operations, i.e. operations on several PVs with scalar values # (5) Multiple compound operations, i.e. operations on several PVS with either scalar values or arrays # (6) Synchronous group operations # (7) Control system parameters, i.e. operating limits, engineerimg units # (8) Monitors, either with or without user supplied callbacks # (9) Asynchronous interactions and retrieving data from Cache # (10) Synchronous group operations, with externally defined groups # (11) Special Methods, match, setAndMatch # (END) Gracefully terminate CAFE ############################################################## PY2 = True PY3 = False if sys.version_info >= (3, 0): PY3 = True PY2 = False print("This is Python Version:\n", sys.version_info) ################################################################# # Test channels ################################################################# # For use in office network cao PV1 = 'ARIDI-BPM-01LE:X-AVG' PV2 = 'ARIDI-BPM-01LE:Y-AVG' PV3 = 'ARIDI-BPM-01LB:X-AVG' PV4 = 'ARIDI-BPM-01LB:Y-AVG' PVWF1 = 'ARIDI-BPM-01LE:WF-INT-1' PVWF2 = 'ARIDI-BPM-01LB:WF-INT-2' PVWF3 = 'ARIDI-BPM-01SE:WF-INT-2' PVWF4 = 'ARIDI-BPM-01SB:WF-INT-2' PVS = 'ARIDI-BPM-01SB:SET-ENABLE' PV_JOKE = 'PV-DOES-NOT:EXIST' PV_REAL = 'SAR-CMON-MAG4531:VOLTAGE-5' pvlist1 = [PV1, PV2, PV3, PV4] pvlistWF = [PVWF1, PVWF2, PVWF3, PVWF4] pvlistAll = [PV1, PV2, PV3, PV4, PVWF1, PVWF2, PVWF3, PVWF4, PVS, PV_JOKE] ################################################################# def py_connect_callback(handle: int = None, pv_name: str = "", status: int = None): try: print("pv_name=", pv_name) print("CONNECT CALLBACK HANDLER INVOKED FOR HANDLE with status:", handle, status) # Usual action is to get the updated value print("isConnected?", cafe.isConnected(handle)) print("Channel=", cafe.getPVNameFromHandle(handle)) print("Value =", cafe.getCache(handle)) # native format # else dt='int', dt='float' print("Value =", cafe.getCache(handle, dt='str')) except PyCafe.CafeException as cafeEx: cafeEx.show() # or cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) print("END: CONNECT CALLBACK HANDLER COMPLETED FOR HANDLE with status:", handle, status) print("") return ################################################################# # A user supplied callback function to be (optionally) used in (8) Monitors # (or puts and gets if required) ################################################################# def py_callback(handle: int = None, pvname: str = ""): # operations permitted from within handle are getCache, set and close # open, get and monitorStart are not permitted try: print("") print("START: MONITOR CALLBACK HANDLER INVOKED FOR HANDLE:", handle) # Usual action is to get the updated value print("isConnected?", cafe.isConnected(handle)) print("Channel=", cafe.getPVNameFromHandle(handle)) print("Value =", cafe.getCache(handle)) # native format # else dt='int', dt='float' print("Value =", cafe.getCache(handle, dt='str')) #print ("DbrDataType =", cafe.getDbrDataTypeInCallback(handle) ) #print ("DataType =", cafe.getDataTypeInCallback(handle) ) #print ("DbrBase =", cafe.getDbrBaseInCallback(handle) ) # This retrieves all the parameters that acted as input to the monitor #Input is handle and monitorId monid = cafe.getMonitorIDInCallback(handle) print("monid ", monid) #mp=cafe.getMonitorPolicyVector(handle, monid) # mp.show() # get PVData p1 = cafe.getPVCache(handle) print("--------") p1.showMax(10) # if waveform print only first 10 elements print("--------") # alternatively: print("Value =", p1.value[0]) print("status = {0}".format(p1.status)) print("alarmStatus = {0}".format(p1.alarmStatus)) print("alarmSeverity = {0}".format(p1.alarmSeverity)) print("ts =", p1.ts[0], p1.ts[1]) print("tsDate =", p1.tsDate[0], p1.tsDate[1], p1.tsDate[2], p1.tsDate[3], p1.tsDate[4], p1.tsDate[5], p1.tsDate[6]) # Increment value - set to this channel # newValue=1+pv.value[0] # if newValue < 10: # cafe.set(handle, newValue) except PyCafe.CafeException as cafeEx: cafeEx.show() # or cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) print("END: MONITOR CALLBACK HANDLER COMPLETED FOR HANDLE:", handle) print("") return ############################################################## ################################################################# # A user supplied callback function to be (optionally) used in (8) Monitors. # This is a variant to the above; it returns a PVData object, handle, and pv name. ################################################################# def py_callback_pvdata(handle: int = None, pvname: str = "", pvdata: PyCafe.pvdata = None ): # operations permitted from within handle are getCache, set and close # open, get and monitorStart are not permitted try: print("MonitorID:", cafe.getMonitorIDInCallback(handle), "for handle/pv", handle, pvname) print("START: MONITOR CALLBACK PVDATA HANDLER INVOKED FOR HANDLE/PV:", handle, pvname) # Usual action is to get the updated value print("isConnected?", cafe.isConnected(handle)) print("Channel=", pvname) print("Value (native) =", pvdata.value[0]) # native format # else dt='int', dt='float' print("Value (str) =", cafe.getCache(handle, dt='str')) #print ("DbrDataType =", cafe.getDbrDataTypeInCallback(handle) ) #print ("DataType =", cafe.getDataTypeInCallback(handle) ) #print ("DbrBase =", cafe.getDbrBaseInCallback(handle) ) print("----------") pvdata.showMax(10) # if waveform print only first 10 elements print("----------") # alternatively: print("Value =", pvdata.value[0]) print("status = {0}".format(pvdata.status)) print("alarmStatus = {0}".format(pvdata.alarmStatus)) print("alarmSeverity = {0}".format(pvdata.alarmSeverity)) print("ts =", pvdata.ts[0], pvdata.ts[1]) print("tsDate =", pvdata.tsDate[0], pvdata.tsDate[1], pvdata.tsDate[2], pvdata.tsDate[3], pvdata.tsDate[4], pvdata.tsDate[5], pvdata.tsDate[6]) except PyCafe.CafeException as cafeEx: cafeEx.show() # or cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) print("END: MONITOR CALLBACK PVDATA HANDLER COMPLETED FOR HANDLE/PV:", handle, pvname) print("") return ############################################################## ################################################################# # A user supplied callback function to be (optionally) used in ctrl monitors. # This is a variant to the above; it returns a PVCtrl object, handle, and pv name. ################################################################# def py_callback_pvctrl(handle: int = None, pvname: str = "", pvctrl: PyCafe.pvctrl = None): # operations permitted from within handle are getCache, set and close # open, get and monitorStart are not permitted try: print("") print("START: MONITOR CALLBACK CTRL HANDLER INVOKED FOR HANDLE/PV:", handle, pvname) # Usual action is to get the updated value print("isConnected?", cafe.isConnected(handle)) print("Channel=", pvname) print("Value (native) =", pvctrl.value[0]) # native format # else dt='int', dt='float' print("Value (str) =", str(pvctrl.value[0])) #print ("DbrDataType =", cafe.getDbrDataTypeInCallback(handle) ) #print ("DataType =", cafe.getDataTypeInCallback(handle) ) #print ("DbrBase =", cafe.getDbrBaseInCallback(handle) ) print("----------") pvctrl.showMax(10) # if waveform print only first 10 elements print("----------") except PyCafe.CafeException as cafeEx: cafeEx.show() # or cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) print("END: MONITOR CALLBACK CTRL HANDLER COMPLETED FOR HANDLE/PV:", handle, pvname) print("") return ################################################################# # A user supplied callback function for put operations (optional) ################################################################# def py_callback_put(handle): print("Channel=", cafe.getPVNameFromHandle(handle)) print("Old Value from Cache =", cafe.getCache(handle)) # native format print("Put HANDLER COMPLETED FOR HANDLE:", handle) return ################################################################# # A user supplied callback function for get operations (optional) ################################################################# def py_callback_get(handle): print("Channel=", cafe.getPVNameFromHandle(handle)) print("Value =", cafe.getCache(handle)) # native format print("Get HANDLER COMPLETED FOR HANDLE:", handle) return ############################################################## ############################################################## # (1) Establishing connections to EPICS Process Variables (PVs) ############################################################## # Explicitly opening channels is good practice even if only optional print("CAFE_VERSION:", cafe.CAFE_version()) print("EPICS_VERSION:", cafe.EPICS_version(), cafe.epics_version_string()) print("CA_VERSION:", cafe.ca_version()) #cafe.monitor("ARIDI-BPM:OFB-YRMS.DESC:EGU", cb=py_callback_pvctrl) #time.sleep(1) #pvc = cafe.getCache("ARIDI-BPM:OFB-YRMS.EGU") #print(pvc) #sys.exit(1) print("INFO: pend time for open", cafe.getOpenDefaultPendTime()) # open a single channel # Connect callback function is optional try: handleS = cafe.open("test ", cb=py_connect_callback) except PyCafe.CafeException as cafeEx: # inst: print("PyCafe.CafeException") # if isinstance(inst.args[0], PyCafe.CyCafeException): # cafeEx=inst.args[0] cafeEx.show() # or cafeEx.reveal() # or print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) # else: # print(inst) except Exception as inst: print("Exception") print(inst.args) print(inst) # better practice is to open all channels at once start = time.time() # cafe.openPrepare() # All Chhanels opened only after openAndWait # Otherwise channels will open after each cafe.open method is executed try: # return list of handles hlist1 = cafe.open(pvlist1, cb=py_connect_callback) print(hlist1) hlistWF = cafe.open(pvlistWF, cb=py_connect_callback) print(hlistWF) # Note: only one handle per channel is created hlistAll = cafe.open(pvlistAll, cb=py_connect_callback) print(hlistAll) except PyCafe.CafeException as cafeEx: cafeEx.show() except Exception as inst: print(inst.args) exit(1) # cafe.openNowAndWait(0.5) #timeout for channels to connect end = time.time() print(end-start) # cafe.terminate() # exit(1) if cafe.allConnected() == False: cafe.printDisconnected() # Alternatively if cafe.allConnected() == False: h, pv = cafe.getDisconnectedHandles() print("---------------------") print("DISCONNECTED CHANNELS") print("---------------------") for i in range(0, len(h)): print(h[i], " ", pv[i]) # Alternatively - show all handles # cafe.printHandles() h, pv = cafe.getHandles() print("---------------------") print("ALL CHANNELS") print("---------------------") for i in range(0, len(h)): print(h[i], " ", pv[i]) h, pv, state = cafe.getHandleStates() print("---------------------") print("ALL CHANNELS AND CONNECTION STATE") print("---------------------") for i in range(0, len(h)): print(h[i], " ", pv[i], " ", state[i]) print("") # END (1) Establishing connections to EPICS Process Variables (PVs) ############################################################## ############################################################## # (2) Simple single channel operations ############################################################## # Now perform some get/set operations # input to get method can be the handle to the PV, or the PV name # If you prefer to check on the value (which will return # a Python None in the event of a failed operation) rather # than catch exceptions then it is possible to turn off exceptions: cafe.withExceptions(False) ##cafe.enableExceptions = False # get 'ARIDI-BPM-01SB:SET-ENABLE' by handle val = cafe.get(hlistAll[8]) # or val = cafe.get(PVS) if val == None: # print ErrorCode by calling cafe.getStatus with handle or PVName as input argument print(cafe.getStatus(hlistAll[8])) # or print(cafe.getStatus(PVS)) # print meaning of error message cafe.printStatusIfError(hlistAll[8], cafe.getStatus(hlistAll[8])) else: print("Value=", val) #enumValue=cafe.getEnumFromString(PVS, val) #print ("enumValue=",enumValue) #enumString=cafe.getStringFromEnum(PVS, enumValue) #print ("enumString=",enumString) # This channel does not exist hence None will be returned # The status code and error message will indicate that the channel was never connected val = cafe.get(PV_JOKE) if val == None: cafe.printStatusIfError(PV_JOKE, cafe.getStatus(PV_JOKE)) else: print("Value=", val) # Now use exceptions for single channel get/set operations ##cafe.enableExceptions = True cafe.withExceptions(True) # Now perform some get operations try: val = cafe.get(hlistAll[8]) print("Channel: ", cafe.getPVNameFromHandle(hlistAll[8]), " value=", val) except PyCafe.CafeException as cafeEx: cafeEx.show() except Exception as inst: print(inst.args) # Retrun pvdata struct, i.e., val, alarms, timestamps try: pv = cafe.getPV(hlistAll[8]) pv.show() except PyCafe.CafeException as cafeEx: cafeEx.show() except Exception as inst: print(inst.args) # Now perform a get operations on a disconnected channel # and catche the exception being thrown try: val = cafe.get(PV_JOKE) # will throw an exception print("Channel: ", PV_JOKE, " value=", val) except PyCafe.CafeException as cafeEx: cafeEx.reveal() except Exception as inst: print(inst) try: val = cafe.get(hlistAll[3]) print("Channel: ", pvlistAll[3], " value=", val) # or print("Channel: ", cafe.getPVNameFromHandle(hlistAll[3]), " value=", val) except PyCafe.CafeException as cafeEx: cafeEx.reveal() except Exception as inst: print(inst) # cafe.get on a WF will return first element only (see(3) fro WFs) try: val = cafe.get('ARIDI-BPM-01SE:WF-INT-2') # will throw an exception print('ARIDI-BPM-01SE:WF-INT-2 has val=', val) except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) # Now perform a set operation on a waveform try: print("set") cafe.set(PV1, 1.234) # set by pvname; value can be in any format print("get") val = cafe.get(PV1, dt='native') # dt='native' (defulat) may be omitted print("Value (should be 1.234) =", val) # default dt='native' cafe.set(hlistAll[0], [4.321]) # set by handle val = cafe.get(PV1, dt='str') # dt='int', dt='float' are other options print("Value (should be 4.321) =", val) # get pvdata struct pv = cafe.getPV(PV1) pv.show() # or print("Value =", pv.value[0]) print("TS =", pv.ts[0], " ", pv.ts[1]) print("tsDate =", pv.tsDate[0], pv.tsDate[1], pv.tsDate[2], pv.tsDate[3], pv.tsDate[4], pv.tsDate[5], pv.tsDate[6] ) print("") except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) # Now perform a set/get operation with user supplied callbacks try: cafe.setCallbackGet(hlist1[0], cb=py_callback_get) cafe.setCallbackPut(hlist1[0], cb=py_callback_put) cafe.setCallbackPut(hlist1[1], cb=py_callback_put) s = cafe.set(hlist1[0], 3.348) #cafe.ca_flush_io() s = cafe.set(hlist1[1], -3.348) #cafe.ca_flush_io() s = cafe.set(hlist1[0], 7.777) #cafe.ca_flush_io() v = cafe.get(hlist1[0]) print("Value should be 7.777", v, s) #s, sl = cafe.waitForBundledEvents(hlist1[0]) v = cafe.getCache(hlist1[0]) s = cafe.getStatus (hlist1[0]) print("Can you see if the callback functions were called for set/get?") print("Value should be 7.777", v, s) print("Waiting 5 seconds to allow data to be viewed") time.sleep(5) # return to default callbacks cafe.setCallbackGet(hlist1[0], cb=None) cafe.setCallbackPut(hlist1[0], cb=None) except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) # END (2) Simple single channel operations ############################################################## #cafe.terminate() #exit(1) ############################################################## # (3) Waveforms and Arrays ############################################################## try: NWF = 10 print('setting no of elements for wf to ', cafe.setNelem(PVWF1, 4084)) # time.sleep(5) # waveform as Python List print("Waveform as a Python List and native data type") start = time.time() for i in range(0, NWF): valList = cafe.getList(PVWF1, dt='native') end = time.time() print(end - start) start = time.time() for i in range(0, NWF): valList = cafe.getList(PVWF1, dt='int8') end = time.time() print(end - start) #print (valList) # waveform as int and as numpy print("Waveform as a numpy and dt='float'") start = time.time() for i in range(0, NWF): valNumpy = cafe.getArray( hlistWF[0], dt='native', art='numpy') # PVWF1, end = time.time() print(end - start) #print (valNumpy) # #cafe.setNelem(PVWF1, 5) # waveform as a float and as a Python array.array print("Waveform as a Python array.array and dt='float'") start = time.time() for i in range(0, NWF): valArray = cafe.getArray( hlistWF[0], dt='native', art='array') # PVWF1, end = time.time() print(end - start) #print (valArray) for i in range(0, min(10, len(valArray))): #print (valArray[i], " [",i,"] ", sep='', end="") print(valArray[i], " [", i, "] ",) print(" ") # waveform as a and as a Python memoryview print("Waveform as a Python memoryview and dt='native' (default)") start = time.time() for i in range(0, NWF): mv = cafe.getArray(hlistWF[0], dt='native', art='memoryview') end = time.time() print(end - start) print(type(mv)) print(type(mv[0])) print(mv[0]) time.sleep(5) # cafe.terminate() # exit(1) # ml=memoryview(mv) #print (type(ml)) #print (type(ml[0])) #print (ml[0], ml[1], ml[4]) #print (ml[2:4].tolist()) status = cafe.set(hlistWF[0], mv) # Did set work? Check on first element print("Value (should be what?)=", cafe.get(PVWF1, dt='float')) ''' #for PY3 for i in range (0,len(mv)): print (mv[i], " ",end="") print (" ") ''' mv_a = np.ndarray(4) # mv_a=mv for i in range(0, 4): # len(mv)): mv[i] = 3.456+i #print (mv[i], " ", sep="", end="") mv_a[i] = mv[i] print(" ") # set first element of wf using memoryview # mv_a[0]=4.567 # mv[0]=4.567 status = cafe.set(PVWF1, mv) # Did set work? Check on first element print("Value (should be 1.23)=", cafe.get(PVWF1, dt='float')) ''' valArrayI=cafe.getArray(PVWF1, dt='int', art='array') print (valArrayI) for i in range (0,min(4,len(valArrayI))): print (valArrayI[i], " ",) print (" ") valArrayI=cafe.getArray(PVWF1, dt='int', art='array') print (valArrayI) for i in range (0,min(4,len(valArrayI))): print (valArrayI[i], " ",) print (" ") ''' print('nelemCtrl=', cafe.setNelemCtrl(PVWF1, 20)) valC = cafe.getCtrl(PVWF1, dt='int') print(valC) # for i in range (0,min(50,len(valC.value))): #print (valC.value[i], " [",i,"] ", sep='', end="") #print (valC.value[i], " [",i,"] ",) #print (" ") # set wf using array.array valArray[0] = 5.678 status = cafe.set(PVWF1, valArray) print("Value (should be 5.678)=", cafe.get(PVWF1, dt='float')) # set wf using numpy array valNumpy[0] = 6.543 status = cafe.set(PVWF1, valNumpy) print("Value (should be 6)=", cafe.get(PVWF1, dt='int')) # set wf using Python List valList[0] = '1.23' valList[1] = '2.10' status = cafe.set(PVWF1, valList) vL = cafe.getList(PVWF1, dt='float') if vL[0] != None: print("Values (should be 1.23, 2.1)=", vL[0], vL[1]) except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) ############################################################## # cafe.terminate() # exit(1) ############################################################## # (4) Multiple scalar operations ############################################################## # Now work with multiple scalars - far far more efficient to get multiple data-sets with one call # If a channel is not connected (or other error) then it is reported in the ! # These methods do not throw exceptions valueList, status, statusList = cafe.getScalarList( hlist1, 'str') # hlist1 or pvlist1 if status != cyca.ICAFE_NORMAL: cafe.printStatusIfError(hlist1, statusList) for i in range(0, len(valueList)): print(valueList[i], " [", i, "] ",) print(" ") if status != cyca.ICAFE_NORMAL: for i in range(0, len(statusList)): print(cafe.getStatusCodeAsText(statusList[i]), "[", i, "]") print(" ") try: val = cafe.getPV(hlistAll[8], dt='int') print(pvlistAll[8], val) val.show() except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) valueList, status, statusList = cafe.getScalarList( hlistAll[0:9], dt='double') # hlistAll or pvlistALL print("--------------------------------------------------------") print("valueList from cafe.getScalarList(hlistAll,dt='native') ") print("Note the different data types appearing in the list ") print("If a WF is among the list, only the first element is returned") print("--------------------------------------------------------") for i in range(0, len(valueList)): print(pvlistAll[i], valueList[i], " [", i, "] ", statusList[i]) print(" ") if status != cyca.ICAFE_NORMAL: cafe.printStatusIfError(hlistAll, statusList) ''' if PY3: for i in range (0, len(valueList)): print (valueList[i], " [",i,"] ", end="") print(" ") if status != cyca.ICAFE_NORMAL: for i in range (0, len(statusList)): print (cafe.getStatusCodeAsText(statusList[i]), " [",i,"] ",end="") print(" ") ''' # if PY2: for i in range(0, len(valueList)): print(valueList[i], " [", i, "] ",) print(type(valueList[i])) print(" ") if status != cyca.ICAFE_NORMAL: for i in range(0, len(statusList)): print(cafe.getStatusCodeAsText(statusList[i]), " [", i, "] ") print(" ") print("--------------------------------------------------------") print("--------------------------------------------------------") print("valueList from cafe.getScalarList(hlist1,dt='float') ") print("Values returned should be 5.6, 6.389, 7.7, 22 ") print("--------------------------------------------------------") # Note that different data types are allowed within the input List llist = [5, 6.389, '7.7', 22] status, statusList = cafe.setScalarList(hlist1, llist) valueList, status, statusList = cafe.getScalarList( hlist1, dt='float') # hlist1 or pvlist1 if status != cyca.ICAFE_NORMAL: cafe.printStatusIfError(hlist1, statusList) for i in range(0, len(valueList)): print(valueList[i], " [", i, "] ",) print(" ") print("--------------------------------------------------------") ############################################################## ############################################################## # (5) Mulitple compound operations ############################################################## print("--------------------------------------------------------") print("valueList from cafe.getCompoundList(hlistAll,dt='native') ") print("A WF is returned as a List within the List ") print("--------------------------------------------------------") val, s, sl = cafe.getCompoundList(hlistAll, dt='native') # print one of the waveforms in above val List mval = 10 if len(val) > 4: if isinstance(val[4], (list)): mval = len(val[4]) # print 10 first elements of WF for i in range(0, min(10, mval)): print(val[4][i], " [", i, "] ") print(" ") print("--------------------------------------------------------") print("valueList from cafe.getPVList(hlistAll,dt='native') for comparison to above") print("A WF is returned as a List within the List ") print("--------------------------------------------------------") pvl, s = cafe.getPVList(hlistAll, dt='native') for i in range(0, len(pvl)): print(hlistAll[i], " ", cafe.getPVNameFromHandle(hlistAll[i])) pvl[i].show() print(" ") print(s) print("--------------------------------------------------------") cafe.printStatusIfError(hlistAll, sl) if len(val) > 2: val[2] = 0.7123 s, sl = cafe.setCompoundList(hlistAll, val) if (s != cyca.ICAFE_NORMAL): cafe.printStatusIfError(hlistAll, sl) try: val2 = cafe.get(hlistAll[2]) # readback to check that above set worked print("Readback value should be", val[2], " val=", val2) print("--------------------------------------------------------") print("--------------------------------------------------------") except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) ############################################################## ############################################################## # (6) Synchronous group operations and like ############################################################## print("--------------------------------------------------------") print(" Synchronous group operations ") print("--------------------------------------------------------") gh=cafe.grouping('testg', pvlist1) # Return a group of PV structs pvg = cafe.getPVGroup(gh) pvg.show() # or pvg.showWithPV(pvlist1) # define a group on the fly cafe.defineGroup('gBPM', pvlist1) groupHandle1 = cafe.groupOpen('gBPM') glist = cafe.groupMemberList('gBPM') # Return a group of PV structs pvg = cafe.getPVGroup(groupHandle1) pvg.show() # or pvg.showWithPV(glist) # or for i in range(0, pvg.npv): print(glist[i], " value=", pvg.pvdata[i].value[0],) print(" ") print("--------------------------------------------------------") # extract all values from pvgroup into a list setList = [] setList = cafe.PVGroupValuesToList(pvg) # modify values setList[0] = setList[0]+0.1234567 setList[1] = setList[1]+0.9876543 # set new values s, sL = cafe.setGroup(groupHandle1, setList) # readback new values values, s, sl = cafe.getGroup(groupHandle1) # by group handle print(values) values, s, sl = cafe.getGroup('gBPM') # by group name print(values) # Now define another group cafe.defineGroup('gAll', pvlistAll[0:9]) #take out PV-JOKE groupHandle2 = cafe.groupOpen('gAll') pvg = cafe.getPVGroup(groupHandle2) # pvg.show() # or pvg.showWithPV(pvlistAll[0:9]) # or # for i in range (0, pvg.npv): # print(glist[i], " value=", pvg.pvdata[i].value[0],) # print(" " print("--------------------------------------------------------") values, s, sl = cafe.getGroup(groupHandle2) # by group handle print(values) if s != cyca.ICAFE_NORMAL: cafe.printStatusIfError(pvlistAll, sl) else: # change some values: values[0] = values[0] + 0.234 values[1] = values[1] + 0.456 values[8] = "monitor" s, sl = cafe.setGroup(groupHandle2, values) if s != cyca.ICAFE_NORMAL: cafe.printStatusIfError(pvlistAll, sl) newValues, s, sl = cafe.getGroup(groupHandle2) # by group handle print(newValues[0], newValues[1]) if s != cyca.ICAFE_NORMAL: cafe.printStatusIfError(pvlistAll, sl) print("--------------------------------------------------------") print("Note: getCompoundPVGroup does a collective asynchronous get on all group members") print("--------------------------------------------------------") print("Data from getCompoundPVGroup") glist = cafe.groupMemberList('gAll') print(glist) pvg = cafe.getCompoundPVGroup('gAll', dt='str') pvg.showWithPV(pvlistAll[0:9]) # or pvg.showWithPV(glist[0:9]) print("Values of first element:") for i in range(0, pvg.npv): print(i, glist[i], " value=", pvg.pvdata[i].value[0],) print(" ") print("Data from getCompoundPVGroup by groupHandle") pvg = cafe.getCompoundPVGroup(groupHandle2, dt='float') pvg.showWithPV(pvlistAll[0:9]) # or print("Values of first element:") for i in range(0, pvg.npv): print(pvlistAll[i], " value=", pvg.pvdata[i].value[0],) print(" ") ############################################################## ############################################################## # (7) Get Ctrl Parameters ############################################################## try: pvctrl = cafe.getCtrl(hlistAll[8]) # or from Cache would normally suffice as we are not interested in .value pvctrl.show() pvctrl = cafe.getCtrlCache(hlistAll[8]) print(pvctrl.enumStrings) print(pvctrl.units) # if any except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) ############################################################## #cafe.enableExceptions = False cafe.withExceptions(False) ############################################################## # (8) Monitors ############################################################## cafe.openMonitorPrepare() # user supplied callback m0 = cafe.monitorStart(hlist1[0], cb=py_callback_pvdata, dbr=cyca.CY_DBR_TIME, mask=cyca.CY_DBE_VALUE | cyca.CY_DBE_ALARM) m2 = cafe.monitorStart(hlist1[0], cb=py_callback_pvdata, dbr=cyca.CY_DBR_TIME, mask=cyca.CY_DBE_VALUE | cyca.CY_DBE_ALARM) # default input parameters for dbr and mask m1 = cafe.monitorStart(hlist1[1], cb=py_callback_pvctrl, dbr=cyca.CY_DBR_CTRL) # optional, getCache methods get from cache without pre-checks, i.e. isChannel Connected #cafe.setGetCacheWaitPolicy(hlist[0], cyca.GET_CACHE_NO_CHECK) #cafe.setGetCacheWaitPolicy(hlist[1], cyca.GET_CACHE_NO_CHECK) print("Monitor STARTING ------------------------------------------------------------- ", m0, m1) cafe.openMonitorNowAndWait(1.0) val = -2.0 # watch the callbacks being invoked for i in range(0, 5): cafe.set(hlist1[0], val+i) cafe.set(hlist1[2], val+i) #cafe.set(hlist1[1], val+i+0.373) time.sleep(2.0) #print (" ") #print ("Latest Value for channel",cafe.getPVNameFromHandle(hlist1[0]), " is", cafe.getCache(hlist1[0], dt='native')) #print (" ") print('getNoMonitors ', cafe.getNoMonitors(hlist1[0])) # cafe.monitorStop(hlist1[0], mpid=m0) # mpid=m0 is optional and may be omitted # cafe.monitorStop(hlist1[0]) # optional, getCache methods get from cache with pre-checks (back to default) #cafe.setGetCacheWaitPolicy(hlist[0], cyca.GET_CACHE_WAIT) #cafe.setGetCacheWaitPolicy(hlist[1], cyca.GET_CACHE_WAIT) ############################################################## ############################################################## # (9) Asynchronous interactions and retrieving data from Cache ############################################################## print("--------------------------------------------------------") print("Asynchronous interactions and retrieving data from Cache") print("--------------------------------------------------------") # Check on return value or status instead of exceptions ##print("Exceptions enabled?", cafe.enableExceptions) s = cafe.set(hlistAll[0], 1.111789) s, sl = cafe.getAsyn(hlistAll) print("status of cafe.getAsyn(hlistAll)", s) if s != cyca.ICAFE_NORMAL: print(sl) # optional - may be omitted s, sl = cafe.waitForBundledEvents(hlistAll) # will wait for callback to be invoked if above omitted v = cafe.getCache(hlistAll[0]) if v != None: print("Value from Cache ", v) # get array v = cafe.getArrayCache(hlistAll[4], art='numpy') if v[0] != None: print("Value from Cache ", v) pv = cafe.getPVCache(hlistAll[4]) print(cafe.getPVNameFromHandle(hlistAll[4]), ":") pv.showMax(4) # show max 4 elements of wf ############################################################## ############################################################# # (10) More on groups ############################################################## # loads groups defined by virtual accelerator (SF network only) # SF specific, please delete ''' cafe.loadSFGroups() print ("loadSFGroups") ll=cafe.groupList() print ("----------------/") print (ll ) print ("----------------/") inl=['MQUA080','PS-MODE'] ll2=cafe.getChannelList(inl) #search for channels containing inl in pc name print ("--------------------//") print (ll2) print ("--------------------//") #View members of group ll[3] gml=cafe.groupMemberList(ll[3]) print ("------------------------///") print (gml) print ("------------------------///") ''' # See that a number of groups have been added to the groupList ll = cafe.groupList() print("----------------------------////") print(ll) print("----------------------------////") try: cafe.openGroupPrepare() gHandle = cafe.groupOpen(ll[0]) if (len(ll) > 0): gHandle2 = cafe.groupOpen(ll[1]) gl = [] gl.append(gHandle) if (len(ll) > 0): gl.append(gHandle2) cafe.openGroupNowAndWaitForInputGroups( 3.0, [ll[0], gHandle2]) # maximum timeout pvg = cafe.getPVGroup(gHandle) pvg.showWithPV(cafe.groupMemberList(ll[0])) cafe.closeDisconnectedChannelsWithinGroup([ll[0], gHandle2]) # cafe.closeChannelKeepHandle(pvlist1) pvg = cafe.getPVGroup(gHandle) # or # pvg = cafe.getPVGroup(ll[1]) pvg.showWithPV(cafe.groupMemberList(ll[0])) # 'testg' # cafe.terminate() # exit(0) # Start a Collective monitor on all group memebers with the same user supplied cb function cbf = [] for i in range(0, len(cafe.groupMemberList(ll[0]))): cbf.append(py_callback) # _pvdata) print(len(cafe.groupMemberList(ll[0])), len(cbf)) s, sV = cafe.groupMonitorStartWithCBList(gHandle, cbf) # or # s,sV=cafe.groupMonitorStartWithCBList(ll[0],cbf) # Start a monitor on all group members with default callback # If a channel is disconnected, then the monitor will start automatically on connection s, sV = cafe.groupMonitorStart('gAll') val, s, sl = cafe.getGroupCache(gHandle) # wait a tick for callbacks to complete before sets are done time.sleep(0.5) print("--------------------------------/") print("SET to monitored channels") print("--------------------------------/") for i in range(0, len(val)): val[i] = val[i]+0.9099999 s, sl = cafe.setGroup(gHandle, val) time.sleep(0.5) s, sV = cafe.groupMonitorStop(gHandle) s, sV = cafe.groupMonitorStop('gAll') except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) time.sleep(1) ''' #load collections and groups from external file cafe.loadCollectionsFromXML("Collections/collection_swissfel.xml"); cafe.loadGroupsFromXML("Groups/group_swissfel.xml"); cafe.loadCollectionsFromXML ("cNodes.xml") cafe.loadGroupsFromXML ("gDBPM.xml") # get static BPM data, i.e., names/positions BPMdev, BPMpos=cafe.devicePositionMap("cDBPM") nDBPM=len(BPMdev) print ("No. of DBPs devices =", nDBPM) for i in range (0, len(BPMdev)): print (i, " " + BPMdev[i], " " , BPMpos[i] ''' ############################################################## # (11) Special methods: ############################################################## # int match(valueToReach, handleMatch, tolerance, timeout, printFlag) # This method does not do a set, just waits until valueToReach # for channel hlist1[0] is reached print(" ") print("START cafe.match------------------------------------------------------") try: cafe.set(hlist1[0], 2.001) print(hlist1[0], "hlist1[0]", type(hlist1[0])) s = cyca.ICAFE_NORMAL s = cafe.match(float(2.34), int(hlist1[0]) , float(0.0011), float(10.0), bool(True)) # s=cafe.match(cafe.getEnumFromString(PVS,"monitor"),hlist1[0],0.0011,10.0,True) print("Status of match method: ", cafe.getStatusCodeAsText(s)) except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) print("Exception for cafe match ") print("Status of match method: ", cafe.getStatusCodeAsText(cafe.getStatus(hlist1[0]))) print("END cafe.match------------------------------------------------------") #cafe.terminate() #exit() # int setAndMatch(handlePVtoSet, valueToSet, handlePVtoReadback, tolerance, timeout, printFlag) # Set Channel1 followed by a readback of Channel 2 \n # Method verifies whether or not the 2 values agree within the given tolerance and timeout # Method returns with ECA_NORMAL as soon as a match is reached print(" ") print("START cafe.setAndMatch------------------------------------------------------") try: cafe.set(hlist1[1], 2.0201) s = cafe.setAndMatch(hlist1[0], 2.02, hlist1[1], 0.001, 10.0, True) # s=cafe.setAndMatch(hlist1[0],cafe.getEnumFromString(PVS,"monitor"),hlist1[1],0.001,1,True) print("Status of set and match method: ", cafe.getStatusCodeAsText(s)) except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) print("EXCEPTION AT SET AND MATCH") print("Status of set and match method: ", cafe.getStatusCodeAsText(cafe.getStatus(hlist1[0]))) print("END cafe.setAndMatch------------------------------------------------------") # Throw exception try: cafe.getEnumFromString(PVS, "Monitor") except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) # Set Channels followed by a corresponding readback of Channels \n # Method verifies whether or not the set/readback values agree within the given tolerance and timeout \n # Method returns with ECA_NORMAL as soon as a match is reached magnetSetList = ['ARIMA-CV-12LB:I-SET', 'ARIMA-CV-12LE:I-SET'] magnetReadList = ['ARIMA-CV-12LB:I-READ', 'ARIMA-CV-12LE:I-READ'] cafe.openPrepare() mSetHandleList = cafe.open(magnetSetList) mReadHandleList = cafe.open(magnetReadList) cafe.openNowAndWait(0.4) valInput = [] valInput.append(3.5) valInput.append(3.6) # int setAndMatchMany(handlePVArraytoSet, valueArrayToSet, handlePVArraytoReadback, tolerance, timeout, printFlag) print(" ") print("START cafe.setAndMatchMany------------------------------------------------------") try: s, sL = cafe.setScalarList(mSetHandleList, valInput) s, sL = cafe.setScalarList(mReadHandleList, [3.501, 3.599]) s = cafe.setAndMatchMany(mSetHandleList, valInput, mReadHandleList, 0.002, 10.0, True) print("Status of set and match method: ", cafe.getStatusCodeAsText(s)) except PyCafe.CafeException as cafeEx: cafeEx.reveal() # or print(cafeEx.name, "(handle=", cafeEx.handle, ")") print(cafeEx.error_code, ":", cafeEx.error_text, cafeEx.error_info) except Exception as inst: print(inst) print("END cafe.setAndMatch------------------------------------------------------") # int gameSetAndMatch(handlePVArraytoSet, valueArrayToSet, handlePVActiontoSet, valueActionToSet, handlePVArraytoReadback, tolerance, timeout, printFlag) print(" ") print("START cafe.gameSetAndMatch------------------------------------------------------") try: s, sL = cafe.setScalarList(mSetHandleList, valInput) s, sL = cafe.setScalarList(mReadHandleList, [3.501, 3.599]) s = cafe.gameSetAndMatch( mSetHandleList, valInput, mReadHandleList[0], "1", mReadHandleList, 0.002, 20.0, True) print("Status of set and match method: ", cafe.getStatusCodeAsText(s)) except PyCafe.CafeException as cafeEx: cafeEx.reveal() except Exception as inst: print(inst) print("END cafe.gameSetAndMatch------------------------------------------------------") ############################################################## # Test with attaching context (would do this from another thread) #print(cafe.getStatusCodeAsText(cafe.attachContext(1))) #print(cafe.getStatusCodeAsText(cafe.attachContext(999))) if (cafe.attachContext(1) == cyca.CY_ECA_ISATTACHED): print("TEST: Should be attached", cafe.getStatusCodeAsText(cyca.CY_ECA_ISATTACHED)) if (cafe.attachContext(999) == cyca.ECAFE_NULLCONTEXT): print("TEST: Should not be attached", cafe.getStatusCodeAsText(cyca.ECAFE_NULLCONTEXT)) ############################################################## # END Gracefully terminate CAFE ############################################################## cafe.terminate() exit(0) ##############################################################