add select_experiment

This commit is contained in:
2025-02-27 10:41:17 +01:00
parent 65aa822b96
commit 9ec122a146
5 changed files with 96 additions and 22 deletions

View File

@ -379,8 +379,9 @@ function successHandler(s, message) {
begin = timeRange[0] - timeRange[1]; begin = timeRange[0] - timeRange[1];
select.value = begin; select.value = begin;
// Server-request for variable-list.*/ // Server-request for variable-list.*/
console.log('TIME', window['clientTags'], timeRange)
reqJSONPOST(0, "http://" + hostPort + "/getvars", reqJSONPOST(0, "http://" + hostPort + "/getvars",
"time=" + timeRange[1] "time=" + timeRange[0] + ',' + timeRange[1]
+ window['clientTags'] + window['clientTags']
+ "&userconfiguration=" + JSON.stringify(getFormattedUserConfigurationFromLocalStorage()) + "&userconfiguration=" + JSON.stringify(getFormattedUserConfigurationFromLocalStorage())
+ "&id=" + clientID, successHandler, errorHandler); + "&id=" + clientID, successHandler, errorHandler);

View File

@ -1071,7 +1071,7 @@ let graphs = (function (){
currentMaxTime = maxTime; currentMaxTime = maxTime;
currentMinTime = minTime; currentMinTime = minTime;
} }
AJAX("http://" + hostPort + "/gettime?time=-1800,0&id="+ clientID).getJSON().then(function(data){ AJAX("http://" + hostPort + "/gettime?time=" + window['timerange'] + "&id="+ clientID).getJSON().then(function(data){
startTime = data.time[1]*1000; startTime = data.time[1]*1000;
maxTime = startTime; maxTime = startTime;
currentMaxTime = maxTime + 60000; currentMaxTime = maxTime + 60000;

View File

@ -81,7 +81,8 @@ new Settings()
.treat("showAsync", "sa", to_bool, false) .treat("showAsync", "sa", to_bool, false)
.treat("device", "dev", 0, "*") .treat("device", "dev", 0, "*")
.treat("server", "srv", 0, "*") .treat("server", "srv", 0, "*")
.treat("instrument", "ins", 0, "") .treat("instrument", "instrument", 0, "")
.treat("timerange", "time", 0, "-1800,0")
if (window['instrument']) { if (window['instrument']) {
window['clientTags'] = "&instrument=" + window["instrument"]; window['clientTags'] = "&instrument=" + window["instrument"];
@ -96,11 +97,11 @@ function loadFirstBlocks() {
if (showMain) pushInitCommand("getblock?path=main&", "main") if (showMain) pushInitCommand("getblock?path=main&", "main")
if (showConsole) pushInitCommand("console?", "console") if (showConsole) pushInitCommand("console?", "console")
if (nColumns == 1) { // probably mobile phone} if (nColumns == 1) { // probably mobile phone}
if (showGraphics) pushInitCommand("gettime?time=-1800,0&", "graphics") if (showGraphics) pushInitCommand("gettime?time=" + window["timerange"] + "&", "graphics")
if (showOverview) pushInitCommand("getblock?path=_overview&", "overview") if (showOverview) pushInitCommand("getblock?path=_overview&", "overview")
} else { } else {
if (showOverview) pushInitCommand("getblock?path=_overview&", "overview") if (showOverview) pushInitCommand("getblock?path=_overview&", "overview")
if (showGraphics) pushInitCommand("gettime?time=-1800,0&", "graphics") if (showGraphics) pushInitCommand("gettime?time=" + window["timerange"] + "&", "graphics")
// last is shown first // last is shown first
} }
} }

View File

@ -5,7 +5,7 @@ import io
import uuid import uuid
from configparser import ConfigParser from configparser import ConfigParser
from math import ceil from math import ceil
from sehistory.influx import InfluxDBWrapper from sehistory.seinflux import SEHistory
from colors import assign_colors_to_curves from colors import assign_colors_to_curves
from chart_config import ChartConfig from chart_config import ChartConfig
from base import Instrument, get_abs_time from base import Instrument, get_abs_time
@ -84,8 +84,10 @@ class InfluxGraph:
logging.info('LIVE %g %g %d %d', end, now, end >= now, self.livemode) logging.info('LIVE %g %g %d %d', end, now, end >= now, self.livemode)
if interval: if interval:
interval = float(interval) interval = float(interval)
print('CURVES', start - now, end - now, self.tags)
result = self.db.curves(start, end, queried_variables, merge='_measurement', result = self.db.curves(start, end, queried_variables, merge='_measurement',
interval=interval or None, **self.tags) interval=interval or None, **self.tags)
print('LEN', len(result))
self.update_last(result) self.update_last(result)
self.db.complete(result, self.last_time, 'stream') self.db.complete(result, self.last_time, 'stream')
self.last_minute = now // 60 self.last_minute = now // 60
@ -145,19 +147,19 @@ class InfluxGraph:
self.tags = split_tags(tags) self.tags = split_tags(tags)
if instrument: if instrument:
tags['stream'] = list(self.db.get_streams(instrument)) self.tags['stream'] = list(self.db.get_streams(instrument))
print('GETAV', self.tags) print('TAGS', self.tags)
blocks = self.get_available_variables(start_time, end_time, self.chart_configs, userconfiguration) blocks = self.get_available_variables(start_time, end_time, self.chart_configs, userconfiguration)
device_name = tags.get('device', '<unknown>') device_name = self.tags.get('device', '<unknown>')
# initialize self.last_values to keep track of the available variables # initialize self.last_values to keep track of the available variables
self.last_values = {var["name"]: [0, None] for block in blocks for var in block["curves"]} self.last_values = {var["name"]: [0, None] for block in blocks for var in block["curves"]}
assign_colors_to_curves(blocks) assign_colors_to_curves(blocks)
result = dict(type='var_list') result = dict(type='var_list')
result['blocks'] = blocks result['blocks'] = blocks
result['device'] = device_name result['device'] = device_name
print('DEVICE', device_name, tags) # print('DEVICE', device_name, tags)
for block in blocks: # for block in blocks:
print(block['tag'], [c['name'] for c in block['curves']]) # print(block['tag'], [c['name'] for c in block['curves']])
return result return result
def get_available_variables(self, start_time, end_time, chart_configs=None, user_config=None): def get_available_variables(self, start_time, end_time, chart_configs=None, user_config=None):
@ -307,7 +309,7 @@ class InfluxGraph:
# the server is only waiting after a None return # the server is only waiting after a None return
# this avoids to many queries with expected empty result # this avoids to many queries with expected empty result
return None return None
last_time = int(min(self.last_time.values())) last_time = int(min(self.last_time.values(), default=now-3600))
# if len(self.last_time) > 1: # if len(self.last_time) > 1:
# print('time_poll_jitter', max(self.last_time.values()) - min(self.last_time.values())) # print('time_poll_jitter', max(self.last_time.values()) - min(self.last_time.values()))
prev_minute, self.last_minute = self.last_minute, now // 60 prev_minute, self.last_minute = self.last_minute, now // 60
@ -416,7 +418,7 @@ class SecopInfluxInstrument(SecopInstrument):
config.optionxform = str config.optionxform = str
config.read("./config/influx.ini") config.read("./config/influx.ini")
section = config["INFLUX"] section = config["INFLUX"]
self.db = InfluxDBWrapper('linse-c') self.db = SEHistory()
# self.db = InfluxDBWrapper(uri=section["url"], token=section["token"], # self.db = InfluxDBWrapper(uri=section["url"], token=section["token"],
# org=section["org"], bucket=section['bucket']) # org=section["org"], bucket=section['bucket'])
# self.influx_data_getter = InfluxDataGetter(self.db, inst_name) # self.influx_data_getter = InfluxDataGetter(self.db, inst_name)
@ -425,7 +427,9 @@ class SecopInfluxInstrument(SecopInstrument):
def new_client(self): def new_client(self):
return self.register(SecopInfluxClient(self)) return self.register(SecopInfluxClient(self))
def get_stream_tags(self, timestamp=None): def get_streams(self, timestamp=None):
return self.db.get_streams(None, timestamp) return self.db.get_streams(None, timestamp)
def get_experiments(self, start=None, stop=None):
return self.db.get_experiments(start, stop)

View File

@ -88,7 +88,6 @@ def get_update(path=None):
logging.info('CLOSED %s', client.id) logging.info('CLOSED %s', client.id)
print('CLOSE client') print('CLOSE client')
instrument.remove(client) instrument.remove(client)
pass
except Exception as e: except Exception as e:
logging.info('error') logging.info('error')
logging.error('%s', traceback.format_exc()) logging.error('%s', traceback.format_exc())
@ -211,21 +210,21 @@ def replace_by_empty(file):
@app.route('/') @app.route('/')
def main(): def default():
return general_file('SEAWebClient.html') return general_file('SEAWebClient.html')
@app.route('/select') @app.route('/select_instrument')
def default(): def select_instrument():
out = ['''<html><body><table> out = ['''<html><body><table>
<style> <style>
th { th {
text-align: left; text-align: left;
} }
</style> </style>
<tr><th>Instrument</th><th colspan=99>Devices</th></tr>'''] <tr><th>instrument</th><th colspan=99>devices</th></tr>''']
result = {} result = {}
for stream, tags in instrument.get_stream_tags().items(): for stream, tags in instrument.get_streams().items():
ins = tags.get('instrument', '0') ins = tags.get('instrument', '0')
result.setdefault(ins, []).append((stream, tags.get('device'))) result.setdefault(ins, []).append((stream, tags.get('device')))
bare_streams = result.pop('0', []) bare_streams = result.pop('0', [])
@ -235,7 +234,76 @@ th {
out.append('</tr>') out.append('</tr>')
for stream, device in bare_streams: for stream, device in bare_streams:
out.append(f'<tr><td><a href="/?srv={stream}">{stream}</a></td><td>{device}</td><tr>') out.append(f'<tr><td><a href="/?srv={stream}">{stream}</a></td><td>{device}</td><tr>')
out.extend(['</table></body?</html>', '']) out.extend(['</table></body></html>', ''])
return '\n'.join(out)
@app.route('/select_experiment')
def select_experiment():
out = ['''<html><body>
<style>
th {
text-align: left;
background-color: #cccccc;
}
a {
text-decoration: none;
}
</style><table>
''']
showtitle = 0
ONEMONTH = 30 * 24 * 3600
def title(text):
out.append(f'<tr><td colspan=2><b>{text}</b></td></tr>')
# TODO: sort this by (instrument / device) and list dates
# period format: Ymd..Ymd, Ymd (single date), Ymd..now, HM..now
try:
now = time.time()
timerange = flask.request.values.get('time')
if timerange == 'all':
starttime, endtime = None, None
elif timerange:
timerange = timerange.split(',')
starttime, endtime = [None if timerange[i] == '0' else int(timerange[i]) for i in (0, -1)]
else:
starttime, endtime = now - ONEMONTH, now
chunk_list = []
for key, chunk_dict in instrument.get_experiments(starttime, endtime).items():
for (streams, devices), chunks in chunk_dict.items():
chunk_list.extend((r[1], r[0], key, devices) for r in chunks)
chunk_list.sort(reverse=True)
for end, beg, key, devices in chunk_list:
today, begdate, enddate = (time.strftime("%Y-%m-%d", time.localtime(t)) for t in (now, beg, end))
args = ['='.join(key)]
if end > now:
if begdate == today:
daterange = f'since {time.strftime("%H:%M", time.localtime(beg))}'
else:
daterange = f'since {begdate}'
if showtitle == 0:
title('currently running')
showtitle = 1
else:
daterange = begdate if begdate == enddate else f'{begdate}...{enddate}'
if end > now - ONEMONTH:
if showtitle == 1:
title('older than 30 days')
showtitle = 2
print('A', args)
out.append(f'<tr><th><a href="/?{"&".join(args)}">{key[1]} / {" ".join(devices)}</a></th>')
out.append(f'<td>{daterange}</td></tr>')
if timerange:
out.append(f'<h3><a href="/select_experiment?time=all">earlier dates</a></h3><br>')
out.extend(['</table></body></html>', ''])
except Exception as e:
logging.error('%s', traceback.format_exc())
circularlog.log()
out = [f"ERROR {e!r}"]
return '\n'.join(out) return '\n'.join(out)