8085 lines
320 KiB
Cython
8085 lines
320 KiB
Cython
# dtutils: language = c++
|
|
# file: PyCafe.pyx
|
|
|
|
"""Cython interface to the C++ CAFE library. |br|
|
|
To import the resulting Python module and instantiate the Cython class:
|
|
::
|
|
|
|
import PyCafe
|
|
cafe = PyCafe.CyCafe()
|
|
cyca = PyCafe.CyCa()
|
|
|
|
"""
|
|
|
|
import array
|
|
import ctypes
|
|
import cython
|
|
import inspect
|
|
import numbers
|
|
import numpy as np
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import timeit
|
|
|
|
import Cython.Compiler.Options
|
|
|
|
from collections import OrderedDict
|
|
|
|
from copy import deepcopy
|
|
from cython cimport view
|
|
from cython.operator cimport dereference as deref
|
|
from cython.operator cimport preincrement as inc
|
|
from cython.view cimport array as cvarray
|
|
from cpython cimport array
|
|
from cpython.object cimport PyObject
|
|
from cpython.ref cimport Py_INCREF
|
|
|
|
from libc.stdlib cimport malloc, free
|
|
|
|
cimport numpy as cnp
|
|
cimport PyCafe as ccafe
|
|
|
|
# from libcpp.string cimport string
|
|
#Cython.Compiler.Options.annotate = True
|
|
|
|
_pymodule = "PyCafe.pyx"
|
|
_pymodule_parts = _pymodule.split(".")
|
|
_appname = _pymodule_parts[0]
|
|
|
|
_python_version = sys.version_info #[0:4]
|
|
|
|
cdef dict hmd = {}
|
|
|
|
#needed to initialize PyArray_API in order to be able to use it
|
|
cnp.import_array()
|
|
|
|
|
|
cdef class MemoryNanny:
|
|
cdef void* ptr # set to NULL by "constructor"
|
|
def __dealloc__(self):
|
|
print("freeing ptr=", <unsigned long long>(self.ptr)) #just for debugging
|
|
free(self.ptr)
|
|
|
|
@staticmethod
|
|
cdef create(void* ptr):
|
|
cdef MemoryNanny result = MemoryNanny()
|
|
result.ptr = ptr
|
|
print("nanny for ptr=", <unsigned long long>(result.ptr)) #just for debugging
|
|
return result
|
|
|
|
cdef extern from "numpy/arrayobject.h":
|
|
# a little bit awkward: the reference to obj will be stolen
|
|
# using PyObject* to signal that Cython cannot handle it automatically
|
|
int PyArray_SetBaseObject(cnp.ndarray arr, PyObject *obj) except -1 # -1 means there was an error
|
|
|
|
cdef array_from_ptr(void * ptr, cnp.npy_intp N, int np_type):
|
|
#start = time.time()
|
|
cdef cnp.ndarray arr = cnp.PyArray_SimpleNewFromData(1, &N, np_type, ptr)
|
|
nanny = MemoryNanny.create(ptr)
|
|
Py_INCREF(nanny) # a reference will get stolen, so prepare nanny
|
|
PyArray_SetBaseObject(arr, <PyObject*>nanny)
|
|
#print("array_from_ptr", time.time() - start)
|
|
return arr
|
|
|
|
include "PyCafeDefs.pxi"
|
|
|
|
def verify_handlepv(func):
|
|
"""Decorator to validate handle/PV input argument.
|
|
|
|
PyCafe methods that act on a single channel accept either the PV name or
|
|
the handle (object reference) to the PV as returned by the ``open`` method.
|
|
If a PV name is given, the decorator retrieves the associated handle to
|
|
pass on to the underlying C++ CAFE method.
|
|
|
|
Args:
|
|
func: The function to be wrapped
|
|
|
|
Returns:
|
|
The modified input function
|
|
|
|
Raises:
|
|
TypeError: If handle/PV is not `int` or `str`, respectively.
|
|
ValueError: If handle is invalid.
|
|
|
|
"""
|
|
#This outer code (only) is executed at import PyCafe (compile time)
|
|
#while the below is not
|
|
|
|
def wrapper(self, *args,**kwargs):
|
|
|
|
#print('The positional arguments are', args)
|
|
#print('The keyword arguments are', kwargs)
|
|
|
|
handlePV = args[0]
|
|
cdef unsigned int handle = 0
|
|
|
|
|
|
#Accept if pv/handle is in list of length one
|
|
if isinstance(handlePV, list):
|
|
if len(handlePV) == 1:
|
|
handlePV = handlePV[0]
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
if handlePV < 0:
|
|
raise ValueError(
|
|
"{} {}.pyx: {} \n{}".format(
|
|
"Exception raised in", _appname, func.__name__,
|
|
("A handle can never hold a negative value! ")))
|
|
|
|
handle = handlePV
|
|
|
|
if not self.isValid(handle):
|
|
raise ValueError(
|
|
"{} {}.pyx: {} \n{}".format(
|
|
"Exception raised in", _appname, func.__name__,
|
|
("Invalid handle of type <class 'int'>. If handle is not "
|
|
"known, \nsuggest using PV name of type <class 'str'> "
|
|
"as input argument instead. ")))
|
|
|
|
elif isinstance(handlePV, str):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise TypeError(
|
|
"{} {}.pyx: {} \n{}".format(
|
|
"Exception raised in", _appname, func.__name__,
|
|
("First input argument, should be of type <class 'int'> "
|
|
"if handle, else <class 'str'> if PV")))
|
|
|
|
##kwargs_keys = list(kwargs.keys())
|
|
##return func(self, handle, **kwargs) # **splat operator
|
|
|
|
|
|
if not kwargs:
|
|
if len(args) == 1:
|
|
|
|
return func(self, handle)
|
|
|
|
else:
|
|
return func(self, handle, *args[1:])
|
|
|
|
elif len(kwargs) > 0:
|
|
if len(args) == 1:
|
|
|
|
return func(self, handle, **kwargs)
|
|
|
|
else:
|
|
return func(self, handle, *args[1:], **kwargs) #dt=kwargs[kwargs_keys[0]])
|
|
|
|
return wrapper
|
|
|
|
################################################################################
|
|
cdef class CyCafe:
|
|
"""
|
|
Class with associated process variable meta data.
|
|
|
|
Attributes:
|
|
_c_cafe (PyCafe.CAFE): The CAFE class.
|
|
_enable_exceptions (bool): Activates exceptions for single pv operations
|
|
_exception_text (str): Default text for CyCafe exceptions that do not
|
|
originate from the C++ CAFE exception
|
|
|
|
"""
|
|
cdef:
|
|
ccafe.CAFE * _c_cafe
|
|
|
|
double valFloat # cython float64
|
|
dbr_long_t valInt
|
|
string valStr
|
|
|
|
vector[double] vFloat # cython float64
|
|
vector[dbr_long_t] vInt
|
|
vector[string] vStr
|
|
|
|
str _exception_text
|
|
bint _enable_exceptions
|
|
double _min_timeout
|
|
|
|
CAFEStatus cs
|
|
CAFEStatusSeverity css
|
|
|
|
HandleHelper hh
|
|
PolicyHelper ph
|
|
|
|
ChannelRegalia channelInfo
|
|
# PyGILState_STATE gstate
|
|
|
|
###########################################################################
|
|
def __cinit__(self):
|
|
"""Initializes CAFE and CyCafe class attributes.
|
|
|
|
"""
|
|
cdef str _METHOD = "__cinit__"
|
|
self._c_cafe = new ccafe.CAFE() ##_c_cafe ##
|
|
|
|
if self._c_cafe is NULL:
|
|
raise MemoryError("Failed to instantiate CAFE()")
|
|
|
|
self.cs = self._c_cafe.getCafeStatus()
|
|
|
|
self._exception_text = "Exception raised in PyCafe.pyx:"
|
|
self._enable_exceptions = False
|
|
|
|
self._min_timeout = 0.001 #cannot be zero
|
|
|
|
try:
|
|
self._c_cafe.init()
|
|
except RuntimeError as e:
|
|
if isinstance(e.args, (tuple)):
|
|
# equivalent to e.what()
|
|
if 'CAFEException_init' in (e.args[0]):
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_error_code=ECA_ALLOCMEM,
|
|
_error_text=self.cs.code(ECA_ALLOCMEM),
|
|
_error_info=self.cs.info(ECA_ALLOCMEM))
|
|
raise _cafeException
|
|
raise Exception("{} {} \n{}".format(self._exception_text, _METHOD, e))
|
|
|
|
|
|
print("PY_VERSION_HEX is ", hex(PY_VERSION_HEX))
|
|
|
|
IF PY_EXT_C:
|
|
print("USING PUBLIC PyCafe.h INTERFACE FOR CALLBACKS")
|
|
ELSE:
|
|
print("USING API PyCafe_api.h INTERFACE FOR CALLBACKS")
|
|
|
|
# Required with gil for callbacks
|
|
# Placed in cafe.init()
|
|
# Py_Initialize()
|
|
# PyEval_InitThreads()
|
|
|
|
###########################################################################
|
|
def __dealloc__(self):
|
|
del self._c_cafe
|
|
|
|
###########################################################################
|
|
|
|
@verify_handlepv
|
|
def get_wf_express(self, handlePV, nelem):
|
|
print("get_wf_express")
|
|
|
|
#'''
|
|
valCharArray = <dbr_char_t * > malloc(nelem * sizeof(dbr_char_t))
|
|
status = self._c_cafe.wfExpress(handlePV, nelem, valCharArray)
|
|
#print("status", status, valCharArray[0])
|
|
mvUInt8n = np.empty(nelem, dtype=np.uint8, order='C')
|
|
for ij in range(0, nelem):
|
|
mvUInt8n[ij] = <cnp.uint8_t > valCharArray[ij]
|
|
free(valCharArray)
|
|
|
|
return mvUInt8n
|
|
#'''
|
|
|
|
def ca_version(self):
|
|
return self._c_cafe._ca_version()
|
|
|
|
def epics_version_string(self):
|
|
return self._c_cafe._epics_version()
|
|
def CAFE_version(self):
|
|
return CAFE_VERSION
|
|
|
|
def EPICS_version(self):
|
|
return EPICS_VERSION
|
|
|
|
@verify_handlepv
|
|
def setPyConnectCallbackFn(self, handlePV, cb: object = None):
|
|
if cb is None:
|
|
return
|
|
pv_name = handlePV
|
|
self.hh.setPyConnectCallbackFn(handlePV, <void *>cb)
|
|
|
|
|
|
############################################################################
|
|
def init(self):
|
|
"""Initialize channel access.
|
|
|
|
This method is called by ``__cinit__`` when instantiating CyCafe.
|
|
It may, optionally, be called by the user when creating a new channel
|
|
access context, e.g., if in a separate thread. If omitted, it will
|
|
otherwise be called internally by CAFE.
|
|
|
|
Raises:
|
|
MemoryError: If insufficient memory to initialize channel access.
|
|
Epics status reports ECA_ALLOCMEM. Application cannot continue.
|
|
|
|
"""
|
|
cdef str _METHOD = "init"
|
|
try:
|
|
self._c_cafe.init()
|
|
except RuntimeError as e:
|
|
if isinstance(e.args, (tuple)):
|
|
# e.args[0] is e.what()
|
|
if 'CAFEException_init' in (e.args[0]):
|
|
raise MemoryError(
|
|
"{} {} \n{}\n{}".format(
|
|
self._exception_text, _METHOD,
|
|
"ECA_ALLOCMEM error in initializing ca context ",
|
|
self.cs.info(ECA_ALLOCMEM)))
|
|
|
|
raise Exception("{} {} \n{}".format(self._exception_text, _METHOD, e))
|
|
|
|
|
|
def withExceptions(self, bint exceptions=True):
|
|
"""Activate/deactivate CAFE exceptions for single channel operations.
|
|
|
|
If the input argument, exceptions, is set to False, the user is obliged
|
|
to examine the return code of any set/get method that instigates a CAFE
|
|
transaction on a single channel.
|
|
|
|
Args:
|
|
exceptions (bool): Activates/deactivates CAFE exceptions if
|
|
True/False for single channel operations. The default is True.
|
|
|
|
Returns:
|
|
bool: Confirmation of the set value
|
|
::
|
|
|
|
res = cafe.withExceptions(True|False)
|
|
"""
|
|
|
|
self._enable_exceptions = exceptions
|
|
return self._enable_exceptions
|
|
|
|
|
|
@property
|
|
def enableExceptions(self):
|
|
"""Activate/deactivate CAFE exceptions for single channel operations.
|
|
|
|
The default value is True.
|
|
If set to False, the user is obliged to examine the return code of any
|
|
set/get method that instigates a CAFE transaction on a single channel.
|
|
|
|
Returns:
|
|
bool: The current value
|
|
::
|
|
|
|
cafe.enableExceptions = True | False
|
|
res = cafe.enableExceptions
|
|
|
|
"""
|
|
|
|
return self._enable_exceptions
|
|
|
|
@enableExceptions.setter
|
|
def enableExceptions(self, bint enable):
|
|
self._enable_exceptions = enable
|
|
|
|
cdef prepareCafeException(
|
|
self, int status, str _METHOD,
|
|
unsigned int handle = 0, pv_name: str = None):
|
|
if handle > 0 and pv_name is None:
|
|
pv_name=self._c_cafe.getPVFromHandle(handle)
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_error_code=status, _pv_name=pv_name,
|
|
_error_text=self.cs.code(status), _error_info=self.cs.info(status))
|
|
return _cafeException
|
|
|
|
############################################################################
|
|
|
|
def isValid(self, unsigned int handle):
|
|
return self._c_cafe.isValid(handle)
|
|
|
|
|
|
############################################################################
|
|
def removeWidget(self, unsigned int handle, object widget):
|
|
return self.hh.removeWidget(handle, <void *> widget)
|
|
|
|
def addWidget(self, unsigned int handle, object widget):
|
|
return self.hh.addWidget(handle, <void *> widget)
|
|
|
|
def getWidgets(self, unsigned int handle):
|
|
cdef vector[void *] widgetV
|
|
widgetV.reserve(2)
|
|
widgetList = []
|
|
status = self.hh.getWidgets(handle, widgetV)
|
|
for i in range(0, widgetV.size()):
|
|
widgetList.append( < object > widgetV[i])
|
|
return widgetList
|
|
############################################################################
|
|
|
|
############################################################################
|
|
# Cython exceptions, only e.what() is preserved. See https:
|
|
# //cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html
|
|
############################################################################
|
|
|
|
|
|
def open(self, pv, cb: object = None):
|
|
"""Returns handle (object reference) for given process variable.
|
|
|
|
Establishes a channel access virtual circuit to the given process
|
|
variable, pv. The optional user supplied callback function reports on
|
|
the connection state. Within the callback, all cafe operations that
|
|
retrieve data from cache and send data values to the process variable
|
|
are permitted. Typically, such callback functions are used in GUI
|
|
development, and in complex procedures, such as feedback systems in
|
|
virtual accelerators.
|
|
|
|
Args:
|
|
pv (:obj:`str`, :obj:`bytes`, :obj:`list` of :obj:`str` or :obj:`bytes`):
|
|
The process variable name(s)
|
|
cb (:obj:`object`, optional): A user supplied callback function to
|
|
be invoked upon first connection and subsequent changes to the
|
|
connection state. Defaults to None. The callback function must
|
|
have the required signature (:obj:`int`, :obj:`str`, :obj:`int`)
|
|
|
|
Returns:
|
|
:obj:`int` | :obj:`list` of :obj:`int`: handle(s) to the given pv(s).
|
|
|
|
|
|
Raises:
|
|
TypeError: If handle/PV is not instance of `int` or (`str`,`bytes`),
|
|
respectively.
|
|
|
|
.. code-block:: python
|
|
|
|
py_connect_callback(handle, pv_name, status):
|
|
if status == cyca.ICAFE_CS_CONN:
|
|
value = cafe.getCache(handle[, dt=`str`])
|
|
...
|
|
elif status == cyca.ICAFE_CS_DISCONN:
|
|
...
|
|
|
|
::
|
|
|
|
handle = cafe.open(pv=pv_name[, cb=py_connect_callback])
|
|
|
|
"""
|
|
cdef str _METHOD = "open"
|
|
cdef vector[string] pvV
|
|
cdef vector[unsigned int] handleV
|
|
cdef bytes py_string
|
|
|
|
if isinstance(pv, (list)):
|
|
for i in range(0, len(pv)):
|
|
if isinstance(pv[i], str):
|
|
pvV.push_back(pv[i])
|
|
elif isinstance(pv[i], bytes):
|
|
pvV.push_back(pv[i].decode('utf_8') )
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("The pv name entered within list should be "
|
|
"of type <class 'str'> or <class 'bytes'>")))
|
|
try:
|
|
if cb is not None:
|
|
|
|
self._c_cafe.channelCreatePolicy.setPyCallbackFlag(True)
|
|
self._c_cafe.channelCreatePolicy.setPyConnectHandler(<void *>cb)
|
|
|
|
IF PY_EXT_C:
|
|
with nogil:
|
|
status = self._c_cafe.openV(pvV, handleV)
|
|
ELSE:
|
|
#Gil acquired and released within conduit.h
|
|
#with nogil:
|
|
status = self._c_cafe.openV(pvV, handleV)
|
|
if not self.initCallbackComplete(handleV):
|
|
time.sleep(0.2)
|
|
else:
|
|
time.sleep(0.02)
|
|
except RuntimeError as e:
|
|
# Reset
|
|
if cb is not None:
|
|
self._c_cafe.channelCreatePolicy.setPyCallbackFlag(False)
|
|
|
|
if isinstance(e.args, (tuple)):
|
|
# equivalent to e.what()
|
|
if 'CAFEException' in (e.args[0]):
|
|
errors = e.args[0].split(",")
|
|
if len(errors) > 5:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_pv_name=errors[1], _handle=int(errors[2]),
|
|
_error_code=int(errors[3]),
|
|
_error_text=errors[4], _error_info=errors[5])
|
|
raise _cafeException
|
|
raise Exception("{} {} \n{}".format(self._exception_text, _METHOD, e))
|
|
|
|
if cb is not None:
|
|
# Reset
|
|
self._c_cafe.channelCreatePolicy.setPyCallbackFlag(False)
|
|
return handleV
|
|
|
|
elif not isinstance(pv, (bytes, str)):
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
"Input argument, pv, should be of type <class 'str'>"))
|
|
|
|
cdef unsigned int handle = 0
|
|
cdef vector[string] vecS
|
|
|
|
cdef char * pvStr = pv
|
|
|
|
if cb is not None:
|
|
|
|
self._c_cafe.channelCreatePolicy.setPyCallbackFlag(True)
|
|
self._c_cafe.channelCreatePolicy.setPyConnectHandler(<void *>cb)
|
|
try:
|
|
IF PY_EXT_C:
|
|
#print("OPEN WITH NO GIL==>", pvStr)
|
|
with nogil:
|
|
self._c_cafe.open(pvStr, handle)
|
|
#print("OPEN WITH NO GIL//==>", pvStr, handle)
|
|
ELSE:
|
|
#Gil acquired and released within conduit.h
|
|
#with nogil:
|
|
self._c_cafe.open(pvStr, handle)
|
|
except RuntimeError as e:
|
|
# Reset
|
|
if cb is not None:
|
|
self._c_cafe.channelCreatePolicy.setPyCallbackFlag(False)
|
|
if isinstance(e.args, (tuple)):
|
|
if 'CAFEException' in (e.args[0]):
|
|
errors = e.args[0].split(",") # from e.what()
|
|
if len(errors) > 5:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_pv_name=errors[1],
|
|
_handle=int(errors[2]), _error_code=int(errors[3]),
|
|
_error_text=errors[4], _error_info=errors[5])
|
|
raise _cafeException
|
|
|
|
raise Exception("{} {} \n{}".format(self._exception_text, _METHOD, e))
|
|
|
|
# Reset
|
|
if cb is not None:
|
|
self._c_cafe.channelCreatePolicy.setPyCallbackFlag(False)
|
|
# A notch to allow for possible race condition
|
|
if not self._c_cafe.isChannelConnected(handle):
|
|
time.sleep(0.1)
|
|
else:
|
|
time.sleep(0.01) # Let pycallbacks complete
|
|
return handle
|
|
|
|
############################################################################
|
|
def openNoWait(self):
|
|
# channelOpenPolicy.setFlushSendBufferKind(WITH_POLL)
|
|
# channelOpenPolicy.setWhenToFlushSendBuffer(
|
|
# FLUSH_DESIGNATED_TO_CLIENT)
|
|
with nogil:
|
|
self._c_cafe.openNoWait()
|
|
return
|
|
|
|
def openPrepare(self):
|
|
# self._c_cafe.channelOpenPolicy.setFlushSendBufferKind(WITH_POLL)
|
|
# self._c_cafe.channelOpenPolicy.setWhenToFlushSendBuffer(
|
|
# FLUSH_DESIGNATED_TO_CLIENT)
|
|
with nogil:
|
|
self._c_cafe.openPrepare()
|
|
|
|
def openGroupPrepare(self):
|
|
# self._c_cafe.channelOpenGroupPolicy.setFlushSendBufferKind(
|
|
# WITH_PEND_EVENT)
|
|
# self._c_cafe.channelOpenGroupPolicy.setWhenToFlushSendBuffer(
|
|
# FLUSH_DESIGNATED_TO_CLIENT)
|
|
with nogil:
|
|
self._c_cafe.openGroupPrepare()
|
|
|
|
def setOpenDefaultPendTime(self, double timeout):
|
|
return self._c_cafe.channelOpenPolicy.setDefaultTimeout(timeout)
|
|
|
|
def getOpenDefaultPendTime(self):
|
|
return self._c_cafe.channelOpenPolicy.getDefaultTimeout()
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def openNow(self):
|
|
# self._c_cafe.channelOpenPolicy.flushSendBufferNow()
|
|
# self._c_cafe.channelOpenPolicy.setWhenToFlushSendBuffer(FLUSH_NOW)
|
|
# self._c_cafe.channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT)
|
|
with nogil:
|
|
self._c_cafe.openNow()
|
|
|
|
#############################################################################
|
|
|
|
def openNowAndWait(self, double timeout=0, handlesPV=None):
|
|
cdef str _METHOD = "openNowAndWait"
|
|
|
|
if timeout <=0 :
|
|
timeout = self._c_cafe.channelOpenPolicy.getTimeout()
|
|
|
|
# self._c_cafe.channelOpenPolicy.setTimeout(timeout)
|
|
# self._c_cafe.channelOpenPolicy.flushSendBufferNow()
|
|
# reset
|
|
# self._c_cafe.channelOpenPolicy.setWhenToFlushSendBuffer(FLUSH_NOW)
|
|
# self._c_cafe.channelOpenPolicy.setFlushSendBufferKind(WITH_PEND_EVENT)
|
|
# self._c_cafe.channelOpenPolicy.setTimeoutToDefault()
|
|
|
|
cdef vector[unsigned int] hList
|
|
cdef vector[string] pvV
|
|
cdef npoll = 0
|
|
|
|
if handlesPV is not None:
|
|
if isinstance(handlesPV, (list)):
|
|
for i in range(0, len(handlesPV)):
|
|
if isinstance(handlesPV[i], (int, long)):
|
|
hList.push_back(handlesPV[i])
|
|
elif isinstance(handlesPV[i], (str)):
|
|
hList.push_back(self.getHandleFromPVName(handlesPV[i]))
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("List input arguments, should be < type 'int' >" +
|
|
"if handle, else < type 'str' > if pv name")))
|
|
elif isinstance(handlesPV, (int, long)):
|
|
hList.push_back(handlesPV)
|
|
elif isinstance(handlesPV, (str)):
|
|
hList.push_back(self.getHandleFromPVName(handlesPV))
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"Input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if pv name"))
|
|
with nogil:
|
|
self._c_cafe.openNowAndWaitHandleV(hList, timeout)
|
|
# Did all callbacks complete? wait 50ms
|
|
for i in range(0, 100):
|
|
if not self._c_cafe.initCallbackCompleteV(hList):
|
|
time.sleep(0.001)
|
|
npoll = npoll+1
|
|
else:
|
|
break
|
|
# if npoll > 1:
|
|
# print("npoll in _c_cafe.initCallbackCompleteV(hList)", npoll)
|
|
|
|
else:
|
|
with nogil:
|
|
self._c_cafe.openNowAndWait(timeout)
|
|
###handleList, pvList = self.getHandles()
|
|
|
|
self.hh.getHandles(hList, pvV)
|
|
# Did all callbacks complete? wait 10ms
|
|
for i in range(0, 100):
|
|
if not self._c_cafe.initCallbackCompleteV(hList):
|
|
time.sleep(0.001)
|
|
npoll = npoll+1
|
|
else:
|
|
break
|
|
#print("npoll in self._c_cafe.initCallbackCompleteV(hList)", npoll)
|
|
|
|
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def openGroupNowAndWait(self, double timeout=0):
|
|
if timeout <= 0:
|
|
self._c_cafe.channelOpenGroupPolicy.getTimeout()
|
|
# self._c_cafe.channelOpenGroupPolicy.setTimeout(timeout)
|
|
# self._c_cafe.channelOpenGroupPolicy.flushSendBufferNow()
|
|
# reset
|
|
# self._c_cafe.channelOpenGroupPolicy.setWhenToFlushSendBuffer(
|
|
# FLUSH_NOW)
|
|
# self._c_cafe.channelOpenGroupPolicy.setFlushSendBufferKind(
|
|
# WITH_PEND_EVENT)
|
|
# self._c_cafe.channelOpenGroupPolicy.setTimeoutToDefault()
|
|
with nogil:
|
|
self._c_cafe.openGroupNowAndWait(timeout)
|
|
return
|
|
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def openGroupNowAndWaitForInputGroups(self, double timeout, groupHandles):
|
|
cdef str _METHOD = "openGroupNowAndWaitForInputGroups"
|
|
|
|
cdef vector[unsigned int] hList
|
|
|
|
if isinstance(groupHandles, (list)):
|
|
for i in range(0, len(groupHandles)):
|
|
if isinstance(groupHandles[i], (int, long)):
|
|
hList.push_back(groupHandles[i])
|
|
elif isinstance(groupHandles[i], (str)):
|
|
hList.push_back(
|
|
self.hh.getGroupHandleFromGroupName(groupHandles[i]))
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
"List input arguments, should be of type <class 'int'> \
|
|
if group handle, else <class 'str'> if group name"))
|
|
elif isinstance(groupHandles, (int, long)):
|
|
hList.push_back(groupHandles)
|
|
elif isinstance(groupHandles, (str)):
|
|
hList.push_back(self.hh.getGroupHandleFromGroupName(groupHandles))
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("Second input argument (if not a list), should be of "
|
|
"type <class 'int'> if group handle, "
|
|
"else <class 'str'> if group name")))
|
|
|
|
# list to vector
|
|
with nogil:
|
|
self._c_cafe.groupOpenNowAndWait(timeout, hList)
|
|
return
|
|
|
|
############################################################################
|
|
|
|
def openMonitorPrepare(self):
|
|
# self._c_cafe.channelMonitorPolicy.setFlushSendBufferKind(WITH_FLUSH_IO)
|
|
# self._c_cafe.channelMonitorPolicy.setWhenToFlushSendBuffer(
|
|
# FLUSH_DESIGNATED_TO_CLIENT)
|
|
with nogil:
|
|
self._c_cafe.openMonitorPrepare()
|
|
return
|
|
|
|
##############################################################################
|
|
|
|
def openMonitorNow(self):
|
|
# self._c_cafe.channelMonitorPolicy.flushSendBufferNow()
|
|
# reset
|
|
# self._c_cafe.channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_NOW)
|
|
# self._c_cafe.channelMonitorPolicy.setFlushSendBufferKind(
|
|
# WITH_FLUSH_IO)
|
|
with nogil:
|
|
self._c_cafe.openMonitorNow()
|
|
time.sleep(0.01)
|
|
return
|
|
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
cdef getMonitorWhenToFlushSendBuffer(self):
|
|
return self._c_cafe.channelMonitorPolicy.getWhenToFlushSendBuffer()
|
|
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def openMonitorNowAndWait(self, double timeout):
|
|
cdef _METHOD = "openMonitorNowAndWait(timeout)"
|
|
# self._c_cafe.channelMonitorPolicy.setTimeout(timeout)
|
|
# self._c_cafe.channelMonitorPolicy.flushSendBufferNow()
|
|
# time.sleep(timeout)
|
|
# reset
|
|
# self._c_cafe.channelMonitorPolicy.setWhenToFlushSendBuffer(FLUSH_NOW)
|
|
# self._c_cafe.channelMonitorPolicy.setFlushSendBufferKind(WITH_FLUSH_IO)
|
|
|
|
with nogil:
|
|
self._c_cafe.openMonitorNowAndWait(max(timeout, self._min_timeout))
|
|
|
|
if timeout <= 0:
|
|
raise UserWarning \
|
|
("{} {} \n{} {}".format(
|
|
self._exception_text, _METHOD,
|
|
("input argument, timeout, must be a positive number!\n"
|
|
"timeout reset to:"), self._min_timeout))
|
|
|
|
|
|
############################################################################
|
|
|
|
def ca_pend_event(self, double timeout):
|
|
cdef _METHOD = "ca_pend_event(timeout)"
|
|
|
|
cdef double _timeout = timeout
|
|
if timeout <= 0:
|
|
_timeout = DEFAULT_TIMEOUT_PEND_EVENT
|
|
|
|
self._c_cafe._ca_pend_event(_timeout)
|
|
|
|
if timeout < 0:
|
|
raise UserWarning \
|
|
("{} {} \n{} {}".format(
|
|
self._exception_text, _METHOD,
|
|
("input argument, timeout, must be a positive number!\n"
|
|
"timeout reset to CAFE default:"), _timeout))
|
|
|
|
def ca_pend_io(self, double timeout):
|
|
cdef _METHOD = "ca_pend_io(timeout)"
|
|
|
|
cdef double _timeout = timeout
|
|
if timeout <= 0:
|
|
_timeout = DEFAULT_TIMEOUT_PEND_IO
|
|
|
|
self._c_cafe._ca_pend_io(timeout)
|
|
|
|
if timeout < 0:
|
|
raise UserWarning \
|
|
("{} {} \n{} {}".format(
|
|
self._exception_text, _METHOD,
|
|
("input argument, timeout, must be a positive number!\n"
|
|
"timeout reset to CAFE default:"), _timeout))
|
|
|
|
def ca_poll(self):
|
|
with nogil:
|
|
self._c_cafe._ca_poll()
|
|
|
|
|
|
def ca_flush_io(self):
|
|
with nogil:
|
|
self._c_cafe._ca_flush_io()
|
|
|
|
|
|
############################################################################
|
|
def setChannelRequestPolicyGet(
|
|
self, handlePV, ChannelWhenToFlushSendBufferPolicyKind when,
|
|
ChannelWaitForResponsePolicyKind wait,
|
|
ChannelRequestPolicyKind method, cb: object = None):
|
|
|
|
cdef str _METHOD = "setChannelRequestPolicyGet"
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First Input argument should be of type <class 'int'> "
|
|
"if handle, else <class 'str'> if PV")))
|
|
|
|
|
|
cdef ChannelRequestPolicy crp
|
|
self.ph.getChannelRequestPolicyGet(handlePV, crp)
|
|
if when:
|
|
crp.setWhenToFlushSendBuffer(when)
|
|
if wait:
|
|
crp.setWaitKind(wait)
|
|
if method:
|
|
crp.setMethodKind(method)
|
|
if cb is not None:
|
|
crp.setPyHandlerGet(<void *> cb) # forces when=WITH_CALLBACK_USER_SUPPLIED
|
|
|
|
self.ph.setChannelRequestPolicyGet(handlePV, crp)
|
|
return
|
|
################################################################################
|
|
|
|
################################################################################
|
|
|
|
|
|
def initCallbackComplete(self, handlePV):
|
|
cdef str _METHOD = "initCallbackComplete"
|
|
cdef vector[unsigned int] hList
|
|
|
|
if isinstance(handlePV, (list)):
|
|
for i in range(0, len(handlePV)):
|
|
if isinstance(handlePV[i], (int, long)):
|
|
hList.push_back(handlePV[i])
|
|
elif isinstance(handlePV[i], (str)):
|
|
hList.push_back(self.getHandleFromPV(handlePV[i]))
|
|
else:
|
|
raise Exception("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("List input arguments, should be of type <class 'int'> if handle" +
|
|
"else <class 'str'> if pvname")))
|
|
return self._c_cafe.initCallbackCompleteV(hList)
|
|
|
|
elif isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("Input argument should be of type <class 'int'> if handle," +
|
|
"else <class 'str'> if pvname")))
|
|
|
|
#print("cb complete", self._c_cafe.initCallbackCompleteHandle(handle))
|
|
return self._c_cafe.initCallbackCompleteHandle(handle)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def setCallbackGet(self, handlePV, object cb = None):
|
|
|
|
cdef str _METHOD = "setCallbackGet"
|
|
|
|
cdef ChannelRequestPolicy crp
|
|
self.ph.getChannelRequestPolicyGet(handlePV, crp)
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV"))
|
|
|
|
if cb is not None:
|
|
crp.setPyHandlerGet(<void *>cb) # forces when=WITH_CALLBACK_USER_SUPPLIED
|
|
else:
|
|
crp.setMethodKind(WITH_CALLBACK_DEFAULT)
|
|
|
|
self.ph.setChannelRequestPolicyGet(handlePV, crp)
|
|
return
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def setCallbackPut(self, handlePV, object cb=None):
|
|
|
|
cdef str _METHOD = "setCallbackPut"
|
|
|
|
cdef ChannelRequestPolicy crp
|
|
self.ph.getChannelRequestPolicyPut(handlePV, crp)
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV"))
|
|
|
|
if cb is not None:
|
|
crp.setPyHandlerPut(<void *>cb) # forces when=WITH_CALLBACK_USER_SUPPLIED
|
|
else:
|
|
crp.setMethodKind(WITH_CALLBACK_DEFAULT)
|
|
|
|
self.ph.setChannelRequestPolicyPut(handlePV, crp)
|
|
return
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def setTimeout(self, timeout):
|
|
return self.ph.setTimeout(timeout)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getTimeoutGet(self):
|
|
cdef double minValue, p, g
|
|
minValue = 0
|
|
p = 0
|
|
g = 0
|
|
self.ph.getTimeoutMin(p, g)
|
|
minValue = g
|
|
self.ph.getTimeoutMax(p, g)
|
|
if (g < minValue):
|
|
minValue = g
|
|
return minValue
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def getTimeoutPut(self):
|
|
cdef double minValue, p, g
|
|
minValue = 0
|
|
p = 0
|
|
g = 0
|
|
self.ph.getTimeoutMin(p, g)
|
|
minValue = p
|
|
self.ph.getTimeoutMax(p, g)
|
|
if (p < minValue):
|
|
minValue = g
|
|
return minValue
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def setSelfGoverningTimeout(self, bint b):
|
|
return self.ph.setSelfGoverningTimeout(b)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
# Synchronous Groups
|
|
############################################################################
|
|
def setSGTimeout(self, double timeout):
|
|
return self.ph.setSGTimeout(timeout)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getSGTimeoutGet(self):
|
|
cdef double minValue, p, g
|
|
minValue = 0
|
|
p = 0
|
|
g = 0
|
|
self.ph.getSGTimeoutMin(p, g)
|
|
minValue = g
|
|
self.ph.getSGTimeoutMax(p, g)
|
|
if (g < minValue):
|
|
minValue = g
|
|
|
|
return minValue
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getSGTimeoutPut(self):
|
|
cdef double minValue, p, g
|
|
minValue = 0
|
|
p = 0
|
|
g = 0
|
|
self.ph.getSGTimeoutMin(p, g)
|
|
minValue = p
|
|
self.ph.getSGTimeoutMax(p, g)
|
|
if (p < minValue):
|
|
minValue = p
|
|
|
|
return minValue
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def setSGSelfGoverningTimeout(self, bint b):
|
|
cdef PolicyHelper ph
|
|
return ph.setSGSelfGoverningTimeout(b)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def getContext(self, handlePV):
|
|
cdef str _METHOD = "getContext"
|
|
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
return < long > self.hh.getContextFromHandle(handlePV)
|
|
elif isinstance(handlePV, (str)):
|
|
return < long > self.hh.getContextFromPV(handlePV)
|
|
else:
|
|
_cafeException = CafeException(
|
|
_type='TypeError', _source=_METHOD,
|
|
_error_info=(
|
|
"First input argument should be of type <class 'int'> if handle, "
|
|
"else <class 'str'> if PV"))
|
|
raise _cafeException
|
|
|
|
|
|
############################################################################
|
|
|
|
def attachContext(self, handlePV):
|
|
cdef str _METHOD = "attachContext"
|
|
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
return self._c_cafe.attachContextByHandle(handlePV)
|
|
elif isinstance(handlePV, (str)):
|
|
return self._c_cafe.attachContextByPVName(handlePV)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV"))
|
|
|
|
|
|
############################################################################
|
|
def collectionDefine(self, const char * cName, vector[string] cMembers):
|
|
with nogil:
|
|
self._c_cafe.collectionDefine(cName, cMembers)
|
|
|
|
############################################################################
|
|
def defineCollection(self, const char * cName, vector[string] cMembers):
|
|
with nogil:
|
|
self._c_cafe.collectionDefine(cName, cMembers)
|
|
|
|
############################################################################
|
|
def collectionList(self):
|
|
cdef vector[string] collectionList
|
|
with nogil:
|
|
self._c_cafe.collectionList(collectionList)
|
|
return collectionList
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def collectionMemberList(self, const char * cName):
|
|
cdef vector[string] cMemberList
|
|
with nogil:
|
|
self._c_cafe.collectionMemberList(cName, cMemberList)
|
|
return cMemberList
|
|
############################################################################
|
|
|
|
|
|
############################################################################
|
|
#def loadCollectionsFromXML(self, const char * fileName):
|
|
# with nogil:
|
|
# status = self._c_cafe.loadCollectionsFromXML(fileName)
|
|
# return status
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
#def loadGroupsFromXML(self, const char * fileName):
|
|
# with nogil:
|
|
# status = self._c_cafe.loadGroupsFromXML(fileName)
|
|
# return status
|
|
############################################################################
|
|
|
|
def devicePositionMap(self, const char * collectionName):
|
|
p = []
|
|
d = []
|
|
cdef map[float, string] mmfs
|
|
cdef map[float, string].iterator it
|
|
self._c_cafe.devicePositionMap(collectionName, mmfs)
|
|
it = mmfs.begin()
|
|
tup = () # tuple
|
|
while it != mmfs.end():
|
|
tup = deref(it)
|
|
p.append(tup[0])
|
|
d.append(tup[1])
|
|
inc(it)
|
|
return d, p
|
|
|
|
def devicePositionV(self, const char * collectionName):
|
|
cdef str _METHOD = "devicePositionV"
|
|
# p=[]
|
|
# d=[]
|
|
cdef vector[string] dev
|
|
cdef vector[float] pos
|
|
status = self._c_cafe.devicePositionV(collectionName, dev, pos)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
raise Exception("{} {} {} {} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"status=", status, self.cs.code(status), self.cs.code(status)))
|
|
|
|
# for i in range (0, dev.size()):
|
|
# d.append(dev[i])
|
|
# p.append(pos[i])
|
|
return dev, pos
|
|
|
|
############################################################################
|
|
|
|
def groupList(self):
|
|
cdef vector[string] gList
|
|
# conservative guess
|
|
gList.reserve(36)
|
|
|
|
self._c_cafe.groupList(gList)
|
|
|
|
# Place in list to avoid this warning:
|
|
# warning: comparison between signed and unsigned integer expressions
|
|
# gl=[]
|
|
# for i in range (0, len(gList)):
|
|
# gl.append(gList[i])
|
|
return gList
|
|
############################################################################
|
|
|
|
def getDataTypeNative(self, handlePV):
|
|
cdef str _METHOD = "getDataTypeNative"
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV"))
|
|
|
|
cdef long ndt = -1
|
|
|
|
self.hh.getDataTypeNative(handle, ndt)
|
|
return ndt
|
|
|
|
def getDataTypeRequest(self, handlePV):
|
|
cdef str _METHOD = "getDataTypeRequest"
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument, should be of type <class 'int'> if handle,\
|
|
else <class 'str'> if PV"))
|
|
|
|
cdef long rdt = -1
|
|
self.hh.getDataTypeRequest(handle, rdt)
|
|
return rdt
|
|
|
|
def getMonitorIDInCallback(self, handlePV):
|
|
cdef str _METHOD = "getMonitorIDInCallback"
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV"))
|
|
return self.hh.getUsrArgsAsUInt(handle)
|
|
|
|
def getDataTypeInCallback(self, handlePV):
|
|
cdef str _METHOD = "getDataTypeInCallback"
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV"))
|
|
return < long > self.hh.getDataTypeCB(handle)
|
|
|
|
def getDbrDataTypeInCallback(self, handlePV):
|
|
cdef str _METHOD = "getDbrDataTypeInCallback"
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First input argument, should be of type <class 'int'> if handle," +
|
|
"else <class 'str'> if PV")))
|
|
return < long > self.hh.getDbrDataTypeCB(handle)
|
|
|
|
def getDbrBaseInCallback(self, handlePV):
|
|
cdef str _METHOD = "getDbrBaseInCallback"
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First input argument, should be of type <class 'int'> if handle," +
|
|
"else <class 'str'> if PV")))
|
|
return < unsigned int > self.hh.getCafeDbrTypeCB(handle)
|
|
|
|
############################################################################
|
|
def getHandlesFromWithinGroup(self, gHandleName):
|
|
|
|
cdef str _METHOD = "getHandlesFromWithinGroup"
|
|
|
|
cdef unsigned int groupHandle = 0
|
|
if isinstance(gHandleName, (int, long)):
|
|
groupHandle = gHandleName
|
|
elif isinstance(gHandleName, (str)):
|
|
groupHandle = self.hh.getGroupHandleFromGroupName(gHandleName)
|
|
else:
|
|
raise Exception("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First input argument, should be of type <class 'int'> if group handle,"
|
|
+ "else <class 'str'> if group name")))
|
|
|
|
cdef vector[unsigned int] hList
|
|
hList = self.hh.getHandlesFromWithinGroupV(groupHandle)
|
|
return hList
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def close(self, handlePV):
|
|
cdef str _METHOD = "close"
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First input argument, should be of type <class 'int'> if handle," +
|
|
"else <class 'str'> if PV")))
|
|
|
|
cdef int status
|
|
with nogil:
|
|
status = self._c_cafe.close(handle)
|
|
|
|
return status
|
|
|
|
############################################################################
|
|
def closeChannels(self):
|
|
cdef int status
|
|
with nogil:
|
|
status = self._c_cafe.closeChannels()
|
|
return status
|
|
|
|
############################################################################
|
|
def closeHandles(self, list handleList):
|
|
cdef str _METHOD = "closeHandles"
|
|
if not handleList:
|
|
return ICAFE_NORMAL
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList, force=False)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("{} {} {}".format(self._exception_text, _METHOD,
|
|
"First input argument, should be a 'list' of of type <class 'int'> \
|
|
if handles or <class 'str'> if PVs"))
|
|
|
|
# Do this only to avoid compiler warnings
|
|
cdef vector[unsigned int] v
|
|
for i in range(0, len(handleList)):
|
|
v.push_back(handleList[i])
|
|
cdef int status
|
|
with nogil:
|
|
status = self._c_cafe.closeHandlesV(v)
|
|
return status
|
|
|
|
############################################################################
|
|
|
|
def closeDisconnectedChannelsWithinGroup(self, ghandleName):
|
|
cdef str _METHOD = "closeDisconnectedChannelsWithinGroup"
|
|
cdef vector[unsigned int] hList
|
|
cdef vector[unsigned int] disHandles
|
|
|
|
if isinstance(ghandleName, (list)):
|
|
for i in range(0, len(ghandleName)):
|
|
if isinstance(ghandleName[i], (int, long)):
|
|
hList.push_back(ghandleName[i])
|
|
elif isinstance(ghandleName[i], (str)):
|
|
hList.push_back(self.checkForGroupHandle(ghandleName[i]))
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"List input arguments, should be of type <class 'int'> \
|
|
if group handle, else <class 'str'> if group name"))
|
|
|
|
elif isinstance(ghandleName, (int, long)):
|
|
hList.push_back(ghandleName)
|
|
elif isinstance(ghandleName, (str)):
|
|
hList.push_back(self.checkForGroupHandle(ghandleName))
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument (if not list), should be of type <class 'int'> \
|
|
if group handle, else <class 'str'> if group name"))
|
|
|
|
for i in range(0, len(hList)):
|
|
with nogil:
|
|
self._c_cafe.closeDisconnectedChannelsFromWithinGroupV(
|
|
hList[i])
|
|
return
|
|
|
|
############################################################################
|
|
def closeChannelKeepHandle(self, handlePV):
|
|
cdef str _METHOD = "closeChannelKeepHandle"
|
|
|
|
cdef vector[unsigned int] hList
|
|
cdef int statusClose
|
|
|
|
if isinstance(handlePV, (list)):
|
|
for i in range(0, len(handlePV)):
|
|
if isinstance(handlePV[i], (int, long)):
|
|
hList.push_back(handlePV[i])
|
|
elif isinstance(handlePV[i], (str)):
|
|
hList.push_back(self.checkForHandle(handlePV[i]))
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"List input arguments, should be of type <class 'int'> \
|
|
if group handle, else <class 'str'> if group name"))
|
|
|
|
elif isinstance(handlePV, (int, long)):
|
|
hList.push_back(handlePV)
|
|
elif isinstance(handlePV, (str)):
|
|
hList.push_back(self.checkForHandle(handlePV))
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument (if not list), should be of type <class 'int'> \
|
|
if handle, else <class 'str'> if PV"))
|
|
|
|
with nogil:
|
|
statusClose = self._c_cafe.closeChannelsKeepHandles(hList)
|
|
return statusClose
|
|
|
|
#def reconnect(self, vector[unsigned int] handleList):
|
|
def reconnect(self, list handleList):
|
|
cdef int status1 = ICAFE_NORMAL
|
|
cdef int status2 = ICAFE_NORMAL
|
|
cdef vector[unsigned int] v
|
|
v.reserve(len(handleList))
|
|
for i in range(0, len(handleList)):
|
|
v.push_back(handleList[i])
|
|
#print("Channels Closing...")
|
|
self.openMonitorPrepare()
|
|
|
|
for i in range (0, len(handleList)):
|
|
self.monitorStop(handleList[i])
|
|
|
|
self.openMonitorNow()
|
|
time.sleep(0.05)
|
|
#with nogil:
|
|
# status= self._c_cafe.reconnect(handleList)
|
|
#print("Channels Closing...")
|
|
with nogil:
|
|
status1 = self._c_cafe.closeChannelsKeepHandles(v)
|
|
time.sleep(0.05)
|
|
#print("Channels Closed")
|
|
self.openPrepare()
|
|
with nogil:
|
|
status2 = self._c_cafe.openChannelsWithHandles(v)
|
|
#print("Channels Opened")
|
|
|
|
self.openNowAndWait(self._c_cafe.channelOpenPolicy.getTimeout(), v)
|
|
#print("Channels Opened//", status1, status2)
|
|
time.sleep(0.05)
|
|
return max(status1, status2)
|
|
|
|
############################################################################
|
|
|
|
def allConnected(self):
|
|
return <bint> self._c_cafe.allChannelsConnected()
|
|
|
|
############################################################################
|
|
|
|
@verify_handlepv
|
|
def isConnected(self, handlePV):
|
|
cdef str _METHOD = "isConnected"
|
|
return <bint> self._c_cafe.isChannelConnected(handlePV)
|
|
|
|
############################################################################
|
|
def supplementHandles(self, handleList=None):
|
|
cdef str _METHOD = "supplementHandles"
|
|
if handleList is None:
|
|
with nogil:
|
|
self._c_cafe.supplementHandles()
|
|
elif isinstance(handleList, (list)):
|
|
#Convert to vector
|
|
self.supplementHandlesV(handleList)
|
|
elif isinstance(handleList, (int, long, str)):
|
|
self.supplementHandle(handleList)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"Input argument, if given, should be <type 'list'> if list of \
|
|
handles or PVs, else of type <class 'int'> if handle or <class 'str'> if \
|
|
PV. If no input argument, then all channels are supplemented."))
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def supplementHandle(self, handlePV):
|
|
#decorator casts handlePV to int
|
|
cdef unsigned int handle = handlePV
|
|
with nogil:
|
|
self._c_cafe.supplementHandle(handle)
|
|
|
|
############################################################################
|
|
|
|
def supplementHandlesV(self, handleList):
|
|
cdef str _METHOD = "supplementHandlesV"
|
|
if isinstance(handleList, (str, int, long)):
|
|
hl = []
|
|
hl.append(handleList)
|
|
#handleList = []
|
|
handleList = hl
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument should be a 'list' of of type <class 'int'> \
|
|
if handles, else <class 'str'> if PVs"))
|
|
cdef vector[unsigned int] v
|
|
for i in range(0, len(handleList)):
|
|
v.push_back(handleList[i])
|
|
|
|
with nogil:
|
|
self._c_cafe.supplementHandlesV(v)
|
|
|
|
############################################################################
|
|
|
|
def printDisconnected(self):
|
|
self._c_cafe.printDisconnectedHandles()
|
|
|
|
def printDisconnectedHandles(self):
|
|
self._c_cafe.printDisconnectedHandles()
|
|
|
|
############################################################################
|
|
def printHandles(self):
|
|
self._c_cafe.printHandles()
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def printHandle(self, handlePV):
|
|
self._c_cafe.printHandle(handlePV)
|
|
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def printHandlesV(self, list handleList):
|
|
cdef str _METHOD = "printHandlesV"
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument, should be a 'list' of of type <class 'int'> \
|
|
if handles, else <class 'str'> if PVs"))
|
|
|
|
# Do this only to avoid compiler warnings
|
|
cdef vector[unsigned int] v
|
|
for i in range(0, len(handleList)):
|
|
v.push_back(handleList[i])
|
|
self.hh.printHandlesV(v)
|
|
return
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getDisconnectedHandles(self):
|
|
cdef vector[unsigned int] dhV
|
|
cdef vector[string] pvV
|
|
self.hh.getDisconnectedHandles(dhV, pvV)
|
|
return dhV, pvV
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def getHandles(self, asDict=False):
|
|
cdef vector[unsigned int] dhV
|
|
cdef vector[string] pvV
|
|
self.hh.getHandles(dhV, pvV)
|
|
if asDict:
|
|
return dict(zip(dhV, pvV))
|
|
else:
|
|
return dhV, pvV
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def getHandleStates(self):
|
|
cdef vector[unsigned int] dhV
|
|
cdef vector[string] pvV
|
|
cdef vector[unsigned short] stateV
|
|
self.hh.getHandleStates(dhV, pvV, stateV)
|
|
return dhV, pvV, stateV
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getStatusSeverity(self, int statusCode):
|
|
return self._c_cafe.getCafeStatusSeverity().message(statusCode)
|
|
|
|
############################################################################
|
|
def getStatusCodeAsText(self, int statusCode):
|
|
return self.cs.code(statusCode)
|
|
|
|
############################################################################
|
|
def getStatusCodeAsString(self, int statusCode):
|
|
return self.cs.code(statusCode)
|
|
|
|
############################################################################
|
|
def getStatusInfo(self, int statusCode):
|
|
return self.cs.info(statusCode)
|
|
|
|
############################################################################
|
|
def getStatusMsg(self, int statusCode):
|
|
return self.cs.message(statusCode)
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getStatus(self, handlePV):
|
|
return self.hh.getStatus(handlePV)
|
|
|
|
############################################################################
|
|
def getChannelDevice(self, handlePV):
|
|
cdef str _METHOD = "getChannelDevice"
|
|
cdef string valString = str("")
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(pv=handlePV, force=False)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV"))
|
|
if handle == 0:
|
|
valString = str("")
|
|
if isinstance(handlePV, (str)):
|
|
delSplit = handlePV.split(":")
|
|
if (len(delSplit) > 1):
|
|
valString = str(delSplit[0])
|
|
else:
|
|
statusLocal = self.hh.getChannelDevice(handle, valString)
|
|
return valString
|
|
|
|
############################################################################
|
|
def getChannelAttribute(self, handlePV):
|
|
cdef str _METHOD = "getChannelAttribute"
|
|
cdef string valString = str("")
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(pv=handlePV, force=False)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV"))
|
|
if handle == 0:
|
|
valString = str("")
|
|
if isinstance(handlePV, (str)):
|
|
delSplit = handlePV.split(":")
|
|
if (len(delSplit) > 1):
|
|
valString = str(delSplit[0])
|
|
else:
|
|
statusLocal = self.hh.getChannelAttribute(handle, valString)
|
|
return valString
|
|
|
|
############################################################################
|
|
|
|
@verify_handlepv
|
|
def getDescription(self, handlePV):
|
|
cdef unsigned int handle = handlePV
|
|
if not self.hh.hasDescription(handle):
|
|
with nogil:
|
|
self._c_cafe.supplementHandle(handle)
|
|
cdef string valString
|
|
self.hh.getDescription(handle, valString)
|
|
return valString
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def hasDescription(self, handlePV):
|
|
return self.hh.hasDescription(handlePV)
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getUnits(self, handlePV):
|
|
cdef string valString
|
|
self.hh.getUnits(handlePV, valString)
|
|
cdef bytes bVal
|
|
bVal = <bytes> valString
|
|
unicode_units = (bVal).decode('latin-1')
|
|
return unicode_units
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getPrecision(self, handlePV):
|
|
cdef short precision = 0
|
|
self.hh.getPrecision(handlePV, precision)
|
|
return precision
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def hasAlarmStatusSeverity(self, handlePV):
|
|
return self.hh.hasAlarmStatusSeverity(handlePV)
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getAlarmStatusSeverity(self, handlePV):
|
|
cdef short aStatSev[2]
|
|
self.hh.getAlarmStatusSeverity(handlePV, aStatSev)
|
|
return aStatSev[0], aStatSev[1]
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getTimeStamp(self, handlePV):
|
|
|
|
cdef HandleHelper hh
|
|
hh._etsNorm = self.hh.getEpicsTimeStampAsUInt32(handlePV)
|
|
|
|
cdef ll = []
|
|
ll.append(hh._etsNorm.secPastEpoch)
|
|
ll.append(hh._etsNorm.nsec)
|
|
|
|
return ll
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getTimeStampAsDate(self, handlePV):
|
|
|
|
cdef HandleHelper hh
|
|
cdef ld = []
|
|
|
|
hh._etsDate = self.hh.getEpicsTimeStampAsDate(handlePV)
|
|
ld.append(hh._etsDate.year)
|
|
ld.append(hh._etsDate.mon)
|
|
ld.append(hh._etsDate.day)
|
|
ld.append(hh._etsDate.hour)
|
|
ld.append(hh._etsDate.min)
|
|
ld.append(hh._etsDate.sec)
|
|
ld.append(hh._etsDate.nsec)
|
|
|
|
return ld
|
|
|
|
############################################################################
|
|
### Allow user to choose whether or not to open #####
|
|
def checkForHandle(self, str pv, bint force=True):
|
|
cdef unsigned int _handle = 0
|
|
_handle = self.hh.getHandleFromPV(pv)
|
|
if _handle == 0:
|
|
if (force):
|
|
return self.open(pv)
|
|
else:
|
|
return 0
|
|
else:
|
|
return _handle
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def checkForHandleList(self, list pvList, bint force=True):
|
|
|
|
cdef unsigned int nToOpen = 0
|
|
handleList = []
|
|
cdef unsigned int _handle = 0
|
|
for i in range(0, len(pvList)):
|
|
_handle = self.hh.getHandleFromPV(pvList[i])
|
|
if _handle == 0:
|
|
if (force):
|
|
nToOpen = nToOpen+1
|
|
self.openNoWait()
|
|
_handle = self.open(pvList[i])
|
|
handleList.append(_handle)
|
|
else:
|
|
handleList.append(_handle)
|
|
if nToOpen > 0:
|
|
self.openNowAndWait(2.0+nToOpen*0.01)
|
|
return handleList
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def checkForGroupHandle(self, str gName, bint force=True):
|
|
cdef unsigned int _ghandle = 0
|
|
_ghandle = self.hh.getGroupHandleFromGroupName(gName)
|
|
if _ghandle == 0:
|
|
if (force):
|
|
return self.groupOpen(gName)
|
|
else:
|
|
return 0
|
|
else:
|
|
return _ghandle
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def getPVNameFromHandle(self, int h):
|
|
return self._c_cafe.getPVFromHandle(h)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getHandleFromPVName(self, str name):
|
|
# if type(name) is unicode:
|
|
# py_string = (<bytes>name).encode('UTF-8')
|
|
# return self._c_cafe.getHandleFromPV(py_string)
|
|
return self._c_cafe.getHandleFromPV(name)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def getPVFromHandle(self, int h):
|
|
return self._c_cafe.getPVFromHandle(h)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getHandleFromPV(self, str name):
|
|
# if type(name) is unicode:
|
|
# py_string = (<bytes>name).encode('UTF-8')
|
|
# return self._c_cafe.getHandleFromPV(py_string)
|
|
return self._c_cafe.getHandleFromPV(name)
|
|
############################################################################
|
|
|
|
def getChannelDataStore(self, handlePV):
|
|
cdef str _METHOD = "getChannelDataStore"
|
|
cdef unsigned int handle = 0
|
|
cdef str pv = ""
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
pv = self._c_cafe.getPVFromHandle(handle)
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV, force=True)
|
|
pv = handlePV
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV"))
|
|
|
|
if handle == 0:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(ECAFE_INVALID_HANDLE)
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def getChannelDataStore")
|
|
|
|
cdef ChannelDataStore cds
|
|
cdef int status = ICAFE_NORMAL
|
|
|
|
# with nogil:
|
|
# status=self._c_cafe.getChannelDataStore(handle,cds)
|
|
# cdef PVDataHolder pvd
|
|
# pvd.setNelem(self.hh.getNelemToRetrieveFromCache(handle))
|
|
#status=self._c_cafe.getCache(handle, pvd)
|
|
|
|
# cdef PVCtrlHolder pvc
|
|
# pvc.setNelem(self.hh.getNelemToRetrieveFromCtrlCache(handle))
|
|
#status=self._c_cafe.getCtrlCache(handle, pvc)
|
|
|
|
pvds = self.getPVCache(handle)
|
|
pvcs = self.getCtrlCache(handle)
|
|
infos = self.getChannelInfo(handle)
|
|
|
|
'''
|
|
#remove all after "."
|
|
found=pv.find(".")
|
|
if found != -1:
|
|
pv=pv.substring(0,found)
|
|
|
|
pv=pv +".DESC"
|
|
|
|
cdef unsigned int handleDesc=0
|
|
cdef str desc=""
|
|
self.openPrepare()
|
|
handleDesc=self.open(pv)
|
|
self.openNowAndWait(6.0)
|
|
print('handle',handleDesc, 'pv = ', pv)
|
|
desc=self.get(handleDesc,'str')
|
|
print('desc', desc)
|
|
|
|
|
|
if status !=ICAFE_NORMAL:
|
|
if status != ICAFE_CS_CLOSED:
|
|
if PYCAFE_PRINT_LEVEL>=PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
raise Exception("EXCEPTION RAISED in PyCafe def getChannelDataStore. Status = %d" %status)
|
|
'''
|
|
|
|
# return cds.description, channelRegaliaToStruct(cds.info), PVDataHolderToStruct(cds.pvd), PVCtrlHolderToStruct(cds.pvc)
|
|
return infos, pvds, pvcs
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getChannelInfo(self, handlePV):
|
|
cdef str _METHOD = "getChannelInfo(handlePV)"
|
|
|
|
status = self._c_cafe.getChannelInfo(handlePV, self.channelInfo)
|
|
#print("ln", __FILE__, __LINE__,inspect.currentframe().f_lineno )
|
|
if self._enable_exceptions and status != ICAFE_NORMAL:
|
|
PyCafeException = self.prepareCafeException(
|
|
status, _METHOD, handle=handlePV)
|
|
raise PyCafeException
|
|
# cdef channelInfo ci=channelRegaliaToStruct(cr)
|
|
# ci.channelID=self._c_cafe.getChannelIDAsString(cr.getChannelID())
|
|
# do hex(cr.getChannelID()) to get channelId in hex form
|
|
|
|
return channelRegaliaToStruct(self.channelInfo)
|
|
############################################################################
|
|
|
|
|
|
def getChannelList(self, list listStrings):
|
|
return self._c_cafe.getFromGlobalChannelList(listStrings)
|
|
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
@verify_handlepv
|
|
def getWFAsString(self, handlePV, cache: bool = False):
|
|
cdef str _METHOD = "getWFAsString"
|
|
cdef string strWF
|
|
|
|
cdef bytes bWF
|
|
cdef unsigned int handle = handlePV
|
|
if cache:
|
|
status = self._c_cafe.getWFAsStringCache(handle, strWF)
|
|
else:
|
|
with nogil:
|
|
status = self._c_cafe.getWFAsString(handle, strWF)
|
|
|
|
#mport codecs
|
|
#new_str = codecs.decode(strWF.c_str(), 'utf-32', errors='strict') #unicode_escape_decode(strWF)[0]
|
|
#new_str = ("'" + strWF + "'").decode('latin-1')
|
|
#print(new_str)
|
|
#new_new_str = new_str.encode('utf-16', 'surrogatepass').decode('utf-16')
|
|
#strWF= new_new_str
|
|
|
|
|
|
|
|
|
|
#PyCafeException = self.prepareCafeException(
|
|
# status, _METHOD, handle=handle)
|
|
##FOR TESTINg raise PyCafeException
|
|
|
|
if status != ICAFE_NORMAL:
|
|
|
|
if self._enable_exceptions:
|
|
PyCafeException = self.prepareCafeException(
|
|
status, _METHOD, handle=handle)
|
|
raise PyCafeException
|
|
|
|
elif PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
|
|
bWF = <bytes> strWF
|
|
a = (bWF).decode('latin-1')
|
|
return a
|
|
'''
|
|
b = a.encode('latin-1')
|
|
|
|
try:
|
|
c = b.decode('utf-8')
|
|
return c
|
|
except UnicodeError:
|
|
return a
|
|
'''
|
|
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def getWFAsStringCache(self, handlePV):
|
|
return self.getWFAsString(handlePV, cache=True)
|
|
|
|
############################################################################
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def isEnum(self, handlePV):
|
|
return self._c_cafe.isEnum(handlePV)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getEnumStrings(self, handlePV):
|
|
return self.hh.getEnumStrings(handlePV)
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getEnumFromString(self, handlePV, str enumString):
|
|
cdef str _METHOD = "getEnumFromString"
|
|
cdef short enumValue
|
|
enumValue = self.hh.getEnumFromString(handlePV, <string> enumString)
|
|
if enumValue == INVALID_ENUM_RETURN_VALUE:
|
|
raise ValueError(
|
|
"{0} {1} \n{2} {3} {4} \n{5}".format(
|
|
self._exception_text, _METHOD,
|
|
"ENUM string value:", enumString, "not recognized! ",
|
|
"Execute getEnumStrings(handlePV) to view enumerated values"))
|
|
return enumValue
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getStringFromEnum(self, handlePV, unsigned short enumValue = 0):
|
|
cdef str _METHOD = "getStringFromEnum"
|
|
cdef string enumString = self.hh.getStringFromEnum(handlePV, enumValue)
|
|
if enumString == INVALID_ENUM_RETURN_STRING:
|
|
raise ValueError(
|
|
"{} {} \n{} {} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
"ENUM value:", enumValue, "is not a valid option. ",
|
|
"Execute getEnumStrings(handlePV) to view enumerated values"))
|
|
return enumString
|
|
|
|
############################################################################
|
|
|
|
#def loadSFGroups(self):
|
|
# cdef str VA = 'VA'
|
|
# return self._c_cafe.loadSFGroups(<string> VA)
|
|
|
|
#def loadSFGroupsWithBase(self, str VA):
|
|
# return self._c_cafe.loadSFGroups(<string> VA)
|
|
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def setDbrBase(self, handlePV, DBR_TYPE dbrBase):
|
|
|
|
# Print Warning Message
|
|
if dbrBase > DBR_TIME:
|
|
print("WARNING: PyCafe def setDbrBase(handle/PV, DBR_TYPE)")
|
|
print("Allowed DBR_TYPEs are:")
|
|
print("DBR_PLAIN (0), DBR_STS(1), DBR_TIME(2)")
|
|
print("The value entered was", dbrBase, "hence assuming DBR_TIME")
|
|
dbrBase = DBR_TIME
|
|
|
|
return self.hh.setCafeDbrType(handlePV, dbrBase)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getDbrBase(self, handlePV):
|
|
|
|
cdef DBR_TYPE _cafeDbrType = DBR_PLAIN
|
|
cdef int status = self.hh.getCafeDbrType(handlePV, _cafeDbrType)
|
|
|
|
return _cafeDbrType
|
|
|
|
############################################################################
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def setGetCacheWaitPolicy(
|
|
self, handlePV, ChannelGetCacheWaitPolicyKind wpk):
|
|
|
|
# Print Warning Message
|
|
if wpk > GET_CACHE_WAIT:
|
|
print(
|
|
("WARNING: PyCafe def setGetCacheWaitPolicy("
|
|
"handle/PV, ChannelGetCacheWaitPolicyKind)"))
|
|
print("Allowed ChannelGetCacheWaitPolicyKind are:")
|
|
print(
|
|
("GET_CACHE_NO_CHECK (0), GET_CACHE_NO_WAIT (1),"
|
|
"GET_CACHE_WAIT (2)"))
|
|
print(
|
|
"The value entered was", wpk,
|
|
"hence assuming default value GET_CACHE_WAIT")
|
|
wpk = GET_CACHE_WAIT
|
|
|
|
cdef ChannelGetCacheWaitPolicy channelGetCacheWaitPolicy
|
|
channelGetCacheWaitPolicy.setWaitKind(wpk)
|
|
|
|
return self.ph.setChannelGetCacheWaitPolicy(
|
|
handlePV, channelGetCacheWaitPolicy)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def setGetCacheWaitPolicyAllHandles(
|
|
self, ChannelGetCacheWaitPolicyKind wpk):
|
|
|
|
# Print Warning Message
|
|
if wpk > GET_CACHE_WAIT:
|
|
print(
|
|
"WARNING: PyCafe def setGetCacheWaitPolicyAllHandles( \
|
|
ChannelGetCacheWaitPolicyKind)")
|
|
print("Allowed ChannelGetCacheWaitPolicyKind are:")
|
|
print(
|
|
"GET_CACHE_NO_CHECK (0), GET_CACHE_NO_WAIT (1), \
|
|
GET_CACHE_WAIT (2)")
|
|
print(
|
|
"The value entered was", wpk,
|
|
"hence assuming default value GET_CACHE_WAIT")
|
|
wpk = GET_CACHE_WAIT
|
|
|
|
cdef ChannelGetCacheWaitPolicy channelGetCacheWaitPolicy
|
|
channelGetCacheWaitPolicy.setWaitKind(wpk)
|
|
|
|
return self.ph.setChannelGetCacheWaitPolicyAllHandles(
|
|
channelGetCacheWaitPolicy)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def setGetActionWhenMonitorPolicy(
|
|
self, handlePV, ChannelGetActionWhenMonitorPolicyKind wmpk):
|
|
|
|
# Print Warning Message
|
|
if wmpk > GET_FROM_IOC:
|
|
print("WARNING: PyCafe def setGetActionWhenMonitorPolicy")
|
|
print("Allowed ChannelGetActionWhenMonitorPolicyKind are:")
|
|
print("GET_FROM_CACHE (0), GET_FROM_IOC (1)")
|
|
print("The value entered was", wmpk,
|
|
"hence assuming default value GET_FROM_IOC")
|
|
wmpk = GET_FROM_IOC
|
|
|
|
cdef ChannelGetActionWhenMonitorPolicy channelGetActionWhenMonitorPolicy
|
|
channelGetActionWhenMonitorPolicy.setActionKind(wmpk)
|
|
|
|
return self.ph.setChannelGetActionWhenMonitorPolicy(
|
|
handlePV, channelGetActionWhenMonitorPolicy)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def setGetActionWhenMonitorPolicyAllHandles(
|
|
self, ChannelGetActionWhenMonitorPolicyKind wmpk):
|
|
|
|
# Print Warning Message
|
|
if wmpk > GET_FROM_IOC:
|
|
print("WARNING: PyCafe def setGetActionWhenMonitorPolicyAllHandles")
|
|
print("Allowed ChannelGetActionWhenMonitorPolicyKind are:")
|
|
print(" GET_FROM_CACHE (0), GET_FROM_IOC (1)")
|
|
print(
|
|
"The value entered was", wmpk,
|
|
"hence assuming default value GET_FROM_IOC")
|
|
wmpk = GET_FROM_IOC
|
|
|
|
cdef ChannelGetActionWhenMonitorPolicy channelGetActionWhenMonitorPolicy
|
|
channelGetActionWhenMonitorPolicy.setActionKind(wmpk)
|
|
|
|
return self.ph.setChannelGetActionWhenMonitorPolicyAllHandles(
|
|
channelGetActionWhenMonitorPolicy)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getNonBlocking(self, handlePV):
|
|
'''Requires cafe.ca_flush_io by user.
|
|
In this resepct, it differs from cafe.getAsync
|
|
which will accepts a list, and execute a flush
|
|
at the end.
|
|
'''
|
|
cdef unsigned int handle = handlePV
|
|
cdef int status
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getNonBlocking(handle)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def getNonBlocking. \
|
|
Status = {0}".format(status))
|
|
|
|
return status
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getStr(self, handlePV, object cb=None):
|
|
return self.get(handlePV, dt='str')
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getInt(self, handlePV, object cb=None):
|
|
return self.get(handlePV, dt='int')
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getFloat(self, handlePV, object cb=None):
|
|
return self.get(handlePV, dt='float')
|
|
############################################################################
|
|
|
|
def caget(self, str pv_name, str dt='native'):
|
|
return self.get(pv_name, dt)
|
|
|
|
def caput(self, str pv_name, pv_value):
|
|
return self.set(pv_name, pv_value)
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def get(self, handlePV = 0, str dt='native'):
|
|
cdef str _METHOD = "get(handlePV, dt)"
|
|
|
|
cdef unsigned int handle = handlePV
|
|
cdef int status
|
|
cdef long dtr = 0
|
|
|
|
status = self.hh.getDataTypeNative(handle, dtr)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle), _error_code=status,
|
|
_error_text=self.cs.code(status), _error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
return None
|
|
|
|
elif dtr in [CAFE_NO_ACCESS, CAFE_TYPENOTCONN]:
|
|
if not self._c_cafe.isChannelConnected(handle):
|
|
self._c_cafe.getChannelInfo(handle, self.channelInfo)
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatus(
|
|
handle, self.channelInfo.getCafeConnectionState())
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=self.channelInfo.getCafeConnectionState(),
|
|
_error_text=self.cs.code(
|
|
self.channelInfo.getCafeConnectionState()),
|
|
_error_info=self.cs.info(
|
|
self.channelInfo.getCafeConnectionState()))
|
|
raise _cafeException
|
|
|
|
return None
|
|
|
|
# Likely to be superfluous
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatus(handle, ICAFE_TYPENOTCONN)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
type='cafe', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=ICAFE_TYPENOTCONN,
|
|
_error_text=self.cs.code(ICAFE_TYPENOTCONN),
|
|
_error_info=self.cs.info(ICAFE_TYPENOTCONN))
|
|
raise _cafeException
|
|
return None
|
|
|
|
|
|
self._c_cafe.getChannelInfo(handle, self.channelInfo)
|
|
if str(self.channelInfo.getClassNameAsString()) in ['waveform'] \
|
|
and dtr in [DBR_CHAR] and dt in ['str']:
|
|
return self.getWFAsString(handle)
|
|
|
|
cdef int dtcheck = dtr
|
|
dtcheck = getMatchedDataType(dt, dtr)
|
|
|
|
cdef bytes bVal
|
|
|
|
if dtcheck in [CAFE_STRING]:
|
|
with nogil:
|
|
status = self._c_cafe.getString(handle, self.valStr)
|
|
|
|
if status == ICAFE_NORMAL:
|
|
bVal = <bytes> self.valStr
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(handle):
|
|
try:
|
|
valStr = (bVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
valStr = (bVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
valStr = (bVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
valStr = (bVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
valstr =self.valStr
|
|
return valStr
|
|
|
|
elif dtcheck in [CAFE_SHORT, CAFE_CHAR, CAFE_LONG]:
|
|
with nogil:
|
|
status = self._c_cafe.getLong(handle, self.valInt)
|
|
if status == ICAFE_NORMAL:
|
|
return self.valInt
|
|
elif dtcheck in [CAFE_FLOAT, CAFE_DOUBLE]:
|
|
with nogil:
|
|
status = self._c_cafe.getDouble(handle, self.valFloat)
|
|
|
|
if status == ICAFE_NORMAL:
|
|
return self.valFloat
|
|
elif dtcheck == CAFE_ENUM:
|
|
# if enum, string taken as native
|
|
if self._c_cafe.isEnum(handle):
|
|
with nogil:
|
|
status = self._c_cafe.getString(handle, self.valStr)
|
|
if status == ICAFE_NORMAL:
|
|
return self.valStr
|
|
else:
|
|
with nogil:
|
|
status = self._c_cafe.getLong(handle, self.valInt)
|
|
if status == ICAFE_NORMAL:
|
|
return self.valInt
|
|
else:
|
|
print("This line in PyCafe def get should never appear!")
|
|
return None
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
return None
|
|
|
|
############################################################################
|
|
# END: def get(self, handlePV, dt)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getIntList(self, handlePV):
|
|
return self.getList(handlePV, 'int')
|
|
|
|
############################################################################
|
|
def getFloatList(self, handlePV):
|
|
return self.getList(handlePV, 'float')
|
|
|
|
############################################################################
|
|
def getStrList(self, handlePV):
|
|
return self.getList(handlePV, 'str')
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getList(self, handlePV, str dt='native'):
|
|
cdef str _METHOD = "getList"
|
|
cdef unsigned int handle = handlePV
|
|
|
|
cdef int status
|
|
cdef long dtr = 0
|
|
|
|
status = self.hh.getDataTypeNative(handle, dtr)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
return [None]
|
|
|
|
elif dtr in [CAFE_NO_ACCESS, CAFE_TYPENOTCONN]:
|
|
if not self._c_cafe.isChannelConnected(handle):
|
|
self._c_cafe.getChannelInfo(handle, self.channelInfo)
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatus(
|
|
handle, self.channelInfo.getCafeConnectionState())
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=self.channelInfo.getCafeConnectionState(),
|
|
_error_text=self.cs.code(
|
|
self.channelInfo.getCafeConnectionState()),
|
|
_error_info=self.cs.info(
|
|
self.channelInfo.getCafeConnectionState()))
|
|
raise _cafeException
|
|
return [None]
|
|
|
|
# This paragraph should be superfluous
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatus(handle, ICAFE_TYPENOTCONN)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,_handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=ICAFE_TYPENOTCONN,
|
|
_error_text=self.cs.code(ICAFE_TYPENOTCONN),
|
|
_error_info=self.cs.info(ICAFE_TYPENOTCONN))
|
|
raise _cafeException
|
|
return [None]
|
|
|
|
#JC FEB 2022 must be int as CAFE_TYPENOTCONN is -1
|
|
cdef int dtcheck = dtr
|
|
dtcheck = getMatchedDataType(dt, dtr)
|
|
|
|
#print ("dtcheck input/native", dtcheck, dt, dtr)
|
|
|
|
cdef unsigned int nelemNative = self.hh.getNelemNative(handle)
|
|
cdef unsigned int nelemClient = self.hh.getNelemClient(handle)
|
|
cdef unsigned int nelemRequest = self.hh.getNelemRequest(handle)
|
|
|
|
cdef unsigned int nelemMethod = nelemClient
|
|
|
|
cdef dbr_string_t * valStringArray
|
|
cdef dbr_long_t * valIntArray
|
|
cdef dbr_char_t * valCharAray
|
|
cdef dbr_enum_t * valUShortArray
|
|
cdef double * valDoubleArray
|
|
cdef float * valFloatArray
|
|
cdef short * valShortArray
|
|
# cdef vector[short] valShortVector
|
|
# cdef vector[float] valFloatVector
|
|
|
|
cdef bytes bytesVal
|
|
|
|
if dtcheck in [CAFE_STRING]:
|
|
|
|
valStringArray = <char[40]*> malloc(
|
|
nelemMethod * sizeof(dbr_string_t))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getDbrStringArray(handle, valStringArray)
|
|
|
|
ll = []
|
|
for i in range(0, nelemMethod):
|
|
|
|
bytesVal = <bytes> (<string> valStringArray[i])
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(handle):
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf_8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf_16')
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = valStringArray[i]
|
|
|
|
ll.append(strVal)
|
|
free(valStringArray)
|
|
if status == ICAFE_NORMAL:
|
|
return ll
|
|
|
|
elif dtcheck in [CAFE_CHAR]:
|
|
|
|
valCharArray = <dbr_char_t * > malloc(
|
|
nelemMethod * sizeof(dbr_char_t))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCharArray(handle, valCharArray)
|
|
|
|
ll = []
|
|
for i in range(0, nelemMethod):
|
|
ll.append(valCharArray[i])
|
|
free(valCharArray)
|
|
if status == ICAFE_NORMAL:
|
|
return ll
|
|
|
|
elif dtcheck in [CAFE_LONG]:
|
|
|
|
valIntArray = <dbr_long_t *> malloc(
|
|
nelemMethod * sizeof(dbr_long_t))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getLongArray(handle, valIntArray)
|
|
|
|
ll = []
|
|
for i in range(0, nelemMethod):
|
|
ll.append(valIntArray[i])
|
|
free(valIntArray)
|
|
if status == ICAFE_NORMAL:
|
|
return ll
|
|
|
|
elif dtcheck in [CAFE_SHORT]:
|
|
|
|
valShortArray = <short * >malloc(nelemMethod * sizeof(short))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getShortArray(handle, valShortArray)
|
|
|
|
ll = []
|
|
for i in range(0, nelemMethod):
|
|
ll.append(valShortArray[i])
|
|
free(valShortArray)
|
|
if status == ICAFE_NORMAL:
|
|
return ll
|
|
elif dtcheck in [CAFE_FLOAT]:
|
|
'''
|
|
valFloatVector.reserve(nelemMethod)
|
|
start=time.time()
|
|
for i in range (0, 10000):
|
|
with nogil:
|
|
status=self._c_cafe.getFloatVector(handle, valFloatVector)
|
|
end=time.time()
|
|
print ("END TIME FLOAT", end - start)
|
|
return valFloatVector
|
|
'''
|
|
|
|
# Speedier than vectors
|
|
valFloatArray = <float * >malloc(nelemMethod * sizeof(float))
|
|
# start=time.time()
|
|
# for i in range (0, 10000):
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getFloatArray(handle, valFloatArray)
|
|
|
|
# end=time.time()
|
|
#print ("END TIME FLOAT", end - start)
|
|
|
|
ll = []
|
|
for i in range(0, nelemMethod):
|
|
ll.append(valFloatArray[i])
|
|
free(valFloatArray)
|
|
if status == ICAFE_NORMAL:
|
|
return ll
|
|
|
|
elif dtcheck in [CAFE_DOUBLE]:
|
|
|
|
valDoubleArray = <double * >malloc(nelemMethod * sizeof(double))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getDoubleArray(handle, valDoubleArray)
|
|
|
|
ll = []
|
|
for i in range(0, nelemMethod):
|
|
ll.append(valDoubleArray[i])
|
|
free(valDoubleArray)
|
|
if status == ICAFE_NORMAL:
|
|
return ll
|
|
|
|
elif dtcheck == CAFE_ENUM:
|
|
|
|
# if enum, string taken as native
|
|
if self._c_cafe.isEnum(handle):
|
|
valStringArray = <char[40]*> malloc(
|
|
nelemMethod * sizeof(dbr_string_t))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getDbrStringArray(
|
|
handle, valStringArray)
|
|
|
|
ll = []
|
|
for i in range(0, nelemMethod):
|
|
ll.append(valStringArray[i])
|
|
free(valStringArray)
|
|
if status == ICAFE_NORMAL:
|
|
return ll
|
|
else:
|
|
valUShortArray = <dbr_enum_t *> malloc(
|
|
nelemMethod * sizeof(dbr_enum_t))
|
|
with nogil:
|
|
status = self._c_cafe.getUShortArray(
|
|
handle, valUShortArray)
|
|
|
|
ll = []
|
|
for i in range(0, nelemMethod):
|
|
ll.append(valUShortArray[i])
|
|
free(valUShortArray)
|
|
if status == ICAFE_NORMAL:
|
|
return ll
|
|
# Will not happen; already covered above
|
|
elif dtcheck in [CAFE_NO_ACCESS, CAFE_TYPENOTCONN]:
|
|
print("Channel", self._c_cafe.getPVFromHandle(
|
|
handle), " not connected")
|
|
return None
|
|
else:
|
|
print("This line in PyCafe def getAsList should never appear!")
|
|
return None
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions is False:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status,
|
|
_error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
return None
|
|
|
|
##################################################################################
|
|
|
|
def getStrArray(self, handlePV, str art='numpy'):
|
|
return self.getArray(handlePV, dt='str', art=art)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getIntArray(self, handlePV, str art='numpy'):
|
|
return self.getArray(handlePV, dt='int', art=art)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getFloatArray(self, handlePV, str art='numpy'):
|
|
return self.getArray(handlePV, dt='float', art=art)
|
|
############################################################################
|
|
|
|
############################################################################
|
|
@verify_handlepv
|
|
def getArray(self, handlePV, str dt='native', str art='numpy'):
|
|
############################################################################
|
|
# Typed Memoryviews from K.W. Smith
|
|
# Cython has a C-level type the typed memoryview, that conceptually overlaps
|
|
# with the Python memoryiew and expands on it. A typed memory view is used
|
|
# to view (share) data from a buffer-producing object.
|
|
# A typed memoryview has a memory-view like interface and is easier to use
|
|
# than working with C-level buffers directly. And because a typed memoryview
|
|
# is designated to work with the buffer protocol it supports any buffer-
|
|
# producing object efficiently allowing data buffers to be shared without
|
|
# copying.
|
|
# If we declare a typed memoryview with a single colon in each dimension's
|
|
# slot, the typed mv can acquire a buffer from an object if the same
|
|
# dimensionality and with either strided or contiguous packing.
|
|
# Declaring a C-contiguous typed memoryview: all dimensions except the last
|
|
# is specified with two colons followed by a literal 1. The mnemonic is that
|
|
# the last dimension has a unitary stride, i.e., is contiguous in memory,
|
|
# hence C contiguous.
|
|
|
|
##start = time.time()
|
|
cdef str _METHOD = "getArray"
|
|
cdef unsigned int handle = handlePV
|
|
'''
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV"))
|
|
'''
|
|
cdef:
|
|
short * i16val
|
|
dbr_char_t * ui8val
|
|
cvarray cvarr
|
|
int * ival
|
|
double * dval
|
|
float * fval
|
|
dbr_string_t * sval
|
|
cnp.int16_t[::1] mvShort # C-contiguous
|
|
int[::1] mvInt # C-contiguous
|
|
double[::1] mvDouble # C-contiguous
|
|
float[::1] mvFloat # C-contiguous
|
|
# str [:,::1] mvStr
|
|
cnp.ndarray arr
|
|
long dtr = 0
|
|
int status
|
|
# cvarray mvDoubleArray
|
|
|
|
unsigned int i
|
|
unsigned int ij
|
|
array.array a
|
|
|
|
cnp.uint8_t[::1] mvUInt8 # C-contiguous
|
|
cnp.int8_t[::1] mvInt8 # C-contiguous
|
|
cnp.uint16_t[::1] mvUInt16 # C-contiguous
|
|
cnp.int16_t[::1] mvInt16 # C-contiguous
|
|
cnp.uint32_t[::1] mvUInt32 # C-contiguous
|
|
cnp.int32_t[::1] mvInt32 # C-contiguous
|
|
cnp.uint64_t[::1] mvUInt64 # C-contiguous
|
|
cnp.int64_t[::1] mvInt64 # C-contiguous
|
|
# cnp.float16_t [::1] mvFloat16 #C-contiguous
|
|
cnp.float32_t[::1] mvFloat32 # C-contiguous
|
|
cnp.float64_t[::1] mvFloat64 # C-contiguous
|
|
|
|
# cdef PVDataHolder pvd
|
|
|
|
status = self.hh.getDataTypeNative(handle, dtr)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
return [None]
|
|
|
|
elif dtr in [CAFE_NO_ACCESS, CAFE_TYPENOTCONN]:
|
|
if self._c_cafe.isChannelConnected(handle) is False:
|
|
self._c_cafe.getChannelInfo(handle, self.channelInfo)
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatus(
|
|
handle, self.channelInfo.getCafeConnectionState())
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=self.channelInfo.getCafeConnectionState(),
|
|
_error_text=self.cs.code(
|
|
self.channelInfo.getCafeConnectionState()),
|
|
_error_info=self.cs.info(
|
|
self.channelInfo.getCafeConnectionState()))
|
|
raise _cafeException
|
|
return [None]
|
|
|
|
# Likely to be superfluous
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatus(handle, ICAFE_TYPENOTCONN)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=ICAFE_TYPENOTCONN,
|
|
_error_text=self.cs.code(ICAFE_TYPENOTCONN),
|
|
_error_info=self.cs.info(ICAFE_TYPENOTCONN))
|
|
raise _cafeException
|
|
return [None]
|
|
|
|
cdef unsigned int dtcheck = dtr
|
|
|
|
dtcheck = getMatchedDataType(dt, dtr)
|
|
|
|
cdef unsigned int nelemNative = self.hh.getNelemNative(handle)
|
|
cdef unsigned int nelemClient = self.hh.getNelemClient(handle)
|
|
cdef unsigned int nelemRequest = self.hh.getNelemRequest(handle)
|
|
|
|
cdef unsigned int nelemMethod = nelemClient
|
|
# previously nelemNative - has to be at least size of nelemClient
|
|
cdef unsigned int nelemMemory = nelemClient
|
|
|
|
#print('native', self.hh.getNelemNative(handle))
|
|
#print('client', self.hh.getNelemClient(handle))
|
|
#print('request',self.hh.getNelemRequest(handle))
|
|
|
|
#print ('dtcheck', dtcheck)
|
|
|
|
# cdef double [::1] cyarr_view
|
|
# The element type of a typed memoryview may be a numeric scalar type (int, float)
|
|
# It may be a ctypedef alias, or it may be a structured type declared with e.g. cdef struct
|
|
|
|
cdef bytes bVal
|
|
|
|
##end = time.time()
|
|
##print ("PRE-AMBLE", end - start)
|
|
|
|
if dtcheck in [CAFE_STRING, CAFE_ENUM]:
|
|
sval = < char[40]* > malloc(nelemMemory * sizeof(dbr_string_t))
|
|
with nogil:
|
|
status = self._c_cafe.getDbrStringArray(handle, sval)
|
|
|
|
# http://cython.readthedocs.org/en/latest/src/tutorial/numpy.html
|
|
# Some data types are not yet supported, like boolean arrays and string arrays.
|
|
|
|
locallist = []
|
|
|
|
|
|
if status == ICAFE_NORMAL:
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
# elif dt in ['np.string','np.str','np.unicode','np.string_','np.str_','np.unicode_']:
|
|
|
|
mvStr = np.empty(nelemMethod, dtype=(np.str_, 40))
|
|
#mvStr=np.array(self.hh.getNelemRequest(handle), dtype='S40')
|
|
|
|
for i in range(0, nelemMethod):
|
|
|
|
encoding = False
|
|
bVal = <bytes> (<string> sval[i])
|
|
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(handle):
|
|
try:
|
|
mvStr[i] = (bVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
mvStr[i] = bVal.decode('utf_8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
mvStr[i] = bVal.decode('utf_16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
|
|
if not encoding:
|
|
mvStr[i] = sval[i]
|
|
|
|
# locallist.append(sval[i])
|
|
|
|
free(sval)
|
|
|
|
return np.array(mvStr)
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
mvStr = np.empty(nelemMethod, dtype=(
|
|
np.str_, 40), order='C')
|
|
|
|
for ij in range(0, nelemMethod):
|
|
mvStr[ij] = str(sval[ij])
|
|
free(sval)
|
|
|
|
return memoryview(mvStr)
|
|
|
|
elif art in ['array', 'array.array']:
|
|
print(
|
|
"PyCafe.pyx getArray, 'array' type does not support array of strings; returning list")
|
|
# RETURNING LIST - DOES NOT SUPPORT array of strings;
|
|
#arrayArray=array.array('u', 'hello \u2641')
|
|
arrayArray = []
|
|
for ij in range(0, nelemMethod):
|
|
arrayArray.append(str(sval[ij]))
|
|
free(sval)
|
|
return arrayArray
|
|
|
|
elif art in ['ctypes', 'ctype']:
|
|
# c_wchar_p is unicode!
|
|
ctypesArray = (ctypes.c_char_p*nelemMethod)()
|
|
for ij in range(0, nelemMethod):
|
|
ctypesArray[ij] = (sval[ij]).encode('utf-8')
|
|
free(sval)
|
|
return ctypesArray
|
|
|
|
else:
|
|
print("Unknown array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvStr = np.empty(nelemMethod, dtype=(
|
|
np.str_, 40), order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvStr[ij] = <str > sval[ij]
|
|
free(sval)
|
|
|
|
return mvStr
|
|
|
|
elif dtcheck in [CAFE_CHAR]:
|
|
|
|
|
|
##start=time.time()
|
|
ui8val = <dbr_char_t * >malloc(nelemMemory * sizeof(np.uint8))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCharArray(handle, ui8val)
|
|
##end=time.time()
|
|
##print ("END TIME CHAR", end - start)
|
|
##print("length of ui8val", len(ui8val))
|
|
|
|
#print('native', self.hh.getNelemNative(handle))
|
|
#print('client', self.hh.getNelemClient(handle))
|
|
#print('request',self.hh.getNelemRequest(handle))
|
|
|
|
|
|
#nelemMethod = min(len(ui8val), nelemMemory)
|
|
if status == ICAFE_NORMAL:
|
|
# np.empty preferred, else mvInt does not get correct value for first couple of array elements
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
if dt in ['np.short', 'np.int16', 'short', 'int16']:
|
|
mvShort = np.empty(
|
|
nelemMethod, dtype=np.int16, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvShort[ij] = <cnp.int16_t > ui8val[ij]
|
|
free(ui8val)
|
|
return np.array(mvShort)
|
|
|
|
elif dt in ['np.int8', 'np.bool_', 'np.byte', 'bool', 'byte', 'int8']:
|
|
mvInt8 = np.empty(
|
|
nelemMethod, dtype=np.int8, order='C')
|
|
#for ij in range(0, nelemMethod):
|
|
# mvInt8[ij] = <cnp.int8_t > ui8val[ij]
|
|
free(ui8val)
|
|
return mvInt8 #np.array(mvInt8)
|
|
|
|
elif dt in ['uchar', 'np.uint8', 'uint8']:
|
|
#https://stackoverflow.com/questions/21851985/difference-between-np-int-np-int-int-and-np-int-t-in-cython
|
|
#https://stackoverflow.com/questions/25102409/c-malloc-array-pointer-return-in-cython
|
|
#https://stackoverflow.com/questions/23872946/force-numpy-ndarray-to-take-ownership-of-its-memory-in-cython
|
|
#Alterantive copy methods are not faster than the for loop! 0.05 seconds added to ca read time of 0.14s 1.4 million elements
|
|
#'''
|
|
mvUInt8n = np.empty(
|
|
nelemMethod, dtype=np.uint8) # order='C')
|
|
##start = time.time()
|
|
for ij in range(0, nelemMethod):
|
|
mvUInt8n[ij] = <cnp.uint8_t > ui8val[ij]
|
|
free(ui8val)
|
|
##print("Conversion time", time.time()-start)
|
|
return mvUInt8n ##np.array(ui8val) #mvUInt8n #ui8val #np.array(mvUInt8)
|
|
#'''
|
|
#cvarr = <cnp.uint8_t *> ui8val
|
|
#cvarr.free_data = True
|
|
#free(ui8val)
|
|
#return np.asarray(cvarr)
|
|
#mvUInt8 = array_from_ptr(ui8val, nelemMethod, cnp.NPY_UINT8)
|
|
###numpy_array = np.asarray(<cnp.uint8_t *>ui8val)
|
|
#free(ui8val)
|
|
#return mvUInt8 #numpy_array #mvUInt8
|
|
###return array_from_ptr(ui8val, nelemMethod, cnp.NPY_UINT8)
|
|
|
|
else:
|
|
mvUInt8 = np.empty(
|
|
nelemMethod, dtype=np.uint8, order='C')
|
|
#mvShortNP = np.ndarray(buffer=np.array(ui8val), dtype=np.uint8, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvUInt8[ij] = <cnp.uint8_t> ui8val[ij]
|
|
# mvShortNP=cnp.asarray(ui8val)
|
|
|
|
# aaa=np.full(nelemMethod,<mvShort, dtype=np.uint8, order='C')
|
|
free(ui8val)
|
|
return np.array(mvUInt8) # arr
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
mvShort = np.empty(nelemMethod, dtype=np.int16, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvShort[ij] = <short > ui8val[ij]
|
|
free(ui8val)
|
|
return memoryview(mvShort)
|
|
|
|
elif art in ['array', 'array.array']:
|
|
a = array.array('h')
|
|
for ij in range(0, nelemMethod):
|
|
a.append( < short > ui8val[ij])
|
|
free(ui8val)
|
|
return a
|
|
|
|
elif art in ['ctypes', 'ctype']:
|
|
ctypesArray16 = (ctypes.c_int16*nelemMethod)()
|
|
for ij in range(0, nelemMethod):
|
|
ctypesArray16[ij] = <short > ui8val[ij]
|
|
free(ui8val)
|
|
return ctypesArray16
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvUInt8 = np.empty(nelemMethod, dtype=np.uint8, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvUInt8[ij] = <dbr_char_t> ui8val[ij]
|
|
free(ui8val)
|
|
return mvUInt8
|
|
|
|
elif dtcheck in [CAFE_SHORT]:
|
|
|
|
i16val = <short * >malloc(nelemMemory * sizeof(np.int16))
|
|
# start=time.time()
|
|
with nogil:
|
|
status = self._c_cafe.getShortArray(handle, i16val)
|
|
# end=time.time()
|
|
#print ("END TIME SHORT", end - start)
|
|
if status == ICAFE_NORMAL:
|
|
# np.empty preferred, else mvInt does not get correct value for first couple of array elements
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
# ##mvInt=<int[:nelemMethod]>ival
|
|
# ##arr = np.ascontiguousarray(mvInt)
|
|
# ##set_base(arr, ival)
|
|
|
|
if dt in ['np.short', 'np.int16', 'short', 'int16']:
|
|
mvShort = np.empty(
|
|
nelemMethod, dtype=np.int16, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvShort[ij] = <cnp.int16_t > i16val[ij]
|
|
free(i16val)
|
|
return np.array(mvShort)
|
|
|
|
elif dt in ['np.int8', 'np.bool_', 'np.byte', 'bool', 'byte', 'int8']:
|
|
mvInt8 = np.empty(
|
|
nelemMethod, dtype=np.int8, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvInt8[ij] = <cnp.int8_t > i16val[ij]
|
|
free(i16val)
|
|
return np.array(mvInt8)
|
|
|
|
elif dt in ['uchar', 'np.uint8', 'uint8']:
|
|
mvUInt8 = np.empty(
|
|
nelemMethod, dtype=np.uint8, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvUInt8[ij] = <cnp.uint8_t > i16val[ij]
|
|
free(i16val)
|
|
return np.array(mvUInt8)
|
|
|
|
else:
|
|
|
|
mvShort = np.empty(
|
|
nelemMethod, dtype=np.int16, order='C')
|
|
#mvShortNP = np.ndarray(buffer=np.array(i16val), dtype=np.int16, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvShort[ij] = <cnp.int16_t > i16val[ij]
|
|
# mvShortNP=cnp.asarray(i16val)
|
|
|
|
# aaa=np.full(nelemMethod,<mvShort, dtype=np.int16, order='C')
|
|
free(i16val)
|
|
|
|
return np.array(mvShort) # arr
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
mvShort = np.empty(nelemMethod, dtype=np.int16, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvShort[ij] = <short > i16val[ij]
|
|
free(i16val)
|
|
|
|
return memoryview(mvShort)
|
|
|
|
elif art in ['array', 'array.array']:
|
|
|
|
a = array.array('h')
|
|
for ij in range(0, nelemMethod):
|
|
a.append( < short > i16val[ij])
|
|
free(i16val)
|
|
return a
|
|
|
|
elif art in ['ctypes', 'ctype']:
|
|
|
|
ctypesArray16 = (ctypes.c_int16*nelemMethod)()
|
|
for ij in range(0, nelemMethod):
|
|
ctypesArray16[ij] = <short > i16val[ij]
|
|
free(i16val)
|
|
return ctypesArray16
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvShort = np.empty(nelemMethod, dtype=np.int16, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvShort[ij] = <short > i16val[ij]
|
|
free(i16val)
|
|
|
|
return mvShort
|
|
|
|
elif dtcheck in [CAFE_LONG]:
|
|
|
|
ival = <int * >malloc(nelemMemory * sizeof(np.int32))
|
|
with nogil:
|
|
status = self._c_cafe.getLongArray(handle, ival)
|
|
|
|
if status == ICAFE_NORMAL:
|
|
# np.empty preferred, else mvInt does not get correct value for first couple of array elements
|
|
|
|
# nelemMethod=self.hh.getnelemMethod(handle)
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
# elif dt in ['np.intc','np.int_','np.long','np.ulong','np.ushort','np.int32','np.int64','np.uint32','np.uint64']:
|
|
|
|
if dt in ['np.int32', 'int32']:
|
|
mvInt32 = np.empty(
|
|
nelemMethod, dtype=np.int32, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvInt32[ij] = <cnp.int32_t > ival[ij]
|
|
free(ival)
|
|
return np.array(mvInt32)
|
|
elif dt in ['np.uint32', 'uint32']:
|
|
mvUInt32 = np.empty(
|
|
nelemMethod, dtype=np.uint32, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvUInt32[ij] = <cnp.uint32_t > ival[ij]
|
|
free(ival)
|
|
return np.array(mvUInt32)
|
|
|
|
# elif dt in ['np.int64','int64']:
|
|
# mvInt64 = np.empty(nelemMethod, dtype=np.int64, order='C')
|
|
# for ij in range(0, nelemMethod):
|
|
# mvInt64[ij]=<cnp.int64_t>ival[ij]
|
|
# free(ival)
|
|
# return np.array(mvInt64) #
|
|
# elif dt in ['np.uint64','uint64']:
|
|
# mvUInt64 = np.empty(nelemMethod, dtype=np.uint64, order='C')
|
|
# for ij in range(0, nelemMethod):
|
|
# mvUInt64[ij]=<cnp.uint64_t>ival[ij]
|
|
# free(ival)
|
|
# return np.array(mvUInt64)
|
|
|
|
else:
|
|
mvInt = np.empty(
|
|
nelemMethod, dtype=np.int32, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvInt[ij] = <cnp.int32_t > ival[ij]
|
|
free(ival)
|
|
return np.array(mvInt) # arr
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
mvInt = np.empty(nelemMethod, dtype=np.int32, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvInt[ij] = <int > ival[ij]
|
|
free(ival)
|
|
return memoryview(mvInt)
|
|
|
|
elif art in ['array', 'array.array']:
|
|
a = array.array('h')
|
|
for ij in range(0, nelemMethod):
|
|
a.append( < int > ival[ij])
|
|
free(ival)
|
|
return a
|
|
|
|
elif art in ['ctypes', 'ctype']:
|
|
ctypesArray = (ctypes.c_int32*nelemMethod)()
|
|
for ij in range(0, nelemMethod):
|
|
ctypesArray[ij] = <int > ival[ij]
|
|
free(ival)
|
|
return ctypesArray
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvInt = np.empty(nelemMethod, dtype=np.int32, order='C')
|
|
for ij in range(0, nelemMethod):
|
|
mvInt[ij] = <int > ival[ij]
|
|
free(ival)
|
|
return mvInt
|
|
|
|
elif dtcheck in [CAFE_FLOAT]:
|
|
|
|
fval = <float * >malloc(nelemMemory * sizeof(float))
|
|
# start=time.time()
|
|
with nogil:
|
|
status = self._c_cafe.getFloatArray(handle, fval)
|
|
|
|
|
|
# pvd.setNelem(self.hh.getnelemMethod(handle))
|
|
# with nogil:
|
|
# status=self._c_cafe.get(handle, pvd)
|
|
|
|
if status == ICAFE_NORMAL:
|
|
# nelemMethod=self.hh.getnelemMethod(handle)
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
# elif dt in ['np.float16','np.float32']:
|
|
|
|
mvFloat = np.empty(nelemMethod, dtype=np.float32)
|
|
for ij in range(0, nelemMethod):
|
|
mvFloat[ij] = <float > fval[ij] # pvd.getAsFloat(ij)
|
|
# arr=np.asarray(mvFloat)
|
|
|
|
free(fval)
|
|
|
|
#arr = np.ascontiguousarray(mvDouble)
|
|
#set_base(arr, dval)
|
|
|
|
return np.array(mvFloat) # arr
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
|
|
# Method A to return memory view
|
|
mvFloat = np.empty(nelemMethod, dtype=np.float32)
|
|
for ij in range(0, nelemMethod):
|
|
mvFloat[ij] = <float > fval[ij]
|
|
|
|
free(fval)
|
|
# memoryview(mvFloat).tolist() #tolist() only supports byte views
|
|
|
|
return memoryview(mvFloat)
|
|
|
|
# Method B to return memory view
|
|
'''
|
|
mvDoubleArray=cvarray(shape=(nelemMethod,), itemsize=sizeof(double), format="d")
|
|
cyarr_view=mvDoubleArray
|
|
for i in range(0, nelemMethod):
|
|
#mvDoubleArray AVOID COPY TO mvDoubel Array!!
|
|
cyarr_view[i]=dval[i]
|
|
|
|
free(dval)
|
|
return cyarr_view
|
|
'''
|
|
|
|
elif art in ['array', 'array.array']:
|
|
|
|
a = array.array('f')
|
|
|
|
for ij in range(0, nelemMethod):
|
|
a.append(fval[ij])
|
|
free(fval)
|
|
|
|
return a
|
|
'''
|
|
arrayArray=array.array('f')
|
|
for ij in range(0, nelemMethod):
|
|
arrayArray.append(fval[ij])
|
|
free(fval)
|
|
return arrayArray
|
|
'''
|
|
|
|
'''
|
|
cvFloatArray=cvarray(shape=(nelemMethod,), itemsize=sizeof(float), format="f")
|
|
cyarr_view=cvFloatArray
|
|
for i in range(0, nelemMethod):
|
|
#mvDoubleArray AVOID COPY TO mvDoubel Array!!
|
|
cyarr_view[i]=fval[i]
|
|
|
|
free(fval)
|
|
return cyarr_view
|
|
'''
|
|
|
|
elif art in ['ctypes', 'ctype']:
|
|
ctypesArray = (ctypes.c_float*nelemMethod)()
|
|
for ij in range(0, nelemMethod):
|
|
ctypesArray[ij] = fval[ij]
|
|
free(fval)
|
|
return ctypesArray
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvFloat = np.empty(nelemMethod, dtype=np.float32)
|
|
for ij in range(0, nelemMethod):
|
|
mvFloat[ij] = <float > fval[ij]
|
|
free(fval)
|
|
return mvFloat
|
|
|
|
elif dtcheck in [CAFE_DOUBLE]:
|
|
|
|
# start=time.time()
|
|
dval = <double * >malloc(nelemMemory * sizeof(double))
|
|
|
|
with nogil:
|
|
# for ij in range(0, 10000):
|
|
status = self._c_cafe.getDoubleArray(handle, dval)
|
|
|
|
if status == ICAFE_NORMAL:
|
|
# nelemMethod=self.hh.getnelemMethod(handle)
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
# elif dt in ['double', 'np.float_','np.float64']:
|
|
|
|
# mvDouble=<double[:nelemMethod]>dval
|
|
mvDouble = np.empty(nelemMethod, dtype=np.float64)
|
|
for ij in range(0, nelemMethod):
|
|
mvDouble[ij] = <double > dval[ij]
|
|
# arr=np.asarray(mvDouble)
|
|
free(dval)
|
|
# end=time.time()
|
|
#print (end - start)
|
|
return np.array(mvDouble) # arr
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
|
|
# Method A to return memory view
|
|
mvDouble = np.empty(nelemMethod, dtype=np.float64)
|
|
for ij in range(0, nelemMethod):
|
|
mvDouble[ij] = <double > dval[ij]
|
|
free(dval)
|
|
# end=time.time()
|
|
#print (end - start)
|
|
return memoryview(mvDouble)
|
|
|
|
elif art in ['array', 'array.array']:
|
|
a = array.array('d')
|
|
for ij in range(0, nelemMethod):
|
|
a.append(dval[ij])
|
|
free(dval)
|
|
# end=time.time()
|
|
#print (end - start)
|
|
return a
|
|
|
|
elif art in ['ctypes', "ctype"]:
|
|
ctypesArray = (ctypes.c_double*nelemMethod)()
|
|
for ij in range(0, nelemMethod):
|
|
ctypesArray[ij] = dval[ij]
|
|
free(dval)
|
|
return ctypesArray
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvDouble = np.empty(nelemMethod, dtype=np.float64)
|
|
for ij in range(0, nelemMethod):
|
|
mvDouble[ij] = <double > dval[ij]
|
|
free(dval)
|
|
return mvDouble
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status,
|
|
_error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
return [None]
|
|
|
|
############################################################################
|
|
# END: def getArray(self, handlePV, dt):
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def getPVInt(self, handlePV):
|
|
return self.getPV(handlePV, 'int')
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getPVFloat(self, handlePV):
|
|
return self.getPV(handlePV, 'float')
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getPVStr(self, handlePV):
|
|
return self.getPV(handlePV, 'str')
|
|
############################################################################
|
|
|
|
############################################################################
|
|
def getPV(self, handlePV, str dt='native'):
|
|
cdef str _METHOD = "getPV"
|
|
|
|
cdef unsigned int handle = 0
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} {}".format(self._exception_text, _METHOD,
|
|
"First input argument should be of type <class 'int'> if handle, else <class 'str'> if PV"))
|
|
|
|
cdef int status
|
|
cdef PVDataHolder pvd = PVDataHolder(self.hh.getNelemNative(handle))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.get(handle, pvd)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
pvd_valnone = PVDataHolderToStruct(pvd, dt)
|
|
pvd_valnone.value[0] = None
|
|
return pvd_valnone
|
|
|
|
return PVDataHolderToStruct(pvd, dt)
|
|
|
|
##################################################################################
|
|
# END def getPV(self, handlePV):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getPVStrList(self, handleList):
|
|
return self.getPVList(handleList, dt='str')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getPVIntList(self, handleList):
|
|
return self.getPVList(handleList, dt='int')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getPVFloatList(self, handleList):
|
|
return self.getPVList(handleList, dt='float')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getPVList(self, handleList, str dt='native', cacheFlag=False):
|
|
cdef str _METHOD = "getPVList"
|
|
|
|
if isinstance(handleList, (str, int, long)):
|
|
hl = []
|
|
hl.append(handleList)
|
|
handleList = []
|
|
handleList = hl
|
|
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("{} {} {}".format(
|
|
self._exception_text, _METHOD,
|
|
"First input argument should be a 'list' of of type <class 'int'> \
|
|
if handles, else <class 'str'> if PVs"))
|
|
|
|
# cdef unsigned int nelemTotal=0
|
|
# for i in range(0, len(handleList)):
|
|
# nelemTotal+=self.hh.getNelemNative(handleList[i])
|
|
|
|
# cdef int size_cdu = sizeof(CAFE_DATATYPE_UNION) #16 is size of boost_shared_ptr<CAFE_DATATYPE_UNION> (size 40)
|
|
|
|
# cdef PVDataHolder * pvd = \
|
|
# <PVDataHolder *>malloc( 100000000 + \
|
|
# len(handleList) * sizeof(PVDataHolder) + nelemTotal*size_cdu)
|
|
|
|
cdef vector[unsigned int] v
|
|
|
|
# do this to avoid compiler warning messages
|
|
|
|
for i in range(0, len(handleList)):
|
|
v.push_back(handleList[i])
|
|
|
|
cdef PVDataHolder * pvd = self._c_cafe.getPVData(v)
|
|
|
|
for i in range(0, <int>v.size()): # len(handleList)): #
|
|
pvd[i].setNelem(self.hh.getNelemNative(v[i])) # handleList[i]))
|
|
# print " ", pvd[i].getNelem(), self.hh.getNelemNative(handleList[i]), i
|
|
|
|
cdef int status
|
|
|
|
if cacheFlag:
|
|
status = self._c_cafe.getCachePVArray(v, pvd)
|
|
else:
|
|
with nogil:
|
|
status = self._c_cafe.getPVArray(v, pvd)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
for i in range(0, <int>v.size()): #len(handleList)):
|
|
if (pvd[i].getStatus() != ICAFE_NORMAL):
|
|
print("Handle=", handleList[i], "PV=",
|
|
self.hh.getPVFromHandle(handleList[i]))
|
|
print("with error status=", pvd[i].getStatus())
|
|
self._c_cafe.printStatusMessage(status)
|
|
print("")
|
|
#raise Exception("EXCEPTION RAISED in PyCafe def getPVList. Status = %d" %status)
|
|
|
|
cdef unsigned int dtn
|
|
cdef unsigned int dtcheck
|
|
|
|
cdef CAFEDataTypeCode cdt
|
|
|
|
pvdList = []
|
|
cdef pvdata p1
|
|
|
|
cdef bytes bytesVal
|
|
|
|
for i in range(0, <int>v.size()): #len(handleList)):
|
|
dtn = pvd[i].getDataType()
|
|
|
|
dtcheck = getMatchedDataType(dt, dtn)
|
|
localList = []
|
|
|
|
if pvd[i].getNelem() == 1:
|
|
if dtcheck == CAFE_STRING:
|
|
bytesVal = <bytes> pvd[i].getAsString()
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(v[i]):
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = pvd[i].getAsString()
|
|
|
|
localList.append(strVal)
|
|
|
|
elif dtcheck == CAFE_SHORT:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_FLOAT:
|
|
localList.append(pvd[i].getAsDouble())
|
|
elif dtcheck == CAFE_ENUM:
|
|
# if enum, string taken as native
|
|
if self._c_cafe.isEnum(handleList[i]):
|
|
localList.append(pvd[i].getAsString())
|
|
else:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_CHAR:
|
|
# (<unsigned char> pvd[i].getAsChar())
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_LONG:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_DOUBLE:
|
|
localList.append(pvd[i].getAsDouble())
|
|
else:
|
|
localList.append(0) # no data
|
|
|
|
else:
|
|
localListInner = []
|
|
if dtcheck == CAFE_STRING:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
|
|
bytesVal = <bytes> pvd[i].getAsString(j)
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(v[i]):
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = pvd[i].getAsString(j)
|
|
localListInner.append(strVal) #pvd[i].getAsString(j))
|
|
elif dtcheck == CAFE_SHORT:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_FLOAT:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsDouble(j))
|
|
elif dtcheck == CAFE_ENUM:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
# if enum, string taken as native
|
|
if self._c_cafe.isEnum(handleList[i]):
|
|
localListInner.append(pvd[i].getAsString(j))
|
|
else:
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_CHAR:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
# (<unsigned char> pvd[i].getAsChar(j))
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_LONG:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_DOUBLE:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsDouble(j))
|
|
else:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(0) # no data
|
|
localList.append(localListInner)
|
|
|
|
p1 = pvdata()
|
|
p1.value = localList
|
|
p1.status = pvd[i].getStatus()
|
|
p1.statusAsString = pvd[i].getStatusAsString()
|
|
p1.nelem = pvd[i].getNelem()
|
|
p1.alarmStatus = pvd[i].getAlarmStatus()
|
|
p1.alarmSeverity = pvd[i].getAlarmSeverity()
|
|
p1.alarmStatusAsString = pvd[i].getAlarmStatusAsString()
|
|
p1.alarmSeverityAsString = pvd[i].getAlarmSeverityAsString()
|
|
p1.dataType = pvd[i].getDataType()
|
|
p1.dataTypeAsString = cdt.message(pvd[i].getDataType())
|
|
pvd._etsNorm = pvd[i].getEpicsTimeStampAsUInt32()
|
|
|
|
ll = []
|
|
ll.append((pvd[i]._etsNorm).secPastEpoch)
|
|
ll.append((pvd[i]._etsNorm).nsec)
|
|
p1.ts = ll
|
|
|
|
pvd._etsDate = pvd[i].getEpicsTimeStampAsDate()
|
|
|
|
ld = []
|
|
ld.append((pvd[i]._etsDate).year)
|
|
ld.append((pvd[i]._etsDate).mon)
|
|
ld.append((pvd[i]._etsDate).day)
|
|
ld.append((pvd[i]._etsDate).hour)
|
|
ld.append((pvd[i]._etsDate).min)
|
|
ld.append((pvd[i]._etsDate).sec)
|
|
ld.append((pvd[i]._etsDate).nsec)
|
|
p1.tsDate = ld
|
|
|
|
pvdList.append(p1)
|
|
|
|
# free(pvd)
|
|
|
|
return pvdList, status
|
|
|
|
##################################################################################
|
|
# END: def getPVList(self, handlePV, dt):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def printStatusIfError(self, handleList, statusList):
|
|
##################################################################################
|
|
cdef str _METHOD = "printStatusIfError"
|
|
|
|
if isinstance(handleList, (str, int, long)):
|
|
handleListB = []
|
|
handleListB.append(handleList)
|
|
handleList = []
|
|
handleList = handleListB
|
|
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("{} {} {}".format(self._exception_text, _METHOD,
|
|
"First input argument should be a 'list' of of type <class 'int'> if handles or <class 'str'> if PVs"))
|
|
|
|
if isinstance(statusList, (int, long)):
|
|
statusListB = []
|
|
statusListB.append(statusList)
|
|
statusList = []
|
|
statusList = statusListB
|
|
|
|
if not isinstance(statusList, (list)):
|
|
raise Exception("{} {} {}".format(self._exception_text, _METHOD,
|
|
"Second input argument should be <type 'list'> of of type <class 'int'>"))
|
|
|
|
if not isinstance(statusList[0], (int, long, float)):
|
|
raise Exception("{} {} {}".format(self._exception_text, _METHOD,
|
|
"Second input argument should be a <type 'list'> of of type <class 'int'>"))
|
|
|
|
cdef vector[unsigned int] v
|
|
# do next step to avoid:
|
|
# warning: comparison between signed and unsigned integer expressions
|
|
for i in range(0, len(handleList)):
|
|
# do this copy to avoid compiler warning messages
|
|
v.push_back(handleList[i])
|
|
|
|
self._c_cafe.printStatusIfError(v, statusList)
|
|
return
|
|
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getAsyn(self, handleList):
|
|
##################################################################################
|
|
cdef str _METHOD = "getAsyn"
|
|
|
|
if isinstance(handleList, (str, int, long)):
|
|
handleListB = []
|
|
handleListB.append(handleList)
|
|
#handleList = []
|
|
handleList = handleListB
|
|
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("{} {} {}".format(self._exception_text, _METHOD,
|
|
"First input argument should be a 'list' of of type <class 'int'> if handles or <class 'str'> if PVs"))
|
|
|
|
cdef vector[unsigned int] v
|
|
cdef vector[int] vStatus
|
|
v.reserve(len(handleList))
|
|
vStatus.reserve(len(handleList))
|
|
|
|
# do next step to avoid:
|
|
# warning: comparison between signed and unsigned integer expressions
|
|
for i in range(0, len(handleList)):
|
|
# do this copy to avoid compiler warning messages
|
|
v.push_back(handleList[i])
|
|
|
|
# Need to copy to a vector since
|
|
# Coercion from Python not allowed without the GIL
|
|
with nogil:
|
|
status = self._c_cafe.getV(v, vStatus)
|
|
|
|
if (status != ICAFE_NORMAL):
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
print("Error/Warning from def getAsyn: ")
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
return status, vStatus
|
|
|
|
##################################################################################
|
|
# END: def getAsyn(self, handleList):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
@verify_handlepv
|
|
def waitForGetEvent(self, handlePV):
|
|
|
|
cdef unsigned int handle = handlePV
|
|
with nogil:
|
|
status = self._c_cafe.waitForGetEvent(handle)
|
|
return status
|
|
##################################################################################
|
|
# END: def waitForGetEvent(self, handlePV)
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def waitForBundledEvents(self, handleList):
|
|
cdef str _METHOD = "waitForBundledEvents(self, handleList)"
|
|
|
|
if isinstance(handleList, (str, int, long)):
|
|
handleListB = []
|
|
handleListB.append(handleList)
|
|
#handleList = []
|
|
handleList = handleListB
|
|
|
|
if not isinstance(handleList, (list)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def waitForBundledEvents. \n\
|
|
First input argument, should be <type 'list'> of handles or PVs")
|
|
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def waitForBundledEvents. \n\
|
|
First input argument, should be a 'list' of of type <class 'int'> if handles or <class 'str'> if PVs")
|
|
|
|
cdef vector[unsigned int] v
|
|
cdef vector[int] vRB
|
|
|
|
v.reserve(len(handleList))
|
|
vRB.reserve(len(handleList))
|
|
for i in range(0, len(handleList)):
|
|
# do this copy to avoid compiler warning messages
|
|
v.push_back(handleList[i])
|
|
|
|
# Wait for bundle
|
|
with nogil:
|
|
status = self._c_cafe.waitForBundledEvents(v, vRB)
|
|
if (status != ICAFE_NORMAL):
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
print("Error in def waitForBundledEvents: ")
|
|
self._c_cafe.printStatusMessage(status)
|
|
return status
|
|
return status, vRB
|
|
##################################################################################
|
|
# END: def waitForBundledEvents(self, handleList):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getScalarArray(self, handleList, str dt='native', bint cacheFlag=False):
|
|
|
|
cdef str _METHOD = "getScalarArray(handleList, str dt, bint cacheFlag)"
|
|
|
|
# cdef float [::1] mvFloat #C-contiguous
|
|
|
|
if not isinstance(handleList, (list)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getScalarArray. \n\
|
|
First input argument, should be <type 'list'> of handles or PVs")
|
|
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getScalarArray. \n\
|
|
First input argument, should be a 'list' of of type <class 'int'> if handles or <class 'str'> if PVs")
|
|
|
|
nelemPrevious = []
|
|
|
|
for i in range(0, len(handleList)):
|
|
nelemPrevious.append(self._c_cafe.setNelemToOne(handleList[i]))
|
|
|
|
# pack into numpy
|
|
cdef vector[unsigned int] v
|
|
cdef vector[int] vStatus
|
|
|
|
v.reserve(len(handleList))
|
|
vStatus.reserve(len(handleList))
|
|
|
|
for i in range(0, len(handleList)):
|
|
# do this copy to avoid compiler warning messages
|
|
v.push_back(handleList[i])
|
|
|
|
cdef vector[int] vRB
|
|
status = ICAFE_NORMAL
|
|
|
|
if (cacheFlag == False):
|
|
# Need to copy to a vector since
|
|
# Coercion from Python not allowed without the GIL
|
|
with nogil:
|
|
status = self._c_cafe.getV(v, vStatus)
|
|
|
|
# Check for error code 704: ICAFE_WAITING_FOR_PREV_CALLBACK
|
|
# as this may mean we have a double handle instance.
|
|
# This is not a problem as such but if this is the case let's
|
|
# remove the error if the first getAsyn call for the handle in question was OK
|
|
# Functionality not yet moved to CAFE::
|
|
# Required for when dt='native'
|
|
if (status != ICAFE_NORMAL):
|
|
for i in range(0, len(vStatus)):
|
|
if (vStatus[i] == ICAFE_WAITING_FOR_PREV_CALLBACK):
|
|
# getHandle
|
|
for j in range(0, (i-1)):
|
|
if(v[j] == v[i]):
|
|
if (vStatus[j] == ICAFE_NORMAL):
|
|
vStatus[i] = vStatus[j]
|
|
|
|
# ca_poll() Not required as above will flush!
|
|
|
|
# Wait for bundle
|
|
|
|
with nogil:
|
|
statusBundle = self._c_cafe.waitForBundledEvents(v, vRB)
|
|
if (statusBundle != ICAFE_NORMAL):
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
print("Error in def getScalarArray: ")
|
|
self._c_cafe.printStatusMessage(statusBundle)
|
|
|
|
cdef unsigned int dtcheck = CAFE_NOT_REQUESTED # native type not yet know
|
|
dtcheck = getMatchedDataType(dt, dtcheck)
|
|
|
|
#print ("dt=", dt, "dtcheck=", dtcheck)
|
|
|
|
localList = []
|
|
cdef bytes bytesVal
|
|
|
|
if dtcheck in [CAFE_STRING]:
|
|
|
|
self.vStr.clear()
|
|
self.vStr.reserve(len(handleList))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCacheVStr(v, self.vStr, vStatus)
|
|
|
|
for i in range(0, len(handleList)):
|
|
self._c_cafe.setNelemToPrevious(
|
|
handleList[i], nelemPrevious[i])
|
|
|
|
bytesVal = <bytes> (<string> self.vStr[i] )
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(handleList[i]):
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = <string> self.vStr[i]
|
|
|
|
localList.append(strVal)
|
|
|
|
return localList, status, vStatus
|
|
|
|
elif dtcheck in [CAFE_SHORT, CAFE_CHAR, CAFE_LONG]:
|
|
|
|
self.vInt.clear()
|
|
self.vInt.reserve(len(handleList))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCacheVLong(v, self.vInt, vStatus)
|
|
|
|
# for i in range(0, len(vStatus)):
|
|
#print ("status " , vStatus[i], " i", i, self._c_cafe.getPVFromHandle(handleList[i]))
|
|
|
|
for i in range(0, len(handleList)):
|
|
self._c_cafe.setNelemToPrevious(
|
|
handleList[i], nelemPrevious[i])
|
|
|
|
# localList=[]
|
|
# statusList=[]
|
|
|
|
# for i in range(0, len(self.vInt)):
|
|
return self.vInt, status, vStatus
|
|
|
|
elif dtcheck in [CAFE_FLOAT, CAFE_DOUBLE]:
|
|
|
|
self.vFloat.clear()
|
|
self.vFloat.reserve(len(handleList))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCacheVDouble(v, self.vFloat, vStatus)
|
|
|
|
for i in range(0, len(handleList)):
|
|
self._c_cafe.setNelemToPrevious(
|
|
handleList[i], nelemPrevious[i])
|
|
|
|
# for i in range(0, len(vStatus)):
|
|
# print ("status/// " , vStatus[i], " i", i, self._c_cafe.getPVFromHandle(handleList[i]))
|
|
#print ("overall status", status)
|
|
|
|
# localList=[]
|
|
# statusList=[]
|
|
# Method A to return memory view
|
|
#mvFloat = np.empty(len(handleList), dtype=np.float32)
|
|
# for ij in range(0, len(handleList)):
|
|
# mvFloat[ij]=<float>self.vFloat[ij]
|
|
# return mvFloat, status, vStatus
|
|
|
|
# for i in range(0, len(self.vFloat)):
|
|
return self.vFloat, status, vStatus
|
|
|
|
# Native
|
|
|
|
|
|
# cdef unsigned int nelemTotal=0
|
|
# for i in range(0, len(handleList)):
|
|
# nelemTotal+=self.hh.getNelemNative(handleList[i])
|
|
|
|
# cdef int size_cdu = sizeof(CAFE_DATATYPE_UNION) #16 is size of boost_shared_ptr<CAFE_DATATYPE_UNION> (size 40)
|
|
|
|
# Create temporary group from handleList
|
|
# Does group exist?
|
|
cdef PVDataHolder * pvd = self._c_cafe.getPVData(v)
|
|
|
|
|
|
# for i in range (0, len(handleList)):
|
|
# print pvd[i].getPVName(), pvd[i].getAsString(), " [",i,"]"
|
|
# print ""
|
|
|
|
#print ("-----------------------------------------------------------------")
|
|
|
|
# cdef PVDataHolder * pvd = \
|
|
# <PVDataHolder *>malloc( 100000000 + \
|
|
# len(handleList) * sizeof(PVDataHolder) + nelemTotal*size_cdu)
|
|
# print "size_pvd=", sizeof(PVDataHolder)
|
|
# print "sizeoverall", len(handleList) * sizeof(PVDataHolder)*10000
|
|
|
|
# Required to allocate memory for shared pointer
|
|
for i in range(0, <int>v.size()): #len(handleList)):
|
|
pvd[i].setNelem(1)
|
|
|
|
statusNoWait = self._c_cafe.getCachePVArrayNoWait(v, pvd)
|
|
|
|
for i in range(0, len(handleList)):
|
|
self._c_cafe.setNelemToPrevious(handleList[i], nelemPrevious[i])
|
|
|
|
statusList = []
|
|
statusFlag = True
|
|
statusLocal = ICAFE_NORMAL
|
|
if (cacheFlag):
|
|
|
|
# if status !=ICAFE_NORMAL:
|
|
# if PYCAFE_PRINT_LEVEL>=PYCAFE_PRINT_LOW:
|
|
# self._c_cafe.printStatusMessage(status)
|
|
# status=ICAFE_NORMAL
|
|
for i in range(0, <int>v.size()): #len(handleList)):
|
|
statusList.append(pvd[i].getStatus())
|
|
if pvd[i].getStatus() != ICAFE_NORMAL:
|
|
print("Error in Element ", i, " from ", len(
|
|
handleList), " in PyCafe def getScalarArray")
|
|
print("Handle= ", handleList[i], " PV=",
|
|
self.hh.getPVFromHandle(handleList[i]))
|
|
print("with error status=", pvd[i].getStatus())
|
|
self._c_cafe.printStatusMessage(pvd[i].getStatus())
|
|
if statusFlag:
|
|
statusLocal = pvd[i].getStatus()
|
|
statusFlag = False
|
|
|
|
#
|
|
# else:
|
|
# statusList.append(status)
|
|
|
|
# Wht not as a memoryView?
|
|
|
|
cdef unsigned int dtn
|
|
|
|
localList = []
|
|
|
|
|
|
for i in range(0, <int>v.size()): #len(handleList)):
|
|
|
|
dtn = pvd[i].getDataType()
|
|
dtcheck = getMatchedDataType(dt, dtn)
|
|
|
|
#print ("dt=", dt, "dtn=", dtn, "dtcheck=", dtcheck)
|
|
#print (pvd[i].getAsString())
|
|
#print (pvd[i].getAsDouble())
|
|
|
|
if dtcheck == CAFE_STRING:
|
|
bytesVal = <bytes> pvd[i].getAsString()
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(v[i]):
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = pvd[i].getAsString()
|
|
|
|
localList.append(strVal)
|
|
|
|
##localList.append(pvd[i].getAsString())
|
|
elif dtcheck == CAFE_SHORT:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_FLOAT:
|
|
localList.append(pvd[i].getAsDouble())
|
|
elif dtcheck == CAFE_ENUM:
|
|
# if enum, string taken as native
|
|
|
|
if self._c_cafe.isEnum(self.hh.getHandleFromPV(pvd[i].getPVName())):
|
|
localList.append(pvd[i].getAsString())
|
|
else:
|
|
localList.append(pvd[i].getAsLong())
|
|
|
|
elif dtcheck == CAFE_CHAR:
|
|
# <unsigned char> pvd[i].getAsChar()
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_LONG:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_DOUBLE:
|
|
localList.append(pvd[i].getAsDouble())
|
|
else:
|
|
localList.append(0)
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_HIGH:
|
|
print("def getScalarArray:")
|
|
print("Entering 0 for element", i,
|
|
"as channel is not connected!")
|
|
|
|
#print (" vstatus = ", vStatus[i] , " pvd[i].status ", pvd[i].getStatus() )
|
|
|
|
# free(pvd)
|
|
if cacheFlag:
|
|
return localList, statusLocal, statusList
|
|
|
|
# use vstatus instead of statusList (as cache is NoWait)
|
|
return localList, status, vStatus
|
|
|
|
##################################################################################
|
|
# END: def getScalarArray(self, handleList, dt, cacheFlag):
|
|
##################################################################################
|
|
|
|
|
|
|
|
|
|
##################################################################################
|
|
|
|
def getStrScalarList(self, handleList):
|
|
##################################################################################
|
|
return self.getScalarList(handleList, dt='str')
|
|
|
|
##################################################################################
|
|
def getIntScalarList(self, handleList):
|
|
##################################################################################
|
|
return self.getScalarList(handleList, dt='int')
|
|
|
|
##################################################################################
|
|
def getFloatScalarList(self, handleList):
|
|
##################################################################################
|
|
return self.getScalarList(handleList, dt='float')
|
|
|
|
##################################################################################
|
|
def getScalarList(self, handleList, dt: str = 'native',
|
|
cacheFlag: bool = False, dictFlag: bool = False):
|
|
##################################################################################
|
|
cdef str _METHOD = "getScalarList(handleList, str dt, bint cacheFlag)"
|
|
|
|
# cdef float [::1] mvFloat #C-contiguous
|
|
|
|
if not isinstance(handleList, (list)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getScalarList. \n\
|
|
First input argument, should be <type 'list'> of handles or PVs")
|
|
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getScalarList. \n\
|
|
First input argument, should be a 'list' of of type <class 'int'> if handles or <class 'str'> if PVs")
|
|
|
|
nelemPrevious = []
|
|
|
|
|
|
|
|
for i in range(0, len(handleList)):
|
|
nelemPrevious.append(self._c_cafe.setNelemToOne(handleList[i]))
|
|
|
|
#c=self.hh.getNelemClient(handleList[i])
|
|
#n=self.hh.getNelemNative(handleList[i])
|
|
#r=self.hh.getNelemRequest(handleList[i])
|
|
#print("c,n,r", c,n,r, "[",i,"]")
|
|
# c=self.hh.getNelemToRetrieveFromCache(handleList[i])
|
|
# print("cache", c, "[",i,"]")
|
|
|
|
# pack into vectors
|
|
cdef vector[unsigned int] v
|
|
cdef vector[int] vStatus
|
|
|
|
v.reserve(len(handleList))
|
|
vStatus.reserve(len(handleList))
|
|
|
|
for i in range(0, len(handleList)):
|
|
# do this copy to avoid compiler warning messages
|
|
v.push_back(handleList[i])
|
|
|
|
cdef vector[int] vRB
|
|
status = ICAFE_NORMAL
|
|
|
|
cdef bytes bytesVal
|
|
|
|
if (cacheFlag == False):
|
|
# Need to copy to a vector since
|
|
# Coercion from Python not allowed without the GIL
|
|
with nogil:
|
|
status = self._c_cafe.getV(v, vStatus)
|
|
|
|
|
|
#for i in range(0, len(vStatus)):
|
|
# print (vStatus[i])
|
|
# print("====")
|
|
# Check for error code 704: ICAFE_WAITING_FOR_PREV_CALLBACK
|
|
# as this may mean we have a double handle instance.
|
|
# This is not a problem as such but if this is the case let's
|
|
# remove the error if the first getAsyn call for the handle in question was OK
|
|
# Functionality not yet moved to CAFE::
|
|
# Required for when dt='native'
|
|
if (status != ICAFE_NORMAL):
|
|
for i in range(0, len(vStatus)):
|
|
if (vStatus[i] == ICAFE_WAITING_FOR_PREV_CALLBACK):
|
|
# getHandle
|
|
for j in range(0, (i-1)):
|
|
if(v[j] == v[i]):
|
|
if (vStatus[j] == ICAFE_NORMAL):
|
|
vStatus[i] = vStatus[j]
|
|
|
|
# ca_poll() Not required as above will flush!
|
|
# Wait for bundle
|
|
|
|
with nogil:
|
|
statusBundle = self._c_cafe.waitForBundledEvents(v, vRB)
|
|
|
|
if (statusBundle != ICAFE_NORMAL):
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
print("Error in def getScalarList: ")
|
|
self._c_cafe.printStatusMessage(statusBundle)
|
|
|
|
cdef unsigned int dtcheck = CAFE_NOT_REQUESTED # native type not yet know
|
|
dtcheck = getMatchedDataType(dt, dtcheck)
|
|
|
|
#print ("dt=", dt, "dtcheck=", dtcheck)
|
|
|
|
if dtcheck in [CAFE_STRING]:
|
|
|
|
self.vStr.clear()
|
|
self.vStr.reserve(len(handleList))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCacheVStr(v, self.vStr, vStatus)
|
|
|
|
|
|
localList=[]
|
|
# statusList=[]
|
|
|
|
for i in range(0, len(handleList)):
|
|
self._c_cafe.setNelemToPrevious(
|
|
handleList[i], nelemPrevious[i])
|
|
bytesVal = <bytes> (<string> self.vStr[i] )
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(handleList[i]):
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = self.vStr[i]
|
|
|
|
localList.append(strVal)
|
|
|
|
return localList, status, vStatus
|
|
|
|
elif dtcheck in [CAFE_SHORT, CAFE_CHAR, CAFE_LONG]:
|
|
|
|
self.vInt.clear()
|
|
self.vInt.reserve(len(handleList))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCacheVLong(v, self.vInt, vStatus)
|
|
|
|
# for i in range(0, len(vStatus)):
|
|
#print ("status " , vStatus[i], " i", i, self._c_cafe.getPVFromHandle(handleList[i]))
|
|
|
|
for i in range(0, len(handleList)):
|
|
self._c_cafe.setNelemToPrevious(
|
|
handleList[i], nelemPrevious[i])
|
|
|
|
# localList=[]
|
|
# statusList=[]
|
|
|
|
# for i in range(0, len(self.vInt)):
|
|
return self.vInt, status, vStatus
|
|
|
|
elif dtcheck in [CAFE_FLOAT, CAFE_DOUBLE]:
|
|
|
|
self.vFloat.clear()
|
|
self.vFloat.reserve(len(handleList))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCacheVDouble(v, self.vFloat, vStatus)
|
|
|
|
for i in range(0, len(handleList)):
|
|
self._c_cafe.setNelemToPrevious(
|
|
handleList[i], nelemPrevious[i])
|
|
|
|
#for i in range(0, len(vStatus)):
|
|
# print ("status/// " , vStatus[i], " i", i, self._c_cafe.getPVFromHandle(handleList[i]))
|
|
#print ("overall status", status)
|
|
|
|
# localList=[]
|
|
# statusList=[]
|
|
# Method A to return memory view
|
|
#mvFloat = np.empty(len(handleList), dtype=np.float32)
|
|
# for ij in range(0, len(handleList)):
|
|
# mvFloat[ij]=<float>self.vFloat[ij]
|
|
# return mvFloat, status, vStatus
|
|
|
|
# for i in range(0, len(self.vFloat)):
|
|
return self.vFloat, status, vStatus
|
|
|
|
# Native
|
|
|
|
|
|
# cdef unsigned int nelemTotal=0
|
|
# for i in range(0, len(handleList)):
|
|
# nelemTotal+=self.hh.getNelemNative(handleList[i])
|
|
|
|
# cdef int size_cdu = sizeof(CAFE_DATATYPE_UNION) #16 is size of boost_shared_ptr<CAFE_DATATYPE_UNION> (size 40)
|
|
|
|
|
|
cdef PVDataHolder * pvd = self._c_cafe.getPVData(v)
|
|
|
|
#for i in range (0, len(handleList)):
|
|
# print (pvd[i].getPVName(), pvd[i].getAsString(), " [",i,"]", pvd[i].getStatus())
|
|
|
|
|
|
|
|
|
|
# cdef PVDataHolder * pvd = \
|
|
# <PVDataHolder *>malloc( 100000000 + \
|
|
# len(handleList) * sizeof(PVDataHolder) + nelemTotal*size_cdu)
|
|
# print "size_pvd=", sizeof(PVDataHolder)
|
|
# print "sizeoverall", len(handleList) * sizeof(PVDataHolder)*10000
|
|
|
|
# Required to allocate memory for shared pointer
|
|
for i in range(0, <int>v.size()): #len(handleList)):
|
|
pvd[i].setNelem(1)
|
|
|
|
statusNoWait = self._c_cafe.getCachePVArrayNoWait(v, pvd)
|
|
|
|
for i in range(0, len(handleList)):
|
|
self._c_cafe.setNelemToPrevious(handleList[i], nelemPrevious[i])
|
|
|
|
statusList = []
|
|
statusFlag = True
|
|
statusLocal = ICAFE_NORMAL
|
|
|
|
|
|
#self._c_cafe.printStatusMessage(statusNoWait)
|
|
|
|
# if cacheFlag==True:
|
|
if True: # For all cases Added Oct 2018
|
|
# if status !=ICAFE_NORMAL:
|
|
# if PYCAFE_PRINT_LEVEL>=PYCAFE_PRINT_LOW:
|
|
# self._c_cafe.printStatusMessage(status)
|
|
# status=ICAFE_NORMAL
|
|
for i in range(0, <int>v.size()): #len(handleList)):
|
|
statusList.append(pvd[i].getStatus())
|
|
if pvd[i].getStatus() != ICAFE_NORMAL:
|
|
print("Error in Element ", i, " from ", len(
|
|
handleList), " in PyCafe def getScalarList")
|
|
print("Handle= ", handleList[i], " PV=",
|
|
self.hh.getPVFromHandle(handleList[i]))
|
|
print("with error status=", pvd[i].getStatus())
|
|
self._c_cafe.printStatusMessage(pvd[i].getStatus())
|
|
if statusFlag:
|
|
statusLocal = pvd[i].getStatus()
|
|
statusFlag = False
|
|
|
|
#
|
|
# else:
|
|
# statusList.append(status)
|
|
|
|
# Wht not as a memoryView?
|
|
|
|
cdef unsigned int dtn
|
|
|
|
localList = []
|
|
|
|
|
|
for i in range(0, <int>v.size()): #len(handleList)):
|
|
|
|
dtn = pvd[i].getDataType()
|
|
dtcheck = getMatchedDataType(dt, dtn)
|
|
|
|
#print ("dt=", dt, "dtn=", dtn, "dtcheck=", dtcheck)
|
|
#print (pvd[i].getAsString())
|
|
#print (pvd[i].getAsDouble())
|
|
|
|
if dtcheck == CAFE_STRING:
|
|
|
|
bytesVal = <bytes> pvd[i].getAsString()
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(v[i]):
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = pvd[i].getAsString()
|
|
|
|
localList.append(strVal)
|
|
|
|
elif dtcheck == CAFE_SHORT:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_FLOAT:
|
|
localList.append(pvd[i].getAsDouble())
|
|
elif dtcheck == CAFE_ENUM:
|
|
# if enum, string taken as native
|
|
|
|
if self._c_cafe.isEnum(self.hh.getHandleFromPV(pvd[i].getPVName())):
|
|
localList.append(pvd[i].getAsString())
|
|
else:
|
|
localList.append(pvd[i].getAsLong())
|
|
|
|
elif dtcheck == CAFE_CHAR:
|
|
# <unsigned char> pvd[i].getAsChar()
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_LONG:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_DOUBLE:
|
|
localList.append(pvd[i].getAsDouble())
|
|
else:
|
|
localList.append(0)
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_HIGH:
|
|
print("def getScalarList:")
|
|
print("Entering 0 for element", i,
|
|
"as channel is not connected!")
|
|
|
|
#print (" vstatus = ", vStatus[i] , " pvd[i].status ", pvd[i].getStatus() )
|
|
|
|
# free(pvd)
|
|
if (cacheFlag == True):
|
|
return localList, statusLocal, statusList
|
|
|
|
# use vstatus instead of statusList (as cache is NoWait)
|
|
return localList, statusNoWait, vStatus
|
|
# return localList, status, vStatus # use vstatus instead of statusList (as cache is NoWait)
|
|
|
|
##################################################################################
|
|
# END: def getScalarList(self, handleList, dt):
|
|
##################################################################################
|
|
|
|
|
|
def getDictionary(self, pvhandleList, dt: str = 'native', cacheFlag: bool = False,
|
|
scalarOnly: bool = False):
|
|
cdef str _METHOD = "getDictionary(handleList, dt, cacheFlag )"
|
|
|
|
pvList = None
|
|
handleList = pvhandleList
|
|
|
|
if isinstance(handleList, (str)):
|
|
handleList = self.getHandlesFromWithinGroup(handleList)
|
|
if not handleList:
|
|
raise Exception(("EXCEPTION RAISED IN PyCafe def getDictionary. \n" +
|
|
"First input argument should be <type 'list'> " +
|
|
"of handles or PVs\nelse <class 'str'> for " +
|
|
"CAFE 'group' name"))
|
|
else:
|
|
if not isinstance(handleList, (list)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getCompoundList. \n\
|
|
First input argument, should be <type 'list'> of handles or PVs")
|
|
|
|
if isinstance(handleList[0], (str)):
|
|
pvList = handleList
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getCompoundList. \n\
|
|
First input argument, should be a 'list' of of type <class 'int'> if handles or <class 'str'> if PVs")
|
|
|
|
if scalarOnly:
|
|
value, statusOverall, status =self.getScalarList(handleList, dt, cacheFlag)
|
|
else:
|
|
value, statusOverall, status =self.getCompoundList(handleList, dt, cacheFlag)
|
|
|
|
pvdict = OrderedDict()
|
|
for i in range(0, len(handleList)):
|
|
_val = value[i]
|
|
if status[i] != ICAFE_NORMAL:
|
|
_val = None
|
|
pvdict[self._c_cafe.getPVFromHandle(handleList[i])] = _val
|
|
|
|
return pvdict, statusOverall, status
|
|
|
|
# int alarmStatus=None, int alarmSev=None):
|
|
##################################################################################
|
|
def getCompoundList(self, handleList, str dt='native', bint cacheFlag=False):
|
|
##################################################################################
|
|
cdef str _METHOD = "getCompoundList(handleList, str dt='native')"
|
|
|
|
if isinstance(handleList, (str)):
|
|
handleList = self.getHandlesFromWithinGroup(handleList)
|
|
if not handleList:
|
|
raise Exception(("EXCEPTION RAISED IN PyCafe def getCompoundList. \n" +
|
|
"First input argument should be <type 'list'> " +
|
|
"of handles or PVs\nelse <class 'str'> for " +
|
|
"CAFE 'group' name"))
|
|
else:
|
|
if not isinstance(handleList, (list)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getCompoundList. \n\
|
|
First input argument, should be <type 'list'> of handles or PVs")
|
|
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getCompoundList. \n\
|
|
First input argument, should be a 'list' of of type <class 'int'> if handles or <class 'str'> if PVs")
|
|
|
|
# pack into vectors
|
|
cdef vector[unsigned int] v
|
|
cdef vector[int] vStatus
|
|
|
|
cdef vector[int] vRB
|
|
|
|
v.reserve(len(handleList))
|
|
vStatus.reserve(len(handleList))
|
|
|
|
cdef bint flagCompound = False
|
|
|
|
cdef unsigned int nelemLocal = 1
|
|
|
|
for i in range(0, len(handleList)):
|
|
# do this copy to avoid compiler warning messages
|
|
v.push_back(handleList[i])
|
|
|
|
if (nelemLocal == 1):
|
|
nelemLocal = self.hh.getNelemNative(handleList[i])
|
|
if nelemLocal > 1:
|
|
flagCompound = True
|
|
|
|
status = ICAFE_NORMAL
|
|
|
|
if not cacheFlag:
|
|
|
|
# Need to copy to a vector since
|
|
# Coercion from Python not allowed without the GIL
|
|
with nogil:
|
|
status = self._c_cafe.getV(v, vStatus)
|
|
#print("getCompound", status, vStatus)
|
|
# ca_poll() Not required as above will flush!
|
|
|
|
# Wait for bundle
|
|
|
|
with nogil:
|
|
statusBundle = self._c_cafe.waitForBundledEvents(v, vRB)
|
|
|
|
if (statusBundle != ICAFE_NORMAL):
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
print("Error in def getCompoundList: ")
|
|
self._c_cafe.printStatusMessage(statusBundle)
|
|
|
|
cdef int dtcheck = CAFE_NOT_REQUESTED # native type not yet know
|
|
dtcheck = getMatchedDataType(dt, dtcheck)
|
|
|
|
cdef bytes bytesVal
|
|
localList = []
|
|
|
|
|
|
# Use Scalar
|
|
if not flagCompound:
|
|
|
|
if dtcheck in [CAFE_STRING]:
|
|
|
|
self.vStr.clear()
|
|
self.vStr.reserve(len(handleList))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCacheVStr(v, self.vStr, vStatus)
|
|
|
|
#warning: __pyx_v_i may be used uninitialized in this function
|
|
for i in range(0, len(v)):
|
|
bytesVal = <bytes> (<string> self.vStr[i] )
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(v[i]):
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = <string> self.vStr[i]
|
|
|
|
localList.append(strVal)
|
|
|
|
return localList, status, vStatus
|
|
|
|
elif dtcheck in [CAFE_SHORT, CAFE_CHAR, CAFE_LONG]:
|
|
|
|
self.vInt.clear()
|
|
self.vInt.reserve(len(handleList))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCacheVLong(v, self.vInt, vStatus)
|
|
#print("getCompound", status, vStatus)
|
|
return self.vInt, status, vStatus
|
|
|
|
elif dtcheck in [CAFE_FLOAT, CAFE_DOUBLE]:
|
|
|
|
self.vFloat.clear()
|
|
self.vFloat.reserve(len(handleList))
|
|
|
|
with nogil:
|
|
status = self._c_cafe.getCacheVDouble(
|
|
v, self.vFloat, vStatus)
|
|
|
|
return self.vFloat, status, vStatus
|
|
|
|
|
|
# continue Can be a compound or native
|
|
# Native
|
|
# Create temporary group from handleList
|
|
# Does group exist?
|
|
|
|
cdef PVDataHolder * pvd = self._c_cafe.getPVData(v)
|
|
|
|
# Required to allocate memory for shared pointer
|
|
for i in range(0, <int> v.size()): #len(handleList)):
|
|
pvd[i].setNelem(self.hh.getNelemClient(handleList[i]))
|
|
|
|
statusNoWait = self._c_cafe.getCachePVArrayNoWait(v, pvd)
|
|
|
|
statusList = []
|
|
statusFlag = True
|
|
statusLocal = ICAFE_NORMAL
|
|
|
|
if cacheFlag:
|
|
for i in range(0, <int> v.size()): #len(handleList)):
|
|
statusList.append(pvd[i].getStatus())
|
|
if pvd[i].getStatus() != ICAFE_NORMAL:
|
|
print("Error in Element ", i, " from ", len(
|
|
handleList), " in PyCafe def getCompundList")
|
|
print("Handle= ", handleList[i], " PV=",
|
|
self.hh.getPVFromHandle(handleList[i]))
|
|
print("with error status=", pvd[i].getStatus())
|
|
self._c_cafe.printStatusMessage(pvd[i].getStatus())
|
|
if statusFlag:
|
|
statusLocal = pvd[i].getStatus()
|
|
statusFlag = False
|
|
|
|
cdef unsigned int dtn
|
|
|
|
localList = []
|
|
|
|
|
|
for i in range(0, <int> v.size()): #len(handleList)):
|
|
|
|
dtn = pvd[i].getDataType()
|
|
dtcheck = getMatchedDataType(dt, dtn)
|
|
|
|
if pvd[i].getNelem() == 1:
|
|
if dtcheck == CAFE_STRING:
|
|
bytesVal = <bytes> pvd[i].getAsString()
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(v[i]):
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = pvd[i].getAsString()
|
|
|
|
localList.append(strVal)
|
|
|
|
#localList.append(pvd[i].getAsString())
|
|
elif dtcheck == CAFE_SHORT:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_FLOAT:
|
|
localList.append(pvd[i].getAsDouble())
|
|
elif dtcheck == CAFE_ENUM:
|
|
# if enum, string taken as native
|
|
if self._c_cafe.isEnum(handleList[i]) == 1:
|
|
localList.append(pvd[i].getAsString())
|
|
else:
|
|
localList.append(pvd[i].getAsLong())
|
|
|
|
elif dtcheck == CAFE_CHAR:
|
|
localList.append(< unsigned char > pvd[i].getAsChar())
|
|
elif dtcheck == CAFE_LONG:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_DOUBLE:
|
|
localList.append(pvd[i].getAsDouble())
|
|
else:
|
|
localList.append(0) # no data
|
|
else:
|
|
localListInner = []
|
|
if dtcheck == CAFE_STRING:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
|
|
bytesVal = <bytes> pvd[i].getAsString(j)
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(v[i]):
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = pvd[i].getAsString(j)
|
|
|
|
localListInner.append(strVal)
|
|
#localListInner.append(pvd[i].getAsString(j))
|
|
elif dtcheck == CAFE_SHORT:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_FLOAT:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsDouble(j))
|
|
elif dtcheck == CAFE_ENUM:
|
|
|
|
for j in range(0, pvd[i].getNelem()):
|
|
# if enum, string taken as native
|
|
if self._c_cafe.isEnum(handleList[i]) == 1:
|
|
localListInner.append(pvd[i].getAsString(j))
|
|
else:
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
|
|
elif dtcheck == CAFE_CHAR:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
# <unsigned char> pvd[i].getAsChar(j))
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_LONG:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_DOUBLE:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsDouble(j))
|
|
else:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(0) # no data
|
|
localList.append(localListInner)
|
|
|
|
# free(pvd)
|
|
if cacheFlag:
|
|
return localList, statusLocal, statusList
|
|
# use vstatus instead of statusList (as cache is NoWait)
|
|
return localList, status, vStatus
|
|
|
|
##################################################################################
|
|
# END: def getCompoundList(self, handleList, dt):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getCompoundPVGroup(self, ghandleName, str dt='native'):
|
|
##################################################################################
|
|
cdef str _METHOD = "getCompoundPVGroup(ghandleName, str dt='native')"
|
|
|
|
cdef unsigned int ghandle = 0
|
|
if isinstance(ghandleName, (int, long)):
|
|
ghandle = ghandleName
|
|
elif isinstance(ghandleName, (str)):
|
|
ghandle = self.checkForGroupHandle(ghandleName)
|
|
else:
|
|
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getCompoundPVGroup. \n\
|
|
First input argument, should be of type <class 'int'> if group handle, else <class 'str'> if group name")
|
|
|
|
handleList = []
|
|
handleList = self.getHandlesFromWithinGroup(ghandle)
|
|
|
|
localList = []
|
|
statusList = []
|
|
|
|
cdef vector[unsigned int] hV
|
|
|
|
for i in range(0, len(handleList)):
|
|
hV.push_back(handleList[i])
|
|
|
|
self.hh.setCafeDbrTypeV(hV, DBR_TIME)
|
|
|
|
localList, status, statusList = self.getCompoundList(handleList, dt)
|
|
|
|
cdef PVGroup pvg
|
|
|
|
with nogil:
|
|
self._c_cafe.groupAttach(ghandle, pvg)
|
|
|
|
cdef PVDataHolder * pvd
|
|
pvd = pvg.getPVData()
|
|
|
|
cdef pvdata p1
|
|
|
|
localListToStruct = []
|
|
|
|
cdef int groupStatus = ICAFE_NORMAL
|
|
|
|
for i in range(0, pvg.getNPV()):
|
|
p1 = pvdata()
|
|
|
|
# pvd[i].setDouble(localList[i])
|
|
p1 = PVDataHolderToStruct(pvd[i], dt)
|
|
|
|
if not isinstance(localList[i], (list)):
|
|
ll = []
|
|
ll.append(localList[i])
|
|
p1.value = ll
|
|
else:
|
|
p1.value = localList[i] # put into List!
|
|
|
|
p1.status = statusList[i]
|
|
|
|
if groupStatus == ICAFE_NORMAL:
|
|
groupStatus = statusList[i]
|
|
|
|
aStatSev = []
|
|
aStatSev = self.getAlarmStatusSeverity(handleList[i])
|
|
p1.alarmStatus = aStatSev[0]
|
|
p1.alarmSeverity = aStatSev[1]
|
|
|
|
p1.ts = self.getTimeStamp(handleList[i])
|
|
p1.tsDate = self.getTimeStampAsDate(handleList[i])
|
|
|
|
localListToStruct.append(p1)
|
|
|
|
cdef pvgroup pg
|
|
|
|
pg = pvgroup()
|
|
|
|
pg.pvdata = localListToStruct
|
|
# pg.pvdata[0].showMax(10)
|
|
|
|
pg.npv = pvg.getNPV()
|
|
pg.name = pvg.getNameAsString()
|
|
pg.groupStatus = groupStatus # pvg.getStatusGroup()
|
|
pg.groupHandle = pvg.getGroupHandle()
|
|
|
|
pg.showMax(1)
|
|
|
|
return pg
|
|
|
|
##################################################################################
|
|
# END: def getCompoundPVGroup(self, handleList, dt):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getStrCache(self, handlePV):
|
|
return self.getCache(handlePV, 'str')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getIntCache(self, handlePV):
|
|
return self.getCache(handlePV, 'int')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getFloatCache(self, handlePV):
|
|
return self.getCache(handlePV, 'float')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getCache(self, handlePV, str dt='native'):
|
|
cdef str _METHOD = "getCache(handlePV, str dt='native')"
|
|
|
|
cdef unsigned int handle = 0
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getCache. \n\
|
|
First input argument, should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
|
|
cdef long dtr = 0
|
|
status = self.hh.getDataTypeNative(handle, dtr)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def getCache. Status = %d" % status)
|
|
return None
|
|
|
|
elif dtr in [CAFE_NO_ACCESS, CAFE_TYPENOTCONN]:
|
|
if self._c_cafe.isChannelConnected(handle) is False:
|
|
self._c_cafe.getChannelInfo(handle, self.channelInfo)
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatus(
|
|
handle, self.channelInfo.getCafeConnectionState())
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=self.channelInfo.getCafeConnectionState(),
|
|
_error_text=self.cs.code(
|
|
self.channelInfo.getCafeConnectionState()),
|
|
_error_info=self.cs.info(
|
|
self.channelInfo.getCafeConnectionState()))
|
|
raise _cafeException
|
|
return None
|
|
|
|
# Likely to be superfluous
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatus(handle, ICAFE_TYPENOTCONN)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=ICAFE_TYPENOTCONN,
|
|
_error_text=self.cs.code(ICAFE_TYPENOTCONN),
|
|
_error_info=self.cs.info(ICAFE_TYPENOTCONN))
|
|
raise _cafeException
|
|
return None
|
|
|
|
cdef int dtcheck = dtr
|
|
dtcheck = getMatchedDataType(dt, dtr)
|
|
|
|
cdef bytes bVal
|
|
|
|
if dtcheck in [CAFE_STRING]:
|
|
status = self._c_cafe.getCacheString(handle, self.valStr)
|
|
if status == ICAFE_NORMAL:
|
|
bVal = <bytes> self.valStr
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(handle):
|
|
try:
|
|
strVal = (bVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = self.valStr
|
|
|
|
return strVal
|
|
|
|
|
|
elif dtcheck in [CAFE_SHORT, CAFE_CHAR, CAFE_LONG]:
|
|
status = self._c_cafe.getCacheLong(handle, self.valInt)
|
|
if status == ICAFE_NORMAL:
|
|
return self.valInt
|
|
|
|
elif dtcheck in [CAFE_FLOAT, CAFE_DOUBLE]:
|
|
status = self._c_cafe.getCacheDouble(handle, self.valFloat)
|
|
if status == ICAFE_NORMAL:
|
|
return self.valFloat
|
|
|
|
elif dtcheck == CAFE_ENUM:
|
|
# if enum, string taken as native
|
|
if self._c_cafe.isEnum(handle):
|
|
status = self._c_cafe.getCacheString(handle, self.valStr)
|
|
if status == ICAFE_NORMAL:
|
|
return self.valStr
|
|
else:
|
|
status = self._c_cafe.getCacheLong(handle, self.valInt)
|
|
if status == ICAFE_NORMAL:
|
|
return self.valInt
|
|
|
|
else:
|
|
status = self.hh.getStatus(handle)
|
|
if status == ICAFE_NORMAL:
|
|
print("This line in PyCafe def getCache should never appear!")
|
|
print("Datatype unknown, returning value 0")
|
|
return 0
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getStrArrayCache(self, handlePV, str art='numpy'):
|
|
return self.getArrayCache(handlePV, dt='str', art=art)
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getIntArrayCache(self, handlePV, str art='numpy'):
|
|
return self.getArrayCache(handlePV, dt='int', art=art)
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getFloatArrayCache(self, handlePV, str art='numpy'):
|
|
return self.getArrayCache(handlePV, dt='float', art=art)
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getArrayCache(self, handlePV, str dt='native', str art='numpy'):
|
|
##################################################################################
|
|
# Typed Memoryviews from K.W. Smith
|
|
# Cython has a C-level type the typed memoryview, that conceptually overlaps
|
|
# with the Python memoryiew and expands on it. A typed memory view is used to
|
|
# view (share) data from a buffer-producing object.
|
|
# A typed memoryview has a memory-view like interface and is easier to use than
|
|
# workingwith C-lvevel buffers directly. And because a typed memoryview is designed
|
|
# to work with the buffer protocol it supports any buffer-producing object efficiently
|
|
# allowing sharing of data buffers without copying
|
|
|
|
cdef str _METHOD = "getArrayCache"
|
|
|
|
cdef unsigned int handle = 0
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("{} {} {}".format(self._exception_text, _METHOD,
|
|
"First input argument should be of type <class 'int'> if handle, else <class 'str'> if PV"))
|
|
|
|
cdef:
|
|
dbr_char_t * ui8val
|
|
short * i16val
|
|
int * ival
|
|
double * dval
|
|
float * fval
|
|
dbr_string_t * sval
|
|
cnp.int16_t[::1] mvShort # C-contiguous
|
|
int[::1] mvInt # C-contiguous
|
|
double[::1] mvDouble # C-contiguous
|
|
float[::1] mvFloat # C-contiguous
|
|
# str [:,::1] mvStr
|
|
cnp.ndarray arr
|
|
long dtr = 0
|
|
int status
|
|
unsigned int i
|
|
unsigned int ij
|
|
|
|
status = self.hh.getDataTypeNative(handle, dtr)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
return [None]
|
|
|
|
elif dtr in [CAFE_NO_ACCESS, CAFE_TYPENOTCONN]:
|
|
if self._c_cafe.isChannelConnected(handle) is False:
|
|
self._c_cafe.getChannelInfo(handle, self.channelInfo)
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatus(
|
|
handle, self.channelInfo.getCafeConnectionState())
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=self.channelInfo.getCafeConnectionState(),
|
|
_error_text=self.cs.code(
|
|
self.channelInfo.getCafeConnectionState()),
|
|
_error_info=self.cs.info(
|
|
self.channelInfo.getCafeConnectionState()))
|
|
raise _cafeException
|
|
return [None]
|
|
|
|
# Likely to be superfluous
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatus(handle, ICAFE_TYPENOTCONN)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=ICAFE_TYPENOTCONN,
|
|
_error_text=self.cs.code(ICAFE_TYPENOTCONN),
|
|
_error_info=self.cs.info(ICAFE_TYPENOTCONN))
|
|
raise _cafeException
|
|
return [None]
|
|
|
|
cdef unsigned int nelemToRetrieveFromCache = self.hh.getNelemToRetrieveFromCache(handle)
|
|
|
|
cdef unsigned int dtcheck = dtr
|
|
dtcheck = getMatchedDataType(dt, dtr)
|
|
|
|
# The element type of a typed memoryview may be a numeric scalar type (int, float)
|
|
# It may be a ctypedef alias, or it may be a structured type declared with e.g. cdef struct
|
|
|
|
if dtcheck in [CAFE_STRING, CAFE_ENUM]:
|
|
sval = <char[40]*>malloc(nelemToRetrieveFromCache * sizeof(dbr_string_t))
|
|
|
|
status = self._c_cafe.getCacheDbrStringArray(handle, sval)
|
|
|
|
locallist = []
|
|
|
|
if status == ICAFE_NORMAL:
|
|
|
|
for i in range(0, nelemToRetrieveFromCache):
|
|
|
|
bVal = <bytes> (<string> sval[i])
|
|
encoding = False
|
|
if '.EGU' in self._c_cafe.getPVFromHandle(handle):
|
|
try:
|
|
valStr = (bVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
|
|
if not encoding:
|
|
try:
|
|
valStr = (bVal).decode('utf-8')
|
|
encoded = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
valStr = (bVal).decode('utf-16')
|
|
encoded = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
|
|
if not encoding:
|
|
valStr = sval[i]
|
|
|
|
|
|
locallist.append(valStr) #sval[i])
|
|
|
|
free(sval)
|
|
return locallist
|
|
|
|
''' Not for strings
|
|
if status == ICAFE_NORMAL:
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
mvStr = np.empty(nelemToRetrieveFromCache,
|
|
dtype=(np.str_, 40))
|
|
for i in range(0, nelemToRetrieveFromCache):
|
|
mvStr[i] = str(sval[i])
|
|
free(sval)
|
|
|
|
return mvStr
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
mvStr = np.empty(nelemToRetrieveFromCache,
|
|
dtype=(np.str_, 40), order='C')
|
|
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvStr[ij] = str(sval[ij])
|
|
free(sval)
|
|
|
|
return mvStr
|
|
|
|
elif art in ['array', 'array.array']:
|
|
print(
|
|
"PyCafe.pyx getArray, 'array' type does not support array of strings; returning list")
|
|
# RETURNING LIST - DOES NOT SUPPORT array of strings;
|
|
|
|
arrayArray = []
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
arrayArray.append(str(sval[ij]))
|
|
free(sval)
|
|
return arrayArray
|
|
|
|
elif art in ['ctypes', 'ctype']:
|
|
# c_wchar_p is unicode!
|
|
ctypesArray = (ctypes.c_char_p*nelemToRetrieveFromCache)()
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
ctypesArray[ij] = (sval[ij]).encode('utf-8')
|
|
free(sval)
|
|
return ctypesArray
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvStr = np.empty(nelemToRetrieveFromCache,
|
|
dtype=(np.str_, 40), order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvStr[ij] = <str > sval[ij]
|
|
free(sval)
|
|
|
|
return mvStr
|
|
'''
|
|
elif dtcheck in [CAFE_CHAR]:
|
|
|
|
ui8val = <dbr_char_t * >malloc(nelemToRetrieveFromCache * sizeof(np.uint8))
|
|
|
|
status = self._c_cafe.getCacheCharArray(handle, ui8val)
|
|
|
|
if status == ICAFE_NORMAL:
|
|
# np.empty preferred, else mvInt does not get correct value for first couple of array elements
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
if dt in ['np.short', 'np.int16', 'short', 'int16']:
|
|
mvShort = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.int16, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvShort[ij] = <cnp.int16_t > ui8val[ij]
|
|
free(ui8val)
|
|
return np.array(mvShort)
|
|
|
|
elif dt in ['np.int8', 'np.bool_', 'np.byte', 'bool', 'byte', 'int8']:
|
|
mvInt8 = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.int8, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvInt8[ij] = <cnp.int8_t > ui8val[ij]
|
|
free(ui8val)
|
|
return np.array(mvInt8)
|
|
|
|
elif dt in ['uchar', 'np.uint8', 'uint8']:
|
|
mvUInt8 = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.uint8, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvUInt8[ij] = <cnp.uint8_t > ui8val[ij]
|
|
free(ui8val)
|
|
return np.array(mvUInt8)
|
|
|
|
else:
|
|
|
|
mvUInt8 = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.uint8, order='C')
|
|
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvUInt8[ij] = <cnp.uint8_t > ui8val[ij]
|
|
|
|
free(ui8val)
|
|
|
|
return np.array(mvUInt8)
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
mvShort = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.int16, order='C')
|
|
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvShort[ij] = <short> ui8val[ij]
|
|
free(ui8val)
|
|
|
|
return mvShort
|
|
|
|
elif art in ['array', 'array.array']:
|
|
arrayArray = array.array('h')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
arrayArray.append( <dbr_char_t> ui8val[ij])
|
|
free(ui8val)
|
|
return arrayArray
|
|
|
|
elif art in ['ctypes', 'ctype']:
|
|
ctypesArray = (ctypes.c_int16*nelemToRetrieveFromCache)()
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
ctypesArray[ij] = <short> ui8val[ij]
|
|
free(ui8val)
|
|
return ctypesArray
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvUInt8 = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.uint8, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvUInt8[ij] = <dbr_char_t > ui8val[ij]
|
|
free(ui8val)
|
|
|
|
return mvUInt8
|
|
|
|
|
|
|
|
elif dtcheck in [CAFE_SHORT]:
|
|
|
|
i16val = <short * >malloc(nelemToRetrieveFromCache * sizeof(np.int16))
|
|
|
|
status = self._c_cafe.getCacheShortArray(handle, i16val)
|
|
|
|
if status == ICAFE_NORMAL:
|
|
# np.empty preferred, else mvInt does not get correct value for first couple of array elements
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
if dt in ['np.short', 'np.int16', 'short', 'int16']:
|
|
mvShort = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.int16, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvShort[ij] = <cnp.int16_t > i16val[ij]
|
|
free(i16val)
|
|
return np.array(mvShort)
|
|
|
|
elif dt in ['np.int8', 'np.bool_', 'np.byte', 'bool', 'byte', 'int8']:
|
|
mvInt8 = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.int8, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvInt8[ij] = <cnp.int8_t > i16val[ij]
|
|
free(i16val)
|
|
return np.array(mvInt8)
|
|
|
|
elif dt in ['uchar', 'np.uint8', 'uint8']:
|
|
mvUInt8 = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.uint8, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvUInt8[ij] = <cnp.uint8_t > i16val[ij]
|
|
free(i16val)
|
|
return np.array(mvUInt8)
|
|
|
|
else:
|
|
|
|
mvShort = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.int16, order='C')
|
|
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvShort[ij] = <cnp.int16_t > i16val[ij]
|
|
|
|
free(i16val)
|
|
|
|
return np.array(mvShort) # arr
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
mvShort = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.int16, order='C')
|
|
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvShort[ij] = <short > i16val[ij]
|
|
free(i16val)
|
|
|
|
return mvShort
|
|
|
|
elif art in ['array', 'array.array']:
|
|
arrayArray = array.array('h')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
arrayArray.append( < short > i16val[ij])
|
|
free(i16val)
|
|
return arrayArray
|
|
|
|
elif art in ['ctypes', 'ctype']:
|
|
ctypesArray = (ctypes.c_int16*nelemToRetrieveFromCache)()
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
ctypesArray[ij] = <short > i16val[ij]
|
|
free(i16val)
|
|
return ctypesArray
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvShort = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.int16, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvShort[ij] = <short > i16val[ij]
|
|
free(i16val)
|
|
|
|
return mvShort
|
|
|
|
|
|
|
|
|
|
elif dtcheck in [CAFE_LONG]:
|
|
|
|
ival = <int * >malloc(nelemToRetrieveFromCache * sizeof(np.int32))
|
|
|
|
status = self._c_cafe.getCacheLongArray(handle, ival)
|
|
|
|
if status == ICAFE_NORMAL:
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
mvIntNP = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.int32, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvIntNP[ij] = <cnp.int32_t > ival[ij]
|
|
free(ival)
|
|
return mvIntNP # arr
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
mvInt = np.empty(nelemToRetrieveFromCache,
|
|
dtype=np.int32, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvInt[ij] = <int > ival[ij]
|
|
free(ival)
|
|
return mvInt
|
|
|
|
elif art in ['array', 'array.array']:
|
|
arrayArray = array.array('h')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
arrayArray.append( < int > ival[ij])
|
|
free(ival)
|
|
return arrayArray
|
|
|
|
elif art in ['ctypes', 'ctype']:
|
|
ctypesArray = (ctypes.c_int32*nelemToRetrieveFromCache)()
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
ctypesArray[ij] = <int > ival[ij]
|
|
free(ival)
|
|
return ctypesArray
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvInt = np.empty(nelemToRetrieveFromCache,
|
|
dtype=np.int32, order='C')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvInt[ij] = <int > ival[ij]
|
|
free(ival)
|
|
return mvInt
|
|
|
|
elif dtcheck in [CAFE_FLOAT]:
|
|
|
|
fval = <float * >malloc(nelemToRetrieveFromCache * sizeof(float))
|
|
|
|
status = self._c_cafe.getCacheFloatArray(handle, fval)
|
|
|
|
if status == ICAFE_NORMAL:
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
mvFloatNP = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.float32)
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvFloatNP[ij] = <float > fval[ij] # pvd.getAsFloat(ij)
|
|
|
|
free(fval)
|
|
|
|
return mvFloatNP # arr
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
|
|
# Method A to return memory view
|
|
mvFloat = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.float32)
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvFloat[ij] = <float > fval[ij]
|
|
|
|
free(fval)
|
|
return mvFloat
|
|
|
|
# Method B to return memory view
|
|
'''
|
|
mvDoubleArray=cvarray(shape=(nelemToRetrieveFromCache,), itemsize=sizeof(double), format="d")
|
|
cyarr_view=mvDoubleArray
|
|
for i in range(0, nelemToRetrieveFromCache):
|
|
#mvDoubleArray AVOID COPY TO mvDoubel Array!!
|
|
cyarr_view[i]=dval[i]
|
|
|
|
free(dval)
|
|
return cyarr_view
|
|
'''
|
|
|
|
elif art in ['array', 'array.array']:
|
|
arrayArray = array.array('f')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
arrayArray.append(fval[ij])
|
|
free(fval)
|
|
return arrayArray
|
|
|
|
elif art in ['ctypes', "ctype"]:
|
|
ctypesArray = (ctypes.c_float*nelemToRetrieveFromCache)()
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
ctypesArray[ij] = fval[ij]
|
|
free(fval)
|
|
return ctypesArray
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvFloat = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.float32)
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvFloat[ij] = <float > fval[ij]
|
|
free(fval)
|
|
return mvFloat
|
|
|
|
elif dtcheck in [CAFE_DOUBLE]:
|
|
|
|
dval = <double * >malloc(nelemToRetrieveFromCache * sizeof(double))
|
|
|
|
status = self._c_cafe.getDoubleArray(handle, dval)
|
|
|
|
if status == ICAFE_NORMAL:
|
|
|
|
if art in ['numpy', 'ndarray', 'numpy.ndarray', 'np', 'np.ndarray']:
|
|
|
|
mvDoubleNP = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.float64)
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvDoubleNP[ij] = <double > dval[ij]
|
|
|
|
free(dval)
|
|
return mvDoubleNP # arr
|
|
|
|
elif art in ['memoryview', 'mv', 'memoryviewslice']:
|
|
|
|
# Method A to return memory view
|
|
mvDouble = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.float64)
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvDouble[ij] = <double > dval[ij]
|
|
free(dval)
|
|
return mvDouble
|
|
|
|
elif art in ['array', 'array.array']:
|
|
arrayArray = array.array('d')
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
arrayArray.append(dval[ij])
|
|
free(dval)
|
|
return arrayArray
|
|
|
|
elif art in ['ctypes', "ctype"]:
|
|
ctypesArray = (ctypes.c_double*nelemToRetrieveFromCache)()
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
ctypesArray[ij] = dval[ij]
|
|
free(dval)
|
|
return ctypesArray
|
|
|
|
else:
|
|
print("Unknow array type in user request for art='",
|
|
art, "'. Possible types are:")
|
|
print("memoryview, numpy, array, ctypes")
|
|
print("Returning memoryview")
|
|
mvDouble = np.empty(
|
|
nelemToRetrieveFromCache, dtype=np.float64)
|
|
for ij in range(0, nelemToRetrieveFromCache):
|
|
mvDouble[ij] = <double > dval[ij]
|
|
free(dval)
|
|
return mvDouble
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status,
|
|
_error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
return [None]
|
|
|
|
##################################################################################
|
|
# END: def getArrayCache(self, handlePV, dt):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getPVStrCache(self, handlePV):
|
|
return self.getPVCache(handlePV, 'str')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getPVIntCache(self, handlePV):
|
|
return self.getPVCache(handlePV, 'int')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getPVFloatCache(self, handlePV):
|
|
return self.getPVCache(handlePV, 'float')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getPVCache(self, handlePV, str dt='native'):
|
|
##################################################################################
|
|
|
|
cdef str _METHOD = "getPVCache(handlePV, str dt='native'"
|
|
|
|
cdef unsigned int handle = 0
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getPVCache. \n \
|
|
First input argument, should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
|
|
cdef PVDataHolder pvd
|
|
|
|
pvd.setNelem(self.hh.getNelemToRetrieveFromCache(handle))
|
|
|
|
status = self._c_cafe.getCache(handle, pvd)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
pvd_valnone = PVDataHolderToStruct(pvd, dt)
|
|
# pvd_valnone.value[0]=None
|
|
return pvd_valnone
|
|
|
|
return PVDataHolderToStruct(pvd, dt)
|
|
|
|
##################################################################################
|
|
# END def getPVCache(self, handlePV):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def getCtrl(self, handlePV, str dt='native'):
|
|
##################################################################################
|
|
|
|
cdef str _METHOD = "getCtrl(handlePV, str dt='native')"
|
|
|
|
cdef unsigned int handle = 0
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getCtrl. \n\
|
|
First input argument, should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
|
|
cdef PVCtrlHolder pvc
|
|
|
|
pvc.setNelem(self.hh.getNelemClientCtrl(handle)) # do this dynamically
|
|
|
|
cdef int status
|
|
with nogil:
|
|
status = self._c_cafe.getCtrl(handle, pvc)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
pvc_valnone = PVCtrlHolderToStruct(pvc, dt)
|
|
pvc_valnone.value[0] = None
|
|
return pvc_valnone
|
|
return PVCtrlHolderToStruct(pvc, dt)
|
|
|
|
##################################################################################
|
|
# END: def getCtrl(self, handlePV, dt='native'):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getCtrlCache(self, handlePV, str dt='native'):
|
|
##################################################################################
|
|
cdef str _METHOD = "getCtrlCache(handlePV, str dt='native')"
|
|
cdef unsigned int handle = 0
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getCtrlCache. \n\
|
|
First input argument, should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
|
|
cdef PVCtrlHolder pvc
|
|
|
|
pvc.setNelem(self.hh.getNelemToRetrieveFromCtrlCache(handle))
|
|
|
|
|
|
status = self._c_cafe.getCtrlCache(handle, pvc)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle,
|
|
_pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
pvc_valnone = PVCtrlHolderToStruct(pvc, dt)
|
|
pvc_valnone.value[0] = None
|
|
return pvc_valnone
|
|
|
|
return PVCtrlHolderToStruct(pvc, dt)
|
|
|
|
##################################################################################
|
|
# END: def getCtrlCache(self, handlePV, dt='native'):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def groupMonitorStop(self, ghandleName):
|
|
##################################################################################
|
|
cdef str _METHOD = "groupMonitorStop(ghandleName)"
|
|
|
|
cdef unsigned int ghandle = 0
|
|
if isinstance(ghandleName, (int, long)):
|
|
ghandle = ghandleName
|
|
elif isinstance(ghandleName, (str)):
|
|
ghandle = self.checkForGroupHandle(ghandleName)
|
|
else:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_error_info= ("First input argument, should be of type <class 'int'>"
|
|
"if group handle, else <class 'str'> if group name"))
|
|
raise _cafeException
|
|
|
|
cdef PVGroup pvg
|
|
|
|
with nogil:
|
|
self._c_cafe.groupAttach(ghandle, pvg)
|
|
|
|
cdef vector[int] vStatus
|
|
vStatus.reserve(pvg.getNPV())
|
|
|
|
with nogil:
|
|
status = self._c_cafe.groupMonitorStop(ghandle, vStatus)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
return status, vStatus
|
|
|
|
##################################################################################
|
|
# END: def groupMonitorStop(self, ghandleName):
|
|
##################################################################################
|
|
|
|
def getMonitorPolicyVector(self, handlePV, _monid):
|
|
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV, force=True)
|
|
else:
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def getMonitorPolicyVector \n\
|
|
First input argument, should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
|
|
cdef vector[MonitorPolicy] mpV
|
|
|
|
self.hh.getMonitorPolicyVector(handle, mpV)
|
|
|
|
cdef monitorpolicy mp
|
|
|
|
mp = monitorpolicy()
|
|
|
|
cdef unsigned int i
|
|
|
|
for i in range(0, mpV.size()):
|
|
|
|
if mpV[i].getMonitorID() == _monid:
|
|
|
|
mp.monid = mpV[i].getMonitorID()
|
|
|
|
mp.nelem = mpV[i].getNelem()
|
|
|
|
mp.dataType = mpV[i].getDataType()
|
|
mp.userArgs = <long > mpV[i].getUserArgs()
|
|
mp.dbrDataType = mpV[i].getDbrDataType()
|
|
mp.cafeDbrType = mpV[i].getCafeDbrType()
|
|
mp.mask = mpV[i].getMask()
|
|
mp.maskHasDBE_PROPERTY = mpV[i].maskHasDBE_PROPERTY()
|
|
mp.maskHasDBE_VALUE = mpV[i].maskHasDBE_VALUE()
|
|
mp.maskHasDBE_LOG = mpV[i].maskHasDBE_LOG()
|
|
mp.maskHasDBE_ALARM = mpV[i].maskHasDBE_ALARM()
|
|
break
|
|
|
|
return mp
|
|
|
|
def groupMonitor(self, ghandleName, object cb=None, DBR_TYPE dbr=DBR_TIME,
|
|
unsigned int mask=DBE_VALUE | DBE_LOG | DBE_ALARM,
|
|
unsigned short notify_milliseconds=0):
|
|
return self.groupMonitorStart(ghandleName, cb, dbr, mask, notify_milliseconds)
|
|
|
|
##################################################################################
|
|
def groupMonitorStart(self, ghandleName, object cb=None,
|
|
DBR_TYPE dbr=DBR_TIME,
|
|
unsigned int mask=DBE_VALUE | DBE_LOG | DBE_ALARM,
|
|
unsigned short notify_milliseconds=0):
|
|
##################################################################################
|
|
cdef str _METHOD = "groupMonitorStart(ghandleName, cb, dbr, mask)"
|
|
|
|
cdef unsigned int ghandle = 0
|
|
if isinstance(ghandleName, (int, long)):
|
|
ghandle = ghandleName
|
|
elif isinstance(ghandleName, (str)):
|
|
ghandle = self.checkForGroupHandle(ghandleName)
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if group handle, else <class 'str'> if group name")
|
|
raise _cafeException
|
|
|
|
if dbr:
|
|
if dbr not in [DBR_PLAIN, DBR_STS, DBR_TIME, DBR_GR, DBR_CTRL]:
|
|
print(
|
|
"***Warning*** from groupMonitorStart for handle(orPV)=", ghandleName)
|
|
print(
|
|
"dbr base type should be one of DBR_PLAIN, DBR_STS, DBR_TIME, DBR_GR, DBR_CTRL")
|
|
print("Assuming DBR_TIME")
|
|
dbr = DBR_TIME
|
|
|
|
cdef vector[MonitorPolicy] mpV
|
|
cdef unsigned long mpid
|
|
|
|
cdef PVGroup pvg
|
|
|
|
with nogil:
|
|
self._c_cafe.groupAttach(ghandle, pvg)
|
|
|
|
cdef MonitorPolicy * mp
|
|
mp = self._c_cafe.createMonitorPolicyArray(pvg.getNPV())
|
|
|
|
handleList = []
|
|
handleList = self.getHandlesFromWithinGroup(ghandle)
|
|
|
|
#cb_list = [cb] * pvg.getNPV()
|
|
|
|
for i in range(0, pvg.getNPV()):
|
|
|
|
mp[i].setMask(mask)
|
|
mp[i].setCafeDbrType(dbr)
|
|
mp[i].setNotifyDeltaMilliSeconds(notify_milliseconds)
|
|
mpid = mp[i].getMonitorID()
|
|
|
|
if cb:
|
|
sig = inspect.signature(cb)
|
|
# a=inspect.getargspec(cb)
|
|
|
|
mp[i].setUserArgs(< void * > mpid)
|
|
mp[i].setNoCyCallbackParameters(len(sig.parameters))
|
|
mp[i].setPyCyHandler(<void *> cb) #cb_list[i])
|
|
|
|
#print('============//1//')
|
|
#print('SIGNATURE:')
|
|
#print(str(sig))
|
|
#for param in sig.parameters.values():
|
|
# print('Parameter:', param)
|
|
#print('len1', len(sig.parameters.values()))
|
|
#print('len2', len(sig.parameters))
|
|
#print('monitor id', mpid)
|
|
|
|
mpV.push_back(mp[i])
|
|
|
|
cdef vector[int] vStatus
|
|
vStatus.reserve(pvg.getNPV())
|
|
|
|
with nogil:
|
|
status = self._c_cafe.groupMonitorStart(ghandle, vStatus, mpV)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
return status, vStatus
|
|
|
|
##################################################################################
|
|
|
|
############################################################################
|
|
|
|
def groupMonitorStartWithCBList(self,
|
|
ghandleName, list cb=None,
|
|
DBR_TYPE dbr=DBR_TIME,
|
|
unsigned int mask=\
|
|
DBE_VALUE | DBE_LOG | DBE_ALARM,
|
|
unsigned short notify_milliseconds=0):
|
|
############################################################################
|
|
cdef str _METHOD = ("groupMonitorStartWithCBList(ghandleName, cb," +
|
|
"dbr, mask, notify_milliseconds)")
|
|
|
|
cdef unsigned int ghandle = 0
|
|
if isinstance(ghandleName, (int, long)):
|
|
ghandle = ghandleName
|
|
elif isinstance(ghandleName, (str)):
|
|
ghandle = self.checkForGroupHandle(ghandleName)
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if group handle, else <class 'str'> if group name")
|
|
raise _cafeException
|
|
|
|
if dbr:
|
|
if dbr not in [DBR_PLAIN, DBR_STS, DBR_TIME, DBR_GR, DBR_CTRL]:
|
|
print(
|
|
"***Warning*** from groupMonitorStartWithCBList for handle(orPV)=", ghandleName)
|
|
print(
|
|
"dbr base type should be one of DBR_PLAIN, DBR_STS, DBR_TIME, DBR_GR, DBR_CTRL")
|
|
print("Assuming DBR_TIME")
|
|
dbr = DBR_TIME
|
|
|
|
if not isinstance(cb, (list)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def groupMonitorStartWithCBList. \n\
|
|
Input cb should be of type<list> and give the list of cb objects")
|
|
|
|
cdef vector[MonitorPolicy] mpV
|
|
cdef unsigned long mpid
|
|
# cdef void *ptr_mpid
|
|
|
|
cdef PVGroup pvg
|
|
|
|
with nogil:
|
|
self._c_cafe.groupAttach(ghandle, pvg)
|
|
|
|
if (len(cb) != pvg.getNPV()):
|
|
print("No of group members is ", pvg.getNPV(),
|
|
" while list of callback objects is", len(cb))
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def groupMonitorStartWithCBList. \n\
|
|
No of group members doe not match the length of callback object list")
|
|
|
|
cdef MonitorPolicy * mp
|
|
mp = self._c_cafe.createMonitorPolicyArray(pvg.getNPV())
|
|
|
|
handleList = []
|
|
handleList = self.getHandlesFromWithinGroup(ghandle)
|
|
|
|
for i in range(0, pvg.getNPV()):
|
|
|
|
mp[i].setMask(mask)
|
|
mp[i].setCafeDbrType(dbr)
|
|
mp[i].setNotifyDeltaMilliSeconds(notify_milliseconds)
|
|
|
|
mpid = mp[i].getMonitorID()
|
|
# pyobj = <unsigned int> mpid
|
|
# ptr_mpid = <void *> &pyobj
|
|
|
|
# For setUserArgs pass the address of the variable.
|
|
if cb[i]:
|
|
sig = inspect.signature(cb[i])
|
|
mp[i].setUserArgs(< void * > mpid) # (<unsigned long *> ptr_mpid)[0])
|
|
mp[i].setNoCyCallbackParameters(len(sig.parameters))
|
|
mp[i].setPyCyHandler(<void *> cb[i])
|
|
|
|
#print('============')
|
|
#print('SIGNATURE//2//:')
|
|
#print(str(sig))
|
|
#for param in sig.parameters.values():
|
|
# print('Parameter:', param)
|
|
#print('len1', len(sig.parameters.values()))
|
|
#print('len2', len(sig.parameters))
|
|
#print('monitorid', mpid) # (<unsigned int *> ptr_mpid)[0])
|
|
|
|
|
|
mpV.push_back(mp[i])
|
|
|
|
cdef vector[int] vStatus
|
|
vStatus.reserve(pvg.getNPV())
|
|
|
|
with nogil:
|
|
status = self._c_cafe.groupMonitorStart(ghandle, vStatus, mpV)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
return status, vStatus
|
|
|
|
##################################################################################
|
|
def getHandleFromPVWithinGroup(self, str pv, ghandleName):
|
|
cdef str _METHOD = "getHandleFromPVWithinGroup(pv. ghandleName)"
|
|
if isinstance(ghandleName, (int, long)):
|
|
ghandle = ghandleName
|
|
elif isinstance(ghandleName, (str)):
|
|
ghandle = self.hh.getGroupHandleFromGroupName(ghandleName)
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if group handle, else <class 'str'> if group name")
|
|
raise _cafeException
|
|
return self.hh.getHandleFromPVWithinGroup(pv, ghandle)
|
|
|
|
##################################################################################
|
|
|
|
def getGroupStr(self, ghandleName):
|
|
return self.getGroup(ghandleName, 'str')
|
|
|
|
def getGroupInt(self, ghandleName):
|
|
return self.getGroup(ghandleName, 'int')
|
|
|
|
def getGroupFloat(self, ghandleName):
|
|
return self.getGroup(ghandleName, 'float')
|
|
|
|
##################################################################################
|
|
def getGroup(self, ghandleName, str dt='native'):
|
|
cdef str _METHOD = "getGroup(ghandleName, str dt='native')"
|
|
cdef unsigned int ghandle = 0
|
|
if isinstance(ghandleName, (int, long)):
|
|
ghandle = ghandleName
|
|
elif isinstance(ghandleName, (str)):
|
|
ghandle = self.checkForGroupHandle(ghandleName)
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if group handle, else <class 'str'> if group name")
|
|
raise _cafeException
|
|
|
|
cdef PVGroup pvg
|
|
|
|
with nogil:
|
|
self._c_cafe.groupAttach(ghandle, pvg)
|
|
|
|
cdef PVDataHolder * pvd
|
|
pvd = pvg.getPVData()
|
|
for i in range(0, pvg.getNPV()):
|
|
pvd[i].setHasAlarm(False)
|
|
pvd[i].setHasTS(False)
|
|
# pvd[i].setRule(False)
|
|
|
|
pvg.setPVData(pvd)
|
|
# pvd=pvg.getPVData();
|
|
# print "get rule 0p", pvd[0].getRule()
|
|
# print "get rule 1p", pvd[1].getRule()
|
|
# print "get rule 2p", pvd[2].getRule()
|
|
##
|
|
|
|
with nogil:
|
|
status = self._c_cafe.groupGet(ghandle, pvg)
|
|
|
|
if status == ECA_TIMEOUT:
|
|
print("======================================================")
|
|
self._c_cafe.printStatusMessage(status)
|
|
print("TIMEOUT in getGroup; switching to getCompoundList")
|
|
print("======================================================")
|
|
return self.getCompoundList(pvg.getNameAsString(), dt)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
# do not raise exception
|
|
#raise Exception("EXCEPTION RAISED in PyCafe def getGroup. Status = %d" %status)
|
|
# pvg.showMaxMax(5,10)
|
|
|
|
pvd = pvg.getPVData()
|
|
|
|
localList = []
|
|
statusList = []
|
|
cdef unsigned int dtn, dtcheck
|
|
cdef bytes bytesVal
|
|
|
|
for i in range(0, pvg.getNPV()):
|
|
dtn = pvd[i].getDataType()
|
|
|
|
dtcheck = getMatchedDataType(dt, dtn)
|
|
|
|
statusList.append(pvd[i].getStatus())
|
|
|
|
if pvd[i].getNelem() == 1:
|
|
if dtcheck == CAFE_STRING:
|
|
|
|
bytesVal = <bytes> pvd[i].getAsString()
|
|
encoding = False
|
|
if '.EGU' in pvd[i].getPVName():
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf_8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf_16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = pvd[i].getAsString()
|
|
|
|
localList.append(strVal) #pvd[i].getAsString())
|
|
elif dtcheck == CAFE_SHORT:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_FLOAT:
|
|
localList.append(pvd[i].getAsDouble())
|
|
elif dtcheck == CAFE_ENUM:
|
|
# if enum, string taken as native
|
|
|
|
if self._c_cafe.isEnum(self.hh.getHandleFromPVWithinGroup(pvd[i].getPVName(), ghandle)):
|
|
localList.append(pvd[i].getAsString())
|
|
else:
|
|
localList.append(pvd[i].getAsLong())
|
|
|
|
elif dtcheck == CAFE_CHAR:
|
|
localList.append(< unsigned char > pvd[i].getAsChar())
|
|
elif dtcheck == CAFE_LONG:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_DOUBLE:
|
|
localList.append(pvd[i].getAsDouble())
|
|
else:
|
|
localList.append(None) # no data
|
|
else:
|
|
localListInner = []
|
|
if dtcheck == CAFE_STRING:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
|
|
bytesVal = <bytes> pvd[i].getAsString(j)
|
|
encoding = False
|
|
if '.EGU' in pvd[i].getPVName():
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = pvd[i].getAsString(j)
|
|
|
|
localListInner.append(strVal) #pvd[i].getAsString(j))
|
|
|
|
elif dtcheck == CAFE_SHORT:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_FLOAT:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsDouble(j))
|
|
elif dtcheck == CAFE_ENUM:
|
|
|
|
for j in range(0, pvd[i].getNelem()):
|
|
# if enum, string taken as native
|
|
if self._c_cafe.isEnum(self.hh.getHandleFromPVWithinGroup(pvd[i].getPVName(), ghandle)):
|
|
localListInner.append(pvd[i].getAsString(j))
|
|
else:
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
|
|
elif dtcheck == CAFE_CHAR:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
# <unsigned char> pvd[i].getAsChar(j))
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_LONG:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_DOUBLE:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsDouble(j))
|
|
else:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(None) # no data
|
|
localList.append(localListInner)
|
|
|
|
return localList, status, statusList
|
|
|
|
##################################################################################
|
|
# END: def getGroup(self, ghandleName, dt='native'):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getGroupCache(self, ghandleName, str dt='native'):
|
|
cdef str _METHOD = "getGroupCache(self, ghandleName, str dt='native')"
|
|
cdef unsigned int ghandle = 0
|
|
if isinstance(ghandleName, (int, long)):
|
|
ghandle = ghandleName
|
|
elif isinstance(ghandleName, (str)):
|
|
ghandle = self.checkForGroupHandle(ghandleName)
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if group handle, else <class 'str'> if group name")
|
|
raise _cafeException
|
|
|
|
cdef PVGroup pvg
|
|
|
|
with nogil:
|
|
self._c_cafe.groupAttach(ghandle, pvg)
|
|
|
|
cdef PVDataHolder * pvd
|
|
|
|
with nogil:
|
|
status = self._c_cafe.groupGetCache(ghandle, pvg)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
# do not raise exception
|
|
#raise Exception("EXCEPTION RAISED in PyCafe def getGroup. Status = %d" %status)
|
|
|
|
pvd = pvg.getPVData()
|
|
|
|
localList = []
|
|
statusList = []
|
|
cdef unsigned int dtn, dtcheck
|
|
cdef bytesVal
|
|
|
|
for i in range(0, pvg.getNPV()):
|
|
dtn = pvd[i].getDataType()
|
|
|
|
dtcheck = getMatchedDataType(dt, dtn)
|
|
|
|
statusList.append(pvd[i].getStatus())
|
|
|
|
if pvd[i].getNelem() == 1:
|
|
if dtcheck == CAFE_STRING:
|
|
|
|
bytesVal = <bytes> pvd[i].getAsString()
|
|
encoding = False
|
|
if '.EGU' in pvd[i].getPVName():
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf_8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf_16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = pvd[i].getAsString()
|
|
|
|
localList.append(strVal) #pvd[i].getAsString())
|
|
elif dtcheck == CAFE_SHORT:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_FLOAT:
|
|
localList.append(pvd[i].getAsDouble())
|
|
elif dtcheck == CAFE_ENUM:
|
|
# if enum, string taken as native
|
|
|
|
if self._c_cafe.isEnum(self.hh.getHandleFromPVWithinGroup(pvd[i].getPVName(), ghandle)):
|
|
localList.append(pvd[i].getAsString())
|
|
else:
|
|
localList.append(pvd[i].getAsLong())
|
|
|
|
elif dtcheck == CAFE_CHAR:
|
|
localList.append(< unsigned char > pvd[i].getAsChar())
|
|
elif dtcheck == CAFE_LONG:
|
|
localList.append(pvd[i].getAsLong())
|
|
elif dtcheck == CAFE_DOUBLE:
|
|
localList.append(pvd[i].getAsDouble())
|
|
else:
|
|
localList.append(None) # no data
|
|
else:
|
|
localListInner = []
|
|
if dtcheck == CAFE_STRING:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
|
|
bytesVal = <bytes> pvd[i].getAsString(j)
|
|
encoding = False
|
|
if '.EGU' in pvd[i].getPVName():
|
|
try:
|
|
strVal = (bytesVal).decode('latin-1')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
strVal = (bytesVal).decode('utf-16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
strVal = pvd[i].getAsString(j)
|
|
|
|
localListInner.append(strVal) #pvd[i].getAsString(j))
|
|
elif dtcheck == CAFE_SHORT:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_FLOAT:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsDouble(j))
|
|
elif dtcheck == CAFE_ENUM:
|
|
|
|
for j in range(0, pvd[i].getNelem()):
|
|
# if enum, string taken as native
|
|
if self._c_cafe.isEnum(self.hh.getHandleFromPVWithinGroup(pvd[i].getPVName(), ghandle)):
|
|
localListInner.append(pvd[i].getAsString(j))
|
|
else:
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
|
|
elif dtcheck == CAFE_CHAR:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
# <unsigned char> pvd[i].getAsChar(j))
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_LONG:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsLong(j))
|
|
elif dtcheck == CAFE_DOUBLE:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(pvd[i].getAsDouble(j))
|
|
else:
|
|
for j in range(0, pvd[i].getNelem()):
|
|
localListInner.append(None) # no data
|
|
localList.append(localListInner)
|
|
|
|
return localList, status, statusList
|
|
|
|
##################################################################################
|
|
# END: def getGroup(self, ghandleName, dt='native'):
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getPVGroupStr(self, ghandleName):
|
|
return self.getPVGroup(ghandleName, dt='str')
|
|
|
|
def getPVGroupInt(self, ghandleName):
|
|
return self.getPVGroup(ghandleName, dt='int')
|
|
|
|
def getPVGroupFloat(self, ghandleName):
|
|
return self.getPVGroup(ghandleName, dt='float')
|
|
|
|
##################################################################################
|
|
def getPVGroup(self, ghandleName, str dt='native'):
|
|
cdef str _METHOD = "getPVGroup(ghandleName, str dt='native')"
|
|
|
|
cdef unsigned int ghandle = 0
|
|
if isinstance(ghandleName, (int, long)):
|
|
ghandle = ghandleName
|
|
elif isinstance(ghandleName, (str)):
|
|
ghandle = self.checkForGroupHandle(ghandleName)
|
|
# elif isinstance(ghandleName, (pvgroup)) == 1:
|
|
# print ("We have a PV Group ", type(ghandleName) )
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if group handle, else <class 'str'> if group name")
|
|
raise _cafeException
|
|
|
|
cdef PVGroup pvg
|
|
cdef PVDataHolder * pvd
|
|
cdef int status
|
|
|
|
with nogil:
|
|
self._c_cafe.groupAttach(ghandle, pvg)
|
|
|
|
pvd = pvg.getPVData()
|
|
|
|
'''
|
|
for i in range (0, pvg.getNPV()):
|
|
pvd[i].setHasAlarm(True)
|
|
pvd[i].setHasTS(True)
|
|
#pvd[i].setRule(True)
|
|
|
|
pvg.setPVData(pvd)
|
|
'''
|
|
|
|
with nogil:
|
|
status = self._c_cafe.groupGet(ghandle, pvg)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
print("Error in PyCafe def getPVGroup. Status = %d" % status)
|
|
self._c_cafe.printStatusMessage(status)
|
|
# do not raise exception
|
|
#raise Exception("EXCEPTION RAISED in PyCafe def getPVGroup. Status = %d" %status)
|
|
|
|
if status == ECA_TIMEOUT:
|
|
print("======================================================")
|
|
print("TIMEOUT in getGroup; swithing to getCompoundPVGroup")
|
|
print("======================================================")
|
|
return self.getCompoundPVGroup(ghandle, dt)
|
|
|
|
pvd = pvg.getPVData()
|
|
|
|
localList = []
|
|
|
|
for i in range(0, pvg.getNPV()):
|
|
#print(pvd[i].getAsString(0), " " , pvd[i].getStatus())
|
|
#print(pvd[i].getEpicsTimeStampAsUInt32().secPastEpoch, " ", pvd[i].getEpicsTimeStampAsUInt32().nsec)
|
|
localList.append(PVDataHolderToStruct(pvd[i], dt))
|
|
cdef pvgroup pg
|
|
|
|
pg = pvgroup()
|
|
|
|
pg.pvdata = localList
|
|
|
|
pg.npv = pvg.getNPV()
|
|
pg.name = pvg.getNameAsString()
|
|
pg.groupStatus = pvg.getStatusGroup()
|
|
pg.groupHandle = pvg.getGroupHandle()
|
|
|
|
# pg.showMax(1)
|
|
|
|
return pg # localList, status
|
|
##################################################################################
|
|
# END: def getPVGroup(self, ghandleName, str dt='native')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def getPVGroupCache(self, ghandleName, str dt='native'):
|
|
cdef str _METHOD = "getPVGroupCache"
|
|
|
|
cdef unsigned int ghandle = 0
|
|
if isinstance(ghandleName, (int, long)):
|
|
ghandle = ghandleName
|
|
elif isinstance(ghandleName, (str)):
|
|
ghandle = self.checkForGroupHandle(ghandleName)
|
|
# elif isinstance(ghandleName, (pvgroup)) == 1:
|
|
# print ("We have a PV Group ", type(ghandleName) )
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if group handle, else <class 'str'> if group name")
|
|
raise _cafeException
|
|
|
|
cdef PVGroup pvg
|
|
cdef PVDataHolder * pvd
|
|
cdef int status
|
|
|
|
with nogil:
|
|
self._c_cafe.groupAttach(ghandle, pvg)
|
|
print("==============" )
|
|
print(_METHOD)
|
|
pvg.showMax(1)
|
|
|
|
pvd = pvg.getPVData()
|
|
|
|
status = self._c_cafe.groupGetCache(ghandle, pvg)
|
|
pvg.showMax(1)
|
|
print("==============" )
|
|
print(status, pvg.getStatusGroup())
|
|
print("==============" )
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
print("Error in PyCafe def getPVGroupCache. Status = %d" % status)
|
|
self._c_cafe.printStatusMessage(status)
|
|
# do not raise exception
|
|
#raise Exception("EXCEPTION RAISED in PyCafe def getPVGroup. Status = %d" %status)
|
|
|
|
pvd = pvg.getPVData()
|
|
|
|
localList = []
|
|
|
|
for i in range(0, pvg.getNPV()):
|
|
#print(pvd[i].getAsString(0), " " , pvd[i].getStatus())
|
|
#print(pvd[i].getEpicsTimeStampAsUInt32().secPastEpoch, " ", pvd[i].getEpicsTimeStampAsUInt32().nsec)
|
|
localList.append(PVDataHolderToStruct(pvd[i], dt))
|
|
cdef pvgroup pg
|
|
|
|
pg = pvgroup()
|
|
|
|
pg.pvdata = localList
|
|
|
|
pg.npv = pvg.getNPV()
|
|
pg.name = pvg.getNameAsString()
|
|
pg.groupStatus = pvg.getStatusGroup()
|
|
pg.groupHandle = pvg.getGroupHandle()
|
|
|
|
return pg
|
|
##################################################################################
|
|
# END: def getPVGroup(self, ghandleName, str dt='native')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def PVGroupValuesToList(self, pvgroup pg):
|
|
glist = []
|
|
for i in range(0, pg.npv):
|
|
if len(pg.pvdata[i].value) == 1:
|
|
glist.append(pg.pvdata[i].value[0])
|
|
else:
|
|
iL = []
|
|
for j in range(0, len(pg.pvdata[i].value)):
|
|
iL.append(pg.pvdata[i].value[j])
|
|
glist.append(iL)
|
|
return glist
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def groupMemberList(self, str gname):
|
|
cdef str _METHOD = "groupMemberList(self, str gname)"
|
|
cdef vector[string] pvlist
|
|
status = self._c_cafe.groupMemberList(gname, pvlist)
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
return pvlist
|
|
|
|
##################################################################################
|
|
|
|
def grouping(self, char * gname, list _pvlist):
|
|
cdef str _METHOD = "grouping(char * gname, list _pvlist)"
|
|
|
|
cdef int status = self._c_cafe.groupDefine(gname, _pvlist)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
cdef unsigned int ghandle = 0
|
|
cdef char * _gname = gname
|
|
|
|
try:
|
|
IF PY_EXT_C:
|
|
with nogil:
|
|
status = self._c_cafe.groupOpen(_gname, ghandle)
|
|
ELSE:
|
|
#Gil acquired and released within conduit.h
|
|
#with nogil:
|
|
status = self._c_cafe.groupOpen(_gname, ghandle)
|
|
except:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=ghandle,
|
|
_pv_name=_gname,
|
|
_error_code=ECA_ALLOCMEM, _error_text=self.cs.code(ECA_ALLOCMEM),
|
|
_error_info=self.cs.info(ECA_ALLOCMEM))
|
|
raise _cafeException
|
|
|
|
if status != ICAFE_NORMAL:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=ghandle,
|
|
_pv_name=_gname,
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
# cdef PVGroup pvg
|
|
#self._c_cafe.groupAttach(ghandle, pvg);
|
|
|
|
cdef:
|
|
list localList
|
|
list statusList
|
|
|
|
cdef short wtfsb = self._c_cafe.channelOpenGroupPolicy.getWhenToFlushSendBuffer()
|
|
|
|
if wtfsb == FLUSH_NOW:
|
|
|
|
localList, status, statusList = self.getGroup(ghandle)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
print("")
|
|
print("Error in def grouping for group named", _gname)
|
|
self._c_cafe.printStatusMessage(status)
|
|
print("Analysing statusList[]...")
|
|
for i in range(0, len(statusList)):
|
|
if statusList[i] != ICAFE_NORMAL:
|
|
print("PV", _pvlist[i],
|
|
"[", i, "]", " has error: ")
|
|
self._c_cafe.printStatusMessage(statusList[i])
|
|
print("")
|
|
return ghandle
|
|
|
|
|
|
##################################################################################
|
|
def groupDefineFromCollection(self, const char * gname, const char * cname, attrib):
|
|
cdef str _METHOD = "groupDefineFromCollection"
|
|
cdef list _attribute_list
|
|
if isinstance(attrib, str):
|
|
_attribute_list = [attrib]
|
|
elif isinstance(attrib, list):
|
|
_attribute_list = attrib
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info=("Third input argument, should be of type <class 'str'> "
|
|
"else <class 'list'> of <class 'str'>"))
|
|
raise _cafeException
|
|
|
|
status = self._c_cafe.groupDefineFromCollection(gname, cname, _attribute_list)
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
return status
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def groupDefine(self, char * gname, list _pvlist):
|
|
status = self._c_cafe.groupDefine(gname, _pvlist)
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
return status
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def defineGroup(self, char * gname, list _pvlist):
|
|
status = self._c_cafe.groupDefine(gname, _pvlist)
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
return status
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def groupOpen(self, char * gname):
|
|
cdef str _METHOD = "groupOpen(char * gname)"
|
|
|
|
if not isinstance(gname, (str)) :
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument should be <class 'str'> for group name")
|
|
raise _cafeException
|
|
|
|
cdef unsigned int ghandle = 0
|
|
cdef char * _gname = gname
|
|
|
|
try:
|
|
IF PY_EXT_C:
|
|
with nogil:
|
|
status = self._c_cafe.groupOpen(_gname, ghandle)
|
|
ELSE:
|
|
#gil acquired and released in conduit.h at import
|
|
#with nogil:
|
|
status = self._c_cafe.groupOpen(_gname, ghandle)
|
|
|
|
except:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD, _handle=ghandle, _pv_name=_gname,
|
|
_error_code=ECA_ALLOCMEM, _error_text=self.cs.code(ECA_ALLOCMEM), _error_info=self.cs.info(ECA_ALLOCMEM))
|
|
raise _cafeException
|
|
|
|
if status != ICAFE_NORMAL:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD, _handle=ghandle, _pv_name=_gname,
|
|
_error_code=status, _error_text=self.cs.code(status), _error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
return ghandle
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def groupClose(self, gHandleName, bint keepGroupName=False):
|
|
cdef str _METHOD = "groupClose(gHandleName)"
|
|
|
|
cdef unsigned int gHandle = 0
|
|
cdef str _gname = None
|
|
status = ICAFE_NORMAL
|
|
|
|
if isinstance(gHandleName, (int, long)):
|
|
gHandle = gHandleName
|
|
elif isinstance(gHandleName, (str)):
|
|
_gname = gHandleName
|
|
gHandle = self.checkForGroupHandle(gHandleName)
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if group handle, else <class 'str'> if group name")
|
|
raise _cafeException
|
|
|
|
if gHandle == 0:
|
|
status = ECAFE_INVALID_GROUP_HANDLE
|
|
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD, _handle=gHandle, _pv_name=_gname,
|
|
_error_code=status, _error_text=self.cs.code(status), _error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
|
|
with nogil:
|
|
status = self._c_cafe.groupCloseKeepName(gHandle, keepGroupName)
|
|
#self.ca_pend_io(1.0)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD, _handle=gHandle, _pv_name=_gname,
|
|
_error_code=status, _error_text=self.cs.code(status), _error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
return status
|
|
##################################################################################
|
|
|
|
|
|
def isGroup(self, const char * gName):
|
|
return self._c_cafe.isGroup(gName)
|
|
|
|
def isCollection(self, const char * cName):
|
|
return self._c_cafe.isCollection(cName)
|
|
|
|
|
|
##################################################################################
|
|
@verify_handlepv
|
|
def getNoMonitors(self, handlePV):
|
|
cdef unsigned int handle = handlePV
|
|
return self.hh.getNmonitor(handle)
|
|
##################################################################################
|
|
|
|
|
|
##################################################################################
|
|
@verify_handlepv
|
|
def getMonitorIDsInWaiting(self, handlePV):
|
|
cdef unsigned int handle = handlePV
|
|
return self.hh.getMonitorIDsInWaiting(handle)
|
|
############################################################################
|
|
|
|
|
|
##################################################################################
|
|
@verify_handlepv
|
|
def getMonitorIDs(self, handlePV):
|
|
cdef unsigned int handle = handlePV
|
|
return self.hh.getMonitorIDs(handle)
|
|
############################################################################
|
|
|
|
@verify_handlepv
|
|
def updateMonitorPolicyDeltaMS(
|
|
self, handlePV, unsigned int monid=0, unsigned int deltaMS=0):
|
|
cdef unsigned int handle = handlePV
|
|
self.hh.updateMonitorPolicyDeltaMS(handle, monid, deltaMS)
|
|
|
|
|
|
|
|
############################################################################
|
|
def monitor(
|
|
self, handlePV, object cb=None, DBR_TYPE dbr=DBR_TIME,
|
|
unsigned int mask=DBE_VALUE | DBE_LOG | DBE_ALARM,
|
|
unsigned short notify_milliseconds=0):
|
|
|
|
return self.monitorStart(handlePV, cb, dbr, mask, notify_milliseconds)
|
|
|
|
############################################################################
|
|
def monitorStart(
|
|
self, handlePV, cb: object = None, DBR_TYPE dbr=DBR_TIME,
|
|
unsigned int mask=DBE_VALUE | DBE_LOG | DBE_ALARM,
|
|
unsigned int nelem=0,
|
|
unsigned short notify_milliseconds=0):
|
|
|
|
_METHOD = "monitorStart(handlePV, object cb=None, \
|
|
DBR_TYPE dbr=DBR_TIME, \
|
|
unsigned int mask=DBE_VALUE|DBE_LOG|DBE_ALARM)"
|
|
|
|
pv = None
|
|
cdef int status = ICAFE_NORMAL
|
|
|
|
# cdef pCallback my_callback
|
|
# my_callback=<pCallback>callbackHandlerMonitor
|
|
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
pv = handlePV
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV")
|
|
raise _cafeException
|
|
|
|
# Does channel Exist?
|
|
if not self._c_cafe.isValid(handle):
|
|
status = ECAFE_INVALID_HANDLE
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _handle=handle, _pv_name=pv,
|
|
_error_code=status, _error_text=self.cs.code(status),
|
|
_error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
return status
|
|
|
|
cdef MonitorPolicy mp
|
|
cdef unsigned long mpid = mp.getMonitorID()
|
|
|
|
# For setUserArgs pass the address of the variable.
|
|
|
|
#Default is native number
|
|
if nelem:
|
|
mp.setNelem(nelem)
|
|
|
|
mp.setMask(mask)
|
|
mp.setNotifyDeltaMilliSeconds(notify_milliseconds)
|
|
|
|
#print ("dbr=", dbr)
|
|
self._c_cafe.getChannelInfo(handle, self.channelInfo)
|
|
#print ("nativeDataType=", self.channelInfo.getDataType())
|
|
|
|
if dbr in [DBR_PLAIN, DBR_STS, DBR_TIME, DBR_GR, DBR_CTRL]:
|
|
# set Native Datatype first
|
|
mp.setDataType(self.channelInfo.getDataType())
|
|
mp.setCafeDbrType(dbr)
|
|
#print ("def monitorStart ", mp.getCafeDbrType())
|
|
#print ("def monitorStart ", mp.getDbrDataType())
|
|
else:
|
|
print("***Warning*** from monitorStart for handle=", handlePV)
|
|
print("dbr base type should be one of \
|
|
DBR_PLAIN, DBR_STS, DBR_TIME, DBR_GR, DBR_CTRL")
|
|
print("Assuming DBR_TIME")
|
|
mp.setDataType(self.channelInfo.getDataType())
|
|
mp.setCafeDbrType(DBR_TIME)
|
|
|
|
global hmd
|
|
|
|
if cb is not None:
|
|
#Cement to a global dictionary
|
|
hmd[cb] = mpid ##otherwise cb gets ovewritten when casting to an object
|
|
|
|
sig = inspect.signature(cb)
|
|
|
|
# The corresponding setPyHandler has to be set!!
|
|
|
|
mp.setUserArgs(< void * > mpid)
|
|
mp.setNoCyCallbackParameters(len(sig.parameters))
|
|
mp.setPyCyHandler(<void *> cb)
|
|
|
|
with nogil:
|
|
status = self._c_cafe.monitorStart(handle, mp)
|
|
|
|
# Need this to allow a fraction of a second for the callback fn to be called
|
|
# if setPyHandler is used
|
|
cdef short wtfsb = self._c_cafe.channelOpenGroupPolicy.getWhenToFlushSendBuffer()
|
|
if wtfsb == FLUSH_NOW:
|
|
# if self.getMonitorWhenToFlushSendBuffer() == FLUSH_NOW:
|
|
time.sleep(0.01)
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
|
|
return mpid
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def monitorStop(self, handlePV, mpid=None):
|
|
cdef str _METHOD = "monitorStop(handlePV, mpid=None)"
|
|
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV")
|
|
raise _cafeException
|
|
|
|
cdef int status
|
|
cdef unsigned int mpid_no_coercion
|
|
|
|
global hmd
|
|
|
|
if mpid:
|
|
mpid_no_coercion = mpid
|
|
if isinstance(mpid, (int, long)):
|
|
mpid_no_coercion = mpid
|
|
with nogil:
|
|
status = self._c_cafe.monitorStopWithID(handle, mpid_no_coercion)
|
|
time.sleep(0.001)
|
|
l = None
|
|
if mpid not in list(hmd.values()):
|
|
pass #happens when is direct mode in table widget
|
|
else:
|
|
l = list(hmd.keys())[list(hmd.values()).index(mpid)]
|
|
if l is not None:
|
|
del hmd[l]
|
|
else:
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def monitorStop. \n \
|
|
monitorPolicy ID (mpid) should be of type <class 'int'>")
|
|
else:
|
|
mids = self.hh.getMonitorIDs(handle)
|
|
with nogil:
|
|
status = self._c_cafe.monitorStop(handle)
|
|
time.sleep(0.001)
|
|
|
|
for monid in mids:
|
|
if monid not in list(hmd.values()):
|
|
continue
|
|
l = list(hmd.keys())[list(hmd.values()).index(monid)]
|
|
if l is not None:
|
|
del hmd[l]
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
|
|
return status
|
|
|
|
############################################################################
|
|
def monitorStopAll(self):
|
|
|
|
cdef str _METHOD = "monitorStopAll()"
|
|
cdef int status
|
|
|
|
|
|
with nogil:
|
|
status = self._c_cafe.monitorStopAll()
|
|
|
|
# give plenty of time for monitors to stop!
|
|
time.sleep(0.2)
|
|
|
|
hmd.clear()
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def monitorStopAll. Status = {0}"
|
|
.format(status))
|
|
|
|
return status
|
|
##############################################################################
|
|
|
|
##############################################################################
|
|
|
|
def set(self, handlePV, valSet):
|
|
cdef str _METHOD = "set(handlePV, valSet)"
|
|
|
|
cdef unsigned int handle = 0
|
|
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if handle, \
|
|
else <class 'str'> if PV")
|
|
raise _cafeException
|
|
|
|
|
|
# CHECK FOR ALL DATA TYPES!
|
|
|
|
cdef unsigned short valType = CAFE_STRING
|
|
cdef int status = ICAFE_NORMAL
|
|
cdef float valSetF
|
|
cdef double valSetD
|
|
cdef int valSetI
|
|
cdef long long valSetLL
|
|
cdef short valSetShort
|
|
cdef unsigned short valSetUShort
|
|
cdef unsigned char valSetChar
|
|
cdef string valSetS
|
|
cdef vector[double] vecD
|
|
cdef vector[float] vecF
|
|
cdef vector[short] vecShort
|
|
cdef vector[unsigned short] vecUShort
|
|
cdef vector[dbr_char_t] vecChar
|
|
cdef vector[dbr_long_t] vecI
|
|
cdef vector[string] vecS
|
|
|
|
cdef unsigned int nLA = 0
|
|
|
|
cdef tuple ctypesString = (ctypes.c_wchar, ctypes.c_char_p, ctypes.c_wchar_p)
|
|
cdef tuple ctypesUChar = (ctypes.c_char, ctypes.c_ubyte, ctypes.c_bool, ctypes.c_uint8, )
|
|
cdef tuple ctypesShort = (ctypes.c_int16, ctypes.c_int8, ctypes.c_short, ctypes.c_byte)
|
|
cdef tuple ctypesUShort = (ctypes.c_uint16, ctypes.c_ushort)
|
|
cdef tuple ctypesInt = (ctypes.c_int, ctypes.c_int32,
|
|
ctypes.c_long, ctypes.c_size_t)
|
|
cdef tuple ctypesLongLong = (ctypes.c_uint, ctypes.c_uint32, ctypes.c_int64, ctypes.c_uint64,
|
|
ctypes.c_ulong, ctypes.c_ulonglong, ctypes.c_longdouble,
|
|
ctypes.c_longlong, ctypes.c_ssize_t,
|
|
ctypes.c_void_p, ctypes.c_voidp)
|
|
|
|
# ctypes.c_char, ctypes.c_float, ctypes.c_double are separate
|
|
|
|
cdef tuple dtypesString = (np.str_, np.unicode_)
|
|
cdef tuple dtypesUChar = (np.ubyte, np.bool8, np.bool_, np.uint8)
|
|
cdef tuple dtypesShort = (np.byte, np.short, np.int8, np.int16)
|
|
cdef tuple dtypesUShort = (np.uint16, np.ushort)
|
|
cdef tuple dtypesInt = (np.int_, np.intc, np.int32, np.uintp)
|
|
cdef tuple dtypesLongLong = (np.uint, np.uintc, np.uint32, np.int64, np.uint64,
|
|
np.ulonglong, np.longlong, np.intp, np.uintp)
|
|
|
|
cdef tuple dtypesFloat = (np.single, np.float16, np.float32)
|
|
cdef tuple dtypesDouble = (np.double, np.float_, np.float64)
|
|
|
|
# List: Major[0] Minor[1] Patch[2] 'final'[3] 0 [4]
|
|
# print "type= // ", type(valSet)
|
|
|
|
cdef bint isGoodType = False
|
|
cdef bint isBytesType = False
|
|
|
|
# print('set method', type(valSet))
|
|
|
|
# print("is instance array.array", isinstance(valSet, array.array))
|
|
# print("is instance np.ndarray", isinstance(valSet, np.ndarray))
|
|
# print("is instance memoryview", isinstance(valSet, memoryview))
|
|
# print("is instance ctypes float", isinstance(valSet, ctypes.c_float))
|
|
# print("is instance ctypes long ", isinstance(valSet, ctypes.c_long ))
|
|
# print("is instance ctypes int ", isinstance(valSet, ctypes.c_int ))
|
|
# print("is instance int ", isinstance(valSet, int ))
|
|
# print("is instance ctypes char_p ", isinstance(valSet, ctypes.c_char_p ))
|
|
# print("is instance ctypes Array ", isinstance(valSet, ctypes.Array ))
|
|
# print("is instance bytes ", isinstance(valSet, bytes ))
|
|
# print("is instance bytearrays ", isinstance(valSet, bytearray ))
|
|
# ctypes.c_buffer is of class function
|
|
# crtpes.c_buffer(b'abc') is of rtype ctypes.Array (!))
|
|
# print("is instance ctypes buffer ", isinstance(valSet, ctypes.c_buffer )) # no such type!
|
|
|
|
# dir(ctypes)
|
|
# print(type(valSet))
|
|
# print (valSet.__class__)
|
|
cdef str classType = (valSet.__class__).__name__
|
|
cdef str substringmv = "_memoryviewslice"
|
|
|
|
|
|
|
|
# Cython does not know about PyCafe._memoryviewslice
|
|
# if (isinstance(valSet,PyCafe._memoryviewslice)):
|
|
# print('OK for memoryview')
|
|
|
|
if _python_version > (2,6):
|
|
#if ((_python_version[0] > 2) or (_python_version[0] == 2 and _python_version[1] > 6)):
|
|
|
|
if isinstance(valSet, (list, array.array, np.ndarray, cython.view.memoryview, memoryview, ctypes.Array)):
|
|
isGoodType = True
|
|
else:
|
|
if isinstance(valSet, (list, array.array, np.ndarray, ctypes.Array)):
|
|
isGoodType = True
|
|
|
|
if (isGoodType == False):
|
|
if (substringmv in classType):
|
|
isGoodType = True
|
|
|
|
# This is to cater for ctypes.c_buffer which is an instance of ctypes.Array
|
|
# where the element of the array is of type bytes - there need to match to cafe.setString
|
|
if isinstance(valSet, ctypes.Array):
|
|
if isinstance(valSet[0], bytes):
|
|
isGoodType = False
|
|
isBytesType = True
|
|
|
|
# where the element of the array is of type bytes - there need to match to cafe.setSrting
|
|
|
|
# if isinstance(valSet,np.ndarray):
|
|
#print ("np.ndarray is true")
|
|
#print (type(valSet[0]))
|
|
# if isinstance(valSet[0],bytes):
|
|
# isGoodType=False
|
|
# isBytesType=True
|
|
|
|
#print("isGoodType ", isGoodType)
|
|
#print("isBytesType ", isBytesType)
|
|
|
|
self._c_cafe.getChannelInfo(handle, self.channelInfo)
|
|
class_name = str(self.channelInfo.getClassNameAsString())
|
|
data_type = self.channelInfo.getDataType()
|
|
|
|
if class_name in ['waveform'] and data_type in [DBR_CHAR]:
|
|
if isinstance(valSet, (str, bytes)):
|
|
isGoodType = True
|
|
elif isinstance(valSet, list):
|
|
if len(valSet) == 1:
|
|
if isinstance(valSet[0], (str, bytes)):
|
|
isGoodType = True
|
|
valSet = valSet[0]
|
|
|
|
if isGoodType:
|
|
|
|
#print('set method', type(valSet[0]))
|
|
|
|
nLA = len(valSet)
|
|
|
|
# Just check on first element if array.array etc..
|
|
if not isinstance(valSet, (list)):
|
|
# if isinstance(valSet, (array.array, np.ndarray, cython.view.memoryview, memoryview)):
|
|
nLA = 1
|
|
|
|
for i in range(0, nLA):
|
|
|
|
if isinstance(valSet[i], (str, bytes)):
|
|
valType = CAFE_STRING
|
|
break
|
|
elif isinstance(valSet[i], dtypesString):
|
|
valType = CAFE_STRING
|
|
break
|
|
elif isinstance(valSet[i], (float)):
|
|
valType = CAFE_DOUBLE
|
|
elif isinstance(valSet[i], (dtypesDouble)):
|
|
valType = CAFE_DOUBLE
|
|
elif isinstance(valSet[i], (dtypesFloat)):
|
|
valType = CAFE_FLOAT
|
|
elif isinstance(valSet[i], (long, int)):
|
|
valType = CAFE_LONG
|
|
elif isinstance(valSet[i], dtypesInt+dtypesLongLong+dtypesUChar):
|
|
valType = CAFE_LONG
|
|
elif isinstance(valSet[i], dtypesShort):
|
|
valType = CAFE_SHORT
|
|
elif isinstance(valSet[i], dtypesUShort):
|
|
valType = CAFE_USHORT
|
|
else:
|
|
|
|
print("PyCafe.pyx: We do not cater for type ",
|
|
type(valSet[i]), " and thus assume a string")
|
|
valType = CAFE_STRING
|
|
break
|
|
|
|
#print(valSet, len(valSet), valType)
|
|
|
|
# valSet to vector since
|
|
# coercion from Python not allowed without the GIL
|
|
if valType == CAFE_DOUBLE:
|
|
|
|
vecD.reserve(len(valSet))
|
|
for i in range(0, len(valSet)):
|
|
vecD.push_back(valSet[i])
|
|
with nogil:
|
|
status = self._c_cafe.setVDouble(handle, vecD)
|
|
|
|
elif valType == CAFE_FLOAT:
|
|
|
|
vecF.reserve(len(valSet))
|
|
for i in range(0, len(valSet)):
|
|
vecF.push_back(valSet[i])
|
|
with nogil:
|
|
status = self._c_cafe.setVFloat(handle, vecF)
|
|
|
|
elif valType == CAFE_LONG:
|
|
|
|
vecI.reserve(len(valSet))
|
|
for i in range(0, len(valSet)):
|
|
vecI.push_back(valSet[i])
|
|
|
|
with nogil:
|
|
status = self._c_cafe.setVLong(handle, vecI)
|
|
|
|
elif valType == CAFE_SHORT:
|
|
|
|
vecShort.reserve(len(valSet))
|
|
for i in range(0, len(valSet)):
|
|
vecShort.push_back(valSet[i])
|
|
|
|
with nogil:
|
|
status = self._c_cafe.setVShort(handle, vecShort)
|
|
|
|
elif valType == CAFE_USHORT:
|
|
|
|
vecUShort.reserve(len(valSet))
|
|
for i in range(0, len(valSet)):
|
|
vecUShort.push_back(valSet[i])
|
|
|
|
with nogil:
|
|
status = self._c_cafe.setVUShort(handle, vecUShort)
|
|
|
|
elif valType == CAFE_CHAR:
|
|
|
|
vecChar.reserve(len(valSet))
|
|
for i in range(0, len(valSet)):
|
|
vecChar.push_back(valSet[i])
|
|
|
|
with nogil:
|
|
status = self._c_cafe.setVChar(handle, vecChar)
|
|
|
|
elif valType == CAFE_STRING:
|
|
|
|
vecS.reserve(len(valSet))
|
|
for i in range(0, len(valSet)):
|
|
if isinstance(valSet[i], str):
|
|
#valSet[i] = (<unicode>valSet[i]).encode('utf_8')
|
|
temp = (valSet[i]).encode('utf_8')
|
|
elif isinstance(valSet[i], (bytes, bytearray)):
|
|
encoding = False
|
|
if not encoding:
|
|
try:
|
|
temp = (valSet[i]).decode('utf_8')
|
|
encoding = True
|
|
|
|
vecS.push_back(temp.encode('utf_8'))
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
temp = (valSet[i]).decode('utf_16')
|
|
encoding = True
|
|
|
|
vecS.push_back(<string>temp.encode('utf_16').decode('utf_16'))
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
temp = (valSet[i]).decode('utf_32')
|
|
encoding = True
|
|
|
|
vecS.push_back(temp.encode('utf_32'))
|
|
except UnicodeDecodeError:
|
|
pass
|
|
else:
|
|
print('utf-none', type(valSet[i]))
|
|
temp = valSet[i]
|
|
vecS.push_back(<string> temp)
|
|
|
|
with nogil:
|
|
status = self._c_cafe.setVString(handle, vecS)
|
|
|
|
elif isBytesType:
|
|
#print("isBytesType")
|
|
valSetS = <string > valSet.value
|
|
with nogil:
|
|
status = self._c_cafe.setString(handle, valSetS)
|
|
elif isinstance(valSet, (ctypes.c_char)):
|
|
#print("is ctypes.c_char")
|
|
# print(valSet.value)
|
|
# print(valSet.value.decode())
|
|
valSetS = valSet.value.decode()
|
|
with nogil:
|
|
status = self._c_cafe.setString(handle, valSetS)
|
|
elif isinstance(valSet, (ctypes.c_float)):
|
|
valSetF = <float > valSet.value
|
|
with nogil:
|
|
status = self._c_cafe.setFloat(handle, valSetF)
|
|
elif isinstance(valSet, (ctypes.c_double)):
|
|
valSetD = <double > valSet.value
|
|
with nogil:
|
|
status = self._c_cafe.setDouble(handle, valSetD)
|
|
elif isinstance(valSet, ctypesInt):
|
|
# print("ctypesInt")
|
|
valSetI = <int > valSet.value
|
|
with nogil:
|
|
status = self._c_cafe.setLong(handle, valSetI)
|
|
elif isinstance(valSet, ctypesLongLong):
|
|
# print("ctypesLongLong")
|
|
valSetLL = <long long > valSet.value
|
|
with nogil:
|
|
status = self._c_cafe.setLong(handle, valSetLL)
|
|
elif isinstance(valSet, ctypesShort):
|
|
#print("ctypesShort")
|
|
valSetShort = <short > valSet.value
|
|
with nogil:
|
|
status = self._c_cafe.setShort(handle, valSetShort)
|
|
elif isinstance(valSet, ctypesUShort):
|
|
#print("ctypesUShort")
|
|
valSetUShort = <unsigned short > valSet.value
|
|
with nogil:
|
|
status = self._c_cafe.setUShort(handle, valSetUShort)
|
|
elif isinstance(valSet, (ctypesString)):
|
|
#print("ctypesString")
|
|
valSetS = <string > valSet.value
|
|
with nogil:
|
|
status = self._c_cafe.setString(handle, valSetS)
|
|
elif isinstance(valSet, ctypesUChar):
|
|
#print("ctypesUChar")
|
|
valSetUChar = <unsigned char > valSet.value
|
|
with nogil:
|
|
status = self._c_cafe.setChar(handle, valSetUChar)
|
|
elif isinstance(valSet, (float)):
|
|
#print("float type")
|
|
valSetD = <float > valSet
|
|
with nogil:
|
|
status = self._c_cafe.setDouble(handle, valSetD)
|
|
elif isinstance(valSet, (int, long)):
|
|
#print("int/long type")
|
|
valSetI = <int > valSet
|
|
with nogil:
|
|
status = self._c_cafe.setLong(handle, valSetI)
|
|
elif isinstance(valSet, (str)):
|
|
#print("str type", valSet)
|
|
encoding = False
|
|
try:
|
|
valSetS = valSet.encode('utf_8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
valSetS = valSet.encode('utf_16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
|
|
with nogil:
|
|
status = self._c_cafe.setString(handle, valSetS)
|
|
elif isinstance(valSet, (bytes, bytearray)):
|
|
#print("bytes,bytearray")
|
|
encoding = False
|
|
try:
|
|
valSetS = valSet.decode('utf_8')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
pass
|
|
if not encoding:
|
|
try:
|
|
valSetS = <string> valSet.decode('utf_16')
|
|
encoding = True
|
|
except UnicodeDecodeError:
|
|
print('decode utf_16 error')
|
|
pass
|
|
except UnicodeEncodeError as ex:
|
|
print('encode utf_16 error', ex)
|
|
pass
|
|
if not encoding:
|
|
print('no encoding done')
|
|
valSetS = <string> valSet
|
|
with nogil:
|
|
status = self._c_cafe.setString(handle, valSetS)
|
|
elif isinstance(valSet, (unicode)):
|
|
#print("unicode")
|
|
valSetS = valSet.encode('utf-8')
|
|
with nogil:
|
|
status = self._c_cafe.setString(handle, valSetS)
|
|
else:
|
|
print("PyCafe def set WARNING: DATA TYPE NOT SUPPORTED")
|
|
print("Input data (whether within a 'list','array.array','cython.view.memoryview','memoryview' \n\
|
|
or not) should be of of type <class 'int'>, <type 'float'> or <class 'str'>")
|
|
type(valSet)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
if handle == 0:
|
|
self._c_cafe.printStatusMessage(status)
|
|
else:
|
|
self._c_cafe.printStatus(handle, status)
|
|
if self._enable_exceptions:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD, _handle=handle, _pv_name=self._c_cafe.getPVFromHandle(handle),
|
|
_error_code=status, _error_text=self.cs.code(status), _error_info=self.cs.info(status))
|
|
raise _cafeException
|
|
|
|
return status
|
|
############################################################################
|
|
# END def set(self, handlePV, valSet):
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def setScalarList(self, list handleList, list valList):
|
|
cdef str _METHOD = "setScalarList"
|
|
|
|
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setScalarList. \n\
|
|
First input argument, should be a 'list' of of type <class 'int'> \
|
|
if handles or <class 'str'> if PVs")
|
|
|
|
if len(handleList) != len(valList):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setScalarList. \
|
|
Length of handle list ", len(handleList), " does not match \
|
|
the length of data list ", len(valList))
|
|
|
|
nelemPrevious = []
|
|
|
|
# Better with PVDataHolder
|
|
cdef unsigned int nelemTotal = 0
|
|
for i in range(0, len(handleList)):
|
|
# nelemTotal+=self.hh.getNelemNative(handleList[i])
|
|
nelemPrevious.append(self.hh.getNelemClient(handleList[i]))
|
|
|
|
# cdef int size_cdu = sizeof(CAFE_DATATYPE_UNION)
|
|
|
|
# do this to avoid compiler warning messages
|
|
cdef vector[unsigned int] v
|
|
for i in range(0, len(handleList)):
|
|
v.push_back(handleList[i])
|
|
|
|
# Create temporary group from handleList
|
|
# Does group exist?
|
|
cdef PVDataHolder * pvd = self._c_cafe.getPVData(v)
|
|
|
|
# cdef PVDataHolder * pvd = <PVDataHolder *>malloc( 100000000 + \
|
|
# len(handleList) * sizeof(PVDataHolder) + nelemTotal*size_cdu)
|
|
|
|
for i in range(0, <int> v.size()): #len(handleList)):
|
|
# pvd[i].val =<shared_ptr[CAFE_DATATYPE_UNION[]]>malloc(sizeof(CAFE_DATATYPE_UNION))
|
|
#pvd[i]= PVDataHolder(1);
|
|
pvd[i].setNelem(1)
|
|
|
|
#cdef unsigned short valType = CAFE_STRING
|
|
|
|
for i in range(0, <int> v.size()): #len(handleList)):
|
|
if isinstance(valList[i], (str)):
|
|
pvd[i].setString(valList[i])
|
|
elif isinstance(valList[i], (float)):
|
|
pvd[i].setDouble(valList[i])
|
|
elif isinstance(valList[i], (long, int)):
|
|
pvd[i].setInt(valList[i])
|
|
else:
|
|
print("This line in PyCafe def setScalarList should never appear!")
|
|
|
|
cdef int status = ICAFE_NORMAL
|
|
with nogil:
|
|
status = self._c_cafe.setPVArray(v, pvd)
|
|
|
|
for i in range(0, len(handleList)):
|
|
if (nelemPrevious[i] != 1):
|
|
self._c_cafe.setNelemToPrevious(
|
|
handleList[i], nelemPrevious[i])
|
|
|
|
# return status for individual channels
|
|
statusList = []
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
for i in range(0, len(handleList)):
|
|
if (pvd[i].getStatus() != ICAFE_NORMAL):
|
|
print("Handle=", handleList[i], "PV=",
|
|
self.hh.getPVFromHandle(handleList[i]))
|
|
print("with error status=", pvd[i].getStatus())
|
|
self._c_cafe.printStatusMessage(pvd[i].getStatus())
|
|
print("")
|
|
statusList.append(pvd[i].getStatus())
|
|
|
|
# free(pvd)
|
|
|
|
return status, statusList
|
|
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def setCompoundList(self, handleList, list vectorList):
|
|
|
|
cdef str _METHOD = "setCompoundList(handleList, list vectorList)"
|
|
|
|
if isinstance(handleList, (str)):
|
|
handleList = self.getHandlesFromWithinGroup(handleList)
|
|
else:
|
|
if not isinstance(handleList, (list)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setCompoundList. \n\
|
|
First input argument, should be <type 'list'> of handles or PVs")
|
|
|
|
if isinstance(handleList[0], (str)):
|
|
handleList = self.checkForHandleList(handleList)
|
|
elif not isinstance(handleList[0], (int, long)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setCompoundList. \n\
|
|
First input argument, should be a 'list' of of type <class 'int'> if handles or <class 'str'> if PVs")
|
|
|
|
if len(handleList) != len(vectorList):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setCompoundList. \
|
|
Length of handle list ", len(handleList), " does not match the length of data list ", len(vectorList))
|
|
|
|
# do this to avoid compiler warning messages
|
|
cdef vector[unsigned int] v
|
|
cdef int i
|
|
|
|
for i in range(0, len(handleList)):
|
|
v.push_back(handleList[i])
|
|
|
|
# Create temporary group from handleList
|
|
# Does group exist?
|
|
cdef PVDataHolder * pvdata = self._c_cafe.getPVData(v)
|
|
|
|
for i in range(0, len(vectorList)):
|
|
|
|
# if not list
|
|
if isinstance(vectorList[i], (str)):
|
|
pvdata[i].setString(vectorList[i])
|
|
|
|
elif isinstance(vectorList[i], (float)):
|
|
pvdata[i].setDouble(vectorList[i])
|
|
|
|
elif isinstance(vectorList[i], (long, int)):
|
|
pvdata[i].setInt(vectorList[i])
|
|
|
|
elif isinstance(vectorList[i], (list)):
|
|
|
|
# if list
|
|
valType = CAFE_INVALID_DATATYPE
|
|
pvdata[i].setNelem(len(vectorList[i]))
|
|
# for k in range(0, len(vectorList[i])):
|
|
# Just check on first element
|
|
for k in range(0, 1): # can expand this to all elemnts or reduce to 1
|
|
if isinstance(vectorList[i][k], (str)):
|
|
valType = CAFE_STRING
|
|
break
|
|
elif isinstance(vectorList[i][k], (float)):
|
|
valType = CAFE_DOUBLE
|
|
elif isinstance(vectorList[i][k], (long, int)):
|
|
if valType != CAFE_DOUBLE:
|
|
valType = CAFE_LONG
|
|
else:
|
|
valType = CAFE_STRING
|
|
break
|
|
|
|
# check dt of first element
|
|
if valType == CAFE_DOUBLE:
|
|
pvdata[i].setVDouble(vectorList[i])
|
|
elif valType == CAFE_LONG:
|
|
pvdata[i].setVInt(vectorList[i])
|
|
elif valType == CAFE_STRING:
|
|
pvdata[i].setVString(vectorList[i])
|
|
|
|
else:
|
|
print("This line in PyCafe def setCompoundList should never appear!")
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setCompoundList. \n\
|
|
Unknown data input; should be one of of type <class 'int'> , <class 'str'>, <type 'float'> , <type 'list'>")
|
|
|
|
# endForLoop
|
|
|
|
cdef int status = ICAFE_NORMAL
|
|
with nogil:
|
|
status = self._c_cafe.setPVArray(v, pvdata)
|
|
|
|
# return status for individual channels
|
|
statusList = []
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
for i in range(0, len(handleList)):
|
|
if (pvdata[i].getStatus() != ICAFE_NORMAL):
|
|
print("Handle=", handleList[i], "PV=",
|
|
self.hh.getPVFromHandle(handleList[i]))
|
|
print("with error status=", pvdata[i].getStatus())
|
|
self._c_cafe.printStatusMessage(pvdata[i].getStatus())
|
|
print("")
|
|
#raise Exception("EXCEPTION RAISED in PyCafe def setCompoundList. Status = %d" %status)
|
|
statusList.append(pvdata[i].getStatus())
|
|
|
|
return status, statusList
|
|
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
def setGroup(self, ghandleName, list vectorList):
|
|
|
|
cdef str _METHOD = "setGroup(self, ghandleName, list vectorList)"
|
|
|
|
cdef unsigned int ghandle = 0
|
|
if isinstance(ghandleName, (int, long)):
|
|
ghandle = ghandleName
|
|
elif isinstance(ghandleName, (str)):
|
|
ghandle = self.checkForGroupHandle(ghandleName)
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument should be of type <class 'int'> if group handle, else <class 'str'> if group name")
|
|
raise _cafeException
|
|
|
|
cdef PVGroup pvg
|
|
|
|
with nogil:
|
|
self._c_cafe.groupAttach(ghandle, pvg)
|
|
###
|
|
#print ("len V", len(vectorList), " npv=", pvg.getNPV())
|
|
|
|
cdef PVDataHolder * pvdata = pvg.getPVData()
|
|
|
|
for i in range(0, len(vectorList)):
|
|
|
|
# if not list
|
|
if isinstance(vectorList[i], (str)):
|
|
pvdata[i].setString(vectorList[i])
|
|
|
|
elif isinstance(vectorList[i], (float)):
|
|
pvdata[i].setDouble(vectorList[i])
|
|
|
|
elif isinstance(vectorList[i], (long, int)):
|
|
pvdata[i].setInt(vectorList[i])
|
|
|
|
elif isinstance(vectorList[i], (list)):
|
|
|
|
# if list
|
|
valType = CAFE_INVALID_DATATYPE
|
|
pvdata[i].setNelem(len(vectorList[i]))
|
|
# for k in range(0, len(vectorList[i])):
|
|
# Just check on first element
|
|
for k in range(0, 1): # can expand this to all elemnts or reduce to 1
|
|
if isinstance(vectorList[i][k], (str)):
|
|
valType = CAFE_STRING
|
|
break
|
|
elif isinstance(vectorList[i][k], (float)):
|
|
valType = CAFE_DOUBLE
|
|
elif isinstance(vectorList[i][k], (long, int)):
|
|
if valType != CAFE_DOUBLE:
|
|
valType = CAFE_LONG
|
|
else:
|
|
valType = CAFE_STRING
|
|
break
|
|
|
|
# check dt of first element
|
|
if valType == CAFE_DOUBLE:
|
|
pvdata[i].setVDouble(vectorList[i])
|
|
elif valType == CAFE_LONG:
|
|
pvdata[i].setVInt(vectorList[i])
|
|
elif valType == CAFE_STRING:
|
|
pvdata[i].setVString(vectorList[i])
|
|
|
|
else:
|
|
|
|
print("PyCafe def setGroup: Unusual data type for element",
|
|
i, " : ", type(vectorList[i]))
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setGroup. \n\
|
|
Unknown data input; should be one of of type <class 'int'> , <class 'str'>, <type 'float'> , <type 'list'>")
|
|
|
|
# endForLoop
|
|
|
|
cdef int status = ICAFE_NORMAL
|
|
statusList = []
|
|
pvg.setPVData(pvdata)
|
|
|
|
with nogil:
|
|
status = self._c_cafe.groupSet(ghandle, pvg)
|
|
|
|
cdef PVDataHolder * pvd
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
# do not raise exception
|
|
#raise Exception("EXCEPTION RAISED in PyCafe def setGroup. Status = %d" %status)
|
|
|
|
pvd = pvg.getPVData()
|
|
|
|
for i in range(0, pvg.getNPV()):
|
|
statusList.append(pvd[i].getStatus())
|
|
else:
|
|
statusList.append(status)
|
|
|
|
return status, statusList
|
|
|
|
##################################################################################
|
|
# END: def setGroup(self, ghandleName, dt='native')
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def gameSetAndMatch(self, list handlePVSet, list valSet, handlePVAction, valAction, list handlePVMatch, double tolerance, double timeout, bint printFlag):
|
|
cdef str _METHOD = "gameSetAndMatch(list handlePVSet, list valSet, list handlePVMatch, double tolerance, double timeout, bint printFlag)"
|
|
|
|
|
|
if (len(handlePVSet) != len(valSet)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setAndMatchMany. \n\
|
|
Lengths of first (handlePVSet) and second (valSet) input lists must match!")
|
|
|
|
if (len(handlePVSet) != len(handlePVMatch)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setAndMatchMany. \n\
|
|
Lengths of first (handlePVSet) and third (handlePVMatch) input lists must match!")
|
|
|
|
if not isinstance(handlePVAction, (list)):
|
|
tmp = handlePVAction
|
|
handlePVAction = []
|
|
handlePVAction.append(tmp)
|
|
|
|
if not isinstance(valAction, (list)):
|
|
tmp = valAction
|
|
valAction = []
|
|
valAction.append(tmp)
|
|
|
|
cdef vector[unsigned int] handleSet
|
|
handleSet.reserve(len(handlePVSet))
|
|
|
|
cdef vector[unsigned int] handleMatch
|
|
handleMatch.reserve(len(handlePVMatch))
|
|
|
|
cdef vector[double] valSetV
|
|
valSetV.reserve(len(valSet))
|
|
|
|
cdef vector[unsigned int] handleAction
|
|
handleAction.reserve(len(handlePVAction))
|
|
|
|
cdef vector[string] valActionV
|
|
valActionV.reserve(len(valAction))
|
|
|
|
for i in range(0, len(handlePVSet)):
|
|
if isinstance(handlePVSet[i], (int, long)):
|
|
handleSet.push_back(handlePVSet[i])
|
|
elif isinstance(handlePVSet[i], (str)):
|
|
handleSet.push_back(self.checkForHandle(handlePVSet))
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="ThandlePVSet list member should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
raise _cafeException
|
|
|
|
for i in range(0, len(handlePVMatch)):
|
|
if isinstance(handlePVMatch[i], (int, long)):
|
|
handleMatch.push_back(handlePVMatch[i])
|
|
elif isinstance(handlePVMatch[i], (str)):
|
|
handleMatch.push_back(self.checkForHandle(handlePVMatch))
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="handleMatch list member should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
raise _cafeException
|
|
|
|
for i in range(0, len(handlePVAction)):
|
|
if isinstance(handlePVAction[i], (int, long)):
|
|
handleAction.push_back(handlePVAction[i])
|
|
elif isinstance(handlePVAction[i], (str)):
|
|
handleAction.push_back(self.checkForHandle(handlePVAction))
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="handlePVAction list member should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
raise _cafeException
|
|
|
|
for i in range(0, len(valAction)):
|
|
if not isinstance(valAction[i], (str)):
|
|
valActionV.push_back(str(valAction[i]))
|
|
else:
|
|
valActionV.push_back(valAction[i])
|
|
|
|
for i in range(0, len(valSet)):
|
|
valSetV.push_back(valSet[i])
|
|
|
|
cdef int status
|
|
|
|
with nogil:
|
|
status = self._c_cafe.gameSetAndMatch(
|
|
handleSet, valSetV, handleAction, valActionV, handleMatch, tolerance, timeout, printFlag)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def gameSetAndMatch. Status = %d" % status)
|
|
|
|
return status
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def setAndMatchMany(self, list handlePVSet, list valSet, list handlePVMatch, double tolerance, double timeout, bint printFlag):
|
|
cdef str _METHOD = "setAndMatchMany(list handlePVSet, list valSet, list handlePVMatch, double tolerance, double timeout, bint printFlag)"
|
|
|
|
|
|
if (len(handlePVSet) != len(valSet)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setAndMatchMany. \n\
|
|
Lengths of first (handlePVSet) and second (valSet) input lists must match!")
|
|
|
|
if (len(handlePVSet) != len(handlePVMatch)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def setAndMatchMany. \n\
|
|
Lengths of first (handlePVSet) and third (handlePVMatch) input lists must match!")
|
|
|
|
cdef vector[unsigned int] handleSet
|
|
handleSet.reserve(len(handlePVSet))
|
|
|
|
cdef vector[unsigned int] handleMatch
|
|
handleMatch.reserve(len(handlePVMatch))
|
|
|
|
cdef vector[double] valSetV
|
|
valSetV.reserve(len(valSet))
|
|
|
|
for i in range(0, len(handlePVSet)):
|
|
if isinstance(handlePVSet[i], (int, long)):
|
|
handleSet.push_back(handlePVSet[i])
|
|
elif isinstance(handlePVSet[i], (str)):
|
|
handleSet.push_back(self.checkForHandle(handlePVSet))
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="ThandlePVSet list member should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
raise _cafeException
|
|
|
|
for i in range(0, len(handlePVMatch)):
|
|
if isinstance(handlePVMatch[i], (int, long)):
|
|
handleMatch.push_back(handlePVMatch[i])
|
|
elif isinstance(handlePVMatch[i], (str)):
|
|
handleMatch.push_back(self.checkForHandle(handlePVMatch))
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="handleMatch list member should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
raise _cafeException
|
|
|
|
for i in range(0, len(valSet)):
|
|
valSetV.push_back(valSet[i])
|
|
|
|
cdef int status
|
|
|
|
with nogil:
|
|
status = self._c_cafe.setAndMatchMany(
|
|
handleSet, valSetV, handleMatch, tolerance, timeout, printFlag)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def setAndMatchMany. Status = %d" % status)
|
|
|
|
return status
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def setAndMatch(self, handlePVSet, double valSet, handlePVMatch,
|
|
double tolerance, double timeout, bint printFlag):
|
|
cdef str _METHOD = ("setAndMatch(handlePVSet, double valSet,"
|
|
"handlePVMatch, double tolerance,"
|
|
"double timeout, bint printFlag)")
|
|
|
|
cdef unsigned int handleSet = 0
|
|
if isinstance(handlePVSet, (int, long)):
|
|
handleSet = handlePVSet
|
|
elif isinstance(handlePVSet, (str)):
|
|
handleSet = self.checkForHandle(handlePVSet)
|
|
else:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_error_info=("First input argument, should be of type <class 'int'> if handle," +
|
|
"else <class 'str'> if PV"))
|
|
raise _cafeException
|
|
|
|
cdef unsigned int handleMatch = 0
|
|
if isinstance(handlePVMatch, (int, long)):
|
|
handleMatch = handlePVMatch
|
|
elif isinstance(handlePVMatch, (str)):
|
|
handleMatch = self.checkForHandle(handlePVMatch)
|
|
else:
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_error_info=("Third input argument, should be of type <class 'int'> if handle," +
|
|
"else <class 'str'> if PV"))
|
|
raise _cafeException
|
|
|
|
cdef int status
|
|
|
|
with nogil:
|
|
status = self._c_cafe.setAndMatch(
|
|
handleSet, valSet, handleMatch, tolerance, timeout, printFlag)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def setAndMatch. Status = %d" % status)
|
|
|
|
return status
|
|
##################################################################################
|
|
|
|
##################################################################################
|
|
|
|
def matchMany(self, list valSet, list handlePVMatch, double tolerance, double timeout, bint printFlag):
|
|
|
|
cdef str _METHOD = "matchMany(list valSet, list handlePVMatch, double tolerance, double timeout, bint printFlag)"
|
|
|
|
|
|
if (len(valSet) != len(handlePVMatch)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def matchMany. \n\
|
|
Lengths of first (handlePVSet) and third (handlePVMatch) input lists must match!")
|
|
|
|
cdef vector[unsigned int] handleMatch
|
|
handleMatch.reserve(len(handlePVMatch))
|
|
|
|
cdef vector[double] valSetV
|
|
valSetV.reserve(len(valSet))
|
|
|
|
for i in range(0, len(handlePVMatch)):
|
|
if isinstance(handlePVMatch[i], (int, long)):
|
|
handleMatch.push_back(handlePVMatch[i])
|
|
elif isinstance(handlePVMatch[i], (str)):
|
|
handleMatch.push_back(self.checkForHandle(handlePVMatch))
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
raise _cafeException
|
|
|
|
for i in range(0, len(valSet)):
|
|
valSetV.push_back(valSet[i])
|
|
|
|
cdef int status
|
|
|
|
with nogil:
|
|
status = self._c_cafe.matchMany(
|
|
valSetV, handleMatch, tolerance, timeout, printFlag)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def matchMany. Status = %d" % status)
|
|
|
|
return status
|
|
############################################################################
|
|
|
|
|
|
def matchManyWithStatus(self, list valSet, list handlePVMatch, double tolerance, double timeout, bint printFlag):
|
|
|
|
cdef str _METHOD = "matchManyWithStatus(list valSet, list handlePVMatch, double tolerance, double timeout, bint printFlag)"
|
|
|
|
if (len(valSet) != len(handlePVMatch)):
|
|
raise Exception("EXCEPTION RAISED IN PyCafe def matchMany. \n\
|
|
Lengths of first (handlePVSet) and third (handlePVMatch) input lists must match!")
|
|
|
|
cdef vector[unsigned int] handleMatch
|
|
handleMatch.reserve(len(handlePVMatch))
|
|
|
|
cdef vector[double] valSetV
|
|
valSetV.reserve(len(valSet))
|
|
|
|
cdef vector[int] statusV
|
|
statusV.reserve(len(valSet))
|
|
|
|
for i in range(0, len(handlePVMatch)):
|
|
if isinstance(handlePVMatch[i], (int, long)):
|
|
handleMatch.push_back(handlePVMatch[i])
|
|
elif isinstance(handlePVMatch[i], (str)):
|
|
handleMatch.push_back(self.checkForHandle(handlePVMatch))
|
|
else:
|
|
_cafeException = CafeException(_type='CafeError', _source=_METHOD,
|
|
_error_info="First input argument, should be of type <class 'int'> if handle, else <class 'str'> if PV")
|
|
raise _cafeException
|
|
|
|
for i in range(0, len(valSet)):
|
|
valSetV.push_back(valSet[i])
|
|
|
|
cdef int status
|
|
|
|
with nogil:
|
|
status = self._c_cafe.matchManyWithStatus(
|
|
valSetV, handleMatch, tolerance, timeout, printFlag, statusV)
|
|
|
|
print("status from pxy", statusV)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
|
|
return status, statusV
|
|
############################################################################
|
|
|
|
|
|
############################################################################
|
|
|
|
def match(self, double valSet, handlePVMatch, double tolerance, double timeout, bint printFlag):
|
|
|
|
cdef str _METHOD = ("match(double valSet, handlePVMatch, double tolerance, double timeout, bint printFlag)")
|
|
|
|
cdef unsigned int handleMatch = 0
|
|
|
|
if isinstance(handlePVMatch, (int, long)):
|
|
handleMatch = handlePVMatch
|
|
elif isinstance(handlePVMatch, (str)):
|
|
handleMatch = self.checkForHandle(handlePVMatch)
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First Input argument should be of type <class 'int'> "
|
|
"if handle, else <class 'str'> if PV")))
|
|
|
|
cdef int status = ICAFE_NORMAL
|
|
|
|
|
|
with nogil:
|
|
status = self._c_cafe.match(
|
|
valSet, handleMatch, tolerance, timeout, printFlag)
|
|
|
|
if status != ICAFE_NORMAL:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(status)
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def match. Status = %d" % status)
|
|
|
|
return status
|
|
|
|
return 1
|
|
############################################################################
|
|
|
|
############################################################################
|
|
|
|
def setNelemCtrl(self, handlePV, unsigned int nelem):
|
|
cdef str _METHOD = "setNelemCtrl(handlePV, unsigned int nelem)"
|
|
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First Input argument should be of type <class 'int'> "
|
|
"if handle, else <class 'str'> if PV")))
|
|
|
|
if handle == 0:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(ECAFE_INVALID_HANDLE)
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _error_code=ECAFE_INVALID_HANDLE,
|
|
_error_text=self.cs.code(ECAFE_INVALID_HANDLE),
|
|
_error_info=self.cs.info(ECAFE_INVALID_HANDLE))
|
|
raise _cafeException
|
|
|
|
# returns nelem
|
|
return self.hh.setNelemCtrl(handle, nelem)
|
|
|
|
##################################################################################
|
|
|
|
def setNelem(self, handlePV, unsigned int nelem):
|
|
cdef str _METHOD = "setNelem"
|
|
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First Input argument should be of type <class 'int'> "
|
|
"if handle, else <class 'str'> if PV")))
|
|
|
|
if handle == 0:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(ECAFE_INVALID_HANDLE)
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD, _error_code=ECAFE_INVALID_HANDLE,
|
|
_error_text=self.cs.code(ECAFE_INVALID_HANDLE),
|
|
_error_info=self.cs.info(ECAFE_INVALID_HANDLE))
|
|
raise _cafeException
|
|
|
|
|
|
# returns nelem
|
|
return self.hh.setNelem(handle, nelem)
|
|
|
|
############################################################################
|
|
def setNelemToNative(self, handlePV):
|
|
cdef str _METHOD = "setNelemToNative"
|
|
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First Input argument should be of type <class 'int'> "
|
|
"if handle, else <class 'str'> if PV")))
|
|
|
|
if handle == 0:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(ECAFE_INVALID_HANDLE)
|
|
_cafeException = CafeException(
|
|
_type='CafeError', _source=_METHOD,
|
|
_error_code=ECAFE_INVALID_HANDLE,
|
|
_error_text=self.cs.code(ECAFE_INVALID_HANDLE),
|
|
_error_info=self.cs.info(ECAFE_INVALID_HANDLE))
|
|
raise _cafeException
|
|
|
|
# returns nelem
|
|
return self.hh.setNelemToNative(handle)
|
|
|
|
##############################################################################
|
|
|
|
def setNelemToRetrieveFromCacheToOne(self, handlePV):
|
|
cdef str _METHOD = "setNelemToRetrieveFromCacheToOne"
|
|
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First Input argument should be of type <class 'int'> "
|
|
"if handle, else <class 'str'> if PV")))
|
|
|
|
if handle == 0:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(ECAFE_INVALID_HANDLE)
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def setNelemToRetrieveFromCacheToOne")
|
|
|
|
# returns previous nelem
|
|
return self._c_cafe.setNelemToRetrieveFromCacheToOne(handle)
|
|
|
|
################################################################################
|
|
def setNelemToRetrieveFromCache(self, handlePV, int netrfc):
|
|
cdef str _METHOD="etNelemToRetrieveFromCache"
|
|
cdef unsigned int handle = 0
|
|
if isinstance(handlePV, (int, long)):
|
|
handle = handlePV
|
|
elif isinstance(handlePV, (str)):
|
|
handle = self.checkForHandle(handlePV)
|
|
else:
|
|
raise TypeError("{} {} \n{}".format(
|
|
self._exception_text, _METHOD,
|
|
("First Input argument should be of type <class 'int'> "
|
|
"if handle, else <class 'str'> if PV")))
|
|
|
|
if handle == 0:
|
|
if PYCAFE_PRINT_LEVEL >= PYCAFE_PRINT_LOW:
|
|
self._c_cafe.printStatusMessage(ECAFE_INVALID_HANDLE)
|
|
raise Exception(
|
|
"EXCEPTION RAISED in PyCafe def setNelemToRetrieveFromCacheToOne")
|
|
|
|
# returns new nelem
|
|
return self._c_cafe.setNelemToRetrieveFromCacheToPrevious(handle, netrfc)
|
|
|
|
################################################################################
|
|
|
|
def terminate(self):
|
|
with nogil:
|
|
self._c_cafe.terminate()
|
|
return
|
|
################################################################################
|
|
|