frappy_psi.sea: fix issue with missing BUSY after change target

The command 'maw' in NICOS sometimes does complete immediately
instead of waiting for reaching the target. It seems this affects
only SEA drivables. The more important fix for this has to be
done in SEA. The fix here is just to improve behaviour in case
SEA would not do as expected.
This commit is contained in:
l_samenv 2024-08-08 16:35:28 +02:00
parent 2f396e5897
commit 258ec60b4c

View File

@ -39,7 +39,7 @@ from os.path import expanduser, join, exists
from frappy.client import ProxyClient
from frappy.datatypes import ArrayOf, BoolType, \
EnumType, FloatRange, IntRange, StringType, StatusType
from frappy.core import IDLE, BUSY, ERROR, DISABLED
from frappy.core import IDLE, BUSY, WARN, ERROR, DISABLED
from frappy.errors import ConfigError, HardwareError, ReadFailedError, CommunicationFailedError
from frappy.lib import generalConfig, mkthread
from frappy.lib.asynconn import AsynConn, ConnectionClosed
@ -662,9 +662,6 @@ class SeaModule(Module):
self.io.register_obj(self, self.sea_object)
super().initModule()
def doPoll(self):
pass
class SeaReadable(SeaModule, Readable):
_readerror = None
@ -683,6 +680,7 @@ class SeaReadable(SeaModule, Readable):
self.read_status() # send event for ordinary self._status
def update_status(self, value, timestamp, readerror):
# value is the sea status, which is a string, not the SECoP status!
if 'disable' in value.lower():
self._status = DISABLED, value
elif value == '':
@ -698,6 +696,9 @@ class SeaReadable(SeaModule, Readable):
return ERROR, f'{self._readerror.name} - {self._readerror}'
return self._status
def doPoll(self):
self.read_status()
class SeaWritable(SeaReadable, Writable):
def read_value(self):
@ -710,35 +711,53 @@ class SeaWritable(SeaReadable, Writable):
class SeaDrivable(SeaReadable, Drivable):
_is_running = 0
_is_driving = False
_is_running = 0 # SEA is_running flag
_bad_limit = 5
_bad_start = 0 # is set to start time when is_running is not immediately true
status = Parameter(datatype=StatusType(Drivable, 'DISABLED'))
def earlyInit(self):
super().earlyInit()
self._run_event = threading.Event()
def write_target(self, value):
self._run_event.clear()
self._is_driving = True
if not self._is_running:
self._is_running = None
self._bad_start = 0
self.io.query(f'run {self.sea_object} {value}')
if not self._run_event.wait(5):
self.log.warn('target changed but is_running stays 0')
if not self._is_running:
self.log.warn('is_running is not set after run')
self._bad_start = time.time()
self.status = BUSY, 'changed target'
return value
def update_is_running(self, value, timestamp, readerror):
if not readerror:
self._is_running = value
self.read_status()
if value:
self._run_event.set()
def read_status(self):
status = super().read_status()
if self._is_running:
if status[0] >= ERROR:
if status[0] >= ERROR:
if self._is_driving:
return ERROR, 'BUSY + ' + status[1]
return BUSY, 'driving'
return status
return status
if self._is_driving:
if time.time() < self._bad_start + self._bad_limit:
if self._is_running:
self.log.warn('is_running flag delayed by %.2g sec', time.time() - self._bad_start)
self._bad_start = 0
return BUSY, 'waiting for is_running'
if self._is_running:
self._bad_start = 0
return BUSY, 'driving'
if self._is_running is None:
self.log.warn('miss is_running update within delay')
self._is_driving = False
if self._bad_start:
self.log.warn('started, but not running')
if self._bad_start:
return IDLE, f'started, but not running'
return IDLE, ''
def updateTarget(self, module, parameter, value, timestamp, readerror):
if value is not None: