From 8a9675eb7892f91f4df53ebc9043126e04292826 Mon Sep 17 00:00:00 2001 From: Philipp Klaus Date: Tue, 22 Aug 2017 10:37:49 +0200 Subject: [PATCH] OPUS20: MDEL/ADEL (via monkey patching PCASpy) --- LUFFT_OPUS20/lufft_opus20_driver.py | 47 +++++++++++++++++++++++++++++ LUFFT_OPUS20/lufft_opus20_pvdb.py | 15 ++++++--- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/LUFFT_OPUS20/lufft_opus20_driver.py b/LUFFT_OPUS20/lufft_opus20_driver.py index 56a21d8..4e1dfe7 100644 --- a/LUFFT_OPUS20/lufft_opus20_driver.py +++ b/LUFFT_OPUS20/lufft_opus20_driver.py @@ -1,9 +1,28 @@ from pcaspy import Driver, Alarm, Severity +from pcaspy.driver import manager +from pcaspy import PVInfo +from pcaspy import cas +import pcaspy from opus20 import Opus20, OPUS20_CHANNEL_SPEC, Opus20ConnectionException import time, threading +class ExtendedPVInfo(PVInfo): + """ + Derived class from PVInfo + Aim: monkey patching PVInfo to support MDEL/ADEL + """ + def __init__(self, info): + # initialize from info dict with defaults + self.mdel = info.get('mdel', None) + self.adel = info.get('adel', None) + PVInfo.__init__(self, info) + +# apply PVInfo monkey patch: +pcaspy.PVInfo = ExtendedPVInfo +pcaspy.driver.PVInfo = ExtendedPVInfo + class Opus20Driver(Driver): def __init__(self, hostname, opus20_port=None, opus20_timeout=0.1, scan_period=5.0): self.hostname = hostname @@ -15,6 +34,32 @@ class Opus20Driver(Driver): super(Opus20Driver, self).__init__() + def setParamValue(self, reason, value): + """ + overriding Driver.setParamValue() + + Made to support the ADEL/MDEL fields + """ + # check whether update is needed + same = self.pvDB[reason].value == value + if (type(same) == bool and not same) or (hasattr(same, 'all') and not same.all()): + # make a copy of mutable objects, list, numpy.ndarray + if isinstance(value, list): + value = value[:] + elif 'numpy.ndarray' in str(type(value)): + value = value.copy() + mask = 0 + pv = manager.pvs[self.port][reason] + abs_delta = abs(value-self.pvDB[reason].value) + if not pv.info.mdel or (abs_delta > pv.info.mdel): + mask |= cas.DBE_VALUE + if not pv.info.adel or (abs_delta > pv.info.adel): + mask |= cas.DBE_LOG + self.pvDB[reason].value = value + self.pvDB[reason].flag = True + self.pvDB[reason].mask = mask + self.pvDB[reason].time = cas.epicsTimeStamp() + def connect_opus20(self): kwargs = {} if self.opus20_port: kwargs['port'] = self.opus20_port @@ -44,12 +89,14 @@ class Opus20Driver(Driver): except: values = [None] * len(o20_ids) for i, reason in enumerate(pv_names): + self.pvDB[reason].mask = 0 if values[i] is not None: value = values[i] self.setParamStatus(reason, Alarm.NO_ALARM, Severity.NO_ALARM) self.setParam(reason, value) else: self.setParamStatus(reason, Alarm.COMM_ALARM, Severity.MINOR_ALARM) + manager.pvs[self.port][reason].updateValue(self.pvDB[reason]) # if the process was suspended, reset last_time: if time.time() - last_time > self.scan_period: diff --git a/LUFFT_OPUS20/lufft_opus20_pvdb.py b/LUFFT_OPUS20/lufft_opus20_pvdb.py index 4423f74..456ad6f 100644 --- a/LUFFT_OPUS20/lufft_opus20_pvdb.py +++ b/LUFFT_OPUS20/lufft_opus20_pvdb.py @@ -6,7 +6,8 @@ pvdb = { 'low' : 20, 'high' : 28, 'hihi' : 30, - 'scan' : 5, + 'mdel' : .05, + 'adel' : .20, 'asg' : 'readonly', }, 'RelativeHumidity' : { @@ -16,7 +17,8 @@ pvdb = { 'low' : 40, 'high' : 60, 'hihi' : 70, - 'scan' : 5, + 'mdel' : .15, + 'adel' : .60, 'asg' : 'readonly', }, 'AbsoluteHumidity' : { @@ -24,7 +26,8 @@ pvdb = { 'unit' : 'g/m3', 'low' : 5, 'high' : 20, - 'scan' : 5, + 'mdel' : .03, + 'adel' : .12, 'asg' : 'readonly', }, 'Dewpoint' : { @@ -34,7 +37,8 @@ pvdb = { 'low' : -10, 'high' : 16, 'hihi' : 20, - 'scan' : 5, + 'mdel' : .03, + 'adel' : .12, 'asg' : 'readonly', }, 'BatteryVoltage' : { @@ -44,7 +48,8 @@ pvdb = { 'low' : 5.3, 'high' : 6.2, 'hihi' : 6.5, - 'scan' : 5, + 'mdel' : .003, + 'adel' : .012, 'asg' : 'readonly', }, } -- 2.43.0