allow multiple SecNode connections
+ change layout when console is not to be shown + catch file not found error
This commit is contained in:
@ -73,10 +73,10 @@ new Settings()
|
||||
.treat("debugGraphics", "dg", to_bool, false)
|
||||
.treat("hostPort", "hp", 0, location.hostname + ":" + location.port)
|
||||
.treat("showMain", "sm", to_bool, true)
|
||||
.treat("showConsole", "sc", to_bool, true)
|
||||
.treat("showConsole", "sc", to_bool, false)
|
||||
.treat("showOverview", "so", to_bool, false)
|
||||
.treat("showGraphics", "sg", to_bool, true) // false)
|
||||
.treat("hideRightPart", "hr", to_bool, true) //used to completely disable the right part
|
||||
.treat("hideRightPart", "hr", to_bool, false) //used to completely disable the right part
|
||||
.treat("wideGraphs", "wg", to_bool, false) //used to toggle the size of the graphs part
|
||||
.treat("showAsync", "sa", to_bool, false)
|
||||
|
||||
|
@ -94,7 +94,7 @@ function adjustGrid() {
|
||||
case 2:
|
||||
rightWidth = Math.min(50, MINWIDTH / width * 100);
|
||||
leftWidth = 100 - rightWidth;
|
||||
if (nRows == 1) {
|
||||
if (nRows == 1 || !window['showConsole']) {
|
||||
style(0,leftWidth + "vw","100vh");
|
||||
style(1,rightWidth + "vw","100vh");
|
||||
style(2); // hide
|
||||
@ -109,7 +109,7 @@ function adjustGrid() {
|
||||
case 3:
|
||||
rightWidth = MINWIDTH / width * 100;
|
||||
leftWidth = 100 - rightWidth;
|
||||
if (nRows == 1) {
|
||||
if (nRows == 1 || !window['showConsole']) {
|
||||
style(0,leftWidth + "vw","100vh");
|
||||
style(1,rightWidth + "vw","100vh");
|
||||
style(2); // hide
|
||||
@ -124,11 +124,16 @@ function adjustGrid() {
|
||||
case 4:
|
||||
rightWidth = MINWIDTH / width * 100;
|
||||
leftWidth = 100 - 2 * rightWidth;
|
||||
if (nRows == 1) {
|
||||
if (nRows == 1 || !window['showConsole']) {
|
||||
style(0,leftWidth + "vw","100vh");
|
||||
style(1,rightWidth + "vw","100vh");
|
||||
style(2); // hide
|
||||
style(3,rightWidth + "vw","100vh");
|
||||
if (window['showConsole']) {
|
||||
style(2); // hide
|
||||
style(3,rightWidth + "vw","100vh");
|
||||
} else {
|
||||
style(2,rightWidth + "vw","100vh");
|
||||
style(3); // hide
|
||||
}
|
||||
} else {
|
||||
style(0,leftWidth + "vw","100vh");
|
||||
style(1,rightWidth + "vw","50vh");
|
||||
|
129
seaweb.py
129
seaweb.py
@ -133,13 +133,12 @@ def export():
|
||||
id = kwargs.pop('id')
|
||||
client = instrument.clients[id]
|
||||
bytes = client.w_export(**kwargs)
|
||||
|
||||
return flask.send_file(
|
||||
bytes,
|
||||
as_attachment=True,
|
||||
download_name='export.tsv',
|
||||
mimetype='text/tab-separated-values'
|
||||
)
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logging.error('%s', traceback.format_exc())
|
||||
@ -213,7 +212,11 @@ def default():
|
||||
@app.route('/<file>')
|
||||
def general_file(file):
|
||||
subdir = "client/"
|
||||
resp = flask.send_file(subdir+file, mimetype=guess_mimetype(file))
|
||||
try:
|
||||
resp = flask.send_file(subdir+file, mimetype=guess_mimetype(file))
|
||||
except FileNotFoundError:
|
||||
logging.warning('file %s not found', file)
|
||||
return 'file not found'
|
||||
#resp.headers['Content-Security-Policy'] = "sandbox; script-src 'unsafe-inline';"
|
||||
return resp
|
||||
|
||||
@ -920,21 +923,18 @@ def convert_event(messages):
|
||||
for msg in messages:
|
||||
if msg.type == 'update':
|
||||
updates.append(dict(name=msg.par, value=msg.value[0]))
|
||||
elif msg.type == 'error_update':
|
||||
updates.append(dict(name=msg.par, value=f'{msg.value[0]} - {msg.value[1]}'))
|
||||
# updates.append(dict(name=msg.par, value=str(msg.value[0])))
|
||||
return [dict(type='update', updates=updates)]
|
||||
|
||||
|
||||
class SecopClient:
|
||||
prio_par = ["value", "status", "target"]
|
||||
hide_par = ["baseclass", "class", "pollinterval"]
|
||||
skip_par = ["status2"]
|
||||
|
||||
class SecNodeClient:
|
||||
def __init__(self, host_port):
|
||||
self.linesocket = tcp_lineserver.LineClient(host_port)
|
||||
self.id = uuid.uuid4().hex[0:15]
|
||||
self.linesocket = tcp_lineserver.LineClient(hostport_split(host_port))
|
||||
self.consolequeue = []
|
||||
self.queue = []
|
||||
self.syncreply = []
|
||||
self.consolequeue = []
|
||||
#self.out = open("debug.txt", "w")
|
||||
#self.out = sys.stdout
|
||||
self.out = None
|
||||
@ -948,45 +948,83 @@ class SecopClient:
|
||||
self.consolequeue.append(dict(type='command',line=command,origin='self'))
|
||||
self.linesocket.send_line(command)
|
||||
t = 0
|
||||
delta = 0.001
|
||||
while True:
|
||||
if self.syncreply:
|
||||
msg = self.syncreply.pop(0)
|
||||
break
|
||||
line = self.linesocket.get_line()
|
||||
if line != None:
|
||||
if not line.startswith('update'):
|
||||
if line is not None:
|
||||
if not line.startswith(('update', 'error_update')):
|
||||
self.consolequeue.append(dict(type='reply',line=line,origin='other'))
|
||||
if self.out: self.out.write("<"+line+"\n")
|
||||
msg = SecopMsg(line)
|
||||
#print '<', msg.type, msg.par
|
||||
if msg.asynch: # and replytype != msg['type'] + "=" + msg.par:
|
||||
t = 0
|
||||
self.queue.append(msg)
|
||||
else:
|
||||
break
|
||||
if t >= tmo:
|
||||
#print 'TIMEOUT'
|
||||
raise Exception("timeout")
|
||||
gevent.sleep(0.001)
|
||||
t += 0.001
|
||||
#print 'REPLY', msg['type'], msg.par, json.dumps(msg.value)[0:50]
|
||||
gevent.sleep(delta)
|
||||
t += delta
|
||||
delta += 0.001
|
||||
if not replytype.startswith(msg.type):
|
||||
logging.error('REPLY MISMATCH %s <> %s', replytype, repr(msg))
|
||||
self.replytype = ""
|
||||
return msg
|
||||
|
||||
def poll(self):
|
||||
if self.consolequeue:
|
||||
messages = self.consolequeue
|
||||
self.consolequeue = []
|
||||
return messages
|
||||
if self.queue:
|
||||
messages = convert_event(self.queue)
|
||||
self.queue = []
|
||||
return messages
|
||||
line = self.linesocket.get_line()
|
||||
if line:
|
||||
if not line.startswith(('update', 'error_update')):
|
||||
self.consolequeue.append(dict(type='reply',line=line,origin='other'))
|
||||
if self.out: self.out.write("<"+line+"\n")
|
||||
msg = SecopMsg(line)
|
||||
if msg.asynch: # and self.replytype != msg['type'] + "=" + msg.par:
|
||||
return convert_event(SecopMsg(line))
|
||||
self.syncreply.append(msg)
|
||||
return []
|
||||
|
||||
|
||||
|
||||
class SecopClient:
|
||||
prio_par = ["value", "status", "target"]
|
||||
hide_par = ["baseclass", "class", "pollinterval"]
|
||||
skip_par = ["status2"]
|
||||
|
||||
def __init__(self, host_ports):
|
||||
self.nodes = []
|
||||
self.node_map = {}
|
||||
for host_port in host_ports.split(','):
|
||||
node = SecNodeClient(host_port)
|
||||
self.nodes.append(node)
|
||||
for name, mod in node.description["modules"].items():
|
||||
self.node_map[name] = node
|
||||
self.id = uuid.uuid4().hex[0:15]
|
||||
|
||||
def w_getblock(self, path):
|
||||
path = path.split(',')[-1]
|
||||
if path == "main":
|
||||
components = []
|
||||
for name, m in self.description["modules"].items():
|
||||
#components.append(convert_par(name, 'value', m['parameters']['value']))
|
||||
components.append(dict(type='rdlink', name=name+':value', title=name))
|
||||
for node in self.nodes:
|
||||
for name, m in node.description["modules"].items():
|
||||
#components.append(convert_par(name, 'value', m['parameters']['value']))
|
||||
components.append(dict(type='rdlink', name=name+':value', title=name))
|
||||
#print components
|
||||
return dict(type='draw', path='main', title='modules', components=components)
|
||||
else:
|
||||
module = self.description['modules'][path]
|
||||
logging.info('MP %r %r', path, module)
|
||||
node = self.node_map[path]
|
||||
module = node.description['modules'][path]
|
||||
logging.info('MP %r %r', path)
|
||||
parameters = dict(module["accessibles"])
|
||||
components = []
|
||||
for name in SecopClient.skip_par:
|
||||
@ -1007,48 +1045,40 @@ class SecopClient:
|
||||
def w_updateblock(self, path):
|
||||
if path == 'main':
|
||||
path = ''
|
||||
self.cmd_reply(f"activate {path}", "active")
|
||||
for node in self.nodes:
|
||||
node.cmd_reply(f"activate", "active")
|
||||
else:
|
||||
node = self.node_map[path]
|
||||
node.cmd_reply(f"activate {path}", "active")
|
||||
return dict(type='accept-block')
|
||||
|
||||
def w_console(self):
|
||||
return dict(type='accept-console')
|
||||
|
||||
def w_sendcommand(self, command):
|
||||
# TODO: if not obsolete: add node to command. now its always sending to the first node
|
||||
logging.info('SENDCOMMAND %r', command)
|
||||
if not command.strip():
|
||||
return dict(type='accept-command')
|
||||
# cmd = "change " + command
|
||||
cmd = command
|
||||
return self.cmd_reply(cmd, 'event ' + command.split(' ')[0])
|
||||
return self.nodes[0].cmd_reply(cmd, 'event ' + command.split(' ')[0])
|
||||
|
||||
def poll(self):
|
||||
if self.consolequeue:
|
||||
messages = self.consolequeue
|
||||
self.consolequeue = []
|
||||
return messages
|
||||
if self.queue:
|
||||
messages = convert_event(self.queue)
|
||||
self.queue = []
|
||||
return messages
|
||||
line = self.linesocket.get_line()
|
||||
if line:
|
||||
if not line.startswith('update'):
|
||||
self.consolequeue.append(dict(type='reply',line=line,origin='other'))
|
||||
if self.out: self.out.write("<"+line+"\n")
|
||||
msg = SecopMsg(line)
|
||||
if msg.asynch: # and self.replytype != msg['type'] + "=" + msg.par:
|
||||
return convert_event(SecopMsg(line))
|
||||
self.syncreply.append(msg)
|
||||
return []
|
||||
messages = []
|
||||
for node in self.nodes:
|
||||
messages.extend(node.poll())
|
||||
return messages
|
||||
|
||||
def info(self):
|
||||
return ["na"]
|
||||
|
||||
|
||||
class SecopInstrument(Instrument):
|
||||
|
||||
def __init__(self, inst_name, instrument_config):
|
||||
self.instrument_config = instrument_config
|
||||
self.host_port = hostport_split(instrument_config['hostport'])
|
||||
self.host_ports = instrument_config['hostport']
|
||||
self.logger_dir = instrument_config.get('logger_dir', '')
|
||||
#test_day = instrument_config.get('test_day', None)
|
||||
#self.test_day = [int(x) for x in test_day.split('-')] if test_day else None
|
||||
@ -1056,14 +1086,21 @@ class SecopInstrument(Instrument):
|
||||
self.clients = {}
|
||||
|
||||
def newClient(self):
|
||||
return self.register(SecopClient(self.host_port))
|
||||
return self.register(SecopClient(self.host_ports))
|
||||
|
||||
|
||||
class SecopInfluxClient(SecopClient, InfluxGraph):
|
||||
def __init__(self):
|
||||
SecopClient.__init__(self, instrument.host_port)
|
||||
SecopClient.__init__(self, instrument.host_ports)
|
||||
InfluxGraph.__init__(self, instrument.influx_data_getter, instrument.title)
|
||||
|
||||
def poll(self):
|
||||
messages = super().poll()
|
||||
msg = self.graphpoll()
|
||||
if msg:
|
||||
messages.append(msg)
|
||||
return messages
|
||||
|
||||
|
||||
class SecopInfluxInstrument(SecopInstrument):
|
||||
|
||||
|
Reference in New Issue
Block a user