make web client work
This commit is contained in:
@ -86,7 +86,7 @@ function handleUpdateMessage(src, message) {
|
||||
sizeChange();
|
||||
} else {
|
||||
clientTitle = message.instrument + " " + message.device;
|
||||
console.log('loadBlocks')
|
||||
console.log('loadBlocks', message);
|
||||
loadFirstBlocks();
|
||||
}
|
||||
document.title = "SEA "+clientTitle;
|
||||
@ -155,7 +155,6 @@ function handleUpdateMessage(src, message) {
|
||||
case "graph-update":
|
||||
//if (getUpdatesGraphics) {
|
||||
//timeServer = message.time;
|
||||
console.log("graph-update");
|
||||
updateCharts2(message.graph);
|
||||
//}
|
||||
break;
|
||||
@ -207,11 +206,12 @@ function updateValues(message, src) {
|
||||
} else if (type == "input") {
|
||||
var row = matches[j].parentNode.parentNode.parentNode;
|
||||
row.style.backgroundColor = "white";
|
||||
var oldValue = matches[j].getAttribute("oldValue")
|
||||
|| matches[j].value;
|
||||
if (value != matches[j].value && value != oldValue) {
|
||||
var mval = matches[j].value;
|
||||
var oldValue = matches[j].getAttribute("oldValue");
|
||||
if (oldValue === null) oldValue = mval;
|
||||
if (value != mval && parseFloat(value) != parseFloat(mval) && value != oldValue) {
|
||||
if (matches[j] == document.activeElement
|
||||
|| oldValue != matches[j].value) {
|
||||
|| oldValue != mval) {
|
||||
row.style.backgroundColor = "orange";
|
||||
} else {
|
||||
matches[j].value = value;
|
||||
|
@ -106,51 +106,20 @@ function doubleTap(callback){
|
||||
return {stop: function(){ window.removeEventListener('touchend', handler) }}
|
||||
}
|
||||
|
||||
function maxAr(array){
|
||||
function maxAr(array, tmin, tmax){
|
||||
return Math.max.apply(Math, array.map(function(o) {
|
||||
if (o.y == null) return -1e99;
|
||||
if (o.y == null || o.x < tmin || o.x > tmax) return -1e99;
|
||||
return o.y;
|
||||
}));
|
||||
}
|
||||
|
||||
function minAr(array){
|
||||
function minAr(array, tmin, tmax){
|
||||
return Math.min.apply(Math, array.map(function(o) {
|
||||
if (o.y == null) return 1e99;
|
||||
if (o.y == null || o.x < tmin || o.x > tmax) return 1e99;
|
||||
return o.y;
|
||||
}));
|
||||
}
|
||||
|
||||
function autoScale(chart) {
|
||||
axis = chart.options.scales.yAxes[0]
|
||||
datasets = chart.data.datasets;
|
||||
let max = -1e99;
|
||||
let min = 1e99;
|
||||
for (testwidth = 1; testwidth >= 0; testwidth--) {
|
||||
for(let i = 0; i < datasets.length; i++){
|
||||
ds = datasets[i];
|
||||
if (ds.borderWidth == testwidth) continue;
|
||||
let lmax = maxAr(ds.data);
|
||||
let lmin = minAr(ds.data);
|
||||
if(lmax > max)
|
||||
max = lmax;
|
||||
if(lmin < min)
|
||||
min = lmin;
|
||||
}
|
||||
if (min < max) {
|
||||
break;
|
||||
} else if (min == max) {
|
||||
max = min + 0.5;
|
||||
min = max - 1.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//console.log('autoScale', min, max);
|
||||
axis.ticks.min = min - (max - min) * 0.05;
|
||||
axis.ticks.max = max + (max - min) * 0.01;
|
||||
axis.min = axis.ticks.min;
|
||||
axis.max = axis.ticks.max;
|
||||
}
|
||||
|
||||
function strFormat(str, significant_digits) {
|
||||
if (str == null) return '';
|
||||
evalue = str.toExponential(significant_digits-1).replace(/0*e/, 'e').replace(/\.e/, 'e').replace("e+", "e");
|
||||
@ -163,7 +132,7 @@ function strFormat(str, significant_digits) {
|
||||
|
||||
let graphs = (function (){
|
||||
let dataset_to_graph_map = {},
|
||||
blocks, doUpdates=true, top_vars=[], bottom_vars=[], zoomed =false;
|
||||
blocks, liveMode=true, top_vars=[], bottom_vars=[], zoomed =false;
|
||||
|
||||
let type = 'linear';
|
||||
|
||||
@ -175,6 +144,8 @@ let graphs = (function (){
|
||||
|
||||
let container = document.createElement('div');
|
||||
container.classList.add("graphs-container");
|
||||
let currentMinTime = 0;
|
||||
let currentMaxTime = 0;
|
||||
|
||||
for (let i = 0; i < ngraphs; i++) {
|
||||
let gr = document.createElement('div');
|
||||
@ -242,7 +213,7 @@ let graphs = (function (){
|
||||
}
|
||||
//let varlist = top_vars.concat(bottom_vars);
|
||||
varlist = vars_array[gindex];
|
||||
let el =graph_array[gindex];
|
||||
let el = graph_array[gindex];
|
||||
AJAX("http://" + hostPort + "/graph?time=" + minTime/1000 + "," + maxTime/1000 + "&variables=" + varlist + "&id=" + clientID).getJSON().then(function(data){
|
||||
|
||||
//console.log('Graph', block, data)
|
||||
@ -255,13 +226,10 @@ let graphs = (function (){
|
||||
}
|
||||
let pdata = [];
|
||||
for(let e of data.graph[key]){
|
||||
//if(e[1] == null || e[1] == null){
|
||||
// continue;
|
||||
//}
|
||||
pdata.push({x: e[0]*1000, y: e[1]});
|
||||
}
|
||||
if(pdata.length > 0){
|
||||
addDataset(gindex, key, [dict[key].label, dict[key].color, pdata])
|
||||
addDataset(gindex, key, [dict[key].label, dict[key].color, pdata, dict[key].continuous])
|
||||
/*console.log(timeRange);
|
||||
if(data[data.length-1].x-data[0].x > d && data[data.length-1].x-data[0].x < (30*60+10)*1000){ // Adjust to requested time
|
||||
d = data[data.length-1].x-data[0].x
|
||||
@ -271,20 +239,91 @@ let graphs = (function (){
|
||||
}
|
||||
}
|
||||
chart.setMinMax(minTime,maxTime);
|
||||
// chart.autoScaleChart();
|
||||
chart.autoScaleIf();
|
||||
chart.update();
|
||||
|
||||
AJAX( "http://" + hostPort + "/updategraph?id=" + clientID).getJSON(); // why this?
|
||||
result = AJAX( "http://" + hostPort +
|
||||
"/updategraph?variables=" + variables() +
|
||||
"&id=" + clientID).getJSON().then(function(data) {
|
||||
liveMode = data.live;
|
||||
console.log('LIVE create', liveMode)
|
||||
})
|
||||
//console.log('UPDATE LIVE', result);
|
||||
})
|
||||
}
|
||||
|
||||
// add dataset to graph with graph_id
|
||||
function addDataset(gindex, key, dataset){
|
||||
let g = chart_array[gindex];
|
||||
dataset_to_graph_map[key] = [gindex, g.addDataset(dataset)];
|
||||
dataset_to_graph_map[key] = [gindex, g.addDataset(key, dataset)];
|
||||
}
|
||||
|
||||
function autoScale(chart) {
|
||||
axis = chart.options.scales.yAxes[0];
|
||||
tax = chart.options.scales.xAxes[0].ticks;
|
||||
datasets = chart.data.datasets;
|
||||
let max = -1e99;
|
||||
let min = 1e99;
|
||||
// if there are datasets with values and think lines,
|
||||
// consider them only. if not, consider all (second pass in the following loop)
|
||||
let extraMin = min;
|
||||
let extraMax = max;
|
||||
for (testwidth = 1; testwidth >= 0; testwidth--) {
|
||||
for (let i = 0; i < datasets.length; i++){
|
||||
ds = datasets[i];
|
||||
if (ds.borderWidth <= testwidth) continue;
|
||||
let lmax = maxAr(ds.data, tax.min, tax.max);
|
||||
let lmin = minAr(ds.data, tax.min, tax.max);
|
||||
if(lmax > max)
|
||||
max = lmax;
|
||||
if(lmin < min)
|
||||
min = lmin;
|
||||
if (ds.data.length && liveMode) {
|
||||
lasty = ds.data.slice(-1)[0].y;
|
||||
console.log('LASTY', lasty);
|
||||
extraMin = Math.min(extraMin, lasty);
|
||||
extraMax = Math.max(extraMax, lasty);
|
||||
}
|
||||
}
|
||||
if (min > max) continue; // do a second pass over all curves
|
||||
break;
|
||||
}
|
||||
if (min > max) return;
|
||||
if (min == max) {
|
||||
if (min == 0) {
|
||||
ystep = 1;
|
||||
} else {
|
||||
ystep = Math.abs(min * 0.01);
|
||||
}
|
||||
min -= ystep;
|
||||
max += ystep;
|
||||
} else {
|
||||
ystep = (max - min) * 0.1;
|
||||
if (liveMode) {
|
||||
extraMin = Math.min(min, extraMin - ystep);
|
||||
extraMax = Math.max(max, extraMax + ystep);
|
||||
} else {
|
||||
extraMin = min - ystep * 0.5;
|
||||
extraMax = max + ystep * 0.5;
|
||||
}
|
||||
if (min >= axis.ticks.min && axis.ticks.min >= extraMin &&
|
||||
max <= axis.ticks.max && axis.ticks.max <= extraMax) {
|
||||
console.log('NOCHANGE')
|
||||
return; // do not yet change
|
||||
}
|
||||
console.log(min, axis.ticks.min, extraMin)
|
||||
console.log(max, axis.ticks.max, extraMax)
|
||||
min = extraMin;
|
||||
max = extraMax;
|
||||
}
|
||||
//console.log('autoScale', min, max, tax.min, tax.max);
|
||||
axis.min = axis.ticks.min = min;
|
||||
axis.max = axis.ticks.max = max;
|
||||
}
|
||||
|
||||
function setMinMax(min, max){
|
||||
currentMaxTime = max;
|
||||
currentMinTime = min;
|
||||
for (let ch of chart_array) {
|
||||
if (ch) ch.setMinMax(min, max);
|
||||
}
|
||||
@ -326,6 +365,16 @@ let graphs = (function (){
|
||||
chart_array[i[0]].reloadData(i[1], data);
|
||||
}
|
||||
|
||||
function variables() {
|
||||
let vardict = {};
|
||||
for (let vars of vars_array) {
|
||||
for (let v of vars) {
|
||||
vardict[v] = 1;
|
||||
}
|
||||
}
|
||||
return Object.keys(vardict);
|
||||
}
|
||||
|
||||
function reloadData(min, max){
|
||||
|
||||
min = min/1000;
|
||||
@ -334,14 +383,8 @@ let graphs = (function (){
|
||||
}else{
|
||||
max = max/1000;
|
||||
}
|
||||
let vardict = {};
|
||||
for (let vars of vars_array) {
|
||||
for (let v of vars) {
|
||||
vardict[v] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
AJAX("http://" + hostPort + "/graph?time=" + min + ","+max+"&variables=" + Object.keys(vardict) + "&id=" + clientID).getJSON().then(function(data){
|
||||
AJAX("http://" + hostPort + "/graph?time=" + min + ","+max+"&variables=" + variables() + "&id=" + clientID).getJSON().then(function(data){
|
||||
for(let key in data.graph){
|
||||
let pdata = [];
|
||||
for(let e of data.graph[key]){
|
||||
@ -354,10 +397,13 @@ let graphs = (function (){
|
||||
reloadDataFlag(key, pdata);
|
||||
}
|
||||
}
|
||||
for (let ch of chart_array) {
|
||||
if (ch) ch.autoScaleChart(); // should depend on a flag
|
||||
}
|
||||
AJAX( "http://" + hostPort + "/updategraph?id=" + clientID).getJSON(); // why this ?
|
||||
// AJAX( "http://" + hostPort + "/updategraph?id=" + clientID).getJSON(); // activate updates
|
||||
result = AJAX("http://" + hostPort +
|
||||
"/updategraph?variables=" + variables() +
|
||||
"&id=" + clientID).getJSON().then(function(data) {
|
||||
liveMode = data.live;
|
||||
console.log('LIVE reload', liveMode)
|
||||
})
|
||||
update();
|
||||
});
|
||||
}
|
||||
@ -365,19 +411,21 @@ let graphs = (function (){
|
||||
function checkReload(chart){
|
||||
let xmin = chart.options.scales.xAxes[0].ticks.min,
|
||||
xmax = chart.options.scales.xAxes[0].ticks.max;
|
||||
if(xmax < now()-10000){ // was 100000 = 100sec
|
||||
doUpdates = false;
|
||||
if (xmax < now()-100000) { // was 100000 = 100sec
|
||||
if (liveMode) console.log('UPDATES OFF?')
|
||||
//doUpdates = false;
|
||||
}else{
|
||||
doUpdates = true;
|
||||
if (!liveMode) console.log('UPDATES ON?')
|
||||
//doUpdates = true;
|
||||
}
|
||||
if(xmin < minTime || xmax > maxTime || xmax - xmin < 0.5 * (maxTime - minTime)){
|
||||
if (xmin < minTime || xmax > maxTime || xmax - xmin < 0.5 * (maxTime - minTime)) {
|
||||
//TODO: the criterium for getting finer resolution data should depend, if better res. is available
|
||||
// this information has to come from the server
|
||||
reloadData(xmin, xmax);
|
||||
minTime = xmin;
|
||||
maxTime = xmax;
|
||||
} else {
|
||||
autoScale(chart); // TODO: must depend on autoScale flag
|
||||
if (chart.autoScaleFlag) autoScale(chart);
|
||||
chart.update();
|
||||
}
|
||||
}
|
||||
@ -387,7 +435,9 @@ let graphs = (function (){
|
||||
xmax = chart.options.scales.xAxes[0].ticks.max;
|
||||
|
||||
setMinMax(xmin,xmax);
|
||||
//console.log('zoompan', autoScaleFlag);
|
||||
for (let ch of chart_array) {
|
||||
ch.autoScaleIf();
|
||||
if (ch) ch.redraw(redrawX);
|
||||
}
|
||||
update();
|
||||
@ -399,15 +449,27 @@ let graphs = (function (){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let g_varlist = [];
|
||||
function updateAllDisabled(){
|
||||
// not used anymore?
|
||||
AJAX("http://" + hostPort + "/graph?time="+timeRange+"&variables=" + g_varlist + "&id=" + clientID).getJSON().then(function(a){
|
||||
AJAX( "http://" + hostPort + "/updategraph?id=" + clientID).getJSON()
|
||||
});
|
||||
function updateAuto(){
|
||||
if (liveMode) {
|
||||
max = now();
|
||||
if (currentMaxTime && max > currentMaxTime) {
|
||||
max = currentMaxTime + Math.min(60000, 0.1 * (currentMaxTime - currentMinTime));
|
||||
setMinMax(currentMinTime, max);
|
||||
reloadData(currentMinTime, max);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (let ch of chart_array) {
|
||||
if (ch) {
|
||||
ch.autoScaleIf();
|
||||
ch.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
let g_varlist = [];
|
||||
|
||||
function getVarlist(blocks){
|
||||
var varlist = [];
|
||||
for (var i = 0; i < blocks.length; i++) {
|
||||
@ -417,6 +479,7 @@ let graphs = (function (){
|
||||
}
|
||||
return varlist;
|
||||
}
|
||||
*/
|
||||
|
||||
let startTime, recvTime, minTime, maxTime;
|
||||
|
||||
@ -425,13 +488,14 @@ let graphs = (function (){
|
||||
minTime = timeRange[0]*1000;
|
||||
AJAX("http://" + hostPort + "/gettime?time=-1800,0&id="+ clientID).getJSON().then(function(data){
|
||||
startTime = data.time[1]*1000;
|
||||
maxTime = startTime;
|
||||
maxTime = startTime + 60000;
|
||||
console.log('MAXTIME', maxTime - Date.now());
|
||||
minTime = data.time[0]*1000;
|
||||
recvTime = performance.now();
|
||||
});
|
||||
|
||||
|
||||
g_varlist = getVarlist(nblocks)
|
||||
// g_varlist = getVarlist(nblocks)
|
||||
let f = 0;
|
||||
insertSlide(f, "graphics", "graphics", container);
|
||||
blocks = nblocks;
|
||||
@ -514,13 +578,15 @@ let graphs = (function (){
|
||||
zoompan: zoompan,
|
||||
receivedVars: receivedVars,
|
||||
createSelection: createSelection,
|
||||
doUpdates: function(){return doUpdates},
|
||||
doUpdates: function(){return liveMode},
|
||||
update: update,
|
||||
updateAuto: updateAuto,
|
||||
now: now,
|
||||
zoomed: zoomed,
|
||||
checkReload: checkReload,
|
||||
getBlocks: getBlocks,
|
||||
createGraph: createGraph,
|
||||
autoScale: autoScale,
|
||||
}
|
||||
})();
|
||||
|
||||
@ -567,7 +633,7 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
|
||||
y1 = ticks[0];
|
||||
y0 = ticks.slice(-1)[0];
|
||||
span = y1 - y0;
|
||||
step = Math.abs(span * 0.1).toExponential(0);
|
||||
step = Math.abs(span * 0.3).toExponential(0);
|
||||
if (step[0] > '5') {
|
||||
step = '5' + step.substr(1);
|
||||
} else if (step[0] > '2') {
|
||||
@ -651,6 +717,7 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
|
||||
}
|
||||
}
|
||||
});
|
||||
let autoScaleFlag = true;
|
||||
|
||||
//console.log('create legend')
|
||||
let legend = document.createElement('div');
|
||||
@ -724,9 +791,8 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
|
||||
graphs.zoompan(chart);
|
||||
});*/
|
||||
|
||||
addControl("Autoscale Y", function(){
|
||||
autoScale(chart);
|
||||
update();
|
||||
let autoScaleRow = addControl("Autoscale Y <strong>on</strong> off", function(){
|
||||
toggleAutoScale();
|
||||
});
|
||||
|
||||
addControl("Go to now", function(){
|
||||
@ -847,60 +913,91 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
|
||||
chart.update();
|
||||
}
|
||||
|
||||
function addDataset(data){
|
||||
function addDataset(key, data){
|
||||
let dataset_index = chart.data.datasets.length;
|
||||
chart.data.datasets.push({data: data[2], label: data[0], origLabel: data[0],
|
||||
spanGaps: false, lineJoin: 'round', borderWidth: 2,
|
||||
chart.data.datasets.push({data: data[2], label: data[0], key: key,
|
||||
spanGaps: false, lineJoin: 'round', borderWidth: 2, steppedLine: data[3] == 0,
|
||||
borderColor: data[1],fill: false, pointRadius: 0, tension:0, showLine: true});
|
||||
|
||||
let dataset = chart.data.datasets[dataset_index];
|
||||
let legendel = document.createElement('div');
|
||||
let legendelvalue = document.createElement('div');
|
||||
legendelvalue.classList.add('value');
|
||||
legendels[data[0]] = legendelvalue;
|
||||
legendels[key] = legendelvalue;
|
||||
legendel.classList.add('legendel')
|
||||
let color = document.createElement('div');
|
||||
color.classList.add('color')
|
||||
color.style.backgroundColor = dataset.borderColor;
|
||||
legendel.appendChild(color);
|
||||
legendel.innerHTML += dataset.label;
|
||||
legendel.addEventListener('click', function(){
|
||||
let dlabel = document.createElement('div');
|
||||
dlabel.innerHTML = dataset.label;
|
||||
dlabel.addEventListener('click', function(evt){
|
||||
/*
|
||||
console.log('LABEL', evt.target)
|
||||
if(legendmoving)
|
||||
return
|
||||
let meta = dataset._meta[Object.keys(dataset._meta)[0]]
|
||||
/*
|
||||
if(meta.hidden == null){
|
||||
meta.hidden = true;
|
||||
addClass(legendel, 'hidden');
|
||||
}else{
|
||||
meta.hidden = null;
|
||||
delClass(legendel, 'hidden');
|
||||
}
|
||||
legendel.firstChild.style.height = '2px';
|
||||
dataset.borderWidth = 2;
|
||||
labelClicked = true;
|
||||
//console.log('LABEL', evt.target)
|
||||
*/
|
||||
if (dataset.borderWidth == 1) {
|
||||
dataset.borderWidth = 2;
|
||||
} else {
|
||||
dataset.borderWidth = 1;
|
||||
}
|
||||
autoScale(chart);
|
||||
chart.update();
|
||||
})
|
||||
});
|
||||
legendel.appendChild(dlabel);
|
||||
legendel.appendChild(legendelvalue);
|
||||
legendel.addEventListener('click', function(evt){
|
||||
if (legendmoving) return;
|
||||
for (let k in legendels) {
|
||||
// set all labels to normal font
|
||||
legendels[k].parentNode.children[1].style.fontWeight = 400;
|
||||
}
|
||||
if (evt.target == dlabel) {
|
||||
// disable all
|
||||
for (let k in legendels) {
|
||||
legendels[k].parentNode.firstChild.style.height = '1px';
|
||||
}
|
||||
for (ds of chart.data.datasets) {
|
||||
ds.borderWidth = 1;
|
||||
}
|
||||
color.style.height = '2px';
|
||||
dataset.borderWidth = 2;
|
||||
dlabel.style.fontWeight = 700; // bold
|
||||
} else {
|
||||
if (dataset.borderWidth == 1) {
|
||||
legendel.firstChild.style.height = '2px';
|
||||
dataset.borderWidth = 2;
|
||||
} else {
|
||||
legendel.firstChild.style.height = '1px';
|
||||
dataset.borderWidth = 1;
|
||||
}
|
||||
}
|
||||
graphs.autoScale(chart);
|
||||
chart.update();
|
||||
});
|
||||
legend.appendChild(legendel);
|
||||
return dataset_index;
|
||||
}
|
||||
|
||||
function autoScaleChart() {
|
||||
autoScale(chart);
|
||||
function autoScaleIf() {
|
||||
if (autoScaleFlag) graphs.autoScale(chart);
|
||||
}
|
||||
|
||||
function pushData(dataset_index, data_point){
|
||||
chart.data.datasets[dataset_index].data.push(data_point);
|
||||
if(!graphs.zoomed){
|
||||
chart.options.scales.xAxes[0].ticks.max = data_point.x;
|
||||
}else{
|
||||
update_max = data_point.x;
|
||||
data = chart.data.datasets[dataset_index].data;
|
||||
//if (chart.data.datasets[dataset_index].key == 'tt:target')
|
||||
// console.log('BEFORE', data.slice(-3))
|
||||
if (data.slice(-1)[0] && data.slice(-1)[0].x >= data_point.x) {
|
||||
removed = data.pop();
|
||||
}
|
||||
data.push(data_point);
|
||||
//if (chart.data.datasets[dataset_index].key == 'tt:target')
|
||||
// console.log('PUSHED', data.slice(-3))
|
||||
/*
|
||||
if (graphs.zoomed) {
|
||||
update_max = data_point.x;
|
||||
} else {
|
||||
chart.options.scales.xAxes[0].ticks.max = data_point.x;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
function reloadData(index, data){
|
||||
@ -959,6 +1056,17 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
|
||||
ax.ticks.min = min;
|
||||
}
|
||||
|
||||
function toggleAutoScale () {
|
||||
autoScaleFlag = !autoScaleFlag;
|
||||
if (autoScaleFlag) {
|
||||
graphs.autoScale(chart);
|
||||
update();
|
||||
autoScaleRow.innerHTML = "Autoscale <strong>on</strong> off";
|
||||
} else {
|
||||
autoScaleRow.innerHTML = "Autoscale on <strong>off</strong>";
|
||||
}
|
||||
}
|
||||
|
||||
function toggleAxesType(){
|
||||
setAxesType((chart.options.scales.yAxes[0].type=== 'linear') ? 'logarithmic' : 'linear');
|
||||
}
|
||||
@ -972,6 +1080,7 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
|
||||
}
|
||||
chart.options.scales.yAxes[0].type = type;
|
||||
chart.options.animation.duration = 800;
|
||||
if (autoScaleFlag) graphs.autoScale(chart);
|
||||
update();
|
||||
setTimeout(function(){chart.options.animation.duration = 0;},850)
|
||||
}
|
||||
@ -996,7 +1105,7 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
|
||||
let d2 = Math.abs(dp._model.x - x)
|
||||
if(d == 0 || d2 < d){
|
||||
d = d2;
|
||||
legendels[chart.data.datasets[i].label].innerHTML =
|
||||
legendels[chart.data.datasets[i].key].innerHTML =
|
||||
strFormat(chart.data.datasets[i].data[dp._index].y, 6);
|
||||
test[i]=dp
|
||||
}
|
||||
@ -1045,7 +1154,8 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
|
||||
redraw: redraw,
|
||||
update: update,
|
||||
reloadData: reloadData,
|
||||
autoScaleChart: autoScaleChart,
|
||||
autoScaleIf: autoScaleIf,
|
||||
chart: chart,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1096,13 +1206,17 @@ function updateCharts2(graph){
|
||||
return;
|
||||
}
|
||||
for(let key in graph){
|
||||
for (pt of graph[key]) {
|
||||
if (graph[key][1] != null) {
|
||||
// there is at least ONE valid datapoint
|
||||
graphs.newDataHandler(key, {x: graph[key][0][0]*1000, y: graph[key][0][1]});
|
||||
break;
|
||||
if (graph[key][0] != null) {
|
||||
// there is at least ONE valid datapoint
|
||||
for (pt of graph[key]) {
|
||||
graphs.newDataHandler(key, {x: pt[0]*1000, y: pt[1]});
|
||||
}
|
||||
}
|
||||
}
|
||||
graphs.update();
|
||||
graphs.updateAuto();
|
||||
// graphs.update();
|
||||
}
|
||||
|
||||
function createCharts2(arg) {
|
||||
console.log('C2', arg)
|
||||
}
|
@ -250,6 +250,10 @@ function createInput(s, name, title, info) {
|
||||
input.setAttribute("name", name);
|
||||
input.setAttribute("__ctype__", "input");
|
||||
input.style.width = "100px";
|
||||
input.addEventListener("focus", function(evt) {
|
||||
let elm = evt.target;
|
||||
setTimeout(function(){elm.setSelectionRange(0, elm.value.length);},0);
|
||||
});
|
||||
|
||||
input.onkeydown = function (e) {
|
||||
if (e.which === 27 || e.key == "Escape") {
|
||||
@ -281,7 +285,8 @@ function createInput(s, name, title, info) {
|
||||
input.setAttribute("actualValue", oldValue);
|
||||
}
|
||||
var actualValue = input.getAttribute("actualValue");
|
||||
if (value === actualValue || value === oldValue) {
|
||||
if (value == actualValue || value == oldValue ||
|
||||
parseFloat(value) == parseFloat(actualValue) || parseFloat(value) == parseFloat(oldValue)) {
|
||||
input.value = actualValue;
|
||||
// nothing to do.
|
||||
row.style.backgroundColor = "white";
|
||||
|
@ -166,18 +166,25 @@ All other connections are to be closed (getJSON):
|
||||
|
||||
*********************************************************************************************************************************
|
||||
|
||||
/updategraph?id=<id>
|
||||
/updategraph?id=<id>[&variables=<variable list>]
|
||||
|
||||
if <variables list> is given, the given variables will be updated with the graph-update-message
|
||||
|
||||
response: <accept-graph-message>
|
||||
|
||||
<accept-graph-message> = = {
|
||||
"type": "accept-graph"
|
||||
"type": "accept-graph",
|
||||
"live": true/false
|
||||
}
|
||||
|
||||
the "live" flag is true when the last /graph query was including the actual time
|
||||
|
||||
*********************************************************************************************************************************
|
||||
|
||||
/graph?time=<start>,<end>&variables=<variable list>&id=<id>
|
||||
|
||||
the given variables are added to the list of variables being updated with the graph-update-message
|
||||
|
||||
response: <graph-draw-message>
|
||||
|
||||
<graph-draw-message> = = {
|
||||
|
111
histgraph.py
111
histgraph.py
@ -18,51 +18,67 @@ def get_abs_time(*times):
|
||||
|
||||
|
||||
class ColorMap(object):
|
||||
'''
|
||||
""""
|
||||
ColorMap is using official CSS color names, with the exception of Green, as this
|
||||
is defined differently with X11 colors than in SEA, and used heavily in config files.
|
||||
Here Green is an alias to Lime (#00FF00) and MidGreen is #008000, which is called Green in CSS.
|
||||
The function to_code is case insensitive and accepts also names with underscores.
|
||||
The order is choosen by M. Zolliker for the SEA client, originally only the first 16 were used.
|
||||
'''
|
||||
hex_name = (("#FFFFFF","White"), ("#FF0000","Red"), ("#00FF00","Lime"), ("#0000FF","Blue"), ("#FF00FF","Magenta"),
|
||||
("#FFFF00","Yellow"), ("#00FFFF","Cyan"), ("#000000","Black"), ("#FFA500","Orange"), ("#006400","DarkGreen"),
|
||||
("#9400D3","DarkViolet"), ("#A52A2A","Brown"), ("#87CEEB","SkyBlue"), ("#808080","Gray"), ("#FF69B4","HotPink"),
|
||||
("#FFFFE0","LightYellow"), ("#00FF7F","SpringGreen"), ("#000080","Navy"), ("#1E90FF","DodgerBlue"),
|
||||
("#9ACD32","YellowGreen"), ("#008B8B","DarkCyan"), ("#808000","Olive"), ("#DEB887","BurlyWood"),
|
||||
("#7B68EE","MediumSlateBlue"), ("#483D8B","DarkSlateBlue"), ("#98FB98","PaleGreen"), ("#FF1493","DeepPink"),
|
||||
("#FF6347","Tomato"), ("#32CD32","LimeGreen"), ("#DDA0DD","Plum"), ("#7FFF00","Chartreuse"), ("#800080","Purple"),
|
||||
("#00CED1","DarkTurquoise"), ("#8FBC8F","DarkSeaGreen"), ("#4682B4","SteelBlue"), ("#800000","Maroon"),
|
||||
("#3CB371","MediumSeaGreen"), ("#FF4500","OrangeRed"), ("#BA55D3","MediumOrchid"), ("#2F4F4F","DarkSlateGray"),
|
||||
("#CD853F","Peru"), ("#228B22","ForestGreen"), ("#48D1CC","MediumTurquoise"), ("#DC143C","Crimson"),
|
||||
("#D3D3D3","LightGray"), ("#ADFF2F","GreenYellow"), ("#7FFFD4","Aquamarine"), ("#BC8F8F","RosyBrown"),
|
||||
("#20B2AA","LightSeaGreen"), ("#C71585","MediumVioletRed"), ("#F0E68C","Khaki"), ("#6495ED","CornflowerBlue"),
|
||||
("#556B2F","DarkOliveGreen"), ("#CD5C5C","IndianRed "), ("#2E8B57","SeaGreen"), ("#F08080","LightCoral"),
|
||||
("#8A2BE2","BlueViolet"), ("#AFEEEE","PaleTurquoise"), ("#4169E1","RoyalBlue"), ("#0000CD","MediumBlue"),
|
||||
("#B8860B","DarkGoldenRod"), ("#00BFFF","DeepSkyBlue"), ("#FFC0CB","Pink"), ("#4B0082","Indigo "), ("#A0522D","Sienna"),
|
||||
("#FFD700","Gold"), ("#F4A460","SandyBrown"), ("#DAA520","GoldenRod"), ("#DA70D6","Orchid"), ("#E6E6FA","Lavender"),
|
||||
("#5F9EA0","CadetBlue"), ("#D2691E","Chocolate"), ("#66CDAA","MediumAquaMarine"), ("#6B8E23","OliveDrab"),
|
||||
("#A9A9A9","DarkGray"), ("#BDB76B","DarkKhaki"), ("#696969","DimGray"), ("#B0C4DE","LightSteelBlue"),
|
||||
("#191970","MidnightBlue"), ("#FFE4C4","Bisque"), ("#6A5ACD","SlateBlue"), ("#EE82EE","Violet"),
|
||||
("#8B4513","SaddleBrown"), ("#FF7F50","Coral"), ("#008000","MidGreen"), ("#DB7093","PaleVioletRed"), ("#C0C0C0","Silver"),
|
||||
("#E0FFFF","LightCyan"), ("#9370DB","MediumPurple"), ("#FF8C00","DarkOrange"), ("#00FA9A","MediumSpringGreen"),
|
||||
("#E9967A","DarkSalmon"), ("#778899","LightSlateGray"), ("#9932CC","DarkOrchid"), ("#EEE8AA","PaleGoldenRod"),
|
||||
("#F8F8FF","GhostWhite"), ("#FFA07A","LightSalmon"), ("#ADD8E6","LightBlue"), ("#D8BFD8","Thistle"),
|
||||
("#FFE4E1","MistyRose"), ("#FFDEAD","NavajoWhite"), ("#40E0D0","Turquoise"), ("#90EE90","LightGreen"),
|
||||
("#B22222","FireBrick"), ("#008080","Teal"), ("#F0FFF0","HoneyDew"), ("#FFFACD","LemonChiffon"), ("#FFF5EE","SeaShell"),
|
||||
("#F5F5DC","Beige"), ("#DCDCDC","Gainsboro"), ("#FA8072","Salmon"), ("#8B008B","DarkMagenta"), ("#FFB6C1","LightPink"),
|
||||
("#708090","SlateGray"), ("#87CEFA","LightSkyBlue"), ("#FFEFD5","PapayaWhip"), ("#D2B48C","Tan"), ("#FFFFF0","Ivory"),
|
||||
("#F0FFFF","Azure"), ("#F5DEB3","Wheat"), ("#00008B","DarkBlue"), ("#FFDAB9","PeachPuff"), ("#8B0000","DarkRed"),
|
||||
("#FAF0E6","Linen"), ("#B0E0E6","PowderBlue"), ("#FFE4B5","Moccasin"), ("#F5F5F5","WhiteSmoke"), ("#FFF8DC","Cornsilk"),
|
||||
("#FFFAFA","Snow"), ("#FFF0F5","LavenderBlush"), ("#FFEBCD","BlanchedAlmond"), ("#F0F8FF","AliceBlue"),
|
||||
("#FAEBD7","AntiqueWhite"), ("#FDF5E6","OldLace"), ("#FAFAD2","LightGoldenRodYellow"), ("#F5FFFA","MintCream"),
|
||||
("#FFFAF0","FloralWhite"), ("#7CFC00","LawnGreen"), ("#663399","RebeccaPurple"))
|
||||
"""
|
||||
hex_name = (
|
||||
("#FFFFFF", "White"), ("#FF0000", "Red"), ("#00FF00", "Lime"), ("#0000FF", "Blue"), ("#FF00FF", "Magenta"),
|
||||
("#FFFF00", "Yellow"), ("#00FFFF", "Cyan"), ("#000000", "Black"), ("#FFA500", "Orange"),
|
||||
("#006400", "DarkGreen"), ("#9400D3", "DarkViolet"), ("#A52A2A", "Brown"), ("#87CEEB", "SkyBlue"),
|
||||
("#808080", "Gray"), ("#FF69B4", "HotPink"), ("#FFFFE0", "LightYellow"), ("#00FF7F", "SpringGreen"),
|
||||
("#000080", "Navy"), ("#1E90FF", "DodgerBlue"), ("#9ACD32", "YellowGreen"), ("#008B8B", "DarkCyan"),
|
||||
("#808000", "Olive"), ("#DEB887", "BurlyWood"),
|
||||
("#7B68EE", "MediumSlateBlue"), ("#483D8B", "DarkSlateBlue"), ("#98FB98", "PaleGreen"), ("#FF1493", "DeepPink"),
|
||||
("#FF6347", "Tomato"), ("#32CD32", "LimeGreen"), ("#DDA0DD", "Plum"), ("#7FFF00", "Chartreuse"),
|
||||
("#800080", "Purple"), ("#00CED1", "DarkTurquoise"), ("#8FBC8F", "DarkSeaGreen"), ("#4682B4", "SteelBlue"),
|
||||
("#800000", "Maroon"),
|
||||
("#3CB371", "MediumSeaGreen"), ("#FF4500", "OrangeRed"), ("#BA55D3", "MediumOrchid"),
|
||||
("#2F4F4F", "DarkSlateGray"), ("#CD853F", "Peru"), ("#228B22", "ForestGreen"), ("#48D1CC", "MediumTurquoise"),
|
||||
("#DC143C", "Crimson"),
|
||||
("#D3D3D3", "LightGray"), ("#ADFF2F", "GreenYellow"), ("#7FFFD4", "Aquamarine"), ("#BC8F8F", "RosyBrown"),
|
||||
("#20B2AA", "LightSeaGreen"), ("#C71585", "MediumVioletRed"), ("#F0E68C", "Khaki"),
|
||||
("#6495ED", "CornflowerBlue"),
|
||||
("#556B2F", "DarkOliveGreen"), ("#CD5C5C", "IndianRed "), ("#2E8B57", "SeaGreen"), ("#F08080", "LightCoral"),
|
||||
("#8A2BE2", "BlueViolet"), ("#AFEEEE", "PaleTurquoise"), ("#4169E1", "RoyalBlue"), ("#0000CD", "MediumBlue"),
|
||||
("#B8860B", "DarkGoldenRod"), ("#00BFFF", "DeepSkyBlue"), ("#FFC0CB", "Pink"), ("#4B0082", "Indigo "),
|
||||
("#A0522D", "Sienna"),
|
||||
("#FFD700", "Gold"), ("#F4A460", "SandyBrown"), ("#DAA520", "GoldenRod"), ("#DA70D6", "Orchid"),
|
||||
("#E6E6FA", "Lavender"),
|
||||
("#5F9EA0", "CadetBlue"), ("#D2691E", "Chocolate"), ("#66CDAA", "MediumAquaMarine"), ("#6B8E23", "OliveDrab"),
|
||||
("#A9A9A9", "DarkGray"), ("#BDB76B", "DarkKhaki"), ("#696969", "DimGray"), ("#B0C4DE", "LightSteelBlue"),
|
||||
("#191970", "MidnightBlue"), ("#FFE4C4", "Bisque"), ("#6A5ACD", "SlateBlue"), ("#EE82EE", "Violet"),
|
||||
("#8B4513", "SaddleBrown"), ("#FF7F50", "Coral"), ("#008000", "MidGreen"), ("#DB7093", "PaleVioletRed"),
|
||||
("#C0C0C0", "Silver"),
|
||||
("#E0FFFF", "LightCyan"), ("#9370DB", "MediumPurple"), ("#FF8C00", "DarkOrange"),
|
||||
("#00FA9A", "MediumSpringGreen"),
|
||||
("#E9967A", "DarkSalmon"), ("#778899", "LightSlateGray"), ("#9932CC", "DarkOrchid"),
|
||||
("#EEE8AA", "PaleGoldenRod"),
|
||||
("#F8F8FF", "GhostWhite"), ("#FFA07A", "LightSalmon"), ("#ADD8E6", "LightBlue"), ("#D8BFD8", "Thistle"),
|
||||
("#FFE4E1", "MistyRose"), ("#FFDEAD", "NavajoWhite"), ("#40E0D0", "Turquoise"), ("#90EE90", "LightGreen"),
|
||||
("#B22222", "FireBrick"), ("#008080", "Teal"), ("#F0FFF0", "HoneyDew"), ("#FFFACD", "LemonChiffon"),
|
||||
("#FFF5EE", "SeaShell"),
|
||||
("#F5F5DC", "Beige"), ("#DCDCDC", "Gainsboro"), ("#FA8072", "Salmon"), ("#8B008B", "DarkMagenta"),
|
||||
("#FFB6C1", "LightPink"),
|
||||
("#708090", "SlateGray"), ("#87CEFA", "LightSkyBlue"), ("#FFEFD5", "PapayaWhip"), ("#D2B48C", "Tan"),
|
||||
("#FFFFF0", "Ivory"),
|
||||
("#F0FFFF", "Azure"), ("#F5DEB3", "Wheat"), ("#00008B", "DarkBlue"), ("#FFDAB9", "PeachPuff"),
|
||||
("#8B0000", "DarkRed"),
|
||||
("#FAF0E6", "Linen"), ("#B0E0E6", "PowderBlue"), ("#FFE4B5", "Moccasin"), ("#F5F5F5", "WhiteSmoke"),
|
||||
("#FFF8DC", "Cornsilk"),
|
||||
("#FFFAFA", "Snow"), ("#FFF0F5", "LavenderBlush"), ("#FFEBCD", "BlanchedAlmond"), ("#F0F8FF", "AliceBlue"),
|
||||
("#FAEBD7", "AntiqueWhite"), ("#FDF5E6", "OldLace"), ("#FAFAD2", "LightGoldenRodYellow"),
|
||||
("#F5FFFA", "MintCream"),
|
||||
("#FFFAF0", "FloralWhite"), ("#7CFC00", "LawnGreen"), ("#663399", "RebeccaPurple"))
|
||||
codes = {}
|
||||
for i, pair in enumerate(hex_name):
|
||||
codes[pair[0]] = i
|
||||
low = pair[1].lower()
|
||||
codes[low] = i
|
||||
codes[low.replace("gray","grey")] = i
|
||||
codes[low.replace("gray", "grey")] = i
|
||||
codes["green"] = 2
|
||||
codes["fuchsia"] = 4
|
||||
codes["aqua"] = 6
|
||||
@ -72,7 +88,7 @@ class ColorMap(object):
|
||||
try:
|
||||
return int(colortext)
|
||||
except ValueError:
|
||||
return ColorMap.codes.get(colortext.lower().replace("_",""),-1)
|
||||
return ColorMap.codes.get(colortext.lower().replace("_", ""),-1)
|
||||
|
||||
@staticmethod
|
||||
def check_hex(code):
|
||||
@ -96,7 +112,6 @@ class ColorMap(object):
|
||||
return -1
|
||||
|
||||
|
||||
|
||||
def get_vars(main, time):
|
||||
result = {}
|
||||
|
||||
@ -112,10 +127,13 @@ def get_vars(main, time):
|
||||
vars.append(vars[0])
|
||||
if len(vars) == 3:
|
||||
vars.append("")
|
||||
name, unit, label, color = vars
|
||||
if len(vars) == 4:
|
||||
vars.append("") # exact flag
|
||||
name, unit, label, color, continuous = vars
|
||||
continuous = int(continuous) if continuous else 0
|
||||
if not unit in result:
|
||||
result[unit] = dict(tag = unit, unit = unit.split("_")[0], curves=Dict())
|
||||
result[unit]["curves"][name] = dict(name=name, label=label, color=color)
|
||||
result[unit] = dict(tag=unit, unit=unit.split("_")[0], curves=Dict())
|
||||
result[unit]["curves"][name] = dict(name=name, label=label, color=color, continuous=continuous)
|
||||
|
||||
for unit, curvegroup in result.items():
|
||||
color_set = set()
|
||||
@ -137,14 +155,19 @@ def get_vars(main, time):
|
||||
color_set.add(c)
|
||||
curve["original_color"] = col
|
||||
curve["color"] = ColorMap.to_hex(c)
|
||||
c = 1 # omit white
|
||||
c = 1 # omit white
|
||||
for curve in auto_curves:
|
||||
while c in color_set: c += 1 # find unused color
|
||||
while c in color_set:
|
||||
c += 1 # find unused color
|
||||
curve["color"] = ColorMap.to_hex(c)
|
||||
c += 1
|
||||
return result
|
||||
|
||||
|
||||
def get_curves(main, keys, timerange, show_empty=True):
|
||||
curves = main.get_curves(keys, get_abs_time(*timerange), maxpoints=500)
|
||||
def get_curves(main, keys, timerange, cut_begin=True):
|
||||
curves = main.get_curves(keys, get_abs_time(*timerange), maxpoints=500, cut_begin=cut_begin)
|
||||
#if 'tt:target' in curves:
|
||||
# print('---')
|
||||
# print(curves['tt:target'].fmtm())
|
||||
# print('TT', curves['tt:target'].for_json()[-5:])
|
||||
return {k: c.for_json() for k, c in curves.items()}
|
||||
|
101
seaweb_hist.py
101
seaweb_hist.py
@ -64,7 +64,7 @@ def get_update(path=None):
|
||||
@flask.stream_with_context
|
||||
def generator():
|
||||
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, device=instrument.device);
|
||||
msg = dict(type='id', id=client.id, instrument=instrument.title, device=instrument.device);
|
||||
yield to_json_sse(msg)
|
||||
try:
|
||||
lastmsg = time.time()
|
||||
@ -130,6 +130,7 @@ def reply():
|
||||
try:
|
||||
id = kwargs.pop('id')
|
||||
client = instrument.clients[id]
|
||||
print('PATH', path)
|
||||
msg = getattr(client, "w_" + path[1:])(**kwargs)
|
||||
except Exception as e:
|
||||
logging.error('%s', traceback.format_exc())
|
||||
@ -257,6 +258,7 @@ class Instrument:
|
||||
self.clients[client.id] = client
|
||||
return client
|
||||
|
||||
|
||||
class SeaInstrument(Instrument):
|
||||
# convert SEA layout tag like "-W" to more meaningful name.
|
||||
# the code: 0: modifier, 1: enum name, 2: input element
|
||||
@ -502,17 +504,18 @@ class SeaGraph:
|
||||
LIVE = 2
|
||||
|
||||
def __init__(self):
|
||||
self.livemode = self.HISTORICAL
|
||||
self.livemode = self.ACTUAL
|
||||
self.time = [0, 0]
|
||||
self.lastvalues = {}
|
||||
self.variables = []
|
||||
|
||||
def graphpoll(self):
|
||||
if self.livemode == self.LIVE:
|
||||
self.time[1], = get_abs_time(0)
|
||||
else:
|
||||
self.time[1] = self.time[0] # do not update
|
||||
self.time[1] = self.time[0] # do not update
|
||||
if self.time[1] > self.time[0]:
|
||||
result = get_curves(main_cache, self.variables, self.time, show_empty=False)
|
||||
result = get_curves(main_cache, self.variables, self.time, cut_begin=False)
|
||||
self.strip_future(result)
|
||||
if int(self.time[1] / 60) != int(self.time[0] / 60):
|
||||
# update unchanged values
|
||||
@ -533,14 +536,8 @@ class SeaGraph:
|
||||
self.lastvalues[var] = (endtime, lastx)
|
||||
|
||||
def strip_future(self, result):
|
||||
"""strip future points (happens only on dummy test_day)"""
|
||||
# if self.livemode == self.LIVE:
|
||||
for c in result.values():
|
||||
while len(c):
|
||||
lastt, lastx = c[-1]
|
||||
if lastt <= self.time[1]:
|
||||
break
|
||||
c.pop()
|
||||
"""strip future points (implemented on dummy test_day)"""
|
||||
pass # do nothing here
|
||||
|
||||
def w_gettime(self, time):
|
||||
result = get_abs_time(*[float(t) for t in time.split(',')])
|
||||
@ -552,7 +549,8 @@ class SeaGraph:
|
||||
self.last_t = 0
|
||||
start, end, now = get_abs_time(*time, 0)
|
||||
self.time = [start, end]
|
||||
self.variables = variables.split(',')
|
||||
oldvars = set(self.variables)
|
||||
self.variables.extend((v for v in variables.split(',') if v not in oldvars))
|
||||
self.livemode = self.ACTUAL if end >= now else self.HISTORICAL
|
||||
logging.info('LIVE %g %g %d %d', end, now, end >= now, self.livemode)
|
||||
# self.scanner = seagraph.NumericScanner(instrument.logger_dir, instrument.test_day)
|
||||
@ -561,7 +559,7 @@ class SeaGraph:
|
||||
self.strip_future(result)
|
||||
logging.info('VARIABLES: %r %r %r', self.variables, start-now, end-now)
|
||||
for var, curve in list(result.items()):
|
||||
logging.info(' %s %r len=%d', var, curve[-1][0] - curve[0][0], len(curve))
|
||||
logging.info(' %s %r len=%d', var, curve[-1][0] - curve[0][0] if len(curve) else None, len(curve))
|
||||
self.complete_to_end(result, end)
|
||||
self.time[0] = self.time[1]
|
||||
# reduction not yet implemented
|
||||
@ -575,8 +573,10 @@ class SeaGraph:
|
||||
logging.info('GotVARS %r', result)
|
||||
return result
|
||||
|
||||
def w_updategraph(self):
|
||||
logging.info("UPD GRAPH %d", self.livemode)
|
||||
def w_updategraph(self, variables=''):
|
||||
if variables:
|
||||
self.variables = variables.split(',')
|
||||
logging.info("UPD GRAPH %d %r", self.livemode, self.variables)
|
||||
if self.livemode == self.HISTORICAL:
|
||||
return dict(type='accept-graph', live=False)
|
||||
else:
|
||||
@ -658,7 +658,7 @@ class SeaClient(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):
|
||||
self.linesocket = tcp_lineserver.LineClient(host_port)
|
||||
@ -678,7 +678,7 @@ class DummyClient(SeaGraph):
|
||||
line = self.linesocket.get_line()
|
||||
if line != None:
|
||||
msg = json.loads(line)
|
||||
if msg.type in self.async:
|
||||
if msg.type in self.asynch:
|
||||
t = 0
|
||||
# print 'PUSH',msg, replytype
|
||||
self.queue.append(msg)
|
||||
@ -693,6 +693,12 @@ class DummyClient(SeaGraph):
|
||||
logging.error('REPLY MISMATCH %s %s <> %s', command, replytype, msg.type)
|
||||
return msg
|
||||
|
||||
def strip_future(self, result):
|
||||
for c in result.values():
|
||||
while len(c):
|
||||
if c[-1][0] <= self.time[1]:
|
||||
break
|
||||
c.pop()
|
||||
|
||||
def w_getblock(self, path):
|
||||
return self.cmd_reply(dict(type='getblock', path=path, id=self.id), 'draw')
|
||||
@ -718,7 +724,7 @@ class DummyClient(SeaGraph):
|
||||
messages = []
|
||||
if line:
|
||||
msg = json.loads(line)
|
||||
if msg.type in self.async:
|
||||
if msg.type in self.asynch:
|
||||
messages.append(msg)
|
||||
else:
|
||||
self.syncreply.append(msg)
|
||||
@ -761,7 +767,7 @@ class SecopMsg:
|
||||
self.par = sl[1]
|
||||
if len(sl) > 2:
|
||||
self.value = json.loads(' '.join(sl[2:]))
|
||||
self.async = self.type in ('update', 'error_update')
|
||||
self.asynch = self.type in ('update', 'error_update')
|
||||
|
||||
def __repr__(self):
|
||||
value = repr(self.value)
|
||||
@ -828,15 +834,15 @@ class SecopClient(SeaGraph):
|
||||
msg = self.syncreply.pop(0)
|
||||
break
|
||||
line = self.linesocket.get_line()
|
||||
if line != None:
|
||||
if line is not None:
|
||||
msg = SecopMsg(line)
|
||||
if msg.async:
|
||||
if msg.asynch:
|
||||
self.consolequeue.append(dict(type='reply',line=line,origin='async'))
|
||||
else:
|
||||
self.consolequeue.append(dict(type='reply',line=line,origin='other'))
|
||||
if self.out: self.out.write("<"+line+"\n")
|
||||
#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
|
||||
self.queue.append(msg)
|
||||
else:
|
||||
@ -895,31 +901,41 @@ class SecopClient(SeaGraph):
|
||||
if not command:
|
||||
return dict(type='accept-command')
|
||||
cmd = "change " + command
|
||||
return self.cmd_reply(cmd, 'changed ' + command.split(' ')[0])
|
||||
self.cmd_reply(cmd, 'changed ' + command.split(' ')[0])
|
||||
return dict(type='accept-command')
|
||||
|
||||
def poll(self):
|
||||
messages = []
|
||||
if self.consolequeue:
|
||||
messages = self.consolequeue
|
||||
messages.extend(self.consolequeue)
|
||||
self.consolequeue = []
|
||||
return messages
|
||||
if self.queue:
|
||||
messages = convert_event(self.queue)
|
||||
messages.extend(convert_event(self.queue))
|
||||
self.queue = []
|
||||
return messages
|
||||
line = self.linesocket.get_line()
|
||||
# logging.info('poll %s', line)
|
||||
if line:
|
||||
if self.out: self.out.write("<"+line+"\n")
|
||||
while True:
|
||||
line = self.linesocket.get_line()
|
||||
if not line:
|
||||
break
|
||||
# logging.info('poll %s', line)
|
||||
if self.out:
|
||||
self.out.write("<"+line+"\n")
|
||||
msg = SecopMsg(line)
|
||||
if msg.async: # do not flood console with updates
|
||||
self.consolequeue.append(dict(type='reply',line=line,origin='async'))
|
||||
if msg.asynch: # do not flood console with updates
|
||||
if msg.par == 'tt:target':
|
||||
print(msg)
|
||||
self.consolequeue.append(dict(type='reply', line=line, origin='async'))
|
||||
else:
|
||||
self.consolequeue.append(dict(type='reply',line=line,origin='other'))
|
||||
# logging.info('GOT MSG %r %r', msg.async, convert_event(SecopMsg(line)))
|
||||
if msg.async:
|
||||
return convert_event(SecopMsg(line))
|
||||
self.syncreply.append(msg)
|
||||
return []
|
||||
self.consolequeue.append(dict(type='reply', line=line, origin='other'))
|
||||
# logging.info('GOT MSG %r %r', msg.asynch, convert_event(SecopMsg(line)))
|
||||
if msg.asynch:
|
||||
messages.extend(convert_event(SecopMsg(line)))
|
||||
else:
|
||||
self.syncreply.append(msg)
|
||||
# graph messages
|
||||
msg = self.graphpoll()
|
||||
if msg:
|
||||
messages.append(msg)
|
||||
return messages
|
||||
|
||||
def info(self):
|
||||
return ["na"]
|
||||
@ -939,6 +955,7 @@ class SecopInstrument(Instrument):
|
||||
def newClient(self):
|
||||
cl = SecopClient(self.host_port)
|
||||
self.device = cl.description['equipment_id']
|
||||
print('EQU', self.device)
|
||||
logging.info('init done %s %s', self.host_port, self.device)
|
||||
return self.register(cl)
|
||||
|
||||
@ -989,8 +1006,8 @@ if __name__ == '__main__':
|
||||
|
||||
instrument_config = instrument_list[inst_name]
|
||||
|
||||
frd = FrappyReader('/home/l_samenv/sea/%s' % inst_name, gevent=gevent)
|
||||
main_cache = MainCache('/home/l_samenv/histreader/%s_hist' % inst_name, frd, gevent=gevent)
|
||||
frd = FrappyReader('/Users/zolliker/frappyhist/%s' % inst_name, gevent=gevent)
|
||||
main_cache = MainCache('/Users/zolliker/frappyhist/%s_hist' % inst_name, frd, gevent=gevent)
|
||||
|
||||
# logging.basicConfig(filename=inst_name+".log", filemode='w', level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')
|
||||
|
@ -5,6 +5,7 @@ import re
|
||||
import circularlog
|
||||
import logging
|
||||
|
||||
|
||||
class LineHandler(asyncore.dispatcher_with_send):
|
||||
|
||||
def __init__(self, sock):
|
||||
@ -38,6 +39,7 @@ class LineHandler(asyncore.dispatcher_with_send):
|
||||
'''
|
||||
self.send_line("> " + line)
|
||||
|
||||
|
||||
class LineServer(asyncore.dispatcher):
|
||||
|
||||
def __init__(self, host, port, lineHandlerClass):
|
||||
@ -58,9 +60,11 @@ class LineServer(asyncore.dispatcher):
|
||||
def loop(self):
|
||||
asyncore.loop()
|
||||
|
||||
|
||||
class Disconnected(Exception):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class LineClient(object):
|
||||
|
||||
def __init__(self, host_port, announcement=None, filter_ascii=False, ridername="r"):
|
||||
@ -122,7 +126,8 @@ class LineClient(object):
|
||||
def close(self):
|
||||
self.socket.close()
|
||||
self.connected = False
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
server = LineServer("localhost", 9999, LineHandler)
|
||||
server.loop()
|
||||
|
Reference in New Issue
Block a user