From 2ff3a17427cb0a8deca72ba6d50952777df68b55 Mon Sep 17 00:00:00 2001 From: Markus Zolliker Date: Tue, 6 Jul 2021 16:25:35 +0200 Subject: [PATCH] fix simulation Change-Id: Iaa05d3a7a78b6000ab3c372074bf4053dd74aadb --- secop/simulation.py | 84 ++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/secop/simulation.py b/secop/simulation.py index d21b577..ece98c6 100644 --- a/secop/simulation.py +++ b/secop/simulation.py @@ -22,8 +22,6 @@ """Define Simulation classes""" -# TODO: rework after syntax change! - import random from time import sleep @@ -36,82 +34,76 @@ from secop.modules import BasicPoller, Drivable, \ class SimBase: pollerClass = BasicPoller - def __init__(self, cfgdict): - # spice up parameters if requested by extra property - # hint: us a comma-separated list if mor than one extra_param - # BIG FAT WARNING: changing extra params will NOT generate events! - # XXX: implement default read_* and write_* methods to handle - # read and change messages correctly - if '.extra_params' in cfgdict: - extra_params = cfgdict.pop('.extra_params') - # make a copy of self.parameter - self.accessibles = dict((k, v.copy()) for k, v in self.accessibles.items()) + def __new__(cls, devname, logger, cfgdict, dispatcher): + extra_params = cfgdict.pop('extra_params', '') or cfgdict.pop('.extra_params', '') + attrs = {} + if extra_params: for k in extra_params.split(','): k = k.strip() - self.accessibles[k] = Parameter('extra_param: %s' % k.strip(), - datatype=FloatRange(), - default=0.0) - def reader(pname=k): + attrs[k] = Parameter('extra_param: %s' % k.strip(), + datatype=FloatRange(), + default=0.0) + + def reader(self, pname=k): self.log.debug('simulated reading %s' % pname) - return self.accessibles[pname].value - setattr(self, 'read_' + k, reader) - def writer(newval, pname=k): + return self.parameters[pname].value + + attrs['read_' + k] = reader + + def writer(self, newval, pname=k): self.log.debug('simulated writing %r to %s' % (newval, pname)) - self.accessibles[pname].value = newval + self.parameters[pname].value = newval return newval - setattr(self, 'write_' + k, writer) + + attrs['write_' + k] = writer + + return object.__new__(type('SimBase_%s' % devname, (cls,), attrs)) def initModule(self): self._sim_thread = mkthread(self._sim) def _sim(self): try: - while not self.sim(): - pass + if not self.sim(): + self.log.info('sim thread running') + while not self.sim(): + pass + self.log.info('sim thread ended') except Exception as e: self.log.exception(e) - self.log.info('sim thread ended') def sim(self): - return True # nothing to do, stop thread - - def read_value(self): - if 'jitter' in self.accessibles: - return self._value + self.jitter*(0.5-random.random()) - return self._value + return True # nothing to do, stop thread class SimModule(SimBase, Module): - def __init__(self, devname, logger, cfgdict, dispatcher): - SimBase.__init__(self, cfgdict) - Module.__init__(self, devname, logger, cfgdict, dispatcher) + pass class SimReadable(SimBase, Readable): def __init__(self, devname, logger, cfgdict, dispatcher): - SimBase.__init__(self, cfgdict) - Readable.__init__(self, devname, logger, cfgdict, dispatcher) - self._value = self.accessibles['value'].default + super().__init__(devname, logger, cfgdict, dispatcher) + self._value = self.parameters['value'].default + + def read_value(self): + if 'jitter' in self.parameters: + return self._value + self.jitter * (0.5 - random.random()) + return self._value -class SimWritable(SimBase, Writable): - def __init__(self, devname, logger, cfgdict, dispatcher): - SimBase.__init__(self, cfgdict) - Writable.__init__(self, devname, logger, cfgdict, dispatcher) - self._value = self.accessibles['value'].default +class SimWritable(SimReadable, Writable): + def read_value(self): return self.target + def write_target(self, value): self.value = value def _hw_wait(self): pass -class SimDrivable(SimBase, Drivable): - def __init__(self, devname, logger, cfgdict, dispatcher): - SimBase.__init__(self, cfgdict) - Drivable.__init__(self, devname, logger, cfgdict, dispatcher) - self._value = self.accessibles['value'].default + +class SimDrivable(SimReadable, Drivable): def sim(self): while self._value == self.target: