Files
cycafe/examples.py
2022-08-04 10:22:53 +02:00

1404 lines
43 KiB
Python

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