diff --git a/firmware/data/bottom.js b/firmware/data/bottom.js index 4307630..16efd45 100644 --- a/firmware/data/bottom.js +++ b/firmware/data/bottom.js @@ -151,6 +151,119 @@ Plotly.newPlot('plot_chart', [trace1, trace2, trace3, trace4], layout); } setInterval(loadGraphData, 10000); loadGraphData(); +function loadTCGraphData() { +console.log('----> generate tc data graph <----'); +var data = JSON.parse(createJsonFromTable()); +var currenttime = []; +var time = []; +var channel1 = []; +var channel2 = []; +var channel3 = []; +var channel4 = []; +for (var i = 0; i < data['tcdata'].length; i++) { +time.push(data['tcdata'][i]['hour'] + ':' + (data['tcdata'][i]['min'] < 10 ? '0' : '') + data['tcdata'][i]['min']); +channel1.push(data['tcdata'][i]['ch1'] * 100 / 255); +channel2.push(data['tcdata'][i]['ch2'] * 100 / 255); +channel3.push(data['tcdata'][i]['ch3'] * 100 / 255); +channel4.push(data['tcdata'][i]['ch4'] * 100 / 255); +} +currenttime.push(data['currenttime']['hour']); +currenttime.push(data['currenttime']['min']); +var currentTimeStr = currenttime[0] + ':' + (currenttime[1] < 10 ? '0' : '') + currenttime[1]; +var index = time.indexOf(currentTimeStr); +if (index === -1) { +var lowerIndex = -1; +var upperIndex = -1; +for (var i = 0; i < time.length - 1; i++) { +const currentDate = new Date(); +const year = currentDate.getFullYear(); +const month = (currentDate.getMonth() + 1).toString().padStart(2, '0'); +const day = currentDate.getDate().toString().padStart(2, '0'); +const dateString = `${year}-${month}-${day}`; +const start = moment(dateString + ' ' + time[i], 'YYYY-MM-DD HH:mm'); +const curr = moment(dateString + ' ' + currentTimeStr, 'YYYY-MM-DD HH:mm'); +const end = moment(dateString + ' ' + time[i + 1], 'YYYY-MM-DD HH:mm'); +if (curr.isBetween(start, end)) { +lowerIndex = i; +upperIndex = i + 1; +break; +} +} +if (lowerIndex === -1 || upperIndex === -1) { +console.log("Error: Current time not found in time array and not between two elements in time array. Fixing it..."); +lowerIndex = 0; +upperIndex = 1; +var tmp1 = time[0].split(':'); +currenttime[0] = tmp1[0]; +currenttime[1] = tmp1[1]; +} +var lowerTime = time[lowerIndex].split(":"); +var upperTime = time[upperIndex].split(":"); +var timeDiff = (currenttime[0] - lowerTime[0]) + ((currenttime[1] - lowerTime[1]) / 60); +var indexFloat = lowerIndex + timeDiff / ((upperTime[0] - lowerTime[0]) + ((upperTime[1] - lowerTime[1]) / 60)); +} else { +} +if (indexFloat > index) { +index = indexFloat; +} +var trace1 = { +x: time, +y: channel1, +name: 'Channel 1', +type: 'scatter', +mode: 'lines+markers', +}; +var trace2 = { +x: time, +y: channel2, +name: 'Channel 2', +type: 'scatter', +mode: 'lines+markers', +}; +var trace3 = { +x: time, +y: channel3, +name: 'Channel 3', +type: 'scatter', +mode: 'lines+markers', +}; +var trace4 = { +x: time, +y: channel4, +name: 'Channel 4', +type: 'scatter', +mode: 'lines+markers', +}; +var layout = { +title: 'Timing Control Data Blocks', +xaxis: { +title: 'Time', +tickangle: -45, +}, +yaxis: { +title: 'Brightness', +range: [0, 100], +}, +shapes: [{ +type: 'line', +x0: index, +y0: 0, +x1: index, +y1: 255, +line: { +color: 'lightgrey', +width: 3, +dash: 'dot' +} +}] +}; +Plotly.newPlot('tc_plot_chart', [trace1, trace2, trace3, trace4], layout); +} +setInterval(function() { +if (document.getElementById('tab-tde').classList.contains('visible')) { +loadTCGraphData(); +} +}, 2000); function updateLightState() { console.log('----> setting bri and power switch <----'); for (let i = 1; i <= {{LIGHT_COUNT}}; i++) { @@ -232,22 +345,22 @@ headerRow.appendChild(th); table.appendChild(headerRow); for (var i = 1; i <= 10; i++) { var tr = document.createElement("tr"); -var tdHour = createSelectCell(23, 0); +var tdHour = createSelectCell(23, 0, 1); tdHour.id = "hour" + i; tr.appendChild(tdHour); -var tdMinute = createSelectCell(59, 0); +var tdMinute = createSelectCell(59, 0, 1); tdMinute.id = "minute" + i; tr.appendChild(tdMinute); -var tdCh1 = createSelectCell(100, 0); +var tdCh1 = createSelectCell(100, 0, 1); tdCh1.id = "ch1_" + i; tr.appendChild(tdCh1); -var tdCh2 = createSelectCell(100, 0); +var tdCh2 = createSelectCell(100, 0, 1); tdCh2.id = "ch2_" + i; tr.appendChild(tdCh2); -var tdCh3 = createSelectCell(100, 0); +var tdCh3 = createSelectCell(100, 0, 1); tdCh3.id = "ch3_" + i; tr.appendChild(tdCh3); -var tdCh4 = createSelectCell(100, 0); +var tdCh4 = createSelectCell(100, 0, 1); tdCh4.id = "ch4_" + i; tr.appendChild(tdCh4); table.appendChild(tr); @@ -257,9 +370,9 @@ container.innerHTML = ""; container.classList.add("pure-form"); container.appendChild(table); } -function createSelectCell(max, value) { +function createSelectCell(max, value, step) { var select = document.createElement("select"); -for (var i = 0; i <= max; i++) { +for (var i = 0; i <= max; i += step) { var option = document.createElement("option"); option.value = i; option.text = i; @@ -284,6 +397,7 @@ row.cells[3].childNodes[0].value = parseInt(tcdata[i].ch2 * 100 / 255); row.cells[4].childNodes[0].value = parseInt(tcdata[i].ch3 * 100 / 255); row.cells[5].childNodes[0].value = parseInt(tcdata[i].ch4 * 100 / 255); } +loadTCGraphData(); }); } function createJsonFromTable() { @@ -301,20 +415,40 @@ tcdata.push({hour: hour, min: min, ch1: ch1, ch2: ch2, ch3: ch3, ch4: ch4}); } var currentTime = {hour: new Date().getHours(), min: new Date().getMinutes()}; var jsonData = {tcdata: tcdata, currenttime: currentTime}; -console.log("jsonData = " + JSON.stringify(jsonData)); return JSON.stringify(jsonData); } function sendDataToServer() { var jsonData = createJsonFromTable(); var urlEncodedData = encodeURIComponent(jsonData); var url = 'http://{{IP_ADDRESS}}/tc_data_blocks_store?data=' + urlEncodedData; -console.log("url so save = " + url); var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); -xhr.onreadystatechange = function() { -if (xhr.readyState === 4 && xhr.status === 200) { +xhr.onreadystatechange = function () { +if (xhr.readyState === 4) { +var button = document.getElementById("save-button"); +if (xhr.status === 200) { +button.classList.remove("pure-button-primary"); +button.classList.add("success"); +button.innerHTML = "Saved!"; +setTimeout(function () { +button.classList.remove("success"); +button.classList.add("pure-button-primary"); +button.innerHTML = "save"; +}, 2000); console.log('Data successfully sent to server!'); +} else { +button.classList.remove("pure-button-primary"); +button.classList.add("error"); +button.innerHTML = "Error!"; +setTimeout(function () { +button.classList.remove("error"); +button.classList.add("pure-button-primary"); +button.innerHTML = "save"; +}, 2000); +console.log('Error while sending data to server.'); +} } }; xhr.send(); +loadTCGraphData(); } diff --git a/firmware/data/config_template.html b/firmware/data/config_template.html index 820b72a..da7ca3b 100644 --- a/firmware/data/config_template.html +++ b/firmware/data/config_template.html @@ -1,70 +1,70 @@ -
-
-
- -
- - -
-
- - -
-
- -
- - -
-
- - -
-
- -
- -ON -OFF -
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
-
-
+
+
+
+ +
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+
+ +
+ +ON +OFF +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
diff --git a/firmware/data/index_template_bottom.html b/firmware/data/index_template_bottom.html index c1156c1..241e1ee 100644 --- a/firmware/data/index_template_bottom.html +++ b/firmware/data/index_template_bottom.html @@ -6,10 +6,20 @@ Timming control data editor
+ + + + + +
+
+
+
+

-save +save - +

Light {{LIGHT_NUMBER}}

+
+ +ON +OFF +
+
+ + +  +9 +% +
+ + +  + +% + +
diff --git a/firmware/html/bottom.js b/firmware/html/bottom.js index f26968d..cdc7998 100644 --- a/firmware/html/bottom.js +++ b/firmware/html/bottom.js @@ -178,6 +178,135 @@ function loadGraphData() { setInterval(loadGraphData, 10000); loadGraphData(); +function loadTCGraphData() { + console.log('----> generate tc data graph <----'); + + var data = JSON.parse(createJsonFromTable()); + //console.log(data); + var currenttime = []; + var time = []; + var channel1 = []; + var channel2 = []; + var channel3 = []; + var channel4 = []; + for (var i = 0; i < data['tcdata'].length; i++) { + time.push(data['tcdata'][i]['hour'] + ':' + (data['tcdata'][i]['min'] < 10 ? '0' : '') + data['tcdata'][i]['min']); + channel1.push(data['tcdata'][i]['ch1'] * 100 / 255); + channel2.push(data['tcdata'][i]['ch2'] * 100 / 255); + channel3.push(data['tcdata'][i]['ch3'] * 100 / 255); + channel4.push(data['tcdata'][i]['ch4'] * 100 / 255); + } + currenttime.push(data['currenttime']['hour']); + currenttime.push(data['currenttime']['min']); + //console.log(currenttime); + var currentTimeStr = currenttime[0] + ':' + (currenttime[1] < 10 ? '0' : '') + currenttime[1]; + var index = time.indexOf(currentTimeStr); + if (index === -1) { + var lowerIndex = -1; + var upperIndex = -1; + for (var i = 0; i < time.length - 1; i++) { + //console.log(time[i] + ' <= ' + currentTimeStr + ' >= ' + time[i + 1]); + const currentDate = new Date(); + const year = currentDate.getFullYear(); + const month = (currentDate.getMonth() + 1).toString().padStart(2, '0'); + const day = currentDate.getDate().toString().padStart(2, '0'); + const dateString = `${year}-${month}-${day}`; + const start = moment(dateString + ' ' + time[i], 'YYYY-MM-DD HH:mm'); + const curr = moment(dateString + ' ' + currentTimeStr, 'YYYY-MM-DD HH:mm'); + const end = moment(dateString + ' ' + time[i + 1], 'YYYY-MM-DD HH:mm'); + //console.log(start.format('YYYY-MM-DD HH:mm') + ' <= ' + curr.format('YYYY-MM-DD HH:mm') + ' >= ' + end.format('YYYY-MM-DD HH:mm')); + //console.log(curr.isBetween(start, end)); + if (curr.isBetween(start, end)) { + lowerIndex = i; + upperIndex = i + 1; + break; + } + } + //console.log('lowerIndex=' + lowerIndex); + //console.log('upperIndex=' + upperIndex); + if (lowerIndex === -1 || upperIndex === -1) { + console.log("Error: Current time not found in time array and not between two elements in time array. Fixing it..."); + lowerIndex = 0; + upperIndex = 1; + var tmp1 = time[0].split(':'); + //console.log('tmp1 = ' + tmp1); + currenttime[0] = tmp1[0]; + currenttime[1] = tmp1[1]; + } + var lowerTime = time[lowerIndex].split(":"); + var upperTime = time[upperIndex].split(":"); + var timeDiff = (currenttime[0] - lowerTime[0]) + ((currenttime[1] - lowerTime[1]) / 60); + var indexFloat = lowerIndex + timeDiff / ((upperTime[0] - lowerTime[0]) + ((upperTime[1] - lowerTime[1]) / 60)); + //console.log("Index (float): " + indexFloat); + } else { + //console.log("Index (integer): " + index); + //console.log("Index (float): " + index); + } + if (indexFloat > index) { + index = indexFloat; + } + //console.log("index in graph >>>" + index); + var trace1 = { + x: time, + y: channel1, + name: 'Channel 1', + type: 'scatter', + mode: 'lines+markers', + }; + var trace2 = { + x: time, + y: channel2, + name: 'Channel 2', + type: 'scatter', + mode: 'lines+markers', + }; + var trace3 = { + x: time, + y: channel3, + name: 'Channel 3', + type: 'scatter', + mode: 'lines+markers', + }; + var trace4 = { + x: time, + y: channel4, + name: 'Channel 4', + type: 'scatter', + mode: 'lines+markers', + }; + var layout = { + title: 'Timing Control Data Blocks', + xaxis: { + title: 'Time', + tickangle: -45, + }, + yaxis: { + title: 'Brightness', + range: [0, 100], + }, + shapes: [{ + type: 'line', + x0: index, + y0: 0, + x1: index, + y1: 255, + line: { + color: 'lightgrey', + width: 3, + dash: 'dot' + } + }] + }; + Plotly.newPlot('tc_plot_chart', [trace1, trace2, trace3, trace4], layout); + +} + +setInterval(function() { + if (document.getElementById('tab-tde').classList.contains('visible')) { + loadTCGraphData(); + } +}, 2000); + function updateLightState() { console.log('----> setting bri and power switch <----'); for (let i = 1; i <= {{LIGHT_COUNT}}; i++) { @@ -285,32 +414,32 @@ function createTable() { var tr = document.createElement("tr"); // Stunde - var tdHour = createSelectCell(23, 0); + var tdHour = createSelectCell(23, 0, 1); tdHour.id = "hour" + i; tr.appendChild(tdHour); // Minute - var tdMinute = createSelectCell(59, 0); + var tdMinute = createSelectCell(59, 0, 1); tdMinute.id = "minute" + i; tr.appendChild(tdMinute); // ch1 - var tdCh1 = createSelectCell(100, 0); + var tdCh1 = createSelectCell(100, 0, 1); tdCh1.id = "ch1_" + i; tr.appendChild(tdCh1); // ch2 - var tdCh2 = createSelectCell(100, 0); + var tdCh2 = createSelectCell(100, 0, 1); tdCh2.id = "ch2_" + i; tr.appendChild(tdCh2); // ch3 - var tdCh3 = createSelectCell(100, 0); + var tdCh3 = createSelectCell(100, 0, 1); tdCh3.id = "ch3_" + i; tr.appendChild(tdCh3); // ch4 - var tdCh4 = createSelectCell(100, 0); + var tdCh4 = createSelectCell(100, 0, 1); tdCh4.id = "ch4_" + i; tr.appendChild(tdCh4); @@ -323,12 +452,12 @@ function createTable() { container.appendChild(table); } -function createSelectCell(max, value) { +function createSelectCell(max, value, step) { // Erstelle ein neues select-Element var select = document.createElement("select"); // Füge Optionen hinzu - for (var i = 0; i <= max; i++) { + for (var i = 0; i <= max; i += step) { var option = document.createElement("option"); option.value = i; option.text = i; @@ -362,6 +491,8 @@ function fillTableFromJson() { row.cells[4].childNodes[0].value = parseInt(tcdata[i].ch3 * 100 / 255); row.cells[5].childNodes[0].value = parseInt(tcdata[i].ch4 * 100 / 255); } + + loadTCGraphData(); }); } @@ -382,7 +513,7 @@ function createJsonFromTable() { } var currentTime = {hour: new Date().getHours(), min: new Date().getMinutes()}; var jsonData = {tcdata: tcdata, currenttime: currentTime}; - console.log("jsonData = " + JSON.stringify(jsonData)); + //console.log("jsonData = " + JSON.stringify(jsonData)); return JSON.stringify(jsonData); } @@ -390,14 +521,34 @@ function sendDataToServer() { var jsonData = createJsonFromTable(); var urlEncodedData = encodeURIComponent(jsonData); var url = 'http://{{IP_ADDRESS}}/tc_data_blocks_store?data=' + urlEncodedData; - console.log("url so save = " + url); var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); - xhr.onreadystatechange = function() { - if (xhr.readyState === 4 && xhr.status === 200) { - console.log('Data successfully sent to server!'); - } + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + var button = document.getElementById("save-button"); + if (xhr.status === 200) { + button.classList.remove("pure-button-primary"); + button.classList.add("success"); + button.innerHTML = "Saved!"; + setTimeout(function () { + button.classList.remove("success"); + button.classList.add("pure-button-primary"); + button.innerHTML = "save"; + }, 2000); + console.log('Data successfully sent to server!'); + } else { + button.classList.remove("pure-button-primary"); + button.classList.add("error"); + button.innerHTML = "Error!"; + setTimeout(function () { + button.classList.remove("error"); + button.classList.add("pure-button-primary"); + button.innerHTML = "save"; + }, 2000); + console.log('Error while sending data to server.'); + } + } }; xhr.send(); - } - + loadTCGraphData(); // update the tc data graph +} diff --git a/firmware/html/index_template_bottom.html b/firmware/html/index_template_bottom.html index a72b1b7..3a14eee 100644 --- a/firmware/html/index_template_bottom.html +++ b/firmware/html/index_template_bottom.html @@ -6,10 +6,21 @@ Timming control data editor
-
-
+ + + + + +
+
+
+
+
+
+
+
- save + save