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!)
|
# caches (module, parameter) = value, timestamp, readerror (internal names!)
|
||||||
self.cache = Cache() # dict returning Cache.undefined for missing keys
|
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
|
"""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)
|
1) None: general callback (all callbacks)
|
||||||
2) <module name>: callbacks related to a module (not called for 'unhandledMessage')
|
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')
|
3) (<module name>, <parameter name>): callback for specified parameter
|
||||||
- all the following arguments are callback functions. The callback name may be
|
(only called for 'updateEvent' and 'updateItem')
|
||||||
given by the keyword, or, for non-keyworded arguments it is taken from the
|
:param args: callback functions. the callback name is taken from the the __name__ attribute of the function
|
||||||
__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:
|
for cbfunc in args:
|
||||||
kwds[cbfunc.__name__] = cbfunc
|
kwds[cbfunc.__name__] = cbfunc
|
||||||
@ -226,8 +230,8 @@ class ProxyClient:
|
|||||||
if cbname not in self.CALLBACK_NAMES:
|
if cbname not in self.CALLBACK_NAMES:
|
||||||
raise TypeError(f"unknown callback: {', '.join(kwds)}")
|
raise TypeError(f"unknown callback: {', '.join(kwds)}")
|
||||||
|
|
||||||
# immediately call for some callback types
|
# call immediately for some callback types
|
||||||
if cbname in ('updateItem', 'updateEvent') and callimmediately is not False:
|
if cbname in ('updateItem', 'updateEvent') and callimmediately:
|
||||||
if key is None: # case generic callback
|
if key is None: # case generic callback
|
||||||
cbargs = [(m, p, d) for (m, p), d in self.cache.items()]
|
cbargs = [(m, p, d) for (m, p), d in self.cache.items()]
|
||||||
else:
|
else:
|
||||||
|
@ -143,7 +143,7 @@ class Module:
|
|||||||
def _isBusy(self):
|
def _isBusy(self):
|
||||||
return self.status[0] // 100 == StatusType.BUSY // 100
|
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():
|
if self._is_driving and not self._isBusy():
|
||||||
self._is_driving = False
|
self._is_driving = False
|
||||||
self._driving_event.set()
|
self._driving_event.set()
|
||||||
@ -216,10 +216,11 @@ class Module:
|
|||||||
def __call__(self, target=None):
|
def __call__(self, target=None):
|
||||||
if target is None:
|
if target is None:
|
||||||
return self.read()
|
return self.read()
|
||||||
for pname in 'value', 'status':
|
watch_params = ['value', 'status']
|
||||||
|
for pname in watch_params:
|
||||||
self._secnode.register_callback((self._name, pname),
|
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
|
self.target = target # this sets self._is_driving
|
||||||
|
|
||||||
@ -239,11 +240,10 @@ class Module:
|
|||||||
pass
|
pass
|
||||||
clientenv.raise_with_short_traceback(e)
|
clientenv.raise_with_short_traceback(e)
|
||||||
finally:
|
finally:
|
||||||
# self._watch_parameter(self._name, 'status')
|
|
||||||
self._secnode.readParameter(self._name, 'value')
|
self._secnode.readParameter(self._name, 'value')
|
||||||
# self._watch_parameter(self._name, 'value', forced=True)
|
for pname in watch_params:
|
||||||
self._secnode.unregister_callback((self._name, 'value'), updateEvent=self._watch_parameter)
|
self._secnode.unregister_callback((self._name, pname),
|
||||||
self._secnode.unregister_callback((self._name, 'status'), updateEvent=self._watch_parameter)
|
updateEvent=self._watch_parameter)
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -418,8 +418,7 @@ class Client(SecopClient):
|
|||||||
attrs[cname] = Command(cname, modname, self)
|
attrs[cname] = Command(cname, modname, self)
|
||||||
mobj = type(f'M_{modname}', (Module,), attrs)(modname, self)
|
mobj = type(f'M_{modname}', (Module,), attrs)(modname, self)
|
||||||
if 'status' in mobj._parameters:
|
if 'status' in mobj._parameters:
|
||||||
self.register_callback((modname, 'status'), updateEvent=mobj._status_value_update)
|
self.register_callback((modname, 'status'), updateEvent=mobj._status_update)
|
||||||
self.register_callback((modname, 'value'), updateEvent=mobj._status_value_update)
|
|
||||||
clientenv.namespace[modname] = mobj
|
clientenv.namespace[modname] = mobj
|
||||||
if removed_modules:
|
if removed_modules:
|
||||||
self.log.info('removed modules: %s', ' '.join(removed_modules))
|
self.log.info('removed modules: %s', ' '.join(removed_modules))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user