From 38e9ec8f325b8d4bc4c0033c7db3e3b659491392 Mon Sep 17 00:00:00 2001 From: Mario Mariete <11509521+melkati@users.noreply.github.com> Date: Mon, 10 Jun 2024 11:22:49 +0200 Subject: [PATCH] Fixes to merge #228 --- CO2_Gadget.ino | 17 ++++---- CO2_Gadget_EINK.h | 8 ++++ CO2_Gadget_Menu.h | 49 ++++++++++------------- CO2_Gadget_TFT.h | 12 +++++- CO2_Gadget_WIFI.h | 20 ++++++---- webserver/preferences.html | 13 ++++--- webserver/preferences.js | 80 ++++++++++++++++++++------------------ 7 files changed, 111 insertions(+), 88 deletions(-) diff --git a/CO2_Gadget.ino b/CO2_Gadget.ino index ad486eaa..0c6b92a1 100644 --- a/CO2_Gadget.ino +++ b/CO2_Gadget.ino @@ -131,16 +131,17 @@ bool menuInitialized = false; uint16_t DisplayBrightness = 100; bool displayReverse = false; bool showFahrenheit = false; -bool displayShowTemperature = true; -bool displayShowHumidity = true; -bool displayShowBattery = true; -bool displayShowBatteryVoltage = false; -bool displayShowCO2 = true; -bool displayShowPM25 = true; +volatile bool displayShowTemperature = true; +volatile bool displayShowHumidity = true; +volatile bool displayShowBattery = true; +volatile bool displayShowBatteryVoltage = false; +volatile bool displayShowCO2 = true; +volatile bool displayShowPM25 = true; bool debugSensors = false; bool inMenu = false; -bool shouldWakeUpDisplay = false; -bool shouldRedrawDisplay = false; +volatile bool shouldWakeUpDisplay = false; +volatile bool shouldRedrawDisplay = false; +volatile bool redrawDisplayOnNextLoop = false; bool isMenuDirty = false; // To know if we need to redraw the menu uint16_t measurementInterval = 10; uint16_t sampleInterval = 60; diff --git a/CO2_Gadget_EINK.h b/CO2_Gadget_EINK.h index 77e23a66..6e67493c 100644 --- a/CO2_Gadget_EINK.h +++ b/CO2_Gadget_EINK.h @@ -683,6 +683,10 @@ void testRedrawValues(bool randomNumbers = false) { void displayShowValues(bool forceRedraw = false) { static uint32_t lastDisplayUpdate = 0; if (isDownloadingBLE) return; // Do not update display while downloading BLE data to MyAmbiance + if (redrawDisplayOnNextLoop) { + shouldRedrawDisplay = true; + redrawDisplayOnNextLoop = false; + } if (shouldRedrawDisplay) { forceRedraw = true; shouldRedrawDisplay = false; @@ -743,6 +747,10 @@ void displayShowValues(bool forceRedraw = false) { void displayShowValues(bool forceRedraw = false) { static uint32_t lastDisplayUpdate = 0; if (isDownloadingBLE) return; // Do not update display while downloading BLE data to MyAmbiance + if (redrawDisplayOnNextLoop) { + shouldRedrawDisplay = true; + redrawDisplayOnNextLoop = false; + } if (shouldRedrawDisplay) { forceRedraw = true; shouldRedrawDisplay = false; diff --git a/CO2_Gadget_Menu.h b/CO2_Gadget_Menu.h index 11e3a034..f0ad4f74 100644 --- a/CO2_Gadget_Menu.h +++ b/CO2_Gadget_Menu.h @@ -631,7 +631,6 @@ MENU(temperatureConfigMenu, "Temp Config", doNothing, noEvent, wrapStyle TOGGLE(displayOffOnExternalPower, activeDisplayOffMenuOnBattery, "Off on USB: ", doNothing,noEvent, wrapStyle ,VALUE("ON", true, doNothing, noEvent) ,VALUE("OFF", false, doNothing, noEvent)); - result doDisplayReverse(eventMask e, navNode &nav, prompt &item) { #ifdef DEBUG_ARDUINOMENU @@ -664,29 +663,28 @@ result doDisplayReverse(eventMask e, navNode &nav, prompt &item) { } TOGGLE(displayReverse, activeDisplayReverse, "Orient: ", doNothing, noEvent, wrapStyle - ,VALUE("Normal", false, doDisplayReverse, enterEvent) - ,VALUE("Reversed", true, doDisplayReverse, enterEvent)); - + ,VALUE("Normal", false, doDisplayReverse, enterEvent) + ,VALUE("Reversed", true, doDisplayReverse, enterEvent)); TOGGLE(displayShowTemperature, activeDisplayShowTemperature, "Temp: ", doNothing, noEvent, wrapStyle - ,VALUE("Hide", false, doDisplayReverse, enterEvent) - ,VALUE("Show", true, doDisplayReverse, enterEvent)); + ,VALUE("Hide", false, doNothing, enterEvent) + ,VALUE("Show", true, doNothing, enterEvent)); TOGGLE(displayShowHumidity, activeDisplayShowHumidity, "Humidity: ", doNothing, noEvent, wrapStyle - ,VALUE("Hide", false, doDisplayReverse, enterEvent) - ,VALUE("Show", true, doDisplayReverse, enterEvent)); + ,VALUE("Hide", false, doNothing, enterEvent) + ,VALUE("Show", true, doNothing, enterEvent)); TOGGLE(displayShowBattery, activeDisplayShowBattery, "Battery: ", doNothing, noEvent, wrapStyle - ,VALUE("Hide", false, doDisplayReverse, enterEvent) - ,VALUE("Show", true, doDisplayReverse, enterEvent)); + ,VALUE("Hide", false, doNothing, enterEvent) + ,VALUE("Show", true, doNothing, enterEvent)); TOGGLE(displayShowCO2, activeDisplayShowCO2, "CO2: ", doNothing, noEvent, wrapStyle - ,VALUE("Hide", false, doDisplayReverse, enterEvent) - ,VALUE("Show", true, doDisplayReverse, enterEvent)); + ,VALUE("Hide", false, doNothing, enterEvent) + ,VALUE("Show", true, doNothing, enterEvent)); TOGGLE(displayShowPM25, activeDisplayShowPM25, "PM2.5: ", doNothing, noEvent, wrapStyle - ,VALUE("Hide", false, doDisplayReverse, enterEvent) - ,VALUE("Show", true, doDisplayReverse, enterEvent)); + ,VALUE("Hide", false, doNothing, enterEvent) + ,VALUE("Show", true, doNothing, enterEvent)); MENU(displayConfigMenu, "Display Config", doNothing, noEvent, wrapStyle #ifdef ARDUINO_LILYGO_T_DISPLAY_S3 @@ -1183,11 +1181,14 @@ bool menuEntryCharacterReceived() { } void menuLoop() { +#ifdef DEBUG_ARDUINOMENU + if (shouldRedrawDisplay) Serial.println("-->[MENU] Entering menu loop with shouldRedrawDisplay: " + String(shouldRedrawDisplay) + " and redrawDisplayOnNextLoop: " + String(redrawDisplayOnNextLoop)); +#endif if (isDownloadingBLE) return; // Do not run the menu if downloading BLE if ((inMenu) && isMenuDirty) { -#ifdef DEBUG_ARDUINOMENU - Serial.println("-->[MENU] Menu is dirty. Restarting menu..."); +#ifdef DEBUG_ARDUINOMENU + Serial.println("-->[MENU] Menu is dirty. Restarting menu..."); #endif isMenuDirty = false; mainMenu.dirty = true; @@ -1212,6 +1213,9 @@ void menuLoop() { if (!menuInitialized) { #if defined(SUPPORT_TFT) || defined(SUPPORT_OLED) || defined(SUPPORT_EINK) +#ifdef DEBUG_ARDUINOMENU + if (shouldRedrawDisplay) Serial.println("-->[MENU] Displaying values while waiting for Improv-WiFi to start with shouldRedrawDisplay: " + String(shouldRedrawDisplay) + " and redrawDisplayOnNextLoop: " + String(redrawDisplayOnNextLoop)); +#endif displayShowValues(shouldRedrawDisplay); #endif shouldRedrawDisplay = false; @@ -1235,22 +1239,11 @@ void menuLoop() { #ifdef DEBUG_ARDUINOMENU static unsigned long lastPrintTime = 0; if (millis() - lastPrintTime >= 1000) { - Serial.println("-->[MENU] menuLoop"); + Serial.println("-->[MENU] menuLoop. shouldRedrawDisplay: " + String(shouldRedrawDisplay) + " and redrawDisplayOnNextLoop: " + String(redrawDisplayOnNextLoop)); lastPrintTime = millis(); } #endif -#ifdef CONFIG_IDF_TARGET_ESP32S3 - // Workaround: Try to avoid Serial TX buffer full if it's not connected to a receiving device. Looks like the issue is just with ESP32 S3 -/* if ((Serial.availableForWrite() < 100) || (!workingOnExternalPower)) { - Serial.println("[MENU] Serial TX buffer full or not connected to a receiving device. Restarting Serial..."); - Serial.end(); - delay(10); - Serial.begin(115200); - } - */ -#endif - if (activeWIFI) { activeMQTTMenu[0].enable(); } else { diff --git a/CO2_Gadget_TFT.h b/CO2_Gadget_TFT.h index c90a567f..1a004a64 100644 --- a/CO2_Gadget_TFT.h +++ b/CO2_Gadget_TFT.h @@ -651,11 +651,18 @@ void showCO2units(int32_t posX, int32_t posY, bool forceRedraw) { void displayShowValues(bool forceRedraw = false) { uint8_t currentDatum = tft.getTextDatum(); + if (redrawDisplayOnNextLoop) { + shouldRedrawDisplay = true; + redrawDisplayOnNextLoop = false; + } + if (shouldRedrawDisplay) { + forceRedraw = true; + Serial.println("-->[TFT ] Forcing display redraw"); + } tft.unloadFont(); if (forceRedraw) { - // Serial.println("-->[TFT ] Displaying values. Force Redraw: " + String(forceRedraw ? "true" : "false")); + Serial.println("-->[TFT ] Displaying values. Force Redraw: " + String(forceRedraw ? "true" : "false")); tft.fillScreen(TFT_BLACK); // Remove previous remains in the screen - spr.fillSprite(TFT_BLACK); // Remove previous remains in the screen } showCO2(co2, elementPosition.co2X, elementPosition.co2Y, elementPosition.pixelsToBaseline, forceRedraw); showCO2units(elementPosition.co2UnitsX, elementPosition.co2UnitsY, forceRedraw); @@ -668,6 +675,7 @@ void displayShowValues(bool forceRedraw = false) { showBLEIcon(elementPosition.bleIconX, elementPosition.bleIconY, forceRedraw); showEspNowIcon(elementPosition.espNowIconX, elementPosition.espNowIconY, forceRedraw); forceRedraw = false; + shouldRedrawDisplay = false; // Revert the datum setting tft.loadFont(SMALL_FONT); diff --git a/CO2_Gadget_WIFI.h b/CO2_Gadget_WIFI.h index e9542e76..dce75030 100644 --- a/CO2_Gadget_WIFI.h +++ b/CO2_Gadget_WIFI.h @@ -1190,7 +1190,7 @@ void initWebServer() { }; // /settings?ToggleDisplayReverse if (request->hasParam("ToggleDisplayReverse")) { - Serial.println("-->[DISP] Toggle display reverse"); + Serial.println("-->[WEBS] Toggle display reverse"); displayReverse = !displayReverse; #if defined(SUPPORT_TFT) || defined(SUPPORT_OLED) || defined(SUPPORT_EINK) setDisplayReverse(displayReverse); @@ -1203,23 +1203,29 @@ void initWebServer() { }; // /settings?setDisplayBrightness if (request->hasParam("setDisplayBrightness")) { +#if defined(SUPPORT_OLED) || defined(SUPPORT_TFT) inputString = request->getParam("setDisplayBrightness")->value(); - Serial.println("-->[DISP] Set display brightness"); + Serial.println("-->[WEBS] Set display brightness"); DisplayBrightness = inputString.toInt(); setDisplayBrightness(DisplayBrightness); if (inMenu) isMenuDirty = true; +#else + Serial.println("-->[WEBS] Display brightness not supported"); +#endif request->send(200, "text/plain", "OK. Set Display brightness"); }; // /settings?showTemp=${inputShowTemp}&showHumidity=${inputShowHumidity}&showBattery=${inputShowBattery} - if (request->hasParam("showTemp")) { + if (request->hasParam("showTemp") || request->hasParam("showHumidity") || request->hasParam("showBattery")) { displayShowTemperature = (request->getParam("showTemp")->value() == "true" || request->getParam("showTemp")->value() == "1"); displayShowHumidity = (request->getParam("showHumidity")->value() == "true" || request->getParam("showHumidity")->value() == "1"); displayShowBattery = (request->getParam("showBattery")->value() == "true" || request->getParam("showBattery")->value() == "1"); - Serial.println("-->[DISP] showTemp(" + request->getParam("showTemp")->value() + ") - showHumidity(" + request->getParam("showHumidity")->value() + ") - showBAttery(" + request->getParam("showBattery")->value() + ") in display"); - if (!inMenu) shouldRedrawDisplay = true; - request->send(200, "text/plain", "OK. show/hide Temp/Humidity/Battery in display"); + Serial.println("-->[WEBS] showTemp(" + request->getParam("showTemp")->value() + ") - showHumidity(" + request->getParam("showHumidity")->value() + ") - showBAttery(" + request->getParam("showBattery")->value() + ") in display"); + if (!inMenu) { + Serial.println("-->[WEBS] Set shouldRedrawDisplay to true"); + redrawDisplayOnNextLoop = true; + } + request->send(200, "text/plain", "OK. Showing/hidding Temp/Humidity/Battery in display"); }; - // /settings?displayShowBatteryVoltage=true if (request->hasParam("displayShowBatteryVoltage")) { String inputString = request->getParam("displayShowBatteryVoltage")->value(); diff --git a/webserver/preferences.html b/webserver/preferences.html index 34387be3..d5f38c5f 100644 --- a/webserver/preferences.html +++ b/webserver/preferences.html @@ -340,14 +340,14 @@

CO2 Gadget Preferences

- + ℹ️ CO2 level to be considered "warning".
- + ℹ️ CO2 level to be considered "danger".
@@ -510,21 +510,21 @@

CO2 Gadget Preferences

- ℹ️ Show temperature readings on the display.
- ℹ️ Show humidity readings on the display.
- ℹ️ Show battery level on the display.
@@ -559,7 +559,8 @@

CO2 Gadget Preferences

- + ℹ️ Set the display brightness. Lower values will decrease the brightness of the display.
diff --git a/webserver/preferences.js b/webserver/preferences.js index 8d18fd55..13e7535f 100644 --- a/webserver/preferences.js +++ b/webserver/preferences.js @@ -28,7 +28,7 @@ function fetchVersion() { const tooltipText = document.querySelector('.tooltip-text'); let currentText = tooltipText.textContent; currentText += ' Valid brightness values: ' + min + ' to ' + max + '.'; - tooltipText.textContent = currentText; + tooltipText.textContent = currentText; } // TO-DO: Change to use getFeaturesAsJson endpoint to check for "EINK" instead of firmFlavour to reduce complexity @@ -51,7 +51,7 @@ function populateFormWithPreferences(preferences) { if (preferencesDebug) console.log(`Setting relaxedSecurity field to:`, preferences.relaxedSecurity); // If forcedRelaxedSecurity is set because the current URL does contains the "relaxedSecurity" parameter, do not overide the value with the one from the server if (!forcedRelaxedSecurity) { - relaxedSecurity = preferences.relaxedSecurity; + relaxedSecurity = preferences.relaxedSecurity; } } @@ -598,44 +598,14 @@ function handleCalibrationWizard() { }); } -document.addEventListener("DOMContentLoaded", () => { - // Get the current URL - var currentURL = window.location.href; - - // Check if the current URL contains "preferences.html" - if (currentURL.includes("preferences.html")) { - highlightCurrentPage(); // Highlight the current page in the navigation bar - forcedRelaxedSecurity = currentURL.includes("relaxedSecurity"); - relaxedSecurity = forcedRelaxedSecurity; - forceCaptivePortalActive = currentURL.includes("forceCaptivePortalActive"); - handlePasswordFields(); - setTimeout(() => { loadPreferencesFromServer(); }, 50); // Delay of 100ms - setTimeout(() => { fetchVersion(); }, 100); // Delay of 100ms - toggleVisibility('activeWIFI', 'wifiNetworks', (isChecked) => { - document.getElementById('mqttConfig').style.display = isChecked ? 'block' : 'none'; - }); - toggleVisibility('activeMQTT', 'mqttConfig'); - toggleVisibility('activeESPNOW', 'espNowConfig'); - toggleVisibility('useStaticIP', 'staticIPSettings'); - handleWiFiMQTTDependency(); - setTimeout(() => { handleCalibrationWizard(); }, 200); // Delay of 500ms - - // Update the battery voltage every second - setInterval(updateVoltage, 1000); - - // Listen for input events on the voltage reference field with a delay of 100ms - document.getElementById('vRef').addEventListener('input', () => { - setTimeout(updateVRef, 100); - }); - } -}); - /** * Sanity Data form before Save */ -function sanityData() { +function sanityCheckData() { var txt_error = ""; let errorMessage = document.getElementById('error-message'); + + // Sanyty check for display brightness const inputDisplayBrightness = document.getElementById("DisplayBright"); if (parseInt(inputDisplayBrightness.value) > parseInt(inputDisplayBrightness.max) || parseInt(inputDisplayBrightness.value) < parseInt(inputDisplayBrightness.min)) { inputDisplayBrightness.classList.remove('valid'); @@ -659,6 +629,7 @@ function sanityData() { inputDisplayBrightness.classList.add('valid'); } + // Sanyty check for CO2 Orange and Red Range const inputco2OrangeRange = document.getElementById("co2OrangeRange"); const inputco2RedRange = document.getElementById("co2RedRange"); if (parseInt(inputco2OrangeRange.value) > parseInt(inputco2RedRange.value)) { @@ -685,6 +656,7 @@ function sanityData() { } return true; } + /** * Runtime display reverse */ @@ -697,6 +669,7 @@ function toggleDisplayReverse() { }) .catch(error => console.error('Error Toggling Display Reverse:', error)); } + /** * Runtime display brightness */ @@ -710,6 +683,7 @@ function setDisplayBrightness() { }) .catch(error => console.error('Error Setting Display brightness:', error)); } + /** * Runtime show/hide Temp/Humidity/Battery in display */ @@ -717,11 +691,43 @@ function showTempHumBatt() { const inputShowTemp = document.getElementById("showTemp").checked; const inputShowHumidity = document.getElementById("showHumidity").checked; const inputShowBattery = document.getElementById("showBattery").checked; - if (preferencesDebug) console.log("show/hide Temp/Humidity/BAttery in display"); + if (preferencesDebug) console.log("Show/hide Temp/Humidity/Battery in display"); fetch(`/settings?showTemp=${inputShowTemp}&showHumidity=${inputShowHumidity}&showBattery=${inputShowBattery}`) .then(response => { if (!response.ok) throw new Error('Error setting show/hide Temp/Humidity/Battery in display'); if (preferencesDebug) console.log('Set show/hide Temp/Humidity/Battery in display successfully'); }) .catch(error => console.error('Error show/hide Temp/Humidity/Battery in display', error)); -} \ No newline at end of file +} + +document.addEventListener("DOMContentLoaded", () => { + // Get the current URL + var currentURL = window.location.href; + + // Check if the current URL contains "preferences.html" + if (currentURL.includes("preferences.html")) { + highlightCurrentPage(); // Highlight the current page in the navigation bar + forcedRelaxedSecurity = currentURL.includes("relaxedSecurity"); + relaxedSecurity = forcedRelaxedSecurity; + forceCaptivePortalActive = currentURL.includes("forceCaptivePortalActive"); + handlePasswordFields(); + setTimeout(() => { loadPreferencesFromServer(); }, 50); // Delay of 100ms + setTimeout(() => { fetchVersion(); }, 100); // Delay of 100ms + toggleVisibility('activeWIFI', 'wifiNetworks', (isChecked) => { + document.getElementById('mqttConfig').style.display = isChecked ? 'block' : 'none'; + }); + toggleVisibility('activeMQTT', 'mqttConfig'); + toggleVisibility('activeESPNOW', 'espNowConfig'); + toggleVisibility('useStaticIP', 'staticIPSettings'); + handleWiFiMQTTDependency(); + setTimeout(() => { handleCalibrationWizard(); }, 200); // Delay of 500ms + + // Update the battery voltage every second + setInterval(updateVoltage, 1000); + + // Listen for input events on the voltage reference field with a delay of 100ms + document.getElementById('vRef').addEventListener('input', () => { + setTimeout(updateVRef, 100); + }); + } +}); \ No newline at end of file