[WIP] work on history writer
Change-Id: If8c42091c734fb8c7b386c06429f1b21a7e169ec
This commit is contained in:
@ -27,7 +27,7 @@ import inspect
|
||||
|
||||
from secop.datatypes import BoolType, CommandType, DataType, \
|
||||
DataTypeType, EnumType, IntRange, NoneOr, OrType, \
|
||||
StringType, StructOf, TextType, TupleOf, ValueType
|
||||
StringType, StructOf, TextType, TupleOf, ValueType, ArrayOf
|
||||
from secop.errors import BadValueError, ProgrammingError
|
||||
from secop.properties import HasProperties, Property
|
||||
|
||||
@ -163,6 +163,52 @@ class Parameter(Accessible):
|
||||
|
||||
default None: write if given in config''', NoneOr(BoolType()),
|
||||
export=False, default=None, settable=False)
|
||||
history_category = Property(
|
||||
'''[custom] category for history
|
||||
|
||||
major: should be shown by default in a history chart, default for value and target
|
||||
minor: to be shown optionally in a history chart, default for other parameters
|
||||
no: history is not saved. default for TextType and ArrayOf
|
||||
|
||||
category is ignored (forced to no) for BlobType
|
||||
|
||||
For structured types, the category may be a comma separated list, overwriting the
|
||||
default for the first or all curves.
|
||||
If it does not contain a comma, it applies for all curves
|
||||
''',
|
||||
NoneOr(StringType()), export=True, default=None, settable=False)
|
||||
history_label = Property(
|
||||
'''[custom] label for history
|
||||
|
||||
default: <modname>:<parname> or <modname> for main value
|
||||
|
||||
For structured types, the label may be a comma separated list, overwriting the
|
||||
default for the first or all curves.
|
||||
If it does not contain a comma, it applies for the first curve only.
|
||||
''',
|
||||
NoneOr(StringType()), export=True, default=None, settable=False)
|
||||
history_group = Property(
|
||||
'''[custom] group for history
|
||||
|
||||
default: unit
|
||||
|
||||
For structured types, the group may be a comma separated list, overwriting the
|
||||
default for the first or all curves. If it does not contain a comma, it is
|
||||
applies for all curves.
|
||||
''',
|
||||
NoneOr(StringType()), export=True, default=None, settable=False)
|
||||
history_stepped = Property(
|
||||
'''[custom] stepped curve
|
||||
|
||||
Whether a curve has to be drawn stepped or connected.
|
||||
default: True when readonly=False, else False
|
||||
|
||||
Applicable to FloatRange and ScaledInteger only, other types are stepped by definition.
|
||||
|
||||
For structured types, stepped may be a list, overwriting the default for the
|
||||
first or all curves. If not, applieas to all curves.
|
||||
''',
|
||||
OrType(BoolType(), ArrayOf(BoolType())), export=True, default=False, settable=False)
|
||||
|
||||
# used on the instance copy only
|
||||
value = None
|
||||
|
@ -47,7 +47,8 @@ from secop.errors import NoSuchCommandError, NoSuchModuleError, \
|
||||
from secop.params import Parameter
|
||||
from secop.protocol.messages import COMMANDREPLY, DESCRIPTIONREPLY, \
|
||||
DISABLEEVENTSREPLY, ENABLEEVENTSREPLY, ERRORPREFIX, EVENTREPLY, \
|
||||
HEARTBEATREPLY, IDENTREPLY, IDENTREQUEST, READREPLY, WRITEREPLY
|
||||
HEARTBEATREPLY, IDENTREPLY, IDENTREQUEST, READREPLY, WRITEREPLY, \
|
||||
ERRORCLOSED
|
||||
|
||||
|
||||
def make_update(modulename, pobj):
|
||||
@ -297,6 +298,7 @@ class Dispatcher:
|
||||
self.log.error('should have been handled in the interface!')
|
||||
|
||||
def handle__ident(self, conn, specifier, data):
|
||||
self._active_connections.discard(conn)
|
||||
return (IDENTREPLY, None, None)
|
||||
|
||||
def handle_describe(self, conn, specifier, data):
|
||||
@ -372,3 +374,12 @@ class Dispatcher:
|
||||
self._active_connections.discard(conn)
|
||||
# XXX: also check all entries in self._subscriptions?
|
||||
return (DISABLEEVENTSREPLY, None, None)
|
||||
|
||||
def close(self):
|
||||
for conn in self._connections:
|
||||
try:
|
||||
# - may be used for the 'closed' message in serial interface
|
||||
# - is used in frappy history for indicating the close time
|
||||
conn.close_message((ERRORCLOSED, None, None))
|
||||
except AttributeError:
|
||||
pass
|
||||
|
@ -62,6 +62,8 @@ HEARTBEATREPLY = 'pong' # +nonce_without_space
|
||||
|
||||
ERRORPREFIX = 'error_' # + specifier + json_extended_info(error_report)
|
||||
|
||||
ERRORCLOSED = 'error_closed'
|
||||
|
||||
HELPREQUEST = 'help' # literal
|
||||
HELPREPLY = 'helping' # +line number +json_text
|
||||
|
||||
|
@ -35,7 +35,6 @@ from collections import OrderedDict
|
||||
from secop.errors import ConfigError, SECoPError
|
||||
from secop.lib import formatException, get_class, getGeneralConfig
|
||||
from secop.modules import Attached
|
||||
from secop.params import PREDEFINED_ACCESSIBLES
|
||||
|
||||
try:
|
||||
from daemon import DaemonContext
|
||||
@ -207,7 +206,11 @@ class Server:
|
||||
self.log.info('startup done, handling transport messages')
|
||||
if systemd:
|
||||
systemd.daemon.notify("READY=1\nSTATUS=accepting requests")
|
||||
self.interface.serve_forever()
|
||||
try:
|
||||
self.interface.serve_forever()
|
||||
except KeyboardInterrupt as e:
|
||||
self._restart = False
|
||||
self.dispatcher.close()
|
||||
self.interface.server_close()
|
||||
if self._restart:
|
||||
self.restart_hook()
|
||||
@ -329,11 +332,8 @@ class Server:
|
||||
self.log.info('all modules and pollers started')
|
||||
history_path = os.environ.get('FRAPPY_HISTORY')
|
||||
if history_path:
|
||||
from secop_psi.historywriter import FrappyHistoryWriter # pylint: disable=import-outside-toplevel
|
||||
writer = FrappyHistoryWriter(history_path, PREDEFINED_ACCESSIBLES.keys(), self.dispatcher)
|
||||
# treat writer as a connection
|
||||
self.dispatcher.add_connection(writer)
|
||||
writer.init(self.dispatcher.handle_describe(writer, None, None))
|
||||
from secop_psi.historywriter import add_writer # pylint: disable=import-outside-toplevel
|
||||
add_writer(history_path, self)
|
||||
# TODO: if ever somebody wants to implement an other history writer:
|
||||
# - a general config file /etc/secp/secop.conf or <frappy repo>/etc/secop.conf
|
||||
# might be introduced, which contains the log, pid and cfg directory path and
|
||||
|
Reference in New Issue
Block a user