omit updates of unchanged values within short time
Sometimes it happens, that the same value determined once is assigned several times to a parameter within a very short period. Sending multiple updates is not useful in this case. Change-Id: Icea66934c831fd9b2eac7d0394a124d002469914 Reviewed-on: https://forge.frm2.tum.de/review/c/sine2020/secop/playground/+/27091 Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de> Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
This commit is contained in:
parent
a64eb7f33b
commit
d76d79aebb
@ -29,7 +29,7 @@ from collections import OrderedDict
|
|||||||
|
|
||||||
from secop.datatypes import ArrayOf, BoolType, EnumType, FloatRange, \
|
from secop.datatypes import ArrayOf, BoolType, EnumType, FloatRange, \
|
||||||
IntRange, StatusType, StringType, TextType, TupleOf
|
IntRange, StatusType, StringType, TextType, TupleOf
|
||||||
from secop.errors import BadValueError, ConfigError, InternalError, \
|
from secop.errors import BadValueError, ConfigError, \
|
||||||
ProgrammingError, SECoPError, SilentError, secop_error
|
ProgrammingError, SECoPError, SilentError, secop_error
|
||||||
from secop.lib import formatException, mkthread
|
from secop.lib import formatException, mkthread
|
||||||
from secop.lib.enum import Enum
|
from secop.lib.enum import Enum
|
||||||
@ -243,12 +243,12 @@ class Module(HasAccessibles):
|
|||||||
|
|
||||||
# reference to the dispatcher (used for sending async updates)
|
# reference to the dispatcher (used for sending async updates)
|
||||||
DISPATCHER = None
|
DISPATCHER = None
|
||||||
|
|
||||||
pollerClass = Poller #: default poller used
|
pollerClass = Poller #: default poller used
|
||||||
|
|
||||||
def __init__(self, name, logger, cfgdict, srv):
|
def __init__(self, name, logger, cfgdict, srv):
|
||||||
# remember the dispatcher object (for the async callbacks)
|
# remember the dispatcher object (for the async callbacks)
|
||||||
self.DISPATCHER = srv.dispatcher
|
self.DISPATCHER = srv.dispatcher
|
||||||
|
self.omit_unchanged_within = getattr(self.DISPATCHER, 'omit_unchanged_within', 0.1)
|
||||||
self.log = logger
|
self.log = logger
|
||||||
self.name = name
|
self.name = name
|
||||||
self.valueCallbacks = {}
|
self.valueCallbacks = {}
|
||||||
@ -441,18 +441,21 @@ class Module(HasAccessibles):
|
|||||||
def announceUpdate(self, pname, value=None, err=None, timestamp=None):
|
def announceUpdate(self, pname, value=None, err=None, timestamp=None):
|
||||||
"""announce a changed value or readerror"""
|
"""announce a changed value or readerror"""
|
||||||
pobj = self.parameters[pname]
|
pobj = self.parameters[pname]
|
||||||
if value is not None:
|
timestamp = timestamp or time.time()
|
||||||
pobj.value = value # store the value even in case of error
|
changed = pobj.value != value
|
||||||
if err:
|
|
||||||
if not isinstance(err, SECoPError):
|
|
||||||
err = InternalError(err)
|
|
||||||
if str(err) == str(pobj.readerror):
|
|
||||||
return # do call updates for repeated errors
|
|
||||||
else:
|
|
||||||
try:
|
try:
|
||||||
|
# store the value even in case of error
|
||||||
pobj.value = pobj.datatype(value)
|
pobj.value = pobj.datatype(value)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
err = secop_error(e)
|
if not err: # do not overwrite given error
|
||||||
|
err = e
|
||||||
|
if err:
|
||||||
|
err = secop_error(err)
|
||||||
|
if str(err) == str(pobj.readerror):
|
||||||
|
return # do call updates for repeated errors
|
||||||
|
elif not changed and timestamp < (pobj.timestamp or 0) + self.omit_unchanged_within:
|
||||||
|
# no change within short time -> omit
|
||||||
|
return
|
||||||
pobj.timestamp = timestamp or time.time()
|
pobj.timestamp = timestamp or time.time()
|
||||||
pobj.readerror = err
|
pobj.readerror = err
|
||||||
if pobj.export:
|
if pobj.export:
|
||||||
|
@ -60,10 +60,11 @@ def make_update(modulename, pobj):
|
|||||||
|
|
||||||
|
|
||||||
class Dispatcher:
|
class Dispatcher:
|
||||||
|
|
||||||
def __init__(self, name, logger, options, srv):
|
def __init__(self, name, logger, options, srv):
|
||||||
# to avoid errors, we want to eat all options here
|
# to avoid errors, we want to eat all options here
|
||||||
self.equipment_id = options.pop('id', name)
|
self.equipment_id = options.pop('id', name)
|
||||||
|
# time interval for omitting updates of unchanged values
|
||||||
|
self.omit_unchanged_within = options.pop('omit_unchanged_within', 0.1)
|
||||||
self.nodeprops = {}
|
self.nodeprops = {}
|
||||||
for k in list(options):
|
for k in list(options):
|
||||||
self.nodeprops[k] = options.pop(k)
|
self.nodeprops[k] = options.pop(k)
|
||||||
|
@ -71,6 +71,12 @@ class Data:
|
|||||||
|
|
||||||
|
|
||||||
class DispatcherStub:
|
class DispatcherStub:
|
||||||
|
# the first update from the poller comes a very short time after the
|
||||||
|
# initial value from the timestamp. However, in the test below
|
||||||
|
# the second update happens after the updates dict is cleared
|
||||||
|
# -> we have to inhibit the 'omit unchanged update' feature
|
||||||
|
omit_unchanged_within = 0
|
||||||
|
|
||||||
def __init__(self, updates):
|
def __init__(self, updates):
|
||||||
self.updates = updates
|
self.updates = updates
|
||||||
|
|
||||||
|
@ -34,7 +34,11 @@ from secop.poller import BasicPoller
|
|||||||
|
|
||||||
|
|
||||||
class DispatcherStub:
|
class DispatcherStub:
|
||||||
OMIT_UNCHANGED_WITHIN = 0
|
# the first update from the poller comes a very short time after the
|
||||||
|
# initial value from the timestamp. However, in the test below
|
||||||
|
# the second update happens after the updates dict is cleared
|
||||||
|
# -> we have to inhibit the 'omit unchanged update' feature
|
||||||
|
omit_unchanged_within = 0
|
||||||
|
|
||||||
def __init__(self, updates):
|
def __init__(self, updates):
|
||||||
self.updates = updates
|
self.updates = updates
|
||||||
|
Loading…
x
Reference in New Issue
Block a user