Added a script which converts html pages into arduino strings. Added beta state code for html page generation.
This commit is contained in:
parent
c0898e2972
commit
a64e4f17cf
5 changed files with 473 additions and 425 deletions
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
String getConfigHTML()
|
||||||
|
{
|
||||||
|
String config_html = ""
|
||||||
|
"<form class=\"pure-form pure-form-aligned\" action=\"/\" method=\"post\">"
|
||||||
|
"<h3>Config</h3>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"startup\">"
|
||||||
|
"<strong>Startup</strong>"
|
||||||
|
"</label>"
|
||||||
|
"<select onchange=\"this.form.submit()\" id=\"startup\" name=\"startup\">"
|
||||||
|
"<option {{STARTUP_SELECTED_LS_0}} value=\"0\">Last state</option>"
|
||||||
|
"<option {{STARTUP_SELECTED_ON_1}} value=\"1\">On</option>"
|
||||||
|
"<option {{STARTUP_SELECTED_OFF_2}} value=\"2\">Off</option>"
|
||||||
|
"</select>"
|
||||||
|
"</div>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"scene\">"
|
||||||
|
"<strong>Scene</strong>"
|
||||||
|
"</label>"
|
||||||
|
"<select onchange=\"this.form.submit()\" id=\"scene\" name=\"scene\">"
|
||||||
|
"<option {{SCENE_SELECTED_RELAX_0}} value=\"0\">Relax</option>"
|
||||||
|
"<option {{SCENE_SELECTED_BRIGHT_1}} value=\"1\">Bright</option>"
|
||||||
|
"<option {{SCENE_SELECTED_NIGHT_2}} value=\"2\">Night</option>"
|
||||||
|
"</select>"
|
||||||
|
"</div>"
|
||||||
|
"<br>"
|
||||||
|
"<h3>Wifi</h3>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"ip\">SSID</label>"
|
||||||
|
"<input id=\"ssid\" name=\"ssid\" type=\"text\" value=\"{{WIFI_SSID}}\">"
|
||||||
|
"</div>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"wpw\">Passphrase</label>"
|
||||||
|
"<input id=\"wpw\" name=\"wpw\" type=\"text\" placeholder=\"1234password\">"
|
||||||
|
"</div>"
|
||||||
|
"<br>"
|
||||||
|
"<h3>Network</h3>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"dip\">"
|
||||||
|
"<strong>Dynamic-IP</strong>"
|
||||||
|
"</label>"
|
||||||
|
"<a class=\"pure-button {{DIP_LINK_ON_PRIMARY}}\" href=\"/?dip=true\">ON</a>"
|
||||||
|
"<a class=\"pure-button {{DIP_LINK_OFF_PRIMARY}}\" href=\"/?dip=false\">OFF</a>"
|
||||||
|
"</div>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"ip\">IP</label>"
|
||||||
|
"<input id=\"ip\" name=\"ip\" type=\"text\" value=\"{{WIFI_IP}}\">"
|
||||||
|
"</div>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"gwip\">Gateway IP</label>"
|
||||||
|
"<input id=\"gwip\" name=\"gwip\" type=\"text\" value=\"{{WIFI_GW}}\">"
|
||||||
|
"</div>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"ip\">Netmask</label>"
|
||||||
|
"<input id=\"netmask\" name=\"netmas\" type=\"text\" value=\"{{WIFI_NM}}\">"
|
||||||
|
"</div>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"ip\">DNS</label>"
|
||||||
|
"<input id=\"netmask\" name=\"dns\" type=\"text\" value=\"{{WIFI_DNS}}\">"
|
||||||
|
"</div>"
|
||||||
|
"<div class=\"pure-controls\">"
|
||||||
|
"<button type=\"submit\" class=\"pure-button pure-button-primary\">Save</button>"
|
||||||
|
"</div>"
|
||||||
|
"</form>";
|
||||||
|
return config_html;
|
||||||
|
}
|
|
@ -610,457 +610,118 @@ void init_webserver()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate HTML page
|
// Generate HTML page
|
||||||
String http_content = "<!doctype html>";
|
String http_content = getIndexHTML();
|
||||||
http_content += "<html>";
|
|
||||||
http_content += "<head>";
|
|
||||||
http_content += "<style></style>";
|
|
||||||
http_content += "<meta charset=\"utf-8\">";
|
|
||||||
http_content += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">";
|
|
||||||
//http_content += "<meta http-equiv=\"refresh\" content=\"15\">"; // Reload the page every 15 seconds automatically
|
|
||||||
http_content += "<title>Light Setup</title>";
|
|
||||||
http_content += "<script src=\"https://code.jquery.com/jquery-3.6.0.min.js\"></script>";
|
|
||||||
http_content += "<script src=\"https://cdn.plot.ly/plotly-latest.min.js\"></script>";
|
|
||||||
http_content += "<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js\"></script>";
|
|
||||||
http_content += "<link rel=\"stylesheet\" href=\"https://unpkg.com/purecss@0.6.2/build/pure-min.css\">";
|
|
||||||
http_content += "</head>";
|
|
||||||
http_content += "<body>";
|
|
||||||
http_content += "<fieldset>";
|
|
||||||
http_content += "<h3>" + (String)light_name + "</h3>";
|
|
||||||
|
|
||||||
http_content += "<div class=\"pure-form pure-form-aligned\">";
|
http_content.replace("{{LIGHT_NAME}}", (String)light_name);
|
||||||
|
|
||||||
http_content += "<div class=\"pure-controls\">";
|
|
||||||
http_content += "<span class=\"pure-form-message\"><a href=\"/?alert=1\">alert</a> <a href=\"/?reset=1\">reset</a> <a href=\"/?resettc\">reset timing control data</a> <a href=\"/update\">update</a></span>";
|
|
||||||
http_content += "<label for=\"cb\" class=\"pure-checkbox\">";
|
|
||||||
http_content += "</label>";
|
|
||||||
http_content += "</div>";
|
|
||||||
|
|
||||||
// timing control button
|
|
||||||
http_content += "<br>";
|
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
|
||||||
http_content += "<label for=\"tc_on\"><strong>Timing control</strong></label>";
|
|
||||||
int tc_val = EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS);
|
int tc_val = EEPROM.read(EEPROM_TIMING_CONTROL_ENABLED_ADDRESS);
|
||||||
http_content += "<a id=\"tc_on\" class=\"pure-button";
|
if (tc_val == TIMING_CONTROL_ENABLED)
|
||||||
if (tc_val == TIMING_CONTROL_ENABLED) http_content += " pure-button-primary";
|
{
|
||||||
http_content += "\" href=\"#\">ON</a>";
|
http_content.replace("{{TC_LINK_PRIMARY_ON}}", "pure-button-primary");
|
||||||
http_content += "<a id=\"tc_off\" class=\"pure-button";
|
} else {
|
||||||
if (tc_val == TIMING_CONTROL_DISABLED) http_content += " pure-button-primary";
|
http_content.replace("{{TC_LINK_PRIMARY_ON}}", "");
|
||||||
http_content += "\" href=\"#\">OFF</a>";
|
}
|
||||||
http_content += "</div>";
|
if (tc_val == TIMING_CONTROL_DISABLED)
|
||||||
http_content += "<script>"
|
{
|
||||||
// Suche nach allen tc Links auf der Seite mit IDs tc_on
|
http_content.replace("{{TC_LINK_PRIMARY_OFF}}", "pure-button-primary");
|
||||||
"var links = document.querySelectorAll('[id^=\"tc_on\"]');"
|
} else {
|
||||||
// Füge einen Klick-Listener zu jedem Link hinzu
|
http_content.replace("{{TC_LINK_PRIMARY_OFF}}", "");
|
||||||
"links.forEach(function(link) {"
|
}
|
||||||
"link.addEventListener('click', function(event) {"
|
|
||||||
// Verhindere, dass der Link die Seite neu lädt
|
|
||||||
"event.preventDefault();"
|
|
||||||
// Erstelle eine neue Anfrage an die entsprechende URL
|
|
||||||
"var xhr = new XMLHttpRequest();"
|
|
||||||
"xhr.open('GET', 'http://192.168.0.26/?tc=true', true);"
|
|
||||||
// Sende die Anfrage im Hintergrund
|
|
||||||
"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');"
|
|
||||||
"});"
|
|
||||||
"});"
|
|
||||||
// Suche nach allen tc Links auf der Seite mit IDs tc_off
|
|
||||||
"var links = document.querySelectorAll('[id^=\"tc_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();"
|
|
||||||
// Erstelle eine neue Anfrage an die entsprechende URL
|
|
||||||
"var xhr = new XMLHttpRequest();"
|
|
||||||
"xhr.open('GET', 'http://192.168.0.26/?tc=false', true);"
|
|
||||||
// Sende die Anfrage im Hintergrund
|
|
||||||
"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');"
|
|
||||||
"});"
|
|
||||||
"});"
|
|
||||||
"</script>";
|
|
||||||
http_content += "<br>";
|
|
||||||
|
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
http_content.replace("{{TRANSITION_TIME}}", (String)default_transitiontime);
|
||||||
http_content += "<label for=\"transition\">Transition time (s)</label>";
|
|
||||||
http_content += "<input id=\"transition\" name=\"transition\" type=\"text\" placeholder=\"10\" value=\"" + (String)default_transitiontime + "\">";
|
|
||||||
http_content += "</div>";
|
|
||||||
http_content += "<br>";
|
|
||||||
|
|
||||||
http_content += "<script>"
|
String light_content = "";
|
||||||
"let timeoutId;" // slider value change submit to server
|
|
||||||
"function sendSliderValue(x) {"
|
|
||||||
"x = x - 1;"
|
|
||||||
"clearTimeout(timeoutId);"
|
|
||||||
"timeoutId = setTimeout(() => {"
|
|
||||||
"var value = document.getElementById(`bri${x}`).value;"
|
|
||||||
"var url = `http://192.168.0.26/?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);"
|
|
||||||
"}</script>";
|
|
||||||
|
|
||||||
http_content += "<br><table border=0><tr><td>";
|
|
||||||
// Light control
|
// Light control
|
||||||
for (uint8 light_num = 0; light_num < LIGHTS_COUNT; light_num++)
|
for (uint8 light_num = 0; light_num < LIGHTS_COUNT; light_num++)
|
||||||
{
|
{
|
||||||
// on/off buttons
|
// Generate lights part of the HTML page
|
||||||
http_content += "<h4>Light " + (String)(light_num + 1) + "</h4>";
|
String tmp_light_content = getLightControlHTML();
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
|
||||||
http_content += "<label for=\"power\"><strong>Power</strong></label>";
|
|
||||||
http_content += "<a id=\"on" + (String)light_num + "_on\" class=\"pure-button\" href=\"#\">ON</a>";
|
|
||||||
http_content += "<a id=\"on" + (String)light_num + "_off\" class=\"pure-button\" href=\"#\">OFF</a>";
|
|
||||||
http_content += "</div>";
|
|
||||||
|
|
||||||
// slider for brightness
|
// on/off buttons and slider
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
tmp_light_content.replace("{{LIGHT_NUMBER}}", (String)(light_num + 1));
|
||||||
http_content += "<label for=\"bri" + (String)light_num + "\">Bri</label>";
|
tmp_light_content.replace("{{LIGHT_NUMBER_DEC}}", (String)light_num);
|
||||||
http_content += "<input id=\"bri" + (String)light_num + "\" onchange=\"sendSliderValue(" + (String)(light_num+1) + ")\" name=\"bri" + (String)light_num + "\" type=\"range\" min=\"0\" max=\"255\" value=\"" + (String)bri[light_num] + "\">";
|
|
||||||
http_content += " <span id=\"bri" + (String)light_num + "_val\" name=\"bri" + (String)light_num + "\">" + (String)(int)(bri[light_num] * 100.0 / 255.0) + "</span>%";
|
|
||||||
http_content += "<br><label for=\"light" + (String)light_num + "_pwm\">PWM-Value</label>";
|
|
||||||
http_content += "<input type=\"range\" min=\"0\" max=\"100\" value=\"0\" id=\"light" + (String)light_num + "_pwm\" disabled>";
|
|
||||||
http_content += " <span id=\"light" + (String)light_num + "_pwm_txt\"></span>%";
|
|
||||||
http_content += "<script>";
|
|
||||||
http_content += "var slider" + (String)light_num + " = document.getElementById(\"bri" + (String)light_num + "\");";
|
|
||||||
http_content += "var output" + (String)light_num + " = document.getElementById(\"bri" + (String)light_num + "_val\");";
|
|
||||||
http_content += "output" + (String)light_num + ".innerHTML = (Math.round((slider" + (String)light_num + ".value * 100.0 / 255.0) * 100) / 100).toFixed(2);";
|
|
||||||
http_content += "slider" + (String)light_num + ".oninput = function() {";
|
|
||||||
http_content += "output" + (String)light_num + ".innerHTML = (Math.round((this.value * 100.0 / 255.0) * 100) / 100).toFixed(2);";
|
|
||||||
http_content += "}";
|
|
||||||
http_content += "</script>";
|
|
||||||
|
|
||||||
http_content += "</div>";
|
|
||||||
|
|
||||||
|
// add the lights code to the html output string
|
||||||
|
light_content += tmp_light_content;
|
||||||
}
|
}
|
||||||
http_content += "<script>"
|
|
||||||
// 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://192.168.0.26/?on' + id + '=false', true);"
|
|
||||||
// Sende die Anfrage im Hintergrund
|
|
||||||
"xhr.send();"
|
|
||||||
"updateLightState();"
|
|
||||||
"});"
|
|
||||||
"});"
|
|
||||||
// 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://192.168.0.26/?on' + id + '=true', true);"
|
|
||||||
// Sende die Anfrage im Hintergrund
|
|
||||||
"xhr.send();"
|
|
||||||
"updateLightState();"
|
|
||||||
"});"
|
|
||||||
"});"
|
|
||||||
"</script>";
|
|
||||||
|
|
||||||
http_content += "<form class=\"pure-form pure-form-aligned\" action=\"/\" method=\"post\">";
|
// add the created lights control code to the html output
|
||||||
|
http_content.replace("{{LIGHTS_CONTROL}}", light_content);
|
||||||
|
|
||||||
// startup state and scene for all of the lights
|
|
||||||
http_content += "</td><td>";
|
|
||||||
http_content += "<div id=\"plot_chart\"></div>";
|
|
||||||
http_content += "</td></tr></table><br>";
|
|
||||||
http_content += "<h3>Config</h3>";
|
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
|
||||||
http_content += "<label for=\"startup\"><strong>Startup</strong></label>";
|
|
||||||
http_content += "<select onchange=\"this.form.submit()\" id=\"startup\" name=\"startup\">";
|
|
||||||
int ls_val = EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS);
|
int ls_val = EEPROM.read(EEPROM_LAST_STATE_STARTUP_ADDRESS);
|
||||||
http_content += "<option ";
|
if (ls_val == LAST_STATE_STARTUP_LIGHT_LAST_STATE)
|
||||||
if (ls_val == LAST_STATE_STARTUP_LIGHT_LAST_STATE) http_content += "selected=\"selected\"";
|
{
|
||||||
http_content += " value=\"0\">Last state</option>";
|
http_content.replace("{{STARTUP_SELECTED_LS_0}}", "selected=\"selected\"");
|
||||||
http_content += "<option ";
|
} else {
|
||||||
if (ls_val == LAST_STATE_STARTUP_LIGHT_ON_STATE) http_content += "selected=\"selected\"";
|
http_content.replace("{{STARTUP_SELECTED_LS_0}}", "");
|
||||||
http_content += " value=\"1\">On</option>";
|
}
|
||||||
http_content += "<option ";
|
|
||||||
if (ls_val == LAST_STATE_STARTUP_LIGHT_OFF_STATE) http_content += "selected=\"selected\"";
|
if (ls_val == LAST_STATE_STARTUP_LIGHT_ON_STATE)
|
||||||
http_content += " value=\"2\">Off</option>";
|
{
|
||||||
http_content += "</select>";
|
http_content.replace("{{STARTUP_SELECTED_ON_1}}", "selected=\"selected\"");
|
||||||
http_content += "</div>";
|
} else {
|
||||||
|
http_content.replace("{{STARTUP_SELECTED_ON_1}}", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ls_val == LAST_STATE_STARTUP_LIGHT_OFF_STATE)
|
||||||
|
{
|
||||||
|
http_content.replace("{{STARTUP_SELECTED_OFF_2}}", "selected=\"selected\"");
|
||||||
|
} else {
|
||||||
|
http_content.replace("{{STARTUP_SELECTED_OFF_2}}", "");
|
||||||
|
}
|
||||||
|
|
||||||
// scene
|
// scene
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
|
||||||
http_content += "<label for=\"scene\"><strong>Scene</strong></label>";
|
|
||||||
http_content += "<select onchange = \"this.form.submit()\" id=\"scene\" name=\"scene\">";
|
|
||||||
int sc_val = EEPROM.read(EEPROM_SCENE_ADDRESS);
|
int sc_val = EEPROM.read(EEPROM_SCENE_ADDRESS);
|
||||||
http_content += "<option ";
|
if (sc_val == SCENE_RELEAX)
|
||||||
if (sc_val == SCENE_RELEAX) http_content += "selected=\"selected\"";
|
{
|
||||||
http_content += " value=\"0\">Relax</option>";
|
http_content.replace("{{SCENE_SELECTED_RELAX_0}}", "selected=\"selected\"");
|
||||||
http_content += "<option ";
|
} else {
|
||||||
if (sc_val == SCENE_BRIGHT) http_content += "selected=\"selected\"";
|
http_content.replace("{{SCENE_SELECTED_RELAX_0}}", "");
|
||||||
http_content += " value=\"1\">Bright</option>";
|
}
|
||||||
http_content += "<option ";
|
if (sc_val == SCENE_BRIGHT)
|
||||||
if (sc_val == SCENE_NIGHTLY) http_content += "selected=\"selected\"";
|
{
|
||||||
http_content += " value=\"2\">Night</option>";
|
http_content.replace("{{SCENE_SELECTED_BRIGHT_1}}", "selected=\"selected\"");
|
||||||
http_content += "</select>";
|
} else {
|
||||||
http_content += "</div>";
|
http_content.replace("{{SCENE_SELECTED_BRIGHT_1}}", "");
|
||||||
|
}
|
||||||
|
if (sc_val == SCENE_NIGHTLY)
|
||||||
|
{
|
||||||
|
http_content.replace("{{SCENE_SELECTED_NIGHT_2}}", "selected=\"selected\"");
|
||||||
|
} else {
|
||||||
|
http_content.replace("{{SCENE_SELECTED_NIGHT_2}}", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate lights part of the HTML page
|
||||||
|
String config_content = getConfigHTML();
|
||||||
|
|
||||||
// Wifi settings
|
// Wifi settings
|
||||||
http_content += "<br>";
|
config_content.replace("{{WIFI_SSIF}}", WiFi.SSID());
|
||||||
http_content += "<h3>Wifi</h3>";
|
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
|
||||||
http_content += "<label for=\"ip\">SSID</label>";
|
|
||||||
http_content += "<input id=\"ssid\" name=\"ssid\" type=\"text\" value=\"" + WiFi.SSID() + "\">";
|
|
||||||
http_content += "</div>";
|
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
|
||||||
http_content += "<label for=\"wpw\">Passphrase</label>";
|
|
||||||
http_content += "<input id=\"wpw\" name=\"wpw\" type=\"text\" placeholder=\"1234password\">";
|
|
||||||
http_content += "</div>";
|
|
||||||
|
|
||||||
// Network settings
|
// Network settings
|
||||||
uint8_t dip = EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS);
|
uint8_t dip = EEPROM.read(EEPROM_DYNAMIC_IP_ADDRESS);
|
||||||
http_content += "<br>";
|
if (dip)
|
||||||
http_content += "<h3>Network</h3>";
|
{
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
config_content.replace("{{DIP_LINK_ON_PRIMARY}}", "pure-button-primary");
|
||||||
http_content += "<label for=\"dip\"><strong>Dynamic-IP</strong></label>";
|
config_content.replace("{{DIP_LINK_OFF_PRIMARY}}", "");
|
||||||
http_content += "<a class=\"pure-button";
|
} else {
|
||||||
if (dip) http_content += " pure-button-primary";
|
config_content.replace("{{DIP_LINK_OFF_PRIMARY}}", "pure-button-primary");
|
||||||
http_content += "\" href=\"/?dip=true\">ON</a>";
|
config_content.replace("{{DIP_LINK_ON_PRIMARY}}", "");
|
||||||
http_content += "<a class=\"pure-button";
|
|
||||||
if (!dip) http_content += " pure-button-primary";
|
|
||||||
http_content += "\" href=\"/?dip=false\">OFF</a>";
|
|
||||||
http_content += "</div>";
|
|
||||||
|
|
||||||
// ip config
|
|
||||||
if (dip == 0) {
|
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
|
||||||
http_content += "<label for=\"ip\">IP</label>";
|
|
||||||
http_content += "<input id=\"ip\" name=\"ip\" type=\"text\" value=\"" + WiFi.localIP().toString() + "\">";
|
|
||||||
http_content += "</div>";
|
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
|
||||||
http_content += "<label for=\"gwip\">Gateway IP</label>";
|
|
||||||
http_content += "<input id=\"gwip\" name=\"gwip\" type=\"text\" value=\"" + WiFi.gatewayIP().toString() + "\">";
|
|
||||||
http_content += "</div>";
|
|
||||||
http_content += "<div class=\"pure-control-group\">";
|
|
||||||
http_content += "<label for=\"ip\">Netmask</label>";
|
|
||||||
http_content += "<input id=\"netmask\" name=\"netmas\" type=\"text\" value=\"" + WiFi.subnetMask().toString() + "\">";
|
|
||||||
http_content += "</div>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The save button
|
// ip config
|
||||||
http_content += "<div class=\"pure-controls\">";
|
if (dip == 0)
|
||||||
http_content += "<button type=\"submit\" class=\"pure-button pure-button-primary\">Save</button>";
|
{
|
||||||
http_content += "</div>";
|
config_content.replace("{{WIFI_IP}}", WiFi.localIP().toString());
|
||||||
|
config_content.replace("{{WIFI_GW}}", WiFi.gatewayIP().toString());
|
||||||
|
config_content.replace("{{WIFI_NM}}", WiFi.subnetMask().toString());
|
||||||
|
config_content.replace("{{WIFI_DNS}}", WiFi.dnsIP().toString());
|
||||||
|
}
|
||||||
|
|
||||||
http_content += "<script>"
|
http_content.replace("{{CONFIG_PAGE}}", config_content);
|
||||||
"function loadData() {" // load tc data and generate graph
|
|
||||||
"console.log('----> generate graph <----');"
|
|
||||||
"$.getJSON('/tc_data_blocks', 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);"
|
|
||||||
|
|
||||||
// index suche für die vertikale linie
|
// set the pwm values
|
||||||
"var currentTimeStr = currenttime[0] + ':' + (currenttime[1] < 10 ? '0' : '') + currenttime[1];"
|
http_content.replace("{{PWM_MIN}}", (String)PWM_MIN);
|
||||||
"var index = time.indexOf(currentTimeStr);"
|
http_content.replace("{{PWM_MAX}}", (String)PWM_MAX);
|
||||||
"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}`;"
|
|
||||||
//"console.log(dateString);" // 2023-04-28
|
|
||||||
|
|
||||||
"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);"
|
|
||||||
|
|
||||||
// TODO in array dynamisch erzeugt umschreiben
|
|
||||||
"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);" // TODO array der traces dynamisch erzeugen
|
|
||||||
"});"
|
|
||||||
"}"
|
|
||||||
"setInterval(loadData, 10000);"
|
|
||||||
"loadData();"
|
|
||||||
|
|
||||||
"function updateLightState() {" // load the light data from server and set on state and brightness
|
|
||||||
"console.log('----> setting bri and power switch <----');"
|
|
||||||
"for (let i = 1; i <= 4; i++) {"
|
|
||||||
"const lightURL = `http://192.168.0.26/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) {"
|
|
||||||
//"console.log('true');"
|
|
||||||
"onLinkOn.classList.add('pure-button-primary');"
|
|
||||||
"onLinkOff.classList.remove('pure-button-primary');"
|
|
||||||
"} else {"
|
|
||||||
//"console.log('false');"
|
|
||||||
"onLinkOn.classList.remove('pure-button-primary');"
|
|
||||||
"onLinkOff.classList.add('pure-button-primary');"
|
|
||||||
"}"
|
|
||||||
"})"
|
|
||||||
".catch(error => console.error(error));"
|
|
||||||
"}"
|
|
||||||
"}"
|
|
||||||
"setInterval(updateLightState, 10000);"
|
|
||||||
"updateLightState();"
|
|
||||||
|
|
||||||
// show pwm values in webinterface
|
|
||||||
"function updatePWMValues() {"
|
|
||||||
"console.log('----> setting pwm data <----');"
|
|
||||||
"for (let i = 0; i < " + (String)LIGHTS_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://192.168.0.26/state?light=${lightID}`;"
|
|
||||||
"fetch(url)"
|
|
||||||
".then(response => response.json())"
|
|
||||||
".then(data => {"
|
|
||||||
"const pwmValue = ((Math.round((data.curpwm - ((data.curpwm >= " + (String)PWM_MIN+ ") ? " + (String)PWM_MIN + " : 0)) / " + (String)PWM_MAX + " * 10000) / 100).toFixed(2));"// pwm as % PWM_MIN to PWM_MAX
|
|
||||||
"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);"
|
|
||||||
"</script>";
|
|
||||||
|
|
||||||
http_content += "</form>";
|
|
||||||
http_content += "</div>";
|
|
||||||
http_content += "</fieldset>";
|
|
||||||
http_content += "</body>";
|
|
||||||
http_content += "</html>";
|
|
||||||
|
|
||||||
server.send(200, "text/html", http_content);
|
server.send(200, "text/html", http_content);
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,280 @@
|
||||||
|
|
||||||
|
String getIndexHTML()
|
||||||
|
{
|
||||||
|
String index_html = ""
|
||||||
|
"<!doctype html>"
|
||||||
|
"<html>"
|
||||||
|
"<head>"
|
||||||
|
"<style></style>"
|
||||||
|
"<meta charset=\"utf-8\">"
|
||||||
|
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
|
||||||
|
"<title>Light setup</title>"
|
||||||
|
"<script src=\"https://code.jquery.com/jquery-3.6.0.min.js\"></script>"
|
||||||
|
"<script src=\"https://cdn.plot.ly/plotly-latest.min.js\"></script>"
|
||||||
|
"<script src=\"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js\"></script>"
|
||||||
|
"<link rel=\"stylesheet\" href=\"https://unpkg.com/purecss@0.6.2/build/pure-min.css\">"
|
||||||
|
"</head>"
|
||||||
|
"<body>"
|
||||||
|
"<fieldset>"
|
||||||
|
"<h3>{{LIGHT_NAME}}</h3>"
|
||||||
|
"<div class=\"pure-form pure-form-aligned\">"
|
||||||
|
"<div class=\"pure-controls\">"
|
||||||
|
"<span class=\"pure-form-message\">"
|
||||||
|
"<a href=\"/?alert=1\">alert</a>"
|
||||||
|
" "
|
||||||
|
"<a href=\"/?reset=1\">reset</a>"
|
||||||
|
" "
|
||||||
|
"<a href=\"/?resettc\">reset timing control data</a>"
|
||||||
|
" "
|
||||||
|
"<a href=\"/update\">update</a>"
|
||||||
|
"</span>"
|
||||||
|
"<label for=\"cb\" class=\"pure-checkbox\"></label>"
|
||||||
|
"</div>"
|
||||||
|
"<br>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"tc_on\">"
|
||||||
|
"<strong>Timing control</strong>"
|
||||||
|
"</label>"
|
||||||
|
"<a id=\"tc_on\" class=\"pure-button {{TC_LINK_PRIMARY_ON}}\" href=\"#\">ON</a>"
|
||||||
|
"<a id=\"tc_off\" class=\"pure-button {{TC_LINK_PRIMARY_OFF\" href=\"#\">OFF</a>"
|
||||||
|
"</div>"
|
||||||
|
"<script>"
|
||||||
|
"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');"
|
||||||
|
"});"
|
||||||
|
"});"
|
||||||
|
"</script>"
|
||||||
|
"<br>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"transition\">Transition time (s)</label>"
|
||||||
|
"<input id=\"transition\" name=\"transition\" type=\"text\" placeholder=\"10\" value=\"{{TRANSITION_TIME}}\">"
|
||||||
|
"</div>"
|
||||||
|
"<br>"
|
||||||
|
"<script>"
|
||||||
|
"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);"
|
||||||
|
"}"
|
||||||
|
"</script>"
|
||||||
|
"<br>"
|
||||||
|
"<table border=0>"
|
||||||
|
"<tr>"
|
||||||
|
"<td>"
|
||||||
|
"{{LIGHTS_CONTROL}}"
|
||||||
|
""
|
||||||
|
"</td>"
|
||||||
|
"<td>"
|
||||||
|
"<div id=\"plot_chart\"></div>"
|
||||||
|
"</td>"
|
||||||
|
"</tr>"
|
||||||
|
"</table>"
|
||||||
|
"{{CONFIG_PAGE}}"
|
||||||
|
"<script>"
|
||||||
|
"function loadGraphData() {"
|
||||||
|
"console.log('----> generate graph <----');"
|
||||||
|
"$.getJSON('/tc_data_blocks', 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_NUM}}; 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_NUM}}; 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);"
|
||||||
|
"</script>"
|
||||||
|
"</div>"
|
||||||
|
"</fieldset>"
|
||||||
|
"</body>"
|
||||||
|
"</html>";
|
||||||
|
return index_html;
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
|
||||||
|
String getLightControlHTML()
|
||||||
|
{
|
||||||
|
String light_control_html = ""
|
||||||
|
"<h4>Light {{LIGHT_NUMBER}}</h4>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"power\">"
|
||||||
|
"<strong>Power</strong>"
|
||||||
|
"</label>"
|
||||||
|
"<a id=\"on{{LIGHT_NUMBER_DEC}}_on\" class=\"pure-button\" href=\"#\">ON</a>"
|
||||||
|
"<a id=\"on{{LIGHT_NUMBER_DEC}}_off\" class=\"pure-button\" href=\"#\">OFF</a>"
|
||||||
|
"</div>"
|
||||||
|
"<div class=\"pure-control-group\">"
|
||||||
|
"<label for=\"bri{{LIGHT_NUMBER_DEC}}\">Bri</label>"
|
||||||
|
"<input id=\"bri{{LIGHT_NUMBER_DEC}}\" onchange=\"sendSliderValue({{LIGHT_NUMBER}})\" name=\"bri{{LIGHT_NUMBER_DEC}}\" type=\"range\" min=\"0\" max=\"255\" value=\"25\">"
|
||||||
|
" "
|
||||||
|
"<span id=\"bri{{LIGHT_NUMBER_DEC}}_val\" name=\"bri{{LIGHT_NUMBER_DEC}}\">9</span>"
|
||||||
|
"%"
|
||||||
|
"<br>"
|
||||||
|
"<label for=\"light{{LIGHT_NUMBER_DEC}}_pwm\">PWM-Value</label>"
|
||||||
|
"<input type=\"range\" min=\"0\" max=\"100\" value=\"0\" id=\"light{{LIGHT_NUMBER_DEC}}_pwm\" disabled>"
|
||||||
|
" "
|
||||||
|
"<span id=\"light{{LIGHT_NUMBER_DEC}}_pwm_txt\"></span>"
|
||||||
|
"%"
|
||||||
|
"<script>"
|
||||||
|
"var slider{{LIGHT_NUMBER_DEC}} = document.getElementById(\"bri{{LIGHT_NUMBER_DEC}}\");"
|
||||||
|
"var output{{LIGHT_NUMBER_DEC}} = document.getElementById(\"bri{{LIGHT_NUMBER_DEC}}_val\");"
|
||||||
|
"output{{LIGHT_NUMBER_DEC}}.innerHTML = (Math.round((slider{{LIGHT_NUMBER_DEC}}.value * 100.0 / 255.0) * 100) / 100).toFixed(2);"
|
||||||
|
"slider{{LIGHT_NUMBER_DEC}}.oninput = function() {"
|
||||||
|
"output{{LIGHT_NUMBER_DEC}}.innerHTML = (Math.round((this.value * 100.0 / 255.0) * 100) / 100).toFixed(2);"
|
||||||
|
"}"
|
||||||
|
"</script>"
|
||||||
|
"</div>";
|
||||||
|
return light_control_html;
|
||||||
|
}
|
5
tools/html2string.sh
Normal file
5
tools/html2string.sh
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
cat $1 | sed -e"s/^ *//ig" | sed -e 's/"/\\"/ig' | sed -e "s/^/\"/ig" | sed -e "s/$/\"/ig"
|
||||||
|
echo ";"
|
||||||
|
|
Loading…
Reference in a new issue