make Graphics work again

as base for Mathis work
This commit is contained in:
l_samenv
2024-07-11 10:05:17 +02:00
parent 3fd8bc6bf3
commit 91be383803
7 changed files with 123 additions and 112 deletions

View File

@ -300,7 +300,8 @@ function successHandler(s, message) {
} }
} }
} else if (message.path == '_overview') { } else if (message.path == '_overview') {
isl = insertSlide(s, message.title, "_overview", createContent(sLocal, message)); // remove comment of next line when you want overview _instead_ of Graphics
// isl = insertSlide(s, message.title, "_overview", createContent(sLocal, message));
// swiper[sLocal].slideTo(isl); /* go to found slide */ // swiper[sLocal].slideTo(isl); /* go to found slide */
} else { } else {
// insertSlide(s, message.title, message.path, createContent(s, message)); // insertSlide(s, message.title, message.path, createContent(s, message));

View File

@ -276,7 +276,7 @@ let graphs = (function (){
tag_dict[block.tag] = gindex; tag_dict[block.tag] = gindex;
let dict = {} let dict = {}
for (let curve of block.curves) { for (let curve of block.curves) {
if (curve.show) { if (curve.show !== false) {
vars_array[gindex].push(curve.name); vars_array[gindex].push(curve.name);
dict[curve.name] = curve; dict[curve.name] = curve;
} }
@ -752,7 +752,7 @@ let graphs = (function (){
} }
// this block is either not shown or only in a hidden graph // this block is either not shown or only in a hidden graph
for (let curve of block.curves) { for (let curve of block.curves) {
if (curve.show) shown = true; if (curve.show !== false) shown = true;
} }
if (shown) break; if (shown) break;
} }
@ -834,6 +834,7 @@ let graphs = (function (){
panCallback: panCallback, panCallback: panCallback,
receivedVars: receivedVars, receivedVars: receivedVars,
createSelection: createSelection, createSelection: createSelection,
createGraphs: createGraphs,
doUpdates: function(){return liveMode}, doUpdates: function(){return liveMode},
update: update, update: update,
updateAuto: updateAuto, updateAuto: updateAuto,

View File

@ -41,9 +41,9 @@ function createContent(s, message) {
for (var i = 0; i < message.components.length; i++) { for (var i = 0; i < message.components.length; i++) {
var component = message.components[i]; var component = message.components[i];
if (!("title" in component)) if (!("title" in component))
component.title = name; component.title = component.name;
if (!("command" in component)) if (!("command" in component))
component.command = name; component.command = component.name;
createFunc = window['create_' + component.type + '_row'] createFunc = window['create_' + component.type + '_row']
if (createFunc) if (createFunc)
content.appendChild(createFunc(s, component)) content.appendChild(createFunc(s, component))

View File

@ -75,7 +75,7 @@ new Settings()
.treat("showMain", "sm", to_bool, true) .treat("showMain", "sm", to_bool, true)
.treat("showConsole", "sc", to_bool, true) .treat("showConsole", "sc", to_bool, true)
.treat("showOverview", "so", to_bool, true) .treat("showOverview", "so", to_bool, true)
.treat("showGraphics", "sg", to_bool, false) .treat("showGraphics", "sg", to_bool, true) // false)
.treat("showAsync", "sa", to_bool, false) .treat("showAsync", "sa", to_bool, false)
function loadFirstBlocks() { function loadFirstBlocks() {

View File

@ -53,6 +53,7 @@ class Scanner(object):
if t > to: if t > to:
break break
except IOError: except IOError:
# print(f'error reading {path}')
pass pass
if t < start: if t < start:
#if t == 0: #if t == 0:

View File

@ -37,7 +37,6 @@ def guess_mimetype(filename):
mimetype = 'text/css' mimetype = 'text/css'
elif filename.endswith('.ico'): elif filename.endswith('.ico'):
mimetype = 'image/x-icon' mimetype = 'image/x-icon'
print('mimetype', mimetype)
else: else:
mimetype = 'text/html' mimetype = 'text/html'
return mimetype return mimetype
@ -66,6 +65,8 @@ def get_update(path=None):
logging.info('UPDATE %s %s', client.id, socket.getfqdn(flask.request.remote_addr.split(':')[-1])) logging.info('UPDATE %s %s', client.id, socket.getfqdn(flask.request.remote_addr.split(':')[-1]))
#msg = dict(type='id', id=client.id, title=instrument.title); #msg = dict(type='id', id=client.id, title=instrument.title);
#yield to_json_sse(msg) #yield to_json_sse(msg)
msg = dict(type='id', id=client.id, instrument=instrument.title, device=instrument.device);
yield to_json_sse(msg)
try: try:
lastmsg = time.time() lastmsg = time.time()
while True: while True:
@ -220,7 +221,8 @@ def sea_request_reply(socket, command, tmo=5):
socket.busy = False socket.busy = False
return data return data
class SeaGroup(object):
class SeaGroup:
def __init__(self): def __init__(self):
self.version = 0 self.version = 0
self.components = [] self.components = []
@ -229,7 +231,8 @@ class SeaGroup(object):
self.lastreq = 0 self.lastreq = 0
self.empty_values = {} self.empty_values = {}
class Instrument(object):
class Instrument:
def remove(self, client): def remove(self, client):
try: try:
del self.clients[client.id] del self.clients[client.id]
@ -240,6 +243,7 @@ class Instrument(object):
self.clients[client.id] = client self.clients[client.id] = client
return client return client
class SeaInstrument(Instrument): class SeaInstrument(Instrument):
# convert SEA layout tag like "-W" to more meaningful name. # convert SEA layout tag like "-W" to more meaningful name.
# the code: 0: modifier, 1: enum name, 2: input element # the code: 0: modifier, 1: enum name, 2: input element
@ -265,6 +269,7 @@ class SeaInstrument(Instrument):
def __init__(self, inst_name, instrument_config): def __init__(self, inst_name, instrument_config):
self.host_port = hostport_split(instrument_config['sea']) self.host_port = hostport_split(instrument_config['sea'])
self.inst_name = inst_name self.inst_name = inst_name
self.title = inst_name
self.clients = {} self.clients = {}
self.logger_dir = instrument_config.get('logger_dir','') self.logger_dir = instrument_config.get('logger_dir','')
test_day = instrument_config.get('test_day', None) test_day = instrument_config.get('test_day', None)
@ -464,8 +469,8 @@ class SeaInstrument(Instrument):
idx = min(len(self.history), self.consolepos - startindex) # distance from end idx = min(len(self.history), self.consolepos - startindex) # distance from end
messages = [] messages = []
for i in range(-idx,0): for i in range(-idx,0):
type, line, hid = self.history[i] typ, line, hid = self.history[i]
messages.append(dict(type=type, line=line, origin=('self' if hid==id else 'other'))) messages.append(dict(type=typ, line=line, origin=('self' if hid==id else 'other')))
return self.consolepos, messages return self.consolepos, messages
def command(self, command, id): def command(self, command, id):
@ -475,7 +480,7 @@ class SeaInstrument(Instrument):
self.lastcmd = command self.lastcmd = command
class SeaGraph(object): class SeaGraph:
HISTORICAL = 0 HISTORICAL = 0
ACTUAL = 1 ACTUAL = 1
LIVE = 2 LIVE = 2
@ -637,7 +642,7 @@ class SeaClient(SeaGraph):
class DummyClient(SeaGraph): class DummyClient(SeaGraph):
async = set(('id','update','redraw','command','reply','graph-update','graph-redraw')) asynch = set(('id','update','redraw','command','reply','graph-update','graph-redraw'))
def __init__(self, host_port): def __init__(self, host_port):
self.linesocket = tcp_lineserver.LineClient(host_port) self.linesocket = tcp_lineserver.LineClient(host_port)
@ -647,7 +652,7 @@ class DummyClient(SeaGraph):
self.syncreply = [] self.syncreply = []
SeaGraph.__init__(self) SeaGraph.__init__(self)
def cmd_reply(self, command, replytype, tmo=5): def cmd_reply(self, command, replytype=None, tmo=5):
self.linesocket.send_line(json.dumps(command)) self.linesocket.send_line(json.dumps(command))
t = 0 t = 0
while True: while True:
@ -657,7 +662,7 @@ class DummyClient(SeaGraph):
line = self.linesocket.get_line() line = self.linesocket.get_line()
if line != None: if line != None:
msg = json.loads(line) msg = json.loads(line)
if msg['type'] in self.async: if msg['type'] in self.asynch:
t = 0 t = 0
# print 'PUSH',msg, replytype # print 'PUSH',msg, replytype
self.queue.append(msg) self.queue.append(msg)
@ -668,7 +673,7 @@ class DummyClient(SeaGraph):
raise Exception("timeout") raise Exception("timeout")
gevent.sleep(0.1) gevent.sleep(0.1)
t += 0.1 t += 0.1
if msg['type'] != replytype: if replytype and msg['type'] != replytype:
logging.error('REPLY MISMATCH %s %s <> %s' , command, replytype, msg['type']) logging.error('REPLY MISMATCH %s %s <> %s' , command, replytype, msg['type'])
return msg return msg
@ -694,7 +699,7 @@ class DummyClient(SeaGraph):
messages = [] messages = []
if line: if line:
msg = json.loads(line) msg = json.loads(line)
if msg['type'] in self.async: if msg['type'] in self.asynch:
messages.append(msg) messages.append(msg)
else: else:
self.syncreply.append(msg) self.syncreply.append(msg)
@ -722,6 +727,7 @@ class DummyInstrument(Instrument):
def newClient(self): def newClient(self):
return self.register(DummyClient(self.host_port)) return self.register(DummyClient(self.host_port))
class SecopMsg: class SecopMsg:
def __init__(self, line): def __init__(self, line):
self.par = None self.par = None
@ -736,7 +742,14 @@ class SecopMsg:
self.par = sl[1] self.par = sl[1]
if len(sl) > 2: if len(sl) > 2:
self.value = json.loads(' '.join(sl[2:])) self.value = json.loads(' '.join(sl[2:]))
self.async = self.type == 'event' self.asynch = self.type in ('update', 'error_update')
def __repr__(self):
value = repr(self.value)
if len(value) > 50:
value = value[:50] + '...'
return "SecopMsg('%s %s %s')" % (self.type, self.par, value)
def SecopEncode(cmd, par=None, value=None): def SecopEncode(cmd, par=None, value=None):
line = cmd line = cmd
@ -746,23 +759,33 @@ def SecopEncode(cmd, par=None, value=None):
line += " " + json.dumps(value) line += " " + json.dumps(value)
return line return line
def convert_par(module, name, par): def convert_par(module, name, par):
result = dict(type='input', name=module+":"+name, title=name) result = dict(type='input', name=module+":"+name, title=name)
if par['readonly']: if par.get('readonly', True):
result['type']='rdonly' result['type'] = 'rdonly'
#print result else:
result['command'] = 'change %s:%s' % (module, name)
if par['datainfo']['type'] == 'enum':
result['enum_names'] = [dict(title=k, value=v) for k, v in par['datainfo']['members'].items()]
result['type'] = 'enum'
elif par['datainfo']['type'] == 'bool':
result['type'] = 'checkbox'
return result return result
def convert_event(messages): def convert_event(messages):
if isinstance(messages, SecopMsg): if isinstance(messages, SecopMsg):
messages = [messages] messages = [messages]
updates = [] updates = []
for msg in messages: for msg in messages:
if msg['type'] == 'event': if msg['type'] == 'update':
updates.append(dict(name=msg.par, value=str(msg.value[0]))) updates.append(dict(name=msg.par, value=msg.value[0]))
# updates.append(dict(name=msg.par, value=str(msg.value[0])))
return [dict(type='update', updates=updates)] return [dict(type='update', updates=updates)]
class SecopClient(object):
class SecopClient:
prio_par = ["value", "status", "target"] prio_par = ["value", "status", "target"]
hide_par = ["baseclass", "class", "pollinterval"] hide_par = ["baseclass", "class", "pollinterval"]
skip_par = ["status2"] skip_par = ["status2"]
@ -796,7 +819,7 @@ class SecopClient(object):
if self.out: self.out.write("<"+line+"\n") if self.out: self.out.write("<"+line+"\n")
msg = SecopMsg(line) msg = SecopMsg(line)
#print '<', msg['type'], msg.par #print '<', msg['type'], msg.par
if msg.async and replytype != msg['type'] + "=" + msg.par: if msg.asynch and replytype != msg['type'] + "=" + msg.par:
t = 0 t = 0
self.queue.append(msg) self.queue.append(msg)
else: else:
@ -866,7 +889,7 @@ class SecopClient(object):
self.consolequeue.append(dict(type='reply',line=line,origin='other')) self.consolequeue.append(dict(type='reply',line=line,origin='other'))
if self.out: self.out.write("<"+line+"\n") if self.out: self.out.write("<"+line+"\n")
msg = SecopMsg(line) msg = SecopMsg(line)
if msg.async and self.replytype != msg['type'] + "=" + msg.par: if msg.asynch and self.replytype != msg['type'] + "=" + msg.par:
return convert_event(SecopMsg(line)) return convert_event(SecopMsg(line))
self.syncreply.append(msg) self.syncreply.append(msg)
return [] return []
@ -900,9 +923,10 @@ class Logger(object):
def flush(self): def flush(self):
pass pass
def handle_pdb(sig, frame): def handle_pdb(sig, frame):
import pdb import pdb
prin ('PDB') print('PDB')
pdb.Pdb().set_trace(frame) pdb.Pdb().set_trace(frame)

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
import sys import sys
sys.path.append("../histreader") sys.path.append("../frappyhistory")
# Make sure your gevent version is >= 1.0 # Make sure your gevent version is >= 1.0
import gevent import gevent
import gevent.pywsgi import gevent.pywsgi
@ -25,8 +25,8 @@ import circularlog
import os import os
import signal import signal
from histgraph import get_vars, get_curves, get_abs_time from histgraph import get_vars, get_curves, get_abs_time
from histreader.histreader import MainCache from main import MainCache
from histreader.frappyreader import FrappyReader from frappyreader import FrappyReader
try: import simplejson as json try: import simplejson as json
except ImportError: import json except ImportError: import json
@ -143,12 +143,7 @@ def reply():
@app.route('/test/<file>') @app.route('/test/<file>')
def subdir_test_file(file): def subdir_test_file(file):
gevent.sleep(2) gevent.sleep(2)
try: resp = flask.send_file("client/test/"+file, mimetype=guess_mimetype(file))
with open("client/test/"+file, 'r') as content_file:
content = content_file.read()
except IOError:
flask.abort(404)
resp = flask.Response(content, mimetype=guess_mimetype(file))
return resp return resp
@app.route('/jsFiles/<file>') @app.route('/jsFiles/<file>')
@ -156,12 +151,7 @@ def subdir_test_file(file):
@app.route('/externalFiles/<file>') @app.route('/externalFiles/<file>')
def subdir_file(file): def subdir_file(file):
subdir = flask.request.path.split('/')[1] subdir = flask.request.path.split('/')[1]
try: resp = flask.send_file("client/" + subdir+"/"+file, mimetype=guess_mimetype(file))
with open("client/" + subdir+"/"+file, 'r') as content_file:
content = content_file.read()
except IOError:
flask.abort(404)
resp = flask.Response(content, mimetype=guess_mimetype(file))
#resp.headers['Content-Security-Policy'] = "sandbox; script-src 'unsafe-inline';" #resp.headers['Content-Security-Policy'] = "sandbox; script-src 'unsafe-inline';"
return resp return resp
@ -176,12 +166,7 @@ def default():
@app.route('/<file>') @app.route('/<file>')
def general_file(file): def general_file(file):
subdir = "client/" subdir = "client/"
try: resp = flask.send_file(subdir+file, mimetype=guess_mimetype(file))
with open(subdir+file, 'r') as content_file:
content = content_file.read()
except IOError:
flask.abort(404)
resp = flask.Response(content, mimetype=guess_mimetype(file))
#resp.headers['Content-Security-Policy'] = "sandbox; script-src 'unsafe-inline';" #resp.headers['Content-Security-Policy'] = "sandbox; script-src 'unsafe-inline';"
return resp return resp
@ -294,6 +279,7 @@ class SeaInstrument(Instrument):
self.seacmd = None self.seacmd = None
self.last_client_remove = time.time() self.last_client_remove = time.time()
self.history = deque(maxlen=1000) self.history = deque(maxlen=1000)
self.title = inst_name # hack?
self.init() self.init()
gevent.Greenlet.spawn(self.checkconnections) gevent.Greenlet.spawn(self.checkconnections)
@ -337,7 +323,7 @@ class SeaInstrument(Instrument):
def poll_groups(self, paths): def poll_groups(self, paths):
'polls values and components of requested groups' 'polls values and components of requested groups'
for path in paths: for path in list(paths):
gobj = self.groups[path] gobj = self.groups[path]
now = time.time() now = time.time()
if now < gobj.lastpoll + 0.5: if now < gobj.lastpoll + 0.5:
@ -483,12 +469,8 @@ class SeaInstrument(Instrument):
idx = min(len(self.history), self.consolepos - startindex) # distance from end idx = min(len(self.history), self.consolepos - startindex) # distance from end
messages = [] messages = []
for i in range(-idx,0): for i in range(-idx,0):
type, line, origin = self.history[i] typ, line, hid = self.history[i]
if origin == id: messages.append(dict(type=typ, line=line, origin=('self' if hid==id else 'other')))
origin = 'self'
elif origin != 'async':
origin = 'other'
messages.append(dict(type=type, line=line, origin=origin))
return self.consolepos, messages return self.consolepos, messages
def command(self, command, id): def command(self, command, id):
@ -636,7 +618,9 @@ class SeaClient(SeaGraph):
def w_getblock(self, path): def w_getblock(self, path):
gobj = instrument.findgroup(path.split(',')[-1]) gobj = instrument.findgroup(path.split(',')[-1])
self.group_version[path] = gobj.version # self.group_version[path] = gobj.version
# simplify: allow only one group per client
self.group_version = {path: gobj.version}
logging.info('getblock %s %d', path, gobj.version) logging.info('getblock %s %d', path, gobj.version)
return dict(type='draw', title=gobj.grouptitle, path=path, components=gobj.components) return dict(type='draw', title=gobj.grouptitle, path=path, components=gobj.components)
@ -678,7 +662,7 @@ class DummyClient(SeaGraph):
line = self.linesocket.get_line() line = self.linesocket.get_line()
if line != None: if line != None:
msg = json.loads(line) msg = json.loads(line)
if msg.type in self.asynch: if msg['type'] in self.asynch:
t = 0 t = 0
# print 'PUSH',msg, replytype # print 'PUSH',msg, replytype
self.queue.append(msg) self.queue.append(msg)
@ -689,8 +673,8 @@ class DummyClient(SeaGraph):
raise Exception("timeout") raise Exception("timeout")
gevent.sleep(0.1) gevent.sleep(0.1)
t += 0.1 t += 0.1
if replytype and msg.type != replytype: if replytype and msg['type'] != replytype:
logging.error('REPLY MISMATCH %s %s <> %s', command, replytype, msg.type) logging.error('REPLY MISMATCH %s %s <> %s', command, replytype, msg['type'])
return msg return msg
def strip_future(self, result): def strip_future(self, result):
@ -724,7 +708,7 @@ class DummyClient(SeaGraph):
messages = [] messages = []
if line: if line:
msg = json.loads(line) msg = json.loads(line)
if msg.type in self.asynch: if msg['type'] in self.asynch:
messages.append(msg) messages.append(msg)
else: else:
self.syncreply.append(msg) self.syncreply.append(msg)