From 1cf68b892267c4e42ce90d872825c5b3d7912797 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Thu, 4 May 2023 12:55:18 +0200 Subject: [PATCH 01/19] Scripts to generate the html output files optimized. --- tools/html2string.sh | 2 +- tools/html_gen_files.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/html2string.sh b/tools/html2string.sh index 73c4797..81b1f4e 100755 --- a/tools/html2string.sh +++ b/tools/html2string.sh @@ -1,4 +1,4 @@ #!/bin/bash -cat $1 | sed -e"s/^ *//ig" | sed -e "s/^\/\/.*//ig" +cat $1 | sed -e"s/^ *//ig" | sed -e "s/^\/\/.*//ig" | sed -e "s/ \/\/ .*//ig" | sed -E '/^\s*$/d' | sed '/^[[:space:]]*$/d' diff --git a/tools/html_gen_files.sh b/tools/html_gen_files.sh index 8665590..b43ffb4 100755 --- a/tools/html_gen_files.sh +++ b/tools/html_gen_files.sh @@ -5,3 +5,4 @@ bash ../../tools/html2string.sh ../html/index_template_middle.html > index_templ bash ../../tools/html2string.sh ../html/index_template_bottom.html > index_template_bottom.html bash ../../tools/html2string.sh ../html/config_template.html > config_template.html bash ../../tools/html2string.sh ../html/light_control_template.html > light_control_template.html +bash ../../tools/html2string.sh ../html/tc_data_edit.html > tc_data_edit.html From 096849b6efbbde4658b9174e495272ef5e570149 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Thu, 4 May 2023 18:24:41 +0200 Subject: [PATCH 02/19] Added third tab which should represend the timing control data blocks editor. --- .gitattributes | 1 + firmware/data/config_template.html | 140 +++--- firmware/data/index_template_bottom.html | 505 ++++++++++---------- firmware/data/index_template_middle.html | 20 +- firmware/data/index_template_top.html | 214 +++++---- firmware/data/light_control_template.html | 58 +-- firmware/data/tc_data_edit.html | 184 ++++++++ firmware/firmware.ino | 30 +- firmware/html/index_template_bottom.html | 540 ++++++++++++---------- firmware/html/index_template_middle.html | 20 +- firmware/html/tc_data_edit.html | 227 +++++++++ firmware/timing_control.ino | 62 ++- tools/html2string.sh | 10 +- 13 files changed, 1262 insertions(+), 749 deletions(-) create mode 100644 .gitattributes create mode 100644 firmware/data/tc_data_edit.html create mode 100644 firmware/html/tc_data_edit.html diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fa1385d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* -text diff --git a/firmware/data/config_template.html b/firmware/data/config_template.html index da7ca3b..820b72a 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 32db70c..7bec1c0 100644 --- a/firmware/data/index_template_bottom.html +++ b/firmware/data/index_template_bottom.html @@ -1,254 +1,251 @@ - - - - - - - + +
+
+
+ + + + + diff --git a/firmware/data/index_template_middle.html b/firmware/data/index_template_middle.html index 90d1ffc..6155028 100644 --- a/firmware/data/index_template_middle.html +++ b/firmware/data/index_template_middle.html @@ -1,12 +1,8 @@ - - - -
- - - - - -
-Not implemented yet. -
+ + + +
+ + + + diff --git a/firmware/data/index_template_top.html b/firmware/data/index_template_top.html index c306e26..fc985f7 100644 --- a/firmware/data/index_template_top.html +++ b/firmware/data/index_template_top.html @@ -1,108 +1,106 @@ - - - - - -Light setup - {{LIGHT_NAME}} - - - - - - - - -
-

{{LIGHT_NAME}}

-
- -
-
-Lights control -Config -Timing data edit -
-
-
-
-
- -ON -OFF -
- - -
-
- -
- - - + + +
- + + + + + +Light setup - {{LIGHT_NAME}} + + + + + + + + +
+

{{LIGHT_NAME}}

+
+ +
+ +
+
+
+
+ +ON +OFF +
+ + +
+
+ +
+ + + - - -
diff --git a/firmware/data/light_control_template.html b/firmware/data/light_control_template.html index 8bc313f..88e7f86 100644 --- a/firmware/data/light_control_template.html +++ b/firmware/data/light_control_template.html @@ -1,29 +1,29 @@ -

Light {{LIGHT_NUMBER}}

-
- -ON -OFF -
-
- - -  -9 -% -
- - -  - -% - -
+

Light {{LIGHT_NUMBER}}

