function addTabListener() { console.log("Try to add tab listener"); 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() { console.log("Switch to main lights tab"); 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() { console.log("Switch to config tab"); 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() { 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"); }); } catch (error) { console.log("Error: 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']); var currentTimeStr = currenttime[0] + ':' + (currenttime[1] < 10 ? '0' : '') + currenttime[1]; var index = time.indexOf(currentTimeStr); if (index === -1) { var lowerIndex = -1; var upperIndex = -1; for (var i = 0; i < time.length - 1; i++) { const currentDate = new Date(); const year = currentDate.getFullYear(); const month = (currentDate.getMonth() + 1).toString().padStart(2, '0'); const day = currentDate.getDate().toString().padStart(2, '0'); const dateString = `${year}-${month}-${day}`; const start = moment(dateString + ' ' + time[i], 'YYYY-MM-DD HH:mm'); const curr = moment(dateString + ' ' + currentTimeStr, 'YYYY-MM-DD HH:mm'); const end = moment(dateString + ' ' + time[i + 1], 'YYYY-MM-DD HH:mm'); if (curr.isBetween(start, end)) { lowerIndex = i; upperIndex = i + 1; break; } } if (lowerIndex === -1 || upperIndex === -1) { console.log("Error: Current time not found in time array and not between two elements in time array. Fixing it..."); lowerIndex = 0; upperIndex = 1; var tmp1 = time[0].split(':'); currenttime[0] = tmp1[0]; currenttime[1] = tmp1[1]; } var lowerTime = time[lowerIndex].split(":"); var upperTime = time[upperIndex].split(":"); var timeDiff = (currenttime[0] - lowerTime[0]) + ((currenttime[1] - lowerTime[1]) / 60); var indexFloat = lowerIndex + timeDiff / ((upperTime[0] - lowerTime[0]) + ((upperTime[1] - lowerTime[1]) / 60)); } else { } if (indexFloat > index) { index = indexFloat; } var trace1 = { x: time, y: channel1, name: 'Channel 1', type: 'scatter', mode: 'lines+markers', }; var trace2 = { x: time, y: channel2, name: 'Channel 2', type: 'scatter', mode: 'lines+markers', }; var trace3 = { x: time, y: channel3, name: 'Channel 3', type: 'scatter', mode: 'lines+markers', }; var trace4 = { x: time, y: channel4, name: 'Channel 4', type: 'scatter', mode: 'lines+markers', }; var layout = { title: 'Timing Control Data Blocks', xaxis: { title: 'Time', tickangle: -45, }, yaxis: { title: 'Brightness', range: [0, 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); 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)); 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 = "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 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.classList.add("pure-form"); container.appendChild(table); container.appendChild(button); }