1100 lines
32 KiB
Python
1100 lines
32 KiB
Python
# python
|
|
|
|
import time
|
|
import timeit
|
|
import numpy as np
|
|
import array
|
|
import inspect
|
|
import os
|
|
import operator
|
|
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-2'
|
|
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.DESC'
|
|
|
|
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]
|
|
|
|
#################################################################
|
|
|
|
|
|
#################################################################
|
|
# A user supplied callback function to be (optionally) used in (8) Monitors
|
|
# (or puts and gets if required)
|
|
#################################################################
|
|
def py_callback(handle):
|
|
#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
|
|
print ("Value =", cafe.getCache(handle, dt='str')) #else dt='int', dt='float'
|
|
#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)
|
|
p1.showMax(10) #if waveform print only first 10 elements
|
|
#alternatively:
|
|
print ("Value =", p1.value[0])
|
|
print ("status = %d" % p1.status)
|
|
print ("alarmStatus = %d" % p1.alarmStatus)
|
|
print ("alarmSeverity = %d" % 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 Exception as inst:
|
|
print ("ERROR IN CALLBACK HANDLER:")
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
cafeEx.show()
|
|
#or
|
|
cafeEx.reveal()
|
|
#or
|
|
print (cafeEx.pv,"(handle=", cafeEx.handle,")")
|
|
print (cafeEx.errorCode,":", cafeEx.errorText,cafeEx.errorInfo)
|
|
else:
|
|
print (inst)
|
|
|
|
print ("END: MONITOR CALLBACK HANDLER COMPLETED FOR HANDLE:", handle)
|
|
print ("")
|
|
return
|
|
##############################################################
|
|
|
|
#################################################################
|
|
# A user supplied callback function for put operations (optional)
|
|
#################################################################
|
|
def py_callback_put(handle):
|
|
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("INFO: pend time for open",cafe.getOpenDefaultPendTime())
|
|
#open a single channel
|
|
try:
|
|
handleS=cafe.open(PVS);
|
|
except Exception as inst:
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
cafeEx.show()
|
|
#or
|
|
cafeEx.reveal()
|
|
#or
|
|
print (cafeEx.errorCode,":", cafeEx.errorText,cafeEx.errorInfo)
|
|
|
|
#better practice is to open all channels at once
|
|
|
|
start=time.time()
|
|
|
|
cafe.openPrepare()
|
|
|
|
try:
|
|
#return list of handles
|
|
hlist1 =cafe.open(pvlist1)
|
|
hlistWF =cafe.open(pvlistWF)
|
|
hlistAll=cafe.open(pvlistAll) #Note: only one handle per channel is created
|
|
except Exception as inst:
|
|
|
|
print(inst.args)
|
|
|
|
cafe.openNowAndWait(0.5) #wait 500ms for channels to connect
|
|
|
|
end=time.time()
|
|
print(end-start)
|
|
|
|
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);
|
|
|
|
#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.withExceptions(True);
|
|
|
|
#Now perform some get operations
|
|
try:
|
|
val=cafe.get(hlistAll[8])
|
|
print ("Channel: ", cafe.getPVNameFromHandle(hlistAll[8])," value=", val)
|
|
except Exception as inst:
|
|
print ("ERROR IN cafe.get")
|
|
print (inst)
|
|
|
|
#Retrun pvdata struct, i.e., val, alarms, timestamps
|
|
try:
|
|
pv=cafe.getPV(hlistAll[8])
|
|
pv.show()
|
|
except Exception as inst:
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
cafeEx.show()
|
|
cafeEx.reveal()
|
|
else:
|
|
print (inst)
|
|
|
|
#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 Exception as inst:
|
|
print ("ERROR IN cafe.get for channel:", PV_JOKE)
|
|
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
cafeEx.show()
|
|
#or
|
|
cafeEx.reveal()
|
|
else:
|
|
print (inst)
|
|
|
|
try:
|
|
val=cafe.get(hlistAll[3])
|
|
print ("Channel: ", pvlistAll[3]," value=", val)
|
|
#or
|
|
print ("Channel: ", cafe.getPVNameFromHandle(hlistAll[3])," value=", val)
|
|
except Exception as inst:
|
|
print ("ERROR IN cafe.get for channel:", PV_JOKE)
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
#cafeEx.show()
|
|
cafeEx.reveal()
|
|
else:
|
|
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 Exception as inst:
|
|
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
cafeEx.show()
|
|
#or
|
|
cafeEx.reveal()
|
|
#or
|
|
print (cafeEx.pv,"(handle=", cafeEx.handle,")")
|
|
print (cafeEx.errorCode,":", cafeEx.errorText,cafeEx.errorInfo)
|
|
else:
|
|
print (inst)
|
|
|
|
#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 Exception as inst:
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
cafeEx.show()
|
|
#or
|
|
cafeEx.reveal()
|
|
#or
|
|
print (cafeEx.pv,"(handle=", cafeEx.handle,")")
|
|
print (cafeEx.errorCode,":", cafeEx.errorText,cafeEx.errorInfo)
|
|
else:
|
|
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)
|
|
|
|
s=cafe.set(hlist1[0],7.777)
|
|
v=cafe.get(hlist1[0])
|
|
|
|
print("Can you see if the callback functions were called for set/get?")
|
|
print("Value should be 7.777", v)
|
|
|
|
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 Exception as inst:
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
cafeEx.show()
|
|
#or
|
|
cafeEx.reveal()
|
|
#or
|
|
print (cafeEx.pv,"(handle=", cafeEx.handle,")")
|
|
print (cafeEx.errorCode,":", cafeEx.errorText,cafeEx.errorInfo)
|
|
else:
|
|
print (inst)
|
|
|
|
|
|
|
|
#END (2) Simple single channel operations
|
|
##############################################################
|
|
|
|
##############################################################
|
|
#(3) Waveforms and Arrays
|
|
##############################################################
|
|
try:
|
|
NWF=5
|
|
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)
|
|
#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])
|
|
|
|
|
|
#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 Exception as inst:
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
cafeEx.show()
|
|
#or
|
|
cafeEx.reveal()
|
|
#or
|
|
print (cafeEx.pv,"(handle=", cafeEx.handle,")")
|
|
print (cafeEx.errorCode,":", cafeEx.errorText,cafeEx.errorInfo)
|
|
else:
|
|
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 statusList!
|
|
#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(" ")
|
|
|
|
valueList,status,statusList=cafe.getScalarList(hlistAll,dt='float') #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("--------------------------------------------------------")
|
|
|
|
a=float('2')
|
|
print ('a=', a)
|
|
|
|
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(val)
|
|
print(sl)
|
|
#print one of the waveforms in above val List
|
|
'''
|
|
if PY3:
|
|
for i in range (0, len(val[4])):
|
|
print (val[4][i], end=" ")
|
|
print(" ")
|
|
'''
|
|
|
|
mval=10
|
|
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],)
|
|
print(" ")
|
|
|
|
cafe.printStatusIfError(hlistAll, sl)
|
|
#or
|
|
'''
|
|
if PY3:
|
|
for i in range (0, len(sl)):
|
|
print (cafe.getStatusCodeAsText(sl[i]), " [",i,"] ",end=" ")
|
|
print(" ")
|
|
'''
|
|
|
|
val[2]=0.7123
|
|
s,sl=cafe.setCompoundList(hlistAll, val)
|
|
if (s != cyca.ICAFE_NORMAL):
|
|
cafe.printStatusIfError(hlistAll, sl)
|
|
|
|
#readback to check that above set worked
|
|
print ("Readback value should be", val[2], " val=", cafe.get(hlistAll[2]))
|
|
print("--------------------------------------------------------")
|
|
print("--------------------------------------------------------")
|
|
##############################################################
|
|
|
|
|
|
##############################################################
|
|
#(6) Synchronous group operations and like
|
|
##############################################################
|
|
print("--------------------------------------------------------")
|
|
print(" Synchronous group operations ")
|
|
print("--------------------------------------------------------")
|
|
|
|
#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)
|
|
|
|
groupHandle2=cafe.groupOpen('gAll')
|
|
pvg =cafe.getPVGroup(groupHandle2)
|
|
#pvg.show()
|
|
#or
|
|
pvg.showWithPV(pvlistAll)
|
|
#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)
|
|
|
|
#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")
|
|
pvg=cafe.getCompoundPVGroup('gAll', dt='str')
|
|
pvg.showWithPV(pvlistAll)
|
|
#or
|
|
glist=cafe.groupMemberList('gAll')
|
|
pvg.showWithPV(glist)
|
|
|
|
print ("Values of first element:")
|
|
for i in range (0, pvg.npv):
|
|
print(glist[i], " value=", pvg.pvdata[i].value[0],)
|
|
print(" ")
|
|
|
|
|
|
print ("Data from getCompoundPVGroup by groupHandle")
|
|
pvg=cafe.getCompoundPVGroup(groupHandle2, dt='float')
|
|
pvg.showWithPV(pvlistAll)
|
|
#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
|
|
##############################################################
|
|
|
|
pvctrl = cafe.getCtrl (hlistAll[8])
|
|
#or from Cache would normally suffice as we are not interested in .value
|
|
pvctrl = cafe.getCtrlCache (hlistAll[8])
|
|
pvctrl.show()
|
|
|
|
print (pvctrl.enumStrings)
|
|
print (pvctrl.units) #if any
|
|
|
|
##############################################################
|
|
|
|
cafe.withExceptions(False);
|
|
|
|
##############################################################
|
|
#(8) Monitors
|
|
##############################################################
|
|
cafe.openMonitorPrepare();
|
|
|
|
#user supplied callback
|
|
m0 =cafe.monitorStart(hlist1[0], cb=py_callback, dbr=cyca.CY_DBR_PLAIN, mask=cyca.CY_DBE_VALUE|cyca.CY_DBE_ALARM)
|
|
print(m0)
|
|
#default input parameters fro dbr and mask
|
|
m1 =cafe.monitorStart(hlist1[0], cb=py_callback )
|
|
print(m1)
|
|
|
|
|
|
#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,10):
|
|
cafe.set(hlist1[0], 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.close(hlist1[0])
|
|
time.sleep(2);
|
|
|
|
#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)
|
|
|
|
cafe.terminate();
|
|
exit(1);
|
|
|
|
|
|
##############################################################
|
|
|
|
##############################################################
|
|
#(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
|
|
|
|
cafe.withExceptions(False);
|
|
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:
|
|
gHandle=cafe.groupOpen(ll[0])
|
|
pvg=cafe.getPVGroup(gHandle)
|
|
#or
|
|
pvg=cafe.getPVGroup(ll[0])
|
|
print ("--------------------------------/")
|
|
pvg.showWithPV(cafe.groupMemberList(ll[0])) #'gBRPM'
|
|
print ("--------------------------------/")
|
|
|
|
#Start a Collective monitor on all group memebers with the same user supplied cb function
|
|
cbf=[]
|
|
for i in range (0, len(ll[0])):
|
|
cbf.append(py_callback)
|
|
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 Exception as inst:
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
cafeEx.show()
|
|
#or
|
|
cafeEx.reveal()
|
|
#or
|
|
print (cafeEx.pv,"(handle=", cafeEx.handle,")")
|
|
print (cafeEx.errorCode,":", cafeEx.errorText,cafeEx.errorInfo)
|
|
else:
|
|
print (inst)
|
|
|
|
|
|
'''
|
|
|
|
#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)
|
|
s=cafe.match(2.34,hlist1[0],0.0011,10.0,True)
|
|
#s=cafe.match(cafe.getEnumFromString(PVS,"monitor"),hlist1[0],0.0011,10.0,True)
|
|
print ("Status of match method: ", cafe.getStatusCodeAsText(s))
|
|
except Exception as inst:
|
|
print ("Exception for cafe match ")
|
|
print ("Status of match method: ", cafe.getStatusCodeAsText(cafe.getStatus(hlist1[0])))
|
|
print ("END cafe.match------------------------------------------------------")
|
|
|
|
|
|
#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 Exception as 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 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 Exception as inst:
|
|
if isinstance(inst.args[0],PyCafe.CyCafeException):
|
|
cafeEx=inst.args[0]
|
|
cafeEx.show()
|
|
#or
|
|
cafeEx.reveal()
|
|
#or
|
|
print (cafeEx.pv,"(handle=", cafeEx.handle,")")
|
|
print (cafeEx.errorCode,":", cafeEx.errorText,cafeEx.errorInfo)
|
|
else:
|
|
print (inst)
|
|
|
|
|
|
|
|
|
|
print ("END cafe.setAndMatch------------------------------------------------------")
|
|
|
|
|
|
|
|
##############################################################
|
|
|
|
|
|
##Test with attaching context (would do this from another thread)
|
|
print ( cafe.getStatusCodeAsText(cafe.attachContext(1)) );
|
|
print ( cafe.getStatusCodeAsText(cafe.attachContext(999999)));
|
|
|
|
if (cafe.attachContext(1) == cyca.CY_ECA_ISATTACHED):
|
|
print (cafe.getStatusCodeAsText(cafe.attachContext(1)));
|
|
|
|
if (cafe.attachContext(99999) == cyca.ECAFE_NULLCONTEXT):
|
|
print (cafe.getStatusCodeAsText(cafe.attachContext(999)));
|
|
|
|
|
|
|
|
##############################################################
|
|
#END Gracefully terminate CAFE
|
|
##############################################################
|
|
cafe.terminate()
|
|
exit(0)
|
|
##############################################################
|
|
|
|
|
|
|
|
|