frappy.client.interactive: improve updates while driving
- instead to show first current 'value' and 'status', and then the changes, show changes only - this way updates appear in the expected order - for this SecopClient.register_callback needs a 'callimmediately' argument Change-Id: I3e91c2c15bca7fee2eba3b1bf1dd27313da3ae29 Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/36291 Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch> Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de>
This commit is contained in:
parent
8f2973c39d
commit
b1c920819e
@ -209,16 +209,20 @@ class ProxyClient:
|
||||
# caches (module, parameter) = value, timestamp, readerror (internal names!)
|
||||
self.cache = Cache() # dict returning Cache.undefined for missing keys
|
||||
|
||||
def register_callback(self, key, *args, callimmediately=None, **kwds):
|
||||
def register_callback(self, key, *args, callimmediately=True, **kwds):
|
||||
"""register callback functions
|
||||
|
||||
- key might be either:
|
||||
several callbacks might be registered within one call.
|
||||
ProxyClient.CALLBACK_NAMES contains all names of valid callbacks
|
||||
|
||||
:param key: might be either:
|
||||
1) None: general callback (all callbacks)
|
||||
2) <module name>: callbacks related to a module (not called for 'unhandledMessage')
|
||||
3) (<module name>, <parameter name>): callback for specified parameter (only called for 'updateEvent')
|
||||
- all the following arguments are callback functions. The callback name may be
|
||||
given by the keyword, or, for non-keyworded arguments it is taken from the
|
||||
__name__ attribute of the function
|
||||
3) (<module name>, <parameter name>): callback for specified parameter
|
||||
(only called for 'updateEvent' and 'updateItem')
|
||||
:param args: callback functions. the callback name is taken from the the __name__ attribute of the function
|
||||
:param callimmediately: True (default): call immediately for updateItem and updateEvent callbacks
|
||||
:param kwds: callback functions. the callback name is taken from the key
|
||||
"""
|
||||
for cbfunc in args:
|
||||
kwds[cbfunc.__name__] = cbfunc
|
||||
@ -226,8 +230,8 @@ class ProxyClient:
|
||||
if cbname not in self.CALLBACK_NAMES:
|
||||
raise TypeError(f"unknown callback: {', '.join(kwds)}")
|
||||
|
||||
# immediately call for some callback types
|
||||
if cbname in ('updateItem', 'updateEvent') and callimmediately is not False:
|
||||
# call immediately for some callback types
|
||||
if cbname in ('updateItem', 'updateEvent') and callimmediately:
|
||||
if key is None: # case generic callback
|
||||
cbargs = [(m, p, d) for (m, p), d in self.cache.items()]
|
||||
else:
|
||||
|
@ -143,7 +143,7 @@ class Module:
|
||||
def _isBusy(self):
|
||||
return self.status[0] // 100 == StatusType.BUSY // 100
|
||||
|
||||
def _status_value_update(self, m, p, status, t, e):
|
||||
def _status_update(self, m, p, status, t, e):
|
||||
if self._is_driving and not self._isBusy():
|
||||
self._is_driving = False
|
||||
self._driving_event.set()
|
||||
@ -216,10 +216,11 @@ class Module:
|
||||
def __call__(self, target=None):
|
||||
if target is None:
|
||||
return self.read()
|
||||
for pname in 'value', 'status':
|
||||
watch_params = ['value', 'status']
|
||||
for pname in watch_params:
|
||||
self._secnode.register_callback((self._name, pname),
|
||||
callimmediately=False,
|
||||
updateEvent=self._watch_parameter)
|
||||
updateEvent=self._watch_parameter,
|
||||
callimmediately=False)
|
||||
|
||||
self.target = target # this sets self._is_driving
|
||||
|
||||
@ -239,11 +240,10 @@ class Module:
|
||||
pass
|
||||
clientenv.raise_with_short_traceback(e)
|
||||
finally:
|
||||
# self._watch_parameter(self._name, 'status')
|
||||
self._secnode.readParameter(self._name, 'value')
|
||||
# self._watch_parameter(self._name, 'value', forced=True)
|
||||
self._secnode.unregister_callback((self._name, 'value'), updateEvent=self._watch_parameter)
|
||||
self._secnode.unregister_callback((self._name, 'status'), updateEvent=self._watch_parameter)
|
||||
for pname in watch_params:
|
||||
self._secnode.unregister_callback((self._name, pname),
|
||||
updateEvent=self._watch_parameter)
|
||||
return self.value
|
||||
|
||||
def __repr__(self):
|
||||
@ -418,8 +418,7 @@ class Client(SecopClient):
|
||||
attrs[cname] = Command(cname, modname, self)
|
||||
mobj = type(f'M_{modname}', (Module,), attrs)(modname, self)
|
||||
if 'status' in mobj._parameters:
|
||||
self.register_callback((modname, 'status'), updateEvent=mobj._status_value_update)
|
||||
self.register_callback((modname, 'value'), updateEvent=mobj._status_value_update)
|
||||
self.register_callback((modname, 'status'), updateEvent=mobj._status_update)
|
||||
clientenv.namespace[modname] = mobj
|
||||
if removed_modules:
|
||||
self.log.info('removed modules: %s', ' '.join(removed_modules))
|
||||
|
Loading…
x
Reference in New Issue
Block a user