Move all communications to separate class

This commit is contained in:
2023-08-18 09:26:45 +02:00
parent 20763016d9
commit 8a3a2340b9
2 changed files with 182 additions and 2 deletions

View File

@@ -80,11 +80,89 @@ pvNextAxisIndexNamePart2 = '-NxtObjId'
pvmiddlestring='Plg-Mtn'
class comSignal(QObject):
data_signal = pyqtSignal(object)
class dataItem():
def __init__(self,pvPrefix , pvSuffix, pluginId, sampleRateHz, maxTimeSeconds):
self.pvPrefix = pvPrefix
self.pvSuffix = pvSuffix
self.sampleRateHz = sampleRateHz
self.pluginId = pluginId
self.maxTimeSeconds = maxTimeSeconds
self.maxElements = int(self.maxTimeSeconds * self.sampleRateHz)
self.data = {}
self.allowDataCollection = False
self.pvName = self.pvPrefix + str(self.pluginId) + '-' + self.pvSuffix
if self.pvName is None:
raise RuntimeError("pvname must not be 'None'")
if len(self.pvName) == 0:
raise RuntimeError("pvname must not be ''")
# Signals
self.pvSignalCallback = comSignal()
self.pvSignalCallback.data_signal.connect(self.sigCallback)
# pv monitor callback
self.pv = epics.PV(self.pvName)
self.pv.add_callback(self.pvMonCallback)
# Signal callbacks (update gui)
def sigCallback(self, value):
if value is not None:
if len(value) > 1: # Array
self.addData(value)
else: # Scalar
self.data = value
# Call custom callback if needed
if self.extSigCallbackFunc is not None:
self.extSigCallbackFunc(value)
# Pv monitor callbacks
def pvMonCallback(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
self.pvSignalCallback.data_signal.emit(value)
# Call custom callback if needed
if self.extPvMonCallbackFunc is not None:
self.extPvMonCallbackFunc(pvname, value, char_value,timestamp, **kw)
def getData(self):
return self.data
def addData(self, values):
if not self.allowDataCollection:
return
# Check if first assignment
if self.data is None:
self.data = values
return
self.data=np.append(self.data,values)
# check if delete in beginning is needed
currcount = len(self.data)
# remove if needed
if currcount > self.maxElements:
self.data=self.data[currcount-self.maxElements:]
self.datalength = len(self.data)
def setAllowDataCollection(self,allow):
self.allowDataCollection = allow
def regExtSigCallback(self, func):
self.extSigCallbackFunc = func
def regExtPvMonCallback(self, func):
self.extPvMonCallbackFunc = func
class ecmcMtnMainGui(QtWidgets.QDialog):
def __init__(self,prefix=None,mtnPluginId=None):
def __init__(self,prefix="IOC_TEST:",mtnPluginId=0):
super(ecmcMtnMainGui, self).__init__()
self.pvnames = {}
@@ -95,6 +173,11 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
self.plottedLineAnalog = {}
self.plottedLineBinary = {}
self.testPV = dataItem(prefix + pvmiddlestring,'PosAct-Arr',mtnPluginId,1000,10)
self.testPV.regExtSigCallback(self.testSigCallback)
self.testPV.regExtPvMonCallback(self.testPVMonCallback)
self.testPV.setAllowDataCollection(True)
for pv in pvAnalog:
self.plottedLineAnalog[pv] = None
@@ -179,6 +262,16 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
self.resize(1000,850)
return
def testPVMonCallback(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
print('PV callback:')
print(pvname)
print(value)
def testSigCallback(self,value):
print('SIG callback:')
print(value)
def createWidgets(self):
self.graphicsLayoutWidget = pg.GraphicsLayoutWidget()
self.graphicsLayoutWidget.setBackground('w')
@@ -514,7 +607,7 @@ class ecmcMtnMainGui(QtWidgets.QDialog):
def sig_cb_PosAct_Arr(self,value):
if(np.size(value)) > 0:
self.MtnYDataValid = True
self.addData('PosAct-Arr', value)
self.addData('PosAct-Arr', value)
def sig_cb_PosSet_Arr(self,value):
self.addData('PosSet-Arr', value)

87
tools/ecmcPvDataItem.py Normal file
View File

@@ -0,0 +1,87 @@
import epics
import numpy as np
import time
import threading
class comSignal(QObject):
data_signal = pyqtSignal(object)
class dataItem():
def __init__(self,pvPrefix , pvSuffix, pluginId, sampleRateHz, maxTimeSeconds):
self.pvPrefix = pvPrefix
self.pvSuffix = pvSuffix
self.sampleRateHz = sampleRateHz
self.pluginId = pluginId
self.maxTimeSeconds = maxTimeSeconds
self.maxElements = int(self.maxTimeSeconds * self.sampleRateHz)
self.data = {}
self.allowDataCollection = False
self.pvName = self.pvPrefix + str(self.pluginId) + '-' + self.pvSuffix
if self.pvName is None:
raise RuntimeError("pvname must not be 'None'")
if len(self.pvName) == 0:
raise RuntimeError("pvname must not be ''")
# Signals
self.pvSignalCallback = comSignal()
self.pvSignalCallback.data_signal.connect(self.sigCallback)
# pv monitor callback
self.pv = epics.PV(self.pvName)
self.pv.add_callback(self.pvMonCallback)
# Signal callbacks (update gui)
def sigCallback(self, value):
if value is not None:
if len(value) > 1: # Array
self.addData(value)
else: # Scalar
self.data = value
# Call custom callback if needed
if self.extSigCallbackFunc is not None:
self.extSigCallbackFunc(value)
# Pv monitor callbacks
def pvMonCallback(self,pvname=None, value=None, char_value=None,timestamp=None, **kw):
self.pvSignalCallback.data_signal.emit(value)
# Call custom callback if needed
if self.extPvMonCallbackFunc is not None:
self.extPvMonCallbackFunc(pvname, value, char_value,timestamp, **kw)
def getData(self):
return self.data
def addData(self, values):
if not self.allowDataCollection:
return
# Check if first assignment
if self.data is None:
self.data = values
return
self.data=np.append(self.data,values)
# check if delete in beginning is needed
currcount = len(self.data)
# remove if needed
if currcount > self.maxElements:
self.data=self.data[currcount-self.maxElements:]
self.datalength = len(self.data)
def setAllowDataCollection(self,allow):
self.allowDataCollection = allow
def regExtSigCallback(self, func):
self.extSigCallbackFunc = func
def regExtPvMonCallback(self, func):
self.extPvMonCallbackFunc = func