+
+ +ON +OFF +
+
+ + +  +9 +% +
+ + +  + +% + +
diff --git a/firmware/data/tc_data_edit.html b/firmware/data/tc_data_edit.html new file mode 100644 index 0000000..e358441 --- /dev/null +++ b/firmware/data/tc_data_edit.html @@ -0,0 +1,184 @@ +
+
+Daten senden + \ No newline at end of file diff --git a/firmware/firmware.ino b/firmware/firmware.ino index 8b5e176..538203b 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -472,13 +472,28 @@ void init_webserver() server.send(200, "text/plain", output); }); - server.on("/tc_data_blocks", []() + server.on("/tc_data_blocks_read", []() { String output = tc_getJsonData(); server.send(200, "application/json", output); }); + server.on("/tc_data_blocks_store", []() + { + if (server.hasArg("data")) + { + String jsonData = server.arg("data"); + tc_jsonDataBlocksToEEPROM(jsonData); + server.send(200, "text/html", "tcdata saved"); + } + }); + + server.on("/tc_data_edit", []() + { + server.send(200, "text/html", genTCEditHTML()); + }); + server.on("/", []() { @@ -703,6 +718,11 @@ String genConfigHTML() return replacePlaceholder(getConfigHTML()); } +String genTCEditHTML() +{ + return replacePlaceholder(getTCDataEditHTML()); +} + String genLightControlHTML() { String http_content = ""; @@ -868,6 +888,14 @@ String getConfigHTML() //********************************// +String getTCDataEditHTML() +{ + // load file + return loadSPIFFSFile("/tc_data_edit.html"); +} + +//********************************// + String getLightControlHTML() { // load file diff --git a/firmware/html/index_template_bottom.html b/firmware/html/index_template_bottom.html index e2c534a..8ab0126 100644 --- a/firmware/html/index_template_bottom.html +++ b/firmware/html/index_template_bottom.html @@ -1,254 +1,286 @@ - - - - - - - + +
+
+
+ + + + + + + diff --git a/firmware/html/index_template_middle.html b/firmware/html/index_template_middle.html index 247d0ae..2b948ab 100644 --- a/firmware/html/index_template_middle.html +++ b/firmware/html/index_template_middle.html @@ -1,12 +1,8 @@ - -
-
-
-
- -
- Not implemented yet. -
+ +
+
+
+
diff --git a/firmware/html/tc_data_edit.html b/firmware/html/tc_data_edit.html new file mode 100644 index 0000000..52139ad --- /dev/null +++ b/firmware/html/tc_data_edit.html @@ -0,0 +1,227 @@ +
+
+Daten senden + + \ No newline at end of file diff --git a/firmware/timing_control.ino b/firmware/timing_control.ino index 304e9e5..c465e0f 100644 --- a/firmware/timing_control.ino +++ b/firmware/timing_control.ino @@ -371,7 +371,7 @@ bool tc_check_no_data_block() uint8_t e = EEPROM.read(EEPROM_TIMING_DATA_ADDRESS); //Serial.println(e); - if (e == 255) + if (e > 23) // the maximum value for tis memory section is 23 { return true; } @@ -416,12 +416,60 @@ void tc_jsonDataBlocksToEEPROM(String json_data_string) for (uint8_t i = 0; i < NUMBER_OF_TIMER_DATA_BLOCKS; i++) { JsonObject obj = doc[i]; - tc_data[i].hh = obj["hour"]; - tc_data[i].mm = obj["min"]; - tc_data[i].ch1 = obj["ch1"]; - tc_data[i].ch2 = obj["ch2"]; - tc_data[i].ch3 = obj["ch3"]; - tc_data[i].ch4 = obj["ch4"]; + + // Check and set the limits of the hour value + int hour = obj["hour"]; + if (hour < 0) { + hour = 0; + } else if (hour > 23) { + hour = 23; + } + tc_data[i].hh = hour; + + // Check and set the limits of the minute value + int minute = obj["min"]; + if (minute < 0) { + minute = 0; + } else if (minute > 59) { + minute = 59; + } + tc_data[i].mm = minute; + + // Check and set the limits of the ch1 value + int ch1 = obj["ch1"]; + if (ch1 < 0) { + ch1 = 0; + } else if (ch1 > 255) { + ch1 = 255; + } + tc_data[i].ch1 = ch1; + + // Check and set the limits of the ch2 value + int ch2 = obj["ch2"]; + if (ch2 < 0) { + ch2 = 0; + } else if (ch2 > 255) { + ch2 = 255; + } + tc_data[i].ch2 = ch2; + + // Check and set the limits of the ch3 value + int ch3 = obj["ch3"]; + if (ch3 < 0) { + ch3 = 0; + } else if (ch3 > 255) { + ch3 = 255; + } + tc_data[i].ch3 = ch3; + + // Check and set the limits of the ch4 value + int ch4 = obj["ch4"]; + if (ch4 < 0) { + ch4 = 0; + } else if (ch4 > 255) { + ch4 = 255; + } + tc_data[i].ch4 = ch4; } // Write the tc_data array to the EEPROM diff --git a/tools/html2string.sh b/tools/html2string.sh index 81b1f4e..5f4c178 100755 --- a/tools/html2string.sh +++ b/tools/html2string.sh @@ -1,4 +1,10 @@ #!/bin/bash -cat $1 | sed -e"s/^ *//ig" | sed -e "s/^\/\/.*//ig" | sed -e "s/ \/\/ .*//ig" | sed -E '/^\s*$/d' | sed '/^[[:space:]]*$/d' - +# Remove leading whitespace and comments starting with // +sed -e 's/^[[:space:]]*//' -e '/^\/\/.*/d' $1 | +# Remove one line comments starting with // +sed -e 's/^\/\/.*$//' | +# Remove trailing comments starting with // +sed -e 's/ \/\/.*$//' | +# Remove empty lines +sed '/^\s*$/d' From 94a347d3d0c96ce09bc4f15520096c3440245908 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 08:21:09 +0200 Subject: [PATCH 03/19] Extracted the javascript code to separate files. Added a initial table for configuring the tc data blocks. Extracted the css styles into a separate file. --- firmware/data/bottom.js | 299 ++++++++++++++++++++ firmware/data/index_template_bottom.html | 251 +---------------- firmware/data/index_template_top.html | 43 +-- firmware/data/style.css | 52 ++++ firmware/data/tc_data_edit.html | 184 ------------ firmware/data/top.js | 41 +++ firmware/firmware.ino | 14 +- firmware/html/bottom.js | 344 +++++++++++++++++++++++ firmware/html/index_template_bottom.html | 284 +------------------ firmware/html/index_template_top.html | 159 ++++------- firmware/html/style.css | 52 ++++ firmware/html/tc_data_edit.html | 227 --------------- firmware/html/top.js | 42 +++ firmware/timing_control.ino | 6 + tools/html_gen_files.sh | 4 +- 15 files changed, 919 insertions(+), 1083 deletions(-) create mode 100644 firmware/data/bottom.js create mode 100644 firmware/data/style.css delete mode 100644 firmware/data/tc_data_edit.html create mode 100644 firmware/data/top.js create mode 100644 firmware/html/bottom.js create mode 100644 firmware/html/style.css delete mode 100644 firmware/html/tc_data_edit.html create mode 100644 firmware/html/top.js diff --git a/firmware/data/bottom.js b/firmware/data/bottom.js new file mode 100644 index 0000000..e997670 --- /dev/null +++ b/firmware/data/bottom.js @@ -0,0 +1,299 @@ +function addTabListener() { +try { +var tabMain = document.getElementById("tab-lights"); +var tabConfig = document.getElementById("tab-config"); +var tabTDE = document.getElementById("tab-tde"); +var amain = document.getElementById("tab-a-lights"); +var acfg = document.getElementById("tab-a-config"); +var atde = document.getElementById("tab-a-tde"); +amain.addEventListener("click", function() { +tabMain.classList.add("visible"); +tabConfig.classList.remove("visible"); +tabTDE.classList.remove("visible"); +amain.classList.add("pure-button-primary"); +acfg.classList.remove("pure-button-primary"); +atde.classList.remove("pure-button-primary"); +}); +acfg.addEventListener("click", function() { +tabMain.classList.remove("visible"); +tabConfig.classList.add("visible"); +tabTDE.classList.remove("visible"); +amain.classList.remove("pure-button-primary"); +acfg.classList.add("pure-button-primary"); +atde.classList.remove("pure-button-primary"); +}); +atde.addEventListener("click", function() { +tabMain.classList.remove("visible"); +tabConfig.classList.remove("visible"); +tabTDE.classList.add("visible"); +amain.classList.remove("pure-button-primary"); +acfg.classList.remove("pure-button-primary"); +atde.classList.add("pure-button-primary"); +createTable(); +}); +} catch (error) { +console.log("Fehler in load listener of the tab action listener management: " + error.message); +} +} +window.addEventListener('load', function() { +addTabListener(); +}); +function loadGraphData() { +console.log('----> generate graph <----'); +$.getJSON('/tc_data_blocks_read', function(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']); +channel2.push(data['tcdata'][i]['ch2']); +channel3.push(data['tcdata'][i]['ch3']); +channel4.push(data['tcdata'][i]['ch4']); +} +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."); +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, 255], +}, +shapes: [{ +type: 'line', +x0: index, +y0: 0, +x1: index, +y1: 255, +line: { +color: 'lightgrey', +width: 3, +dash: 'dot' +} +}] +}; +Plotly.newPlot('plot_chart', [trace1, trace2, trace3, trace4], layout); +}); +} +setInterval(loadGraphData, 10000); +loadGraphData(); +function updateLightState() { +console.log('----> setting bri and power switch <----'); +for (let i = 1; i <= {{LIGHT_COUNT}}; i++) { +const lightURL = `http://{{IP_ADDRESS}}/state?light=${i}`; +fetch(lightURL).then(response => response.json()).then(data => { +const briSlider = document.getElementById(`bri${i - 1}`); +const briSliderVal = document.getElementById(`bri${i - 1}_val`); +const onLinkOn = document.getElementById(`on${i - 1}_on`); +const onLinkOff = document.getElementById(`on${i - 1}_off`); +briSlider.value = data.bri; +briSliderVal.innerHTML = (Math.round((data.bri * 100.0 / 255.0) * 100) / 100).toFixed(2); +console.log('data.on ' + i + ' = ' + data.on); +if (data.on == true) { +onLinkOn.classList.add('pure-button-primary'); +onLinkOff.classList.remove('pure-button-primary'); +} else { +onLinkOn.classList.remove('pure-button-primary'); +onLinkOff.classList.add('pure-button-primary'); +} +}).catch(error => console.error(error)); +} +} +setInterval(updateLightState, 10000); +updateLightState(); +function updatePWMValues() { +console.log('----> setting pwm data <----'); +for (let i = 0; i < {{LIGHT_COUNT}}; i++) { +const lightID = i + 1; +const pwmElement = document.getElementById(`light${i}_pwm`); +const pwmElementTxt = document.getElementById(`light${i}_pwm_txt`); +if (pwmElement) { +const url = `http://{{IP_ADDRESS}}/state?light=${lightID}`; +fetch(url).then(response => response.json()).then(data => { +const pwmValue = ((Math.round((data.curpwm - ((data.curpwm >= {{PWM_MIN}}) ? {{PWM_MIN}} : 0)) / {{PWM_MAX}} * 10000) / 100).toFixed(2)); +console.log('curpwm[' + i + '] = ' + data.curpwm + ' = ' + pwmValue); +pwmElement.innerText = pwmValue.toString(); +pwmElement.value = pwmValue; +pwmElementTxt.innerText = pwmValue.toString(); +}).catch(error => console.error(error)); +} +} +} +updatePWMValues(); +setInterval(updatePWMValues, 5000); +var links = document.querySelectorAll('[id^="on"][id$="_off"]'); +links.forEach(function(link) { +link.addEventListener('click', function(event) { +event.preventDefault(); +var id = this.id.replace('on', '').replace('_off', ''); +var xhr = new XMLHttpRequest(); +xhr.open('GET', 'http://{{IP_ADDRESS}}/?on' + id + '=false&transition=' + document.getElementById('transition').value, true); +xhr.send(); +updateLightState(); +this.classList.add('pure-button-primary'); +document.getElementById('on'+id+'_on').classList.remove('pure-button-primary'); +}); +}); +var links = document.querySelectorAll('[id^="on"][id$="_on"]'); +links.forEach(function(link) { +link.addEventListener('click', function(event) { +event.preventDefault(); +var id = this.id.replace('on', '').replace('_on', ''); +var xhr = new XMLHttpRequest(); +xhr.open('GET', 'http://{{IP_ADDRESS}}/?on' + id + '=true&transition=' + document.getElementById('transition').value, true); +xhr.send(); +updateLightState(); +this.classList.add('pure-button-primary'); +document.getElementById('on'+id+'_off').classList.remove('pure-button-primary'); +}); +}); +function createTable() { +var table = document.createElement("table"); +var headerRow = document.createElement("tr"); +var headers = ["Stunde", "Minute", "ch1", "ch2", "ch3", "ch4"]; +for (var i = 0; i < headers.length; i++) { +var header = document.createElement("th"); +header.innerHTML = headers[i]; +headerRow.appendChild(header); +} +table.appendChild(headerRow); +for (var row = 0; row < 10; row++) { +var contentRow = document.createElement("tr"); +var hourCell = document.createElement("td"); +var hourInput = document.createElement("input"); +hourInput.type = "number"; +hourInput.min = 0; +hourInput.max = 23; +hourCell.appendChild(hourInput); +contentRow.appendChild(hourCell); +var minuteCell = document.createElement("td"); +var minuteSelect = document.createElement("select"); +for (var minute = 0; minute <= 50; minute += 10) { +var option = document.createElement("option"); +option.value = minute; +option.text = minute.toString().padStart(2, "0"); +minuteSelect.appendChild(option); +} +minuteCell.appendChild(minuteSelect); +contentRow.appendChild(minuteCell); +for (var channel = 1; channel <= 4; channel++) { +var channelCell = document.createElement("td"); +var channelInput = document.createElement("input"); +channelInput.type = "number"; +channelInput.min = 0; +channelInput.max = 100; +channelCell.appendChild(channelInput); +contentRow.appendChild(channelCell); +} +table.appendChild(contentRow); +} +var button = document.createElement("button"); +button.innerHTML = "Export als JSON"; +button.onclick = function() { +var data = []; +var rows = table.getElementsByTagName("tr"); +for (var row = 1; row < rows.length; row++) { +var cells = rows[row].getElementsByTagName("td"); +var hour = cells[0].querySelector("input").value; +var minute = cells[1].querySelector("select").value; +var ch1 = cells[2].querySelector("input").value; +var ch2 = cells[3].querySelector("input").value; +var ch3 = cells[4].querySelector("input").value; +var ch4 = cells[5].querySelector("input").value; +var rowObject = {"hour": hour, "min": minute, "ch1": ch1, "ch2": ch2, "ch3": ch3, "ch4": ch4}; +data.push(rowObject); +} +var json = JSON.stringify(data); +console.log(json); +var xhr = new XMLHttpRequest(); +xhr.open("POST", "http://{{IP_ADDRESS}}/tc_data_save?data=" + encodeURIComponent(json), true); +xhr.send(); +}; +var container = document.getElementById("table-container"); +container.innerHTML = ""; +container.appendChild(table); +container.appendChild(button); +} \ No newline at end of file diff --git a/firmware/data/index_template_bottom.html b/firmware/data/index_template_bottom.html index 7bec1c0..990ac03 100644 --- a/firmware/data/index_template_bottom.html +++ b/firmware/data/index_template_bottom.html @@ -1,249 +1,14 @@
-
+
+
+ +
+
-
diff --git a/firmware/data/index_template_top.html b/firmware/data/index_template_top.html index fc985f7..d0cadaf 100644 --- a/firmware/data/index_template_top.html +++ b/firmware/data/index_template_top.html @@ -57,48 +57,7 @@ display: block;
-
diff --git a/firmware/data/style.css b/firmware/data/style.css new file mode 100644 index 0000000..244096a --- /dev/null +++ b/firmware/data/style.css @@ -0,0 +1,52 @@ + #tab-lights, #tab-config, #tab-tde { + display: none; + background-color: #ffffff; + color: black; + font-weight: bold; + } + #tab-lights.visible { + display: block; + } + #tab-config.visible { + display: block; + } + #tab-tde.visible { + display: block; + } + /* CSS-Regeln für die Tabellenzellen */ + .pure-table td { + padding: 4px; + } + + /* CSS-Regeln für die Eingabefelder */ + .pure-form input[type="number"] { + width: 60px; + height: 20px; + border-radius: 3px; + border: 1px solid #ccc; + } + + /* CSS-Regeln für die Auswahllisten */ + .pure-form select { + width: 80px; + height: 26px; + border-radius: 3px; + border: 1px solid #ccc; + background-color: #fff; + } + + /* CSS-Regeln für den Export-Button */ + .pure-button { + background-color: #5a5a5a; + color: #fff; + border-radius: 3px; + border: none; + padding: 8px 12px; + font-size: 14px; + cursor: pointer; + } + + .pure-button:hover { + background-color: #333; + } + diff --git a/firmware/data/tc_data_edit.html b/firmware/data/tc_data_edit.html deleted file mode 100644 index e358441..0000000 --- a/firmware/data/tc_data_edit.html +++ /dev/null @@ -1,184 +0,0 @@ -
-
-Daten senden - \ No newline at end of file diff --git a/firmware/data/top.js b/firmware/data/top.js new file mode 100644 index 0000000..42eebbd --- /dev/null +++ b/firmware/data/top.js @@ -0,0 +1,41 @@ +var links = document.querySelectorAll('[id^="tc_on"]'); +links.forEach(function(link) { +link.addEventListener('click', function(event) { +event.preventDefault(); +var xhr = new XMLHttpRequest(); +xhr.open('GET', 'http://{{IP_ADDRESS}}/?tc=true', true); +xhr.send(); +console.log('tc=true call'); +document.getElementById('tc_on').classList.add('pure-button-primary'); +document.getElementById('tc_off').classList.remove('pure-button-primary'); +}); +}); +var links = document.querySelectorAll('[id^="tc_off"]'); +links.forEach(function(link) { +link.addEventListener('click', function(event) { +event.preventDefault(); +var xhr = new XMLHttpRequest(); +xhr.open('GET', 'http://{{IP_ADDRESS}}/?tc=false', true); +xhr.send(); +console.log('tc=false call'); +document.getElementById('tc_off').classList.add('pure-button-primary'); +document.getElementById('tc_on').classList.remove('pure-button-primary'); +}); +}); +let timeoutId; +function sendSliderValue(x) { +x = x - 1; +clearTimeout(timeoutId); +timeoutId = setTimeout(() => { +var value = document.getElementById(`bri${x}`).value; +var url = `http://{{IP_ADDRESS}}/?bri${x}=${value}`; +fetch(url).then(response => { +if (!response.ok) { +throw new Error(`HTTP error! status: ${response.status}`); +} +console.log(`Sent slider value ${value} to ${url}`); +}).catch(error => { +console.error(`Error sending slider value to ${url}: ${error}`); +}); +}, 500); +} \ No newline at end of file diff --git a/firmware/firmware.ino b/firmware/firmware.ino index 538203b..4b483da 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -489,9 +489,19 @@ void init_webserver() } }); - server.on("/tc_data_edit", []() + server.on("/js_top", []() { - server.send(200, "text/html", genTCEditHTML()); + server.send(200, "text/html", replacePlaceholder(loadSPIFFSFile("/top.js"))); + }); + + server.on("/js_bottom", []() + { + server.send(200, "text/html", replacePlaceholder(loadSPIFFSFile("/bottom.js"))); + }); + + server.on("/css", []() + { + server.send(200, "text/html", loadSPIFFSFile("/style.css")); }); server.on("/", []() diff --git a/firmware/html/bottom.js b/firmware/html/bottom.js new file mode 100644 index 0000000..a01ff19 --- /dev/null +++ b/firmware/html/bottom.js @@ -0,0 +1,344 @@ +function addTabListener() { + try { + var tabMain = document.getElementById("tab-lights"); + var tabConfig = document.getElementById("tab-config"); + var tabTDE = document.getElementById("tab-tde"); + + var amain = document.getElementById("tab-a-lights"); + var acfg = document.getElementById("tab-a-config"); + var atde = document.getElementById("tab-a-tde"); + + + amain.addEventListener("click", function() { + tabMain.classList.add("visible"); + tabConfig.classList.remove("visible"); + tabTDE.classList.remove("visible"); + + amain.classList.add("pure-button-primary"); + acfg.classList.remove("pure-button-primary"); + atde.classList.remove("pure-button-primary"); + }); + + acfg.addEventListener("click", function() { + tabMain.classList.remove("visible"); + tabConfig.classList.add("visible"); + tabTDE.classList.remove("visible"); + + amain.classList.remove("pure-button-primary"); + acfg.classList.add("pure-button-primary"); + atde.classList.remove("pure-button-primary"); + }); + + atde.addEventListener("click", function() { + tabMain.classList.remove("visible"); + tabConfig.classList.remove("visible"); + tabTDE.classList.add("visible"); + + amain.classList.remove("pure-button-primary"); + acfg.classList.remove("pure-button-primary"); + atde.classList.add("pure-button-primary"); + + createTable(); + }); + } catch (error) { + console.log("Fehler in load listener of the tab action listener management: " + error.message); + } +} +window.addEventListener('load', function() { + addTabListener(); +}); + +function loadGraphData() { + console.log('----> generate graph <----'); + $.getJSON('/tc_data_blocks_read', function(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']); + channel2.push(data['tcdata'][i]['ch2']); + channel3.push(data['tcdata'][i]['ch3']); + channel4.push(data['tcdata'][i]['ch4']); + } + 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."); + 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, 255], + }, + shapes: [{ + type: 'line', + x0: index, + y0: 0, + x1: index, + y1: 255, + line: { + color: 'lightgrey', + width: 3, + dash: 'dot' + } + }] + }; + Plotly.newPlot('plot_chart', [trace1, trace2, trace3, trace4], layout); + }); +} +setInterval(loadGraphData, 10000); +loadGraphData(); + +function updateLightState() { + console.log('----> setting bri and power switch <----'); + for (let i = 1; i <= {{LIGHT_COUNT}}; i++) { + const lightURL = `http://{{IP_ADDRESS}}/state?light=${i}`; + fetch(lightURL).then(response => response.json()).then(data => { + const briSlider = document.getElementById(`bri${i - 1}`); + const briSliderVal = document.getElementById(`bri${i - 1}_val`); + const onLinkOn = document.getElementById(`on${i - 1}_on`); + const onLinkOff = document.getElementById(`on${i - 1}_off`); + briSlider.value = data.bri; + briSliderVal.innerHTML = (Math.round((data.bri * 100.0 / 255.0) * 100) / 100).toFixed(2); + console.log('data.on ' + i + ' = ' + data.on); + if (data.on == true) { + onLinkOn.classList.add('pure-button-primary'); + onLinkOff.classList.remove('pure-button-primary'); + } else { + onLinkOn.classList.remove('pure-button-primary'); + onLinkOff.classList.add('pure-button-primary'); + } + }).catch(error => console.error(error)); + } +} +setInterval(updateLightState, 10000); +updateLightState(); + +function updatePWMValues() { + console.log('----> setting pwm data <----'); + for (let i = 0; i < {{LIGHT_COUNT}}; i++) { + const lightID = i + 1; + const pwmElement = document.getElementById(`light${i}_pwm`); + const pwmElementTxt = document.getElementById(`light${i}_pwm_txt`); + if (pwmElement) { + const url = `http://{{IP_ADDRESS}}/state?light=${lightID}`; + fetch(url).then(response => response.json()).then(data => { + const pwmValue = ((Math.round((data.curpwm - ((data.curpwm >= {{PWM_MIN}}) ? {{PWM_MIN}} : 0)) / {{PWM_MAX}} * 10000) / 100).toFixed(2)); + console.log('curpwm[' + i + '] = ' + data.curpwm + ' = ' + pwmValue); + pwmElement.innerText = pwmValue.toString(); + pwmElement.value = pwmValue; + pwmElementTxt.innerText = pwmValue.toString(); + }).catch(error => console.error(error)); + } + } +} +updatePWMValues(); +setInterval(updatePWMValues, 5000); + +// Suche nach allen Links auf der Seite mit IDs von on0_off bis on3_off +var links = document.querySelectorAll('[id^="on"][id$="_off"]'); +// Füge einen Klick-Listener zu jedem Link hinzu +links.forEach(function(link) { + link.addEventListener('click', function(event) { + // Verhindere, dass der Link die Seite neu lädt + event.preventDefault(); + // Extrahiere die Zahl aus der ID des Links + var id = this.id.replace('on', '').replace('_off', ''); + // Erstelle eine neue Anfrage an die entsprechende URL + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'http://{{IP_ADDRESS}}/?on' + id + '=false&transition=' + document.getElementById('transition').value, true); + // Sende die Anfrage im Hintergrund + xhr.send(); + updateLightState(); + this.classList.add('pure-button-primary'); + document.getElementById('on'+id+'_on').classList.remove('pure-button-primary'); + }); +}); +// Suche nach allen Links auf der Seite mit IDs von on0_off bis on3_off +var links = document.querySelectorAll('[id^="on"][id$="_on"]'); +// Füge einen Klick-Listener zu jedem Link hinzu +links.forEach(function(link) { + link.addEventListener('click', function(event) { + // Verhindere, dass der Link die Seite neu lädt + event.preventDefault(); + // Extrahiere die Zahl aus der ID des Links + var id = this.id.replace('on', '').replace('_on', ''); + // Erstelle eine neue Anfrage an die entsprechende URL + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'http://{{IP_ADDRESS}}/?on' + id + '=true&transition=' + document.getElementById('transition').value, true); + // Sende die Anfrage im Hintergrund + xhr.send(); + updateLightState(); + this.classList.add('pure-button-primary'); + document.getElementById('on'+id+'_off').classList.remove('pure-button-primary'); + }); +}); + +function createTable() { +var table = document.createElement("table"); + +// Headerzeile +var headerRow = document.createElement("tr"); +var headers = ["Stunde", "Minute", "ch1", "ch2", "ch3", "ch4"]; +for (var i = 0; i < headers.length; i++) { + var header = document.createElement("th"); + header.innerHTML = headers[i]; + headerRow.appendChild(header); +} +table.appendChild(headerRow); + +// Inhaltszeilen +for (var row = 0; row < 10; row++) { + var contentRow = document.createElement("tr"); + + // Spalte "Stunde" + var hourCell = document.createElement("td"); + var hourInput = document.createElement("input"); + hourInput.type = "number"; + hourInput.min = 0; + hourInput.max = 23; + hourCell.appendChild(hourInput); + contentRow.appendChild(hourCell); + + // Spalte "Minute" + var minuteCell = document.createElement("td"); + var minuteSelect = document.createElement("select"); + for (var minute = 0; minute <= 50; minute += 10) { + var option = document.createElement("option"); + option.value = minute; + option.text = minute.toString().padStart(2, "0"); + minuteSelect.appendChild(option); + } + minuteCell.appendChild(minuteSelect); + contentRow.appendChild(minuteCell); + + // Spalten "ch1" bis "ch4" + for (var channel = 1; channel <= 4; channel++) { + var channelCell = document.createElement("td"); + var channelInput = document.createElement("input"); + channelInput.type = "number"; + channelInput.min = 0; + channelInput.max = 100; + channelCell.appendChild(channelInput); + contentRow.appendChild(channelCell); + } + + table.appendChild(contentRow); +} + +// Button +var button = document.createElement("button"); +button.innerHTML = "Export als JSON"; +button.onclick = function() { + var data = []; + + var rows = table.getElementsByTagName("tr"); + for (var row = 1; row < rows.length; row++) { + var cells = rows[row].getElementsByTagName("td"); + + var hour = cells[0].querySelector("input").value; + var minute = cells[1].querySelector("select").value; + var ch1 = cells[2].querySelector("input").value; + var ch2 = cells[3].querySelector("input").value; + var ch3 = cells[4].querySelector("input").value; + var ch4 = cells[5].querySelector("input").value; + + var rowObject = {"hour": hour, "min": minute, "ch1": ch1, "ch2": ch2, "ch3": ch3, "ch4": ch4}; + data.push(rowObject); + } + + var json = JSON.stringify(data); + console.log(json); + var xhr = new XMLHttpRequest(); + xhr.open("POST", "http://{{IP_ADDRESS}}/tc_data_save?data=" + encodeURIComponent(json), true); + xhr.send(); + +}; + +var container = document.getElementById("table-container"); +container.innerHTML = ""; +container.appendChild(table); +container.appendChild(button); +} \ No newline at end of file diff --git a/firmware/html/index_template_bottom.html b/firmware/html/index_template_bottom.html index 8ab0126..0d0142e 100644 --- a/firmware/html/index_template_bottom.html +++ b/firmware/html/index_template_bottom.html @@ -1,283 +1,15 @@
-
+
+
+ +
+
- diff --git a/firmware/html/index_template_top.html b/firmware/html/index_template_top.html index d70d8b7..6818214 100644 --- a/firmware/html/index_template_top.html +++ b/firmware/html/index_template_top.html @@ -1,108 +1,51 @@ - - - - - - Light setup - {{LIGHT_NAME}} - - - - - - - - -
-

{{LIGHT_NAME}}

-
- -
-
- Lights control - Config - Timing data edit -
-
-
-
-
- - ON - OFF -
- - -
-
- -
-
- -
- + + + + + + Light setup - {{LIGHT_NAME}} + + + + + + + + +
+

{{LIGHT_NAME}}

+
+ +
+ +
+
+
+
+ + ON + OFF +
+ + +
+
+ +
+ + +
+ diff --git a/firmware/html/style.css b/firmware/html/style.css new file mode 100644 index 0000000..244096a --- /dev/null +++ b/firmware/html/style.css @@ -0,0 +1,52 @@ + #tab-lights, #tab-config, #tab-tde { + display: none; + background-color: #ffffff; + color: black; + font-weight: bold; + } + #tab-lights.visible { + display: block; + } + #tab-config.visible { + display: block; + } + #tab-tde.visible { + display: block; + } + /* CSS-Regeln für die Tabellenzellen */ + .pure-table td { + padding: 4px; + } + + /* CSS-Regeln für die Eingabefelder */ + .pure-form input[type="number"] { + width: 60px; + height: 20px; + border-radius: 3px; + border: 1px solid #ccc; + } + + /* CSS-Regeln für die Auswahllisten */ + .pure-form select { + width: 80px; + height: 26px; + border-radius: 3px; + border: 1px solid #ccc; + background-color: #fff; + } + + /* CSS-Regeln für den Export-Button */ + .pure-button { + background-color: #5a5a5a; + color: #fff; + border-radius: 3px; + border: none; + padding: 8px 12px; + font-size: 14px; + cursor: pointer; + } + + .pure-button:hover { + background-color: #333; + } + diff --git a/firmware/html/tc_data_edit.html b/firmware/html/tc_data_edit.html deleted file mode 100644 index 52139ad..0000000 --- a/firmware/html/tc_data_edit.html +++ /dev/null @@ -1,227 +0,0 @@ -
-
-Daten senden - - \ No newline at end of file diff --git a/firmware/html/top.js b/firmware/html/top.js new file mode 100644 index 0000000..73dd43b --- /dev/null +++ b/firmware/html/top.js @@ -0,0 +1,42 @@ +var links = document.querySelectorAll('[id^="tc_on"]'); +links.forEach(function(link) { + link.addEventListener('click', function(event) { + event.preventDefault(); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'http://{{IP_ADDRESS}}/?tc=true', true); + xhr.send(); + //console.log('tc=true call'); + document.getElementById('tc_on').classList.add('pure-button-primary'); + document.getElementById('tc_off').classList.remove('pure-button-primary'); + }); +}); +var links = document.querySelectorAll('[id^="tc_off"]'); +links.forEach(function(link) { + link.addEventListener('click', function(event) { + event.preventDefault(); + var xhr = new XMLHttpRequest(); + xhr.open('GET', 'http://{{IP_ADDRESS}}/?tc=false', true); + xhr.send(); + //console.log('tc=false call'); + document.getElementById('tc_off').classList.add('pure-button-primary'); + document.getElementById('tc_on').classList.remove('pure-button-primary'); + }); +}); + +let timeoutId; +function sendSliderValue(x) { + x = x - 1; + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + var value = document.getElementById(`bri${x}`).value; + var url = `http://{{IP_ADDRESS}}/?bri${x}=${value}`; + fetch(url).then(response => { + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + //console.log(`Sent slider value ${value} to ${url}`); + }).catch(error => { + console.error(`Error sending slider value to ${url}: ${error}`); + }); + }, 500); +} \ No newline at end of file diff --git a/firmware/timing_control.ino b/firmware/timing_control.ino index c465e0f..b63721b 100644 --- a/firmware/timing_control.ino +++ b/firmware/timing_control.ino @@ -180,6 +180,12 @@ void tc_update_main() if (target_data_block >= NUMBER_OF_TIMER_DATA_BLOCKS) { + // we are not between two valid data points, do nothing + // TODO check if setting all lights to false is correct here + for (uint8_t i = 0; i < LIGHTS_COUNT; i++) + { + light_state[i] = false; + } target_data_block = 255; current_target_data_block = 255; return; diff --git a/tools/html_gen_files.sh b/tools/html_gen_files.sh index b43ffb4..61222d8 100755 --- a/tools/html_gen_files.sh +++ b/tools/html_gen_files.sh @@ -5,4 +5,6 @@ bash ../../tools/html2string.sh ../html/index_template_middle.html > index_templ bash ../../tools/html2string.sh ../html/index_template_bottom.html > index_template_bottom.html bash ../../tools/html2string.sh ../html/config_template.html > config_template.html bash ../../tools/html2string.sh ../html/light_control_template.html > light_control_template.html -bash ../../tools/html2string.sh ../html/tc_data_edit.html > tc_data_edit.html +bash ../../tools/html2string.sh ../html/top.js > top.js +bash ../../tools/html2string.sh ../html/bottom.js > bottom.js +cp -av ../html/style.css . From 2f7ce5019ba97a1ba7ff1f5e666775b6a8d88ddc Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 10:15:29 +0200 Subject: [PATCH 04/19] Disabled console logging. --- firmware/data/bottom.js | 22 +++++------------ firmware/data/index_template_top.html | 17 +------------ firmware/data/top.js | 3 --- firmware/html/bottom.js | 35 +++++++++++++++------------ 4 files changed, 26 insertions(+), 51 deletions(-) diff --git a/firmware/data/bottom.js b/firmware/data/bottom.js index e997670..fe6a7d6 100644 --- a/firmware/data/bottom.js +++ b/firmware/data/bottom.js @@ -32,7 +32,7 @@ atde.classList.add("pure-button-primary"); createTable(); }); } catch (error) { -console.log("Fehler in load listener of the tab action listener management: " + error.message); +console.log("Error: load listener of the tab action listener management: " + error.message); } } window.addEventListener('load', function() { @@ -56,14 +56,12 @@ channel4.push(data['tcdata'][i]['ch4']); } 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'); @@ -72,22 +70,17 @@ 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."); +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]; } @@ -95,15 +88,11 @@ 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, @@ -171,7 +160,6 @@ const onLinkOn = document.getElementById(`on${i - 1}_on`); const onLinkOff = document.getElementById(`on${i - 1}_off`); briSlider.value = data.bri; briSliderVal.innerHTML = (Math.round((data.bri * 100.0 / 255.0) * 100) / 100).toFixed(2); -console.log('data.on ' + i + ' = ' + data.on); if (data.on == true) { onLinkOn.classList.add('pure-button-primary'); onLinkOff.classList.remove('pure-button-primary'); @@ -194,7 +182,6 @@ if (pwmElement) { const url = `http://{{IP_ADDRESS}}/state?light=${lightID}`; fetch(url).then(response => response.json()).then(data => { const pwmValue = ((Math.round((data.curpwm - ((data.curpwm >= {{PWM_MIN}}) ? {{PWM_MIN}} : 0)) / {{PWM_MAX}} * 10000) / 100).toFixed(2)); -console.log('curpwm[' + i + '] = ' + data.curpwm + ' = ' + pwmValue); pwmElement.innerText = pwmValue.toString(); pwmElement.value = pwmValue; pwmElementTxt.innerText = pwmValue.toString(); @@ -271,7 +258,9 @@ contentRow.appendChild(channelCell); table.appendChild(contentRow); } var button = document.createElement("button"); -button.innerHTML = "Export als JSON"; +button.innerHTML = "Save"; +button.classList.add("pure-button"); +button.classList.add("pure-button-primary"); button.onclick = function() { var data = []; var rows = table.getElementsByTagName("tr"); @@ -294,6 +283,7 @@ xhr.send(); }; var container = document.getElementById("table-container"); container.innerHTML = ""; +container.classList.add("pure-form"); container.appendChild(table); container.appendChild(button); } \ No newline at end of file diff --git a/firmware/data/index_template_top.html b/firmware/data/index_template_top.html index d0cadaf..e12f53c 100644 --- a/firmware/data/index_template_top.html +++ b/firmware/data/index_template_top.html @@ -9,22 +9,7 @@ - diff --git a/firmware/data/top.js b/firmware/data/top.js index 42eebbd..373f487 100644 --- a/firmware/data/top.js +++ b/firmware/data/top.js @@ -5,7 +5,6 @@ event.preventDefault(); var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://{{IP_ADDRESS}}/?tc=true', true); xhr.send(); -console.log('tc=true call'); document.getElementById('tc_on').classList.add('pure-button-primary'); document.getElementById('tc_off').classList.remove('pure-button-primary'); }); @@ -17,7 +16,6 @@ event.preventDefault(); var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://{{IP_ADDRESS}}/?tc=false', true); xhr.send(); -console.log('tc=false call'); document.getElementById('tc_off').classList.add('pure-button-primary'); document.getElementById('tc_on').classList.remove('pure-button-primary'); }); @@ -33,7 +31,6 @@ fetch(url).then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } -console.log(`Sent slider value ${value} to ${url}`); }).catch(error => { console.error(`Error sending slider value to ${url}: ${error}`); }); diff --git a/firmware/html/bottom.js b/firmware/html/bottom.js index a01ff19..358831b 100644 --- a/firmware/html/bottom.js +++ b/firmware/html/bottom.js @@ -41,7 +41,7 @@ function addTabListener() { createTable(); }); } catch (error) { - console.log("Fehler in load listener of the tab action listener management: " + error.message); + console.log("Error: load listener of the tab action listener management: " + error.message); } } window.addEventListener('load', function() { @@ -66,14 +66,14 @@ function loadGraphData() { } currenttime.push(data['currenttime']['hour']); currenttime.push(data['currenttime']['min']); - console.log(currenttime); + //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]); + //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'); @@ -82,22 +82,22 @@ function loadGraphData() { 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)); + //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); + //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."); + 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); + //console.log('tmp1 = ' + tmp1); currenttime[0] = tmp1[0]; currenttime[1] = tmp1[1]; } @@ -105,15 +105,15 @@ function loadGraphData() { 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); + //console.log("Index (float): " + indexFloat); } else { - console.log("Index (integer): " + index); - console.log("Index (float): " + index); + //console.log("Index (integer): " + index); + //console.log("Index (float): " + index); } if (indexFloat > index) { index = indexFloat; } - console.log("index in graph >>>" + index); + //console.log("index in graph >>>" + index); var trace1 = { x: time, y: channel1, @@ -182,7 +182,7 @@ function updateLightState() { const onLinkOff = document.getElementById(`on${i - 1}_off`); briSlider.value = data.bri; briSliderVal.innerHTML = (Math.round((data.bri * 100.0 / 255.0) * 100) / 100).toFixed(2); - console.log('data.on ' + i + ' = ' + data.on); + //console.log('data.on ' + i + ' = ' + data.on); if (data.on == true) { onLinkOn.classList.add('pure-button-primary'); onLinkOff.classList.remove('pure-button-primary'); @@ -206,7 +206,7 @@ function updatePWMValues() { const url = `http://{{IP_ADDRESS}}/state?light=${lightID}`; fetch(url).then(response => response.json()).then(data => { const pwmValue = ((Math.round((data.curpwm - ((data.curpwm >= {{PWM_MIN}}) ? {{PWM_MIN}} : 0)) / {{PWM_MAX}} * 10000) / 100).toFixed(2)); - console.log('curpwm[' + i + '] = ' + data.curpwm + ' = ' + pwmValue); + //console.log('curpwm[' + i + '] = ' + data.curpwm + ' = ' + pwmValue); pwmElement.innerText = pwmValue.toString(); pwmElement.value = pwmValue; pwmElementTxt.innerText = pwmValue.toString(); @@ -310,7 +310,9 @@ for (var row = 0; row < 10; row++) { // Button var button = document.createElement("button"); -button.innerHTML = "Export als JSON"; +button.innerHTML = "Save"; +button.classList.add("pure-button"); +button.classList.add("pure-button-primary"); button.onclick = function() { var data = []; @@ -339,6 +341,7 @@ button.onclick = function() { var container = document.getElementById("table-container"); container.innerHTML = ""; +container.classList.add("pure-form"); container.appendChild(table); container.appendChild(button); } \ No newline at end of file From 99c0c4a6b5a45a3669a6e96c559f3d5e1edd6a31 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 10:15:56 +0200 Subject: [PATCH 05/19] Added git ignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 63123fb..8395b74 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_store +.vscode/c_cpp_properties.json From 84dd924a1df618c85f5053c286755509956b1acf Mon Sep 17 00:00:00 2001 From: klaute Date: Fri, 5 May 2023 22:59:42 +0200 Subject: [PATCH 06/19] Reader Info that ChatGPT is used added. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a861d0e..f43b7ae 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -This build is based on: https://github.com/mariusmotea/diyHue/tree/master/Lights/Arduino/Generic_Dimmable_Light +This project is based on: https://github.com/mariusmotea/diyHue/tree/master/Lights/Arduino/Generic_Dimmable_Light + +Most of the code was generated by ChatGPT. The controller I use is a old NodeMCU v1.0, which is connected to 4x D4184 MOS breakout boards. See NodeMCU pins table beyond. The cable I use is a https://amzn.eu/d/0jigRCh. I cut it in half and attached it to the MOS boards. From fe8b70a5b9056a6a46c6c62b324bc537bb3eb4c9 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 10:19:46 +0200 Subject: [PATCH 07/19] Indention fixed --- firmware/html/bottom.js | 152 ++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/firmware/html/bottom.js b/firmware/html/bottom.js index 358831b..b3af045 100644 --- a/firmware/html/bottom.js +++ b/firmware/html/bottom.js @@ -257,91 +257,91 @@ links.forEach(function(link) { }); function createTable() { -var table = document.createElement("table"); + var table = document.createElement("table"); -// Headerzeile -var headerRow = document.createElement("tr"); -var headers = ["Stunde", "Minute", "ch1", "ch2", "ch3", "ch4"]; -for (var i = 0; i < headers.length; i++) { - var header = document.createElement("th"); - header.innerHTML = headers[i]; - headerRow.appendChild(header); -} -table.appendChild(headerRow); - -// Inhaltszeilen -for (var row = 0; row < 10; row++) { - var contentRow = document.createElement("tr"); - - // Spalte "Stunde" - var hourCell = document.createElement("td"); - var hourInput = document.createElement("input"); - hourInput.type = "number"; - hourInput.min = 0; - hourInput.max = 23; - hourCell.appendChild(hourInput); - contentRow.appendChild(hourCell); - - // Spalte "Minute" - var minuteCell = document.createElement("td"); - var minuteSelect = document.createElement("select"); - for (var minute = 0; minute <= 50; minute += 10) { - var option = document.createElement("option"); - option.value = minute; - option.text = minute.toString().padStart(2, "0"); - minuteSelect.appendChild(option); + // Headerzeile + var headerRow = document.createElement("tr"); + var headers = ["Stunde", "Minute", "ch1", "ch2", "ch3", "ch4"]; + for (var i = 0; i < headers.length; i++) { + var header = document.createElement("th"); + header.innerHTML = headers[i]; + headerRow.appendChild(header); } - minuteCell.appendChild(minuteSelect); - contentRow.appendChild(minuteCell); + table.appendChild(headerRow); - // Spalten "ch1" bis "ch4" - for (var channel = 1; channel <= 4; channel++) { - var channelCell = document.createElement("td"); - var channelInput = document.createElement("input"); - channelInput.type = "number"; - channelInput.min = 0; - channelInput.max = 100; - channelCell.appendChild(channelInput); - contentRow.appendChild(channelCell); + // Inhaltszeilen + for (var row = 0; row < 10; row++) { + var contentRow = document.createElement("tr"); + + // Spalte "Stunde" + var hourCell = document.createElement("td"); + var hourInput = document.createElement("input"); + hourInput.type = "number"; + hourInput.min = 0; + hourInput.max = 23; + hourCell.appendChild(hourInput); + contentRow.appendChild(hourCell); + + // Spalte "Minute" + var minuteCell = document.createElement("td"); + var minuteSelect = document.createElement("select"); + for (var minute = 0; minute <= 50; minute += 10) { + var option = document.createElement("option"); + option.value = minute; + option.text = minute.toString().padStart(2, "0"); + minuteSelect.appendChild(option); + } + minuteCell.appendChild(minuteSelect); + contentRow.appendChild(minuteCell); + + // Spalten "ch1" bis "ch4" + for (var channel = 1; channel <= 4; channel++) { + var channelCell = document.createElement("td"); + var channelInput = document.createElement("input"); + channelInput.type = "number"; + channelInput.min = 0; + channelInput.max = 100; + channelCell.appendChild(channelInput); + contentRow.appendChild(channelCell); + } + + table.appendChild(contentRow); } - table.appendChild(contentRow); -} + // Button + var button = document.createElement("button"); + button.innerHTML = "Save"; + button.classList.add("pure-button"); + button.classList.add("pure-button-primary"); + button.onclick = function() { + var data = []; -// Button -var button = document.createElement("button"); -button.innerHTML = "Save"; -button.classList.add("pure-button"); -button.classList.add("pure-button-primary"); -button.onclick = function() { - var data = []; + var rows = table.getElementsByTagName("tr"); + for (var row = 1; row < rows.length; row++) { + var cells = rows[row].getElementsByTagName("td"); - var rows = table.getElementsByTagName("tr"); - for (var row = 1; row < rows.length; row++) { - var cells = rows[row].getElementsByTagName("td"); + var hour = cells[0].querySelector("input").value; + var minute = cells[1].querySelector("select").value; + var ch1 = cells[2].querySelector("input").value; + var ch2 = cells[3].querySelector("input").value; + var ch3 = cells[4].querySelector("input").value; + var ch4 = cells[5].querySelector("input").value; - var hour = cells[0].querySelector("input").value; - var minute = cells[1].querySelector("select").value; - var ch1 = cells[2].querySelector("input").value; - var ch2 = cells[3].querySelector("input").value; - var ch3 = cells[4].querySelector("input").value; - var ch4 = cells[5].querySelector("input").value; + var rowObject = {"hour": hour, "min": minute, "ch1": ch1, "ch2": ch2, "ch3": ch3, "ch4": ch4}; + data.push(rowObject); + } - var rowObject = {"hour": hour, "min": minute, "ch1": ch1, "ch2": ch2, "ch3": ch3, "ch4": ch4}; - data.push(rowObject); - } + var json = JSON.stringify(data); + console.log(json); + var xhr = new XMLHttpRequest(); + xhr.open("POST", "http://{{IP_ADDRESS}}/tc_data_save?data=" + encodeURIComponent(json), true); + xhr.send(); - var json = JSON.stringify(data); - console.log(json); - var xhr = new XMLHttpRequest(); - xhr.open("POST", "http://{{IP_ADDRESS}}/tc_data_save?data=" + encodeURIComponent(json), true); - xhr.send(); + }; -}; - -var container = document.getElementById("table-container"); -container.innerHTML = ""; -container.classList.add("pure-form"); -container.appendChild(table); -container.appendChild(button); + var container = document.getElementById("table-container"); + container.innerHTML = ""; + container.classList.add("pure-form"); + container.appendChild(table); + container.appendChild(button); } \ No newline at end of file From d1a0aeb40412ced12c35c915c9828c7e8fb3ad98 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 10:22:52 +0200 Subject: [PATCH 08/19] Indention fixed to save space --- firmware/data/style.css | 95 +++++++++++++++++++---------------------- firmware/html/style.css | 95 +++++++++++++++++++---------------------- 2 files changed, 86 insertions(+), 104 deletions(-) diff --git a/firmware/data/style.css b/firmware/data/style.css index 244096a..e39a471 100644 --- a/firmware/data/style.css +++ b/firmware/data/style.css @@ -1,52 +1,43 @@ - #tab-lights, #tab-config, #tab-tde { - display: none; - background-color: #ffffff; - color: black; - font-weight: bold; - } - #tab-lights.visible { - display: block; - } - #tab-config.visible { - display: block; - } - #tab-tde.visible { - display: block; - } - /* CSS-Regeln für die Tabellenzellen */ - .pure-table td { - padding: 4px; - } - - /* CSS-Regeln für die Eingabefelder */ - .pure-form input[type="number"] { - width: 60px; - height: 20px; - border-radius: 3px; - border: 1px solid #ccc; - } - - /* CSS-Regeln für die Auswahllisten */ - .pure-form select { - width: 80px; - height: 26px; - border-radius: 3px; - border: 1px solid #ccc; - background-color: #fff; - } - - /* CSS-Regeln für den Export-Button */ - .pure-button { - background-color: #5a5a5a; - color: #fff; - border-radius: 3px; - border: none; - padding: 8px 12px; - font-size: 14px; - cursor: pointer; - } - - .pure-button:hover { - background-color: #333; - } - +#tab-lights, #tab-config, #tab-tde { +display: none; +background-color: #ffffff; +color: black; +font-weight: bold; +} +#tab-lights.visible { +display: block; +} +#tab-config.visible { +display: block; +} +#tab-tde.visible { +display: block; +} +.pure-table td { +padding: 4px; +} +.pure-form input[type="number"] { +width: 60px; +height: 20px; +border-radius: 3px; +border: 1px solid #ccc; +} +.pure-form select { +width: 80px; +height: 26px; +border-radius: 3px; +border: 1px solid #ccc; +background-color: #fff; +} +.pure-button { +background-color: #5a5a5a; +color: #fff; +border-radius: 3px; +border: none; +padding: 8px 12px; +font-size: 14px; +cursor: pointer; +} +.pure-button:hover { +background-color: #333; +} \ No newline at end of file diff --git a/firmware/html/style.css b/firmware/html/style.css index 244096a..e39a471 100644 --- a/firmware/html/style.css +++ b/firmware/html/style.css @@ -1,52 +1,43 @@ - #tab-lights, #tab-config, #tab-tde { - display: none; - background-color: #ffffff; - color: black; - font-weight: bold; - } - #tab-lights.visible { - display: block; - } - #tab-config.visible { - display: block; - } - #tab-tde.visible { - display: block; - } - /* CSS-Regeln für die Tabellenzellen */ - .pure-table td { - padding: 4px; - } - - /* CSS-Regeln für die Eingabefelder */ - .pure-form input[type="number"] { - width: 60px; - height: 20px; - border-radius: 3px; - border: 1px solid #ccc; - } - - /* CSS-Regeln für die Auswahllisten */ - .pure-form select { - width: 80px; - height: 26px; - border-radius: 3px; - border: 1px solid #ccc; - background-color: #fff; - } - - /* CSS-Regeln für den Export-Button */ - .pure-button { - background-color: #5a5a5a; - color: #fff; - border-radius: 3px; - border: none; - padding: 8px 12px; - font-size: 14px; - cursor: pointer; - } - - .pure-button:hover { - background-color: #333; - } - +#tab-lights, #tab-config, #tab-tde { +display: none; +background-color: #ffffff; +color: black; +font-weight: bold; +} +#tab-lights.visible { +display: block; +} +#tab-config.visible { +display: block; +} +#tab-tde.visible { +display: block; +} +.pure-table td { +padding: 4px; +} +.pure-form input[type="number"] { +width: 60px; +height: 20px; +border-radius: 3px; +border: 1px solid #ccc; +} +.pure-form select { +width: 80px; +height: 26px; +border-radius: 3px; +border: 1px solid #ccc; +background-color: #fff; +} +.pure-button { +background-color: #5a5a5a; +color: #fff; +border-radius: 3px; +border: none; +padding: 8px 12px; +font-size: 14px; +cursor: pointer; +} +.pure-button:hover { +background-color: #333; +} \ No newline at end of file From 39dc462114547a6e7f431f96898c93730f889165 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 10:41:41 +0200 Subject: [PATCH 09/19] Fixed tab switching --- firmware/data/bottom.js | 5 ++++- firmware/data/index_template_top.html | 17 +++++++++++++++++ firmware/data/style.css | 4 ++-- firmware/html/bottom.js | 6 +++++- firmware/html/index_template_top.html | 17 +++++++++++++++++ firmware/html/style.css | 4 ++-- 6 files changed, 47 insertions(+), 6 deletions(-) diff --git a/firmware/data/bottom.js b/firmware/data/bottom.js index fe6a7d6..e619d89 100644 --- a/firmware/data/bottom.js +++ b/firmware/data/bottom.js @@ -1,4 +1,5 @@ function addTabListener() { +console.log("Try to add tab listener"); try { var tabMain = document.getElementById("tab-lights"); var tabConfig = document.getElementById("tab-config"); @@ -7,6 +8,7 @@ var amain = document.getElementById("tab-a-lights"); var acfg = document.getElementById("tab-a-config"); var atde = document.getElementById("tab-a-tde"); amain.addEventListener("click", function() { +console.log("Switch to main lights tab"); tabMain.classList.add("visible"); tabConfig.classList.remove("visible"); tabTDE.classList.remove("visible"); @@ -15,6 +17,7 @@ acfg.classList.remove("pure-button-primary"); atde.classList.remove("pure-button-primary"); }); acfg.addEventListener("click", function() { +console.log("Switch to config tab"); tabMain.classList.remove("visible"); tabConfig.classList.add("visible"); tabTDE.classList.remove("visible"); @@ -23,13 +26,13 @@ acfg.classList.add("pure-button-primary"); atde.classList.remove("pure-button-primary"); }); atde.addEventListener("click", function() { +console.log("Switch to TDE tab"); tabMain.classList.remove("visible"); tabConfig.classList.remove("visible"); tabTDE.classList.add("visible"); amain.classList.remove("pure-button-primary"); acfg.classList.remove("pure-button-primary"); atde.classList.add("pure-button-primary"); -createTable(); }); } catch (error) { console.log("Error: load listener of the tab action listener management: " + error.message); diff --git a/firmware/data/index_template_top.html b/firmware/data/index_template_top.html index e12f53c..3c7bd96 100644 --- a/firmware/data/index_template_top.html +++ b/firmware/data/index_template_top.html @@ -9,6 +9,23 @@ + diff --git a/firmware/data/style.css b/firmware/data/style.css index e39a471..687ae93 100644 --- a/firmware/data/style.css +++ b/firmware/data/style.css @@ -1,4 +1,4 @@ -#tab-lights, #tab-config, #tab-tde { +/*#tab-lights, #tab-config, #tab-tde { display: none; background-color: #ffffff; color: black; @@ -40,4 +40,4 @@ cursor: pointer; } .pure-button:hover { background-color: #333; -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/firmware/html/bottom.js b/firmware/html/bottom.js index b3af045..b5e3b31 100644 --- a/firmware/html/bottom.js +++ b/firmware/html/bottom.js @@ -1,4 +1,5 @@ function addTabListener() { + console.log("Try to add tab listener"); try { var tabMain = document.getElementById("tab-lights"); var tabConfig = document.getElementById("tab-config"); @@ -10,6 +11,7 @@ function addTabListener() { amain.addEventListener("click", function() { + console.log("Switch to main lights tab"); tabMain.classList.add("visible"); tabConfig.classList.remove("visible"); tabTDE.classList.remove("visible"); @@ -20,6 +22,7 @@ function addTabListener() { }); acfg.addEventListener("click", function() { + console.log("Switch to config tab"); tabMain.classList.remove("visible"); tabConfig.classList.add("visible"); tabTDE.classList.remove("visible"); @@ -30,6 +33,7 @@ function addTabListener() { }); atde.addEventListener("click", function() { + console.log("Switch to TDE tab"); tabMain.classList.remove("visible"); tabConfig.classList.remove("visible"); tabTDE.classList.add("visible"); @@ -38,7 +42,7 @@ function addTabListener() { acfg.classList.remove("pure-button-primary"); atde.classList.add("pure-button-primary"); - createTable(); + //createTable(); // recreate the table on timing data editor tab }); } catch (error) { console.log("Error: load listener of the tab action listener management: " + error.message); diff --git a/firmware/html/index_template_top.html b/firmware/html/index_template_top.html index 6818214..511eecc 100644 --- a/firmware/html/index_template_top.html +++ b/firmware/html/index_template_top.html @@ -9,6 +9,23 @@ + diff --git a/firmware/html/style.css b/firmware/html/style.css index e39a471..687ae93 100644 --- a/firmware/html/style.css +++ b/firmware/html/style.css @@ -1,4 +1,4 @@ -#tab-lights, #tab-config, #tab-tde { +/*#tab-lights, #tab-config, #tab-tde { display: none; background-color: #ffffff; color: black; @@ -40,4 +40,4 @@ cursor: pointer; } .pure-button:hover { background-color: #333; -} \ No newline at end of file +}*/ \ No newline at end of file From b328adb177be54b7e41dadc2fe50b14e4a5f2500 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 10:45:56 +0200 Subject: [PATCH 10/19] Added table update of timing editor --- firmware/data/bottom.js | 5 +---- firmware/html/bottom.js | 10 +++++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/firmware/data/bottom.js b/firmware/data/bottom.js index e619d89..fe6a7d6 100644 --- a/firmware/data/bottom.js +++ b/firmware/data/bottom.js @@ -1,5 +1,4 @@ function addTabListener() { -console.log("Try to add tab listener"); try { var tabMain = document.getElementById("tab-lights"); var tabConfig = document.getElementById("tab-config"); @@ -8,7 +7,6 @@ var amain = document.getElementById("tab-a-lights"); var acfg = document.getElementById("tab-a-config"); var atde = document.getElementById("tab-a-tde"); amain.addEventListener("click", function() { -console.log("Switch to main lights tab"); tabMain.classList.add("visible"); tabConfig.classList.remove("visible"); tabTDE.classList.remove("visible"); @@ -17,7 +15,6 @@ acfg.classList.remove("pure-button-primary"); atde.classList.remove("pure-button-primary"); }); acfg.addEventListener("click", function() { -console.log("Switch to config tab"); tabMain.classList.remove("visible"); tabConfig.classList.add("visible"); tabTDE.classList.remove("visible"); @@ -26,13 +23,13 @@ acfg.classList.add("pure-button-primary"); atde.classList.remove("pure-button-primary"); }); atde.addEventListener("click", function() { -console.log("Switch to TDE tab"); tabMain.classList.remove("visible"); tabConfig.classList.remove("visible"); tabTDE.classList.add("visible"); amain.classList.remove("pure-button-primary"); acfg.classList.remove("pure-button-primary"); atde.classList.add("pure-button-primary"); +createTable(); }); } catch (error) { console.log("Error: load listener of the tab action listener management: " + error.message); diff --git a/firmware/html/bottom.js b/firmware/html/bottom.js index b5e3b31..38d3db1 100644 --- a/firmware/html/bottom.js +++ b/firmware/html/bottom.js @@ -1,5 +1,5 @@ function addTabListener() { - console.log("Try to add tab listener"); + //console.log("Try to add tab listener"); try { var tabMain = document.getElementById("tab-lights"); var tabConfig = document.getElementById("tab-config"); @@ -11,7 +11,7 @@ function addTabListener() { amain.addEventListener("click", function() { - console.log("Switch to main lights tab"); + //console.log("Switch to main lights tab"); tabMain.classList.add("visible"); tabConfig.classList.remove("visible"); tabTDE.classList.remove("visible"); @@ -22,7 +22,7 @@ function addTabListener() { }); acfg.addEventListener("click", function() { - console.log("Switch to config tab"); + //console.log("Switch to config tab"); tabMain.classList.remove("visible"); tabConfig.classList.add("visible"); tabTDE.classList.remove("visible"); @@ -33,7 +33,7 @@ function addTabListener() { }); atde.addEventListener("click", function() { - console.log("Switch to TDE tab"); + //console.log("Switch to TDE tab"); tabMain.classList.remove("visible"); tabConfig.classList.remove("visible"); tabTDE.classList.add("visible"); @@ -42,7 +42,7 @@ function addTabListener() { acfg.classList.remove("pure-button-primary"); atde.classList.add("pure-button-primary"); - //createTable(); // recreate the table on timing data editor tab + createTable(); // recreate the table on timing data editor tab }); } catch (error) { console.log("Error: load listener of the tab action listener management: " + error.message); From 3c69d8bc67cd5f85f9cba05680b0d53d542bda43 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 10:56:16 +0200 Subject: [PATCH 11/19] Fixed css mime type --- firmware/firmware.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/firmware.ino b/firmware/firmware.ino index 4b483da..292bd44 100644 --- a/firmware/firmware.ino +++ b/firmware/firmware.ino @@ -501,7 +501,7 @@ void init_webserver() server.on("/css", []() { - server.send(200, "text/html", loadSPIFFSFile("/style.css")); + server.send(200, "text/css", loadSPIFFSFile("/style.css")); }); server.on("/", []() From 6fec2cffaafea3b133f463b51f3d916ae5f6e1d7 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 10:57:42 +0200 Subject: [PATCH 12/19] Fixed CSS problem that the tabs are not working correct. --- firmware/data/index_template_top.html | 19 +------------------ firmware/data/style.css | 3 ++- firmware/html/index_template_top.html | 19 +------------------ firmware/html/style.css | 3 ++- 4 files changed, 6 insertions(+), 38 deletions(-) diff --git a/firmware/data/index_template_top.html b/firmware/data/index_template_top.html index 3c7bd96..7f237d0 100644 --- a/firmware/data/index_template_top.html +++ b/firmware/data/index_template_top.html @@ -9,24 +9,7 @@ - - diff --git a/firmware/data/style.css b/firmware/data/style.css index 687ae93..ebee311 100644 --- a/firmware/data/style.css +++ b/firmware/data/style.css @@ -1,4 +1,4 @@ -/*#tab-lights, #tab-config, #tab-tde { +#tab-lights, #tab-config, #tab-tde { display: none; background-color: #ffffff; color: black; @@ -16,6 +16,7 @@ display: block; .pure-table td { padding: 4px; } +/* .pure-form input[type="number"] { width: 60px; height: 20px; diff --git a/firmware/html/index_template_top.html b/firmware/html/index_template_top.html index 511eecc..3ac1cf8 100644 --- a/firmware/html/index_template_top.html +++ b/firmware/html/index_template_top.html @@ -9,24 +9,7 @@ - - diff --git a/firmware/html/style.css b/firmware/html/style.css index 687ae93..ebee311 100644 --- a/firmware/html/style.css +++ b/firmware/html/style.css @@ -1,4 +1,4 @@ -/*#tab-lights, #tab-config, #tab-tde { +#tab-lights, #tab-config, #tab-tde { display: none; background-color: #ffffff; color: black; @@ -16,6 +16,7 @@ display: block; .pure-table td { padding: 4px; } +/* .pure-form input[type="number"] { width: 60px; height: 20px; From 840443e46edf7efac6470f7bd368ecb981b92495 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 11:05:35 +0200 Subject: [PATCH 13/19] Enabled mode css --- firmware/data/style.css | 3 +-- firmware/html/style.css | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/firmware/data/style.css b/firmware/data/style.css index ebee311..e39a471 100644 --- a/firmware/data/style.css +++ b/firmware/data/style.css @@ -16,7 +16,6 @@ display: block; .pure-table td { padding: 4px; } -/* .pure-form input[type="number"] { width: 60px; height: 20px; @@ -41,4 +40,4 @@ cursor: pointer; } .pure-button:hover { background-color: #333; -}*/ \ No newline at end of file +} \ No newline at end of file diff --git a/firmware/html/style.css b/firmware/html/style.css index ebee311..e39a471 100644 --- a/firmware/html/style.css +++ b/firmware/html/style.css @@ -16,7 +16,6 @@ display: block; .pure-table td { padding: 4px; } -/* .pure-form input[type="number"] { width: 60px; height: 20px; @@ -41,4 +40,4 @@ cursor: pointer; } .pure-button:hover { background-color: #333; -}*/ \ No newline at end of file +} \ No newline at end of file From 402b63d68088abfa4bd4052b4cc9d5c4fd8dc3f0 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 11:07:56 +0200 Subject: [PATCH 14/19] Input types of tc edit modified --- firmware/data/bottom.js | 26 ++++++++++++++++---------- firmware/html/bottom.js | 26 ++++++++++++++++---------- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/firmware/data/bottom.js b/firmware/data/bottom.js index fe6a7d6..3d0c2f0 100644 --- a/firmware/data/bottom.js +++ b/firmware/data/bottom.js @@ -230,11 +230,14 @@ table.appendChild(headerRow); for (var row = 0; row < 10; row++) { var contentRow = document.createElement("tr"); var hourCell = document.createElement("td"); -var hourInput = document.createElement("input"); -hourInput.type = "number"; -hourInput.min = 0; -hourInput.max = 23; -hourCell.appendChild(hourInput); +var hourSelect = document.createElement("select"); +for (var hour = 0; hour <= 23; hour++) { +var option = document.createElement("option"); +option.value = hour; +option.text = hour.toString().padStart(2, "0"); +hourSelect.appendChild(option); +} +hourCell.appendChild(hourSelect); contentRow.appendChild(hourCell); var minuteCell = document.createElement("td"); var minuteSelect = document.createElement("select"); @@ -248,11 +251,14 @@ minuteCell.appendChild(minuteSelect); contentRow.appendChild(minuteCell); for (var channel = 1; channel <= 4; channel++) { var channelCell = document.createElement("td"); -var channelInput = document.createElement("input"); -channelInput.type = "number"; -channelInput.min = 0; -channelInput.max = 100; -channelCell.appendChild(channelInput); +var channelSelect = document.createElement("select"); +for (var i = 0; i <= 100; i++) { +var option = document.createElement("option"); +option.value = i; +option.text = i.toString(); +channelSelect.appendChild(option); +} +channelCell.appendChild(channelSelect); contentRow.appendChild(channelCell); } table.appendChild(contentRow); diff --git a/firmware/html/bottom.js b/firmware/html/bottom.js index 38d3db1..8f7b39e 100644 --- a/firmware/html/bottom.js +++ b/firmware/html/bottom.js @@ -279,11 +279,14 @@ function createTable() { // Spalte "Stunde" var hourCell = document.createElement("td"); - var hourInput = document.createElement("input"); - hourInput.type = "number"; - hourInput.min = 0; - hourInput.max = 23; - hourCell.appendChild(hourInput); + var hourSelect = document.createElement("select"); + for (var hour = 0; hour <= 23; hour++) { + var option = document.createElement("option"); + option.value = hour; + option.text = hour.toString().padStart(2, "0"); + hourSelect.appendChild(option); + } + hourCell.appendChild(hourSelect); contentRow.appendChild(hourCell); // Spalte "Minute" @@ -301,11 +304,14 @@ function createTable() { // Spalten "ch1" bis "ch4" for (var channel = 1; channel <= 4; channel++) { var channelCell = document.createElement("td"); - var channelInput = document.createElement("input"); - channelInput.type = "number"; - channelInput.min = 0; - channelInput.max = 100; - channelCell.appendChild(channelInput); + var channelSelect = document.createElement("select"); + for (var i = 0; i <= 100; i++) { + var option = document.createElement("option"); + option.value = i; + option.text = i.toString(); + channelSelect.appendChild(option); + } + channelCell.appendChild(channelSelect); contentRow.appendChild(channelCell); } From de5dbda939c335454c9d87a4c922e25440fed271 Mon Sep 17 00:00:00 2001 From: Kai Lauterbach Date: Fri, 5 May 2023 11:14:10 +0200 Subject: [PATCH 15/19] Newline added --- firmware/data/index_template_bottom.html | 2 +- firmware/html/index_template_bottom.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/data/index_template_bottom.html b/firmware/data/index_template_bottom.html index 990ac03..bfdc8ce 100644 --- a/firmware/data/index_template_bottom.html +++ b/firmware/data/index_template_bottom.html @@ -5,7 +5,7 @@ -
+