lumini_p30_control/firmware/index_html.h
2023-05-02 09:04:21 +02:00

284 lines
8.7 KiB
C

String getIndexHTMLTop()
{
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 - {{LIGHT_NAME}}</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>"
"&nbsp; "
"<a href=\"/?reset=1\">reset</a>"
"&nbsp; "
"<a href=\"/?resettc\">reset timing control data</a>"
"&nbsp; "
"<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>";
return index_html;
}
String getIndexHTMLBottom()
{
const char index_html[] = "<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_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);"
"</script>"
"</div>"
"</fieldset>"
"</body>"
"</html>";
return String(index_html);
}