migrated secop_psi drivers to new syntax

- includes all changes up to 'fix inheritance order' from git_mlz
  6a32ecf342

Change-Id: Ie3ceee3dbd0a9284b47b1d5b5dbe262eebe8f283
This commit is contained in:
2021-02-24 16:15:23 +01:00
parent bc5edec06f
commit 41baf5805f
79 changed files with 2610 additions and 3952 deletions

View File

@ -32,21 +32,21 @@ t1:raw tt t1/raw /tt/t1/raw tt t1 raw /tt/t1
rx:bla rx bla /some/rx_a/bla rx bla /some/rx_a
"""
import json
import threading
import time
import json
from os.path import join, expanduser
from os.path import expanduser, join
from secop.modules import Module, Parameter, Command, Override, Drivable, Readable, Writable, Property, Attached
from secop.datatypes import StringType, FloatRange, ArrayOf, BoolType, IntRange, EnumType
from secop.lib import mkthread, getGeneralConfig
from secop.lib.asynconn import AsynConn, ConnectionClosed
from secop.metaclass import ModuleMeta, Done
from secop.errors import HardwareError, secop_error, ConfigError
from secop.client import ProxyClient
from secop.datatypes import ArrayOf, BoolType, \
EnumType, FloatRange, IntRange, StringType
from secop.errors import ConfigError, HardwareError, secop_error
from secop.lib import getGeneralConfig, mkthread
from secop.lib.asynconn import AsynConn, ConnectionClosed
from secop.modules import Attached, Command, Done, Drivable, \
Module, Parameter, Property, Readable, Writable
from secop.protocol.dispatcher import make_update
CFG_HEADER = """[NODE]
id = %(samenv)s.psi.ch
description = %(samenv)s over SEA
@ -76,7 +76,7 @@ def get_sea_port(instance):
for line in f:
linesplit = line.split()
if len(linesplit) == 3:
cmd, var, value = line.split()
_, var, value = line.split()
if var == 'serverport':
return value
except FileNotFoundError:
@ -87,23 +87,10 @@ def get_sea_port(instance):
class SeaClient(ProxyClient, Module):
"""connection to SEA"""
properties = {
'json_path': Property('path to SEA json descriptors',
datatype=StringType(),
default=join(expanduser('~'), 'sea/tcl/json'))
}
parameters = {
'uri':
Parameter('hostname:portnumber', datatype=StringType(), default='localhost:5000'),
'timeout':
Parameter('timeout', datatype=FloatRange(0), default=10),
}
commands = {
'communicate':
Command('send a command to SEA', argument=StringType(), result=StringType()),
'describe':
Command('save objects (and sub-objects) description', result=StringType()),
}
json_path = Property('path to SEA json descriptors', StringType())
uri = Parameter('hostname:portnumber', datatype=StringType(), default='localhost:5000')
timeout = Parameter('timeout', datatype=FloatRange(0), default=10)
def __init__(self, name, log, opts, srv):
instance = srv.node_cfg['name'].rsplit('_', 1)[0]
@ -198,7 +185,7 @@ class SeaClient(ProxyClient, Module):
if msg.startswith('_E '):
try:
_, path, readerror = msg.split(None, 2)
except Exception as e:
except ValueError:
continue
else:
continue
@ -241,11 +228,15 @@ class SeaClient(ProxyClient, Module):
# do not update unchanged values within 0.1 sec
self.updateValue(module, param, value, now, readerror)
def do_communicate(self, command):
@Command
def communicate(self, command):
"""send a command to SEA"""
reply = self.request(command)
return reply
def do_describe(self):
@Command(result=StringType())
def describe(self):
"""save objects (and sub-objects) description"""
reply = self.request('describe_all')
reply = ''.join('' if line.startswith('WARNING') else line for line in reply.split('\n'))
samenv, reply = json.loads(reply)
@ -288,9 +279,7 @@ def get_datatype(paramdesc):
class SeaModule(Module):
properties = {
'iodev': Attached(),
}
iodev = Attached()
# pollerClass=None
path2param = None
@ -329,8 +318,7 @@ class SeaModule(Module):
else: # take all
main = ''
path2param = {}
parameters = {}
attributes = dict(sea_object=sea_object, path2param=path2param, parameters=parameters)
attributes = dict(sea_object=sea_object, path2param=path2param)
for paramdesc in descr:
path = paramdesc['path']
readonly = paramdesc.get('readonly', True)
@ -351,6 +339,7 @@ class SeaModule(Module):
else:
kwds['group'] = pathlist[-2]
# flatten path to parameter name
key = None
for i in reversed(range(len(pathlist))):
key = '_'.join(pathlist[i:])
if not key in cls.accessibles:
@ -361,12 +350,12 @@ class SeaModule(Module):
if key in cls.accessibles:
if key == 'target':
kwds['readonly'] = False
pobj = Override(**kwds)
pobj = cls.accessibles[key].override(**kwds)
datatype = kwds.get('datatype', cls.accessibles[key].datatype)
else:
pobj = Parameter(**kwds)
datatype = pobj.datatype
parameters[key] = pobj
attributes[key] = pobj
if not hasattr(cls, 'read_' + key):
def rfunc(self, cmd='hval /sics/%s/%s' % (sea_object, path)):
print('READ', cmd)
@ -395,19 +384,20 @@ class SeaModule(Module):
return Done
attributes['write_' + key] = wfunc
# create standard parameters like value and status, if not yet there
for pname, pobj in cls.accessibles.items():
if pname == 'pollinterval':
parameters[pname] = Override(export=False)
elif pname not in parameters and isinstance(pobj, Parameter):
parameters[pname] = Override(poll=False, needscfg=False)
attributes[pname] = pobj.override(export=False)
elif pname not in attributes and isinstance(pobj, Parameter):
attributes[pname] = pobj.override(poll=False, needscfg=False)
classname = '%s_%s' % (cls.__name__, sea_object)
newcls = ModuleMeta.__new__(ModuleMeta, classname, (cls,), attributes)
newcls = type(classname, (cls,), attributes)
return Module.__new__(newcls)
def __init__(self, name, logger, cfgdict, dispatcher):
Module.__init__(self, name, logger, cfgdict, dispatcher)
# def __init__(self, name, logger, cfgdict, dispatcher):
# Module.__init__(self, name, logger, cfgdict, dispatcher)
def updateEvent(self, module, parameter, value, timestamp, readerror):
upd = getattr(self, 'update_' + parameter, None)
@ -442,9 +432,9 @@ class SeaReadable(SeaModule, Readable):
if readerror:
value = repr(readerror)
if value == '':
self.status = [self.Status.IDLE, '']
self.status = (self.Status.IDLE, '')
else:
self.status = [self.Status.ERROR, value]
self.status = (self.Status.ERROR, value)
def read_status(self):
return self.status
@ -485,11 +475,11 @@ class SeaDrivable(SeaModule, Drivable):
def updateStatus(self):
if self._sea_status:
self.status = [self.Status.ERROR, self._sea_status]
self.status = (self.Status.ERROR, self._sea_status)
elif self._is_running:
self.status = [self.Status.BUSY, 'driving']
self.status = (self.Status.BUSY, 'driving')
else:
self.status = [self.Status.IDLE, '']
self.status = (self.Status.IDLE, '')
def updateTarget(self, module, parameter, value, timestamp, readerror):
if value is not None: