diff --git a/data/web/app.js b/data/web/app.js index 1997d9cf..80777e2b 100644 --- a/data/web/app.js +++ b/data/web/app.js @@ -553,6 +553,13 @@ function validateSettings() { { id: 'tempCircThreshold', name: 'Circ. Temp Threshold', min: 0, max: 40, type: 'float' }, { id: 'tempCircFactor', name: 'Circ. Temp Factor', min: 0, max: 120, type: 'int' }, { id: 'tempCircMaxRuntime', name: 'Circ. Max Runtime', min: 60, max: 1440, type: 'int' }, + { id: 'btn1Min', name: 'Button 1 Min ADC', min: 0, max: 4095, type: 'int' }, + { id: 'btn1Max', name: 'Button 1 Max ADC', min: 0, max: 4095, type: 'int' }, + { id: 'btn2Min', name: 'Button 2 Min ADC', min: 0, max: 4095, type: 'int' }, + { id: 'btn2Max', name: 'Button 2 Max ADC', min: 0, max: 4095, type: 'int' }, + { id: 'btn3Min', name: 'Button 3 Min ADC', min: 0, max: 4095, type: 'int' }, + { id: 'btn3Max', name: 'Button 3 Max ADC', min: 0, max: 4095, type: 'int' }, + { id: 'btnNoPress', name: 'No-Press Threshold', min: 0, max: 4096, type: 'int' }, ]; for (const f of fields) { const el = document.getElementById(f.id); @@ -572,6 +579,25 @@ function validateSettings() { return false; } } + // Button ADC thresholds must form coherent, non-overlapping ranges + const btnVal = (id) => parseInt(document.getElementById(id).value, 10); + const b1Min = btnVal('btn1Min'), b1Max = btnVal('btn1Max'); + const b2Min = btnVal('btn2Min'), b2Max = btnVal('btn2Max'); + const b3Min = btnVal('btn3Min'), b3Max = btnVal('btn3Max'); + if (b1Min >= b1Max || b2Min >= b2Max || b3Min >= b3Max) { + alert('Each button Min must be less than its Max.'); + return false; + } + if (b1Max > b2Min || b2Max > b3Min) { + alert('Button ADC ranges must not overlap.'); + return false; + } + // No-press threshold must sit above every button range, otherwise + // detectButton() checks THRESH_NO_PRESS first and masks those readings as NONE. + if (btnVal('btnNoPress') <= b3Max) { + alert('No-Press Threshold must be above all button ranges.'); + return false; + } return true; } @@ -589,6 +615,13 @@ async function saveControllerSettings() { const circFactor = document.getElementById('tempCircFactor').value; const circMaxRuntime = document.getElementById('tempCircMaxRuntime').value; const tz = document.getElementById('timezone').value; + const btn1Min = document.getElementById('btn1Min').value; + const btn1Max = document.getElementById('btn1Max').value; + const btn2Min = document.getElementById('btn2Min').value; + const btn2Max = document.getElementById('btn2Max').value; + const btn3Min = document.getElementById('btn3Min').value; + const btn3Max = document.getElementById('btn3Max').value; + const btnNoPress = document.getElementById('btnNoPress').value; // Validate time fields included alongside pool fields const green = parseInt(document.getElementById('timeLossGreen').value, 10); @@ -608,7 +641,7 @@ async function saveControllerSettings() { const res = await fetch('/api/config', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, - body: 'type=settings&mode=' + mode + '&interval=' + interval + '&max_pool=' + maxPool + '&min_solar=' + minSolar + '&hysteresis=' + hysteresis + '&circ_threshold=' + circThreshold + '&circ_factor=' + circFactor + '&circ_max_runtime=' + circMaxRuntime + '&timezone=' + tz + '&green=' + green + '&red=' + red + timerParams() + '&ntp_server=' + ntpServer + body: 'type=settings&mode=' + mode + '&interval=' + interval + '&max_pool=' + maxPool + '&min_solar=' + minSolar + '&hysteresis=' + hysteresis + '&circ_threshold=' + circThreshold + '&circ_factor=' + circFactor + '&circ_max_runtime=' + circMaxRuntime + '&timezone=' + tz + '&green=' + green + '&red=' + red + timerParams() + '&ntp_server=' + ntpServer + '&btn1_min=' + btn1Min + '&btn1_max=' + btn1Max + '&btn2_min=' + btn2Min + '&btn2_max=' + btn2Max + '&btn3_min=' + btn3Min + '&btn3_max=' + btn3Max + '&btn_no_press=' + btnNoPress }); if (res.status === 200) { document.getElementById('poolThreshold').textContent = 'max ' + parseFloat(maxPool).toFixed(1) + 'ยฐC'; @@ -729,6 +762,13 @@ async function loadConfig() { document.getElementById('ntpServer').value = data.ntp.server; document.getElementById('timeLossGreen').value = data.settings.time_loss_green_hours; document.getElementById('timeLossRed').value = data.settings.time_loss_red_hours; + document.getElementById('btn1Min').value = data.settings.btn1_min; + document.getElementById('btn1Max').value = data.settings.btn1_max; + document.getElementById('btn2Min').value = data.settings.btn2_min; + document.getElementById('btn2Max').value = data.settings.btn2_max; + document.getElementById('btn3Min').value = data.settings.btn3_min; + document.getElementById('btn3Max').value = data.settings.btn3_max; + document.getElementById('btnNoPress').value = data.settings.btn_no_press; const pad2 = (n) => n.toString().padStart(2, '0'); document.getElementById('timerStart').value = pad2(data.settings.timer_start_hour) + ':' + pad2(data.settings.timer_start_min); document.getElementById('timerEnd').value = pad2(data.settings.timer_end_hour) + ':' + pad2(data.settings.timer_end_min); diff --git a/data/web/index.html b/data/web/index.html index 09cccd07..2e2d309e 100644 --- a/data/web/index.html +++ b/data/web/index.html @@ -307,6 +307,54 @@