Dos2unix and power link handling added.

This commit is contained in:
Kai Lauterbach 2023-05-02 14:21:15 +02:00
parent 1fe243fb27
commit 6fd27bea16
9 changed files with 522 additions and 0 deletions

View file

@ -0,0 +1,63 @@
<div id="tab-config" class="">
<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_CFG_IP}}">
</div>
<div class="pure-control-group">
<label for="gwip">Gateway IP</label>
<input id="gwip" name="gwip" type="text" value="{{WIFI_CFG_GW}}">
</div>
<div class="pure-control-group">
<label for="ip">Netmask</label>
<input id="netmask" name="netmas" type="text" value="{{WIFI_CFG_NM}}">
</div>
<div class="pure-control-group">
<label for="ip">DNS</label>
<input id="netmask" name="dns" type="text" value="{{WIFI_CFG_DNS}}">
</div>
<div class="pure-controls">
<button type="submit" class="pure-button pure-button-primary">Save</button>
</div>
</form>
</div><!-- end of config div -->

View file

@ -189,6 +189,44 @@ pwmElementTxt.innerText = pwmValue.toString();
updatePWMValues(); updatePWMValues();
setInterval(updatePWMValues, 5000); setInterval(updatePWMValues, 5000);
</script> </script>
<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://{{IP_ADDRESS}}/?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://{{IP_ADDRESS}}/?on' + id + '=true', true);
// Sende die Anfrage im Hintergrund
xhr.send();
updateLightState();
});
});
</script>
</div> </div>
</fieldset> </fieldset>
</body> </body>

View file

@ -0,0 +1,233 @@
<!-- bottom -->
<script>
var tabMain = document.getElementById("tab-main");
var tabConfig = document.getElementById("tab-config");
var amain = document.getElementById("tab1-a");
var acfg = document.getElementById("tab2-a");
document.getElementById("tab1-a").addEventListener("click", function() {
tabMain.classList.add("visible");
tabConfig.classList.remove("visible");
amain.classList.add("pure-button-primary");
acfg.classList.remove("pure-button-primary");
});
document.getElementById("tab2-a").addEventListener("click", function() {
tabMain.classList.remove("visible");
tabConfig.classList.add("visible");
acfg.classList.add("pure-button-primary");
amain.classList.remove("pure-button-primary");
});
</script>
<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>
<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://{{IP_ADDRESS}}/?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://{{IP_ADDRESS}}/?on' + id + '=true', true);
// Sende die Anfrage im Hintergrund
xhr.send();
updateLightState();
});
});
</script>
</div>
</fieldset>
</body>
</html>

View file

@ -0,0 +1,8 @@
<!-- middle -->
</td>
<td>
<div id="plot_chart"></div>
</td>
</tr>
</table>
</div><!-- end of main-tab div -->

View file

@ -0,0 +1,113 @@
<!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">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#tab-main, #tab-config {
display: none;
}
#tab-main.visible {
display: block;
}
#tab-config.visible {
display: block;
}
</style>
</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>
<a href="#" id="tab1-a" class="pure-button pure-button-primary">Main</a>
<a href="#" id="tab2-a" class="pure-button">Config</a>
</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>
<div id="tab-main" class="visible">
<table border=0>
<tr>
<td>

View file

@ -0,0 +1,29 @@
<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">
&nbsp;
<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>
&nbsp;
<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>

View file

@ -189,6 +189,44 @@
updatePWMValues(); updatePWMValues();
setInterval(updatePWMValues, 5000); setInterval(updatePWMValues, 5000);
</script> </script>
<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://{{IP_ADDRESS}}/?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://{{IP_ADDRESS}}/?on' + id + '=true', true);
// Sende die Anfrage im Hintergrund
xhr.send();
updateLightState();
});
});
</script>
</div> </div>
</fieldset> </fieldset>
</body> </body>

0
tools/html2string.sh Normal file → Executable file
View file

0
tools/html_gen_files.sh Normal file → Executable file
View file