//defaults var default_granularity = '5m'; // needs to be specified as string, changes var default_hours = 24; // int is OK, (h) hardcoded var default_end = 0; // detto var network_type='wlan0' // honestly, these two should be generated var iot_type='Tea' // dynamically var base_url = "https://bastart.spoton.cz/data/"; var counter = 0; var tout = 5000; // fresh date refresh rate, in ms var g_tout = 30000; // graph update rate, in ms //initialize the uninitialized var hours = new Object(); var granularity = new Object(); var end = new Object(); var graphdata = new Object(); var data = new Object(); // types match function names in python's Dynamic.py class var types = Array('solcap_monitor', 'cpumem_monitor', 'network_monitor', 'esp_battery_monitor'); // Now let's set up the defaults and primary data sources, leter changed dynamically var types_size = types.length; for(var i=0; iSolar Irradiance', y2label: 'Capacitor [V]', labelsDiv: 'solcap_labels', legend: 'always' } ); cpumem = new Dygraph( document.getElementById("cpumem"), data['cpumem_monitor'] ,{ axes : { x : { drawGrid: true, drawAxis : true }, y : { drawGrid: false, drawAxis : true, valueRange: [0,100] }, y2 : { drawGrid: false, drawAxis: true, valueRange: [0,100], independentTicks: true } }, rollPeriod: 5, interactionModel: {}, connectSeparatedPoints: true, series:{ 'Cpu': { axis: 'y', color: '#999', fillGraph: true, fillAlpha: 0.4 }, 'Mem': { axis: 'y2', color: '#c11' }, 'Disk': { axis: 'y2', color: '#111' } }, ylabel: 'CPU [%]', y2label: 'MEM / DISK [%]', labelsDiv: 'cpumem_labels', legend: 'always' } ); network = new Dygraph( document.getElementById("network"), data['network_monitor'] ,{ axes : { x : { drawGrid: true, drawAxis : true }, y : { drawGrid: false, drawAxis : true, }, y2 : { drawGrid: false, drawAxis: true, independentTicks: true } }, rollPeriod: 2, interactionModel: {}, connectSeparatedPoints: true, series:{ 'Bin': { axis: 'y', color: '#000', fillGraph: true, fillAlpha: 0.1 }, 'Bout': { axis: 'y', color: '#aaa', fillGraph: true, fillAlpha: 0.5 }, 'Din': { axis: 'y2', color: '#ff5500' }, 'Dout': { axis: 'y2', color: '#ff5500' }, 'Ein': { axis: 'y2', color: '#ff2233', fillAlpha: 0.5 }, 'Eout': { axis: 'y2', color: '#ff2233', fillAlpha: 0.5 } }, ylabel: 'kB/s', y2label: 'Drop / Error', labelsDiv: 'network_labels', legend: 'always' } ); esp_battery = new Dygraph( document.getElementById("esp_battery"), data['esp_battery_monitor'] ,{ axes : { x : { drawGrid: true, drawAxis : true }, y : { drawGrid: false, drawAxis : true, valueRange: [2.5,4.5] }, y2 : { drawGrid: false, drawAxis: true, valueRange: [2.5,4.5], independentTicks: true } }, rollPeriod: 5, interactionModel: {}, connectSeparatedPoints: true, series:{ 'batt(Tea)': { axis: 'y', color: '#000', fillGraph: true, fillAlpha: 0.2 }, 'batt_perc(Tea)': { axis: 'y2', color: '#000' }, 'batt_low(Tea)': { axis: 'y2', color: '#e00' } }, ylabel: 'Battery (Tea) [V]', y2label: 'Top [V] / Low [V]', labelsDiv: 'esp_battery_labels', legend: 'always' } ); // re-draw graphs function refreshGraph(source){ graphdata[source] = "https://bastart.spoton.cz/data/" + source + "?range=" + hours[source] + "h&granularity=" + granularity[source] + "&end=" + end[source] + "h"; if(source == 'solcap_monitor'){ solcap.updateOptions({'file': graphdata[source]}); } if(source == 'cpumem_monitor'){ cpumem.updateOptions({'file': graphdata[source]}); } if(source == 'esp_battery_monitor'){ graphdata[source] += "&type=" + iot_type; esp_battery.updateOptions({'file': graphdata[source]}); } if(source == 'network_monitor'){ graphdata[source] += "&type=" + network_type; network.updateOptions({'file': graphdata[source]}); } } // here, target needs to match the python's dynamic class again function setHours(hours_to_set, target){ hours[target] = hours_to_set; switch(hours[target]){ case '1': granularity[target] = '20s'; break; case '6': granularity[target] = '30s'; break; case '12': granularity[target] = '1m'; break; case '24': granularity[target] = '2m'; break; case '168': granularity[target] = '10m'; break; case '720': granularity[target] = '1h'; break; case '4320': granularity[target] = '3h'; break; case '8640': granularity[target] = '1d'; break; default: granularity[target] = '10m'; } end[target] = 0; refreshGraph(target); } // Functions for buttons to scale / move graphs function setBack(target){ disp_range = hours[target]*1 - end[target]*1; hours[target] = hours[target]*1 + disp_range; end[target] = end[target]*1 + disp_range; refreshGraph(target); } function setForth(target){ disp_range = hours[target]*1 - end[target]*1; hours[target] = hours[target]*1 - disp_range; if(hours[target] < disp_range){ hours[target] = disp_range; } end[target] = end[target]*1 - disp_range; if(end[target] < 0){ end[target] = 0; } refreshGraph(target); } function getPageContents(callback,url,params) { if (window.XMLHttpRequest){ // code for IE7+, Firefox, Chrome, Opera, Safari, SeaMonkey xmlhttp=new XMLHttpRequest(); } else{ // code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } if(params!=null) { xmlhttp.open("POST", url, true); xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); } else { xmlhttp.open("GET", url, true); } xmlhttp.onreadystatechange = function() { if(xmlhttp.readyState == 4 && xmlhttp.status == 200) { callback(xmlhttp.responseText); } } xmlhttp.send(params); } function refreshValues(){ fresh_vals_url = '/data/status_realtime_data?type=json' getPageContents(function(result){freshVals=JSON.parse(result);}, fresh_vals_url) document.getElementById('timestamp').innerHTML = freshVals.time; document.getElementById('sol_val').innerHTML = freshVals.iss_solar; document.getElementById('cap_val').innerHTML = freshVals.iss_capacitor; document.getElementById('cpu_val').innerHTML = freshVals.RasPI_cpu; document.getElementById('mem').innerHTML = freshVals.RasPI_mem; document.getElementById('disk').innerHTML = freshVals.RasPI_disk; document.getElementById('net_in').innerHTML = freshVals.net.b_in; document.getElementById('net_out').innerHTML = freshVals.net.b_out; counter = counter + tout; if(counter >= g_tout){ for(var i=0; i