diff --git a/CO2_Gadget_EINK.h b/CO2_Gadget_EINK.h index f8d4da5d..1997c35e 100644 --- a/CO2_Gadget_EINK.h +++ b/CO2_Gadget_EINK.h @@ -642,6 +642,7 @@ void testRedrawValues(bool randomNumbers = false) { #ifdef EINKBOARDGDEM0213B74 void displayShowValues(bool forceRedraw = false) { static uint32_t lastDisplayUpdate = 0; + if (!passMeasurementThresholds(DISPLAY_SHOW)) return; if (isDownloadingBLE) return; // Do not update display while downloading BLE data to MyAmbiance // Return if last update less than 15 seconds ago if (!forceRedraw && (millis() - lastDisplayUpdate < 10000)) { @@ -697,7 +698,8 @@ void displayShowValues(bool forceRedraw = false) { #else // ALL OTHER NOT EINKBOARDGDEM0213B74 BOARDS void displayShowValues(bool forceRedraw = false) { - static uint32_t lastDisplayUpdate = 0; + static uint32_t lastDisplayUpdate = 0; + if (!passMeasurementThresholds(DISPLAY_SHOW)) return; if (isDownloadingBLE) return; // Do not update display while downloading BLE data to MyAmbiance // Return if last update less than 15 seconds ago if (!forceRedraw && (millis() - lastDisplayUpdate < 15000)) { diff --git a/CO2_Gadget_OLED.h b/CO2_Gadget_OLED.h index 2e50ced4..0920f761 100644 --- a/CO2_Gadget_OLED.h +++ b/CO2_Gadget_OLED.h @@ -13,6 +13,7 @@ // clang-format on // #include #include + #include "bootlogo.h" #include "icons.h" U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE); // Frame Buffer: clearBuffer/sendBuffer. More RAM usage, Faster @@ -25,25 +26,29 @@ int displayHeight = 64; #define MENUFONT u8g2_font_5x8_mf void setDisplayBrightness(uint32_t newBrightness) { - Serial.printf("-->[OLED] Setting display brightness value at %d\n", newBrightness); - u8g2.setContrast(newBrightness); - actualDisplayBrightness = newBrightness; + Serial.printf("-->[OLED] Setting display brightness value at %d\n", newBrightness); + u8g2.setContrast(newBrightness); + actualDisplayBrightness = newBrightness; +} + +void displaySleep(bool value = true) { + // u8g2.setPowerSave(number); // Turn off the display } void turnOffDisplay() { - setDisplayBrightness(0); // Turn off the display + setDisplayBrightness(0); // Turn off the display } void displaySplashScreen() { - u8g2.clearDisplay(); - u8g2.firstPage(); - do { - // u8g2.drawXBMP(30, 0, 59, 20, eMarieteLogo); - // u8g2.drawXBM(7, 23, 46, 36, CO2Logo); - // u8g2.drawXBM(60, 32, 61, 23, GadgetLogo); - u8g2.drawXBM(0, 0, 128, 64, splash); - } while (u8g2.nextPage()); - u8g2.setFont(MENUFONT); + u8g2.clearDisplay(); + u8g2.firstPage(); + do { + // u8g2.drawXBMP(30, 0, 59, 20, eMarieteLogo); + // u8g2.drawXBM(7, 23, 46, 36, CO2Logo); + // u8g2.drawXBM(60, 32, 61, 23, GadgetLogo); + u8g2.drawXBM(0, 0, 128, 64, splash); + } while (u8g2.nextPage()); + u8g2.setFont(MENUFONT); } /*************************************************************************************** @@ -54,37 +59,38 @@ void displaySplashScreen() { // notificationText = string to display. // notificationTypes one of enum notificationTypes notifyNothing, notifyInfo, notifyWarning, notifyError bool displayNotification(String notificationText, notificationTypes notificationType) { - uint16_t textColor, boxColor, backgroundColor, boxMarging = 15; - return true; + uint16_t textColor, boxColor, backgroundColor, boxMarging = 15; + return true; } bool displayNotification(String notificationText, String notificationText2, notificationTypes notificationType) { - uint16_t textColor, boxColor, backgroundColor, boxMarging = 15; - return true; + uint16_t textColor, boxColor, backgroundColor, boxMarging = 15; + return true; } -void initDisplay(bool fastMode = false) { // fastMode not used in OLED display. Just for compatibility with TFT and other displays. - Serial.printf("-->[OLED] Initialized: \t#%s#\n", - ((u8g2.begin()) ? "OK" : "Failed")); - u8g2.firstPage(); - do { - u8g2.setFont(u8g2_font_ncenB12_tr); - u8g2.drawStr(0, 15, " eMariete.com"); - u8g2.drawStr(0, 33, " CO2 Gadget"); - u8g2.drawStr(0, 51, " Air Quality"); - } while (u8g2.nextPage()); - u8g2.setFont(MENUFONT); - if (displayReverse) { - u8g2.setDisplayRotation(U8G2_R2); - } else { - u8g2.setDisplayRotation(U8G2_R0); - } - setDisplayBrightness(DisplayBrightness); - displaySplashScreen(); - delay(1000); +void initDisplay(bool fastMode = false) { // fastMode not used in OLED display. Just for compatibility with TFT and other displays. + Serial.printf("-->[OLED] Initialized: \t#%s#\n", + ((u8g2.begin()) ? "OK" : "Failed")); + u8g2.firstPage(); + do { + u8g2.setFont(u8g2_font_ncenB12_tr); + u8g2.drawStr(0, 15, " eMariete.com"); + u8g2.drawStr(0, 33, " CO2 Gadget"); + u8g2.drawStr(0, 51, " Air Quality"); + } while (u8g2.nextPage()); + u8g2.setFont(MENUFONT); + if (displayReverse) { + u8g2.setDisplayRotation(U8G2_R2); + } else { + u8g2.setDisplayRotation(U8G2_R0); + } + setDisplayBrightness(DisplayBrightness); + displaySplashScreen(); + delay(1000); } -void displayShowValues(bool forceRedraw = false) { +void displayShowValues(bool forceRedraw = false) { + if (!passMeasurementThresholds(DISPLAY_SHOW)) return; if ((co2 == 0) || (co2 > 9999)) return; String co2Str = String(co2); if (co2Str.length() < 4) { diff --git a/CO2_Gadget_Sensors.h b/CO2_Gadget_Sensors.h index 551c69ca..7ece213b 100644 --- a/CO2_Gadget_Sensors.h +++ b/CO2_Gadget_Sensors.h @@ -45,7 +45,7 @@ struct SensorConfig { SensorConfig configs[NUM_OUTPUTS] = { // DISPLAY_SHOW { - .enabled = false, + .enabled = true, .co2ThresholdAbsolute = 20, .tempThresholdAbsolute = 0.5f, .humThresholdAbsolute = 1.0f, @@ -101,12 +101,18 @@ void updateLastMeasurementValues(OutputType outputType) { bool checkThresholdsAndMaybeUpdate(OutputType outputType) { const SensorConfig& config = configs[outputType]; if (!config.enabled) return true; + + // Comprobación de división por cero + bool co2DivideByZero = config.previousCO2Value == 0; + bool tempDivideByZero = config.previousTemperatureValue == 0; + bool humDivideByZero = config.previousHumidityValue == 0; + if (abs(co2 - config.previousCO2Value) >= config.co2ThresholdAbsolute || abs(temp - config.previousTemperatureValue) >= config.tempThresholdAbsolute || abs(hum - config.previousHumidityValue) >= config.humThresholdAbsolute || - (config.previousCO2Value != 0 && abs(co2 - config.previousCO2Value) >= config.previousCO2Value * config.co2ThresholdPercentage / 100) || - (config.previousTemperatureValue != 0 && abs(temp - config.previousTemperatureValue) >= config.previousTemperatureValue * config.tempThresholdPercentage / 100) || - (config.previousHumidityValue != 0 && abs(hum - config.previousHumidityValue) >= config.previousHumidityValue * config.humThresholdPercentage / 100)) { + (co2DivideByZero || abs(co2 - config.previousCO2Value) >= config.previousCO2Value * config.co2ThresholdPercentage / 100) || + (tempDivideByZero || abs(temp - config.previousTemperatureValue) >= config.previousTemperatureValue * config.tempThresholdPercentage / 100) || + (humDivideByZero || abs(hum - config.previousHumidityValue) >= config.previousHumidityValue * config.humThresholdPercentage / 100)) { updateLastMeasurementValues(outputType); return true; } @@ -154,8 +160,6 @@ void printSensorsDetected() { void onSensorDataOk() { previousCO2Value = co2; - previousTemperatureValue = temp; - previousHumidityValue = hum; co2 = sensors.getCO2(); hum = sensors.getHumidity(); if (hum == 0.0) hum = sensors.getCO2humi(); diff --git a/CO2_Gadget_TFT.h b/CO2_Gadget_TFT.h index 946ed3b9..91b820d9 100644 --- a/CO2_Gadget_TFT.h +++ b/CO2_Gadget_TFT.h @@ -644,6 +644,7 @@ void showCO2units(int32_t posX, int32_t posY, bool forceRedraw) { } void displayShowValues(bool forceRedraw = false) { + if (!passMeasurementThresholds(DISPLAY_SHOW)) return; uint8_t currentDatum = tft.getTextDatum(); tft.unloadFont(); if (forceRedraw) { diff --git a/CO2_Gadget_WIFI.h b/CO2_Gadget_WIFI.h index 2f407154..076a8e67 100644 --- a/CO2_Gadget_WIFI.h +++ b/CO2_Gadget_WIFI.h @@ -816,6 +816,13 @@ void initWebServer() { request->send(response); }); + server.on("/low_power.html", HTTP_GET, [](AsyncWebServerRequest *request) { + /** GZIPPED CONTENT ***/ + AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/low_power.gz", "text/html"); + response->addHeader("Content-Encoding", "gzip"); + request->send(response); + }); + server.on("/main.js", HTTP_GET, [](AsyncWebServerRequest *request) { /** GZIPPED CONTENT ***/ AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/main.js.gz", "application/javascript"); diff --git a/data/index.html b/data/index.html index 02fb9bf3..1ab1f621 100644 --- a/data/index.html +++ b/data/index.html @@ -19,6 +19,7 @@ Home Preferences Status + Thresholds
diff --git a/data/low_power.html b/data/low_power.html new file mode 100644 index 00000000..90468fdc --- /dev/null +++ b/data/low_power.html @@ -0,0 +1,731 @@ + + + + + + + Formulario con Tabs + + + + + + + +
+

CO2 Gadget Low Power Configuration

+
+ +
+ Low Power Options + +
+ + ℹ️ + Select the power mode to use. + +
+ +
+ + ℹ️ + The time in seconds to wait after start up for the first time before + entering low power mode, it gives you the opportunity to connect to CO2 Gadget.
Every time + you + use the menu or access the web preferences page this time restarts
+ +
+ +
+ + ℹ️ + The time in seconds to be in low power mode in each cycle. + +
+ +
+ + ℹ️ + Every how many cycles the device will connect to WiFi. The web server + will not be available during this time as there is no enough time to handle the request. + +
+ +
+ + ℹ️ + Every how many cycles the display will be redrawn. It applies only when + the display is e-Ink as it takes a lot of time to update. + +
+ +
+ + + ℹ️ + Activate the BLE functionality when the device wakes up. It's very fast + to + send data (few milliseconds). +
+ +
+ + + ℹ️ + Activate the WiFi functionality when the device wakes up. Needed to send + data by MQTT or to the cloud. +
+ +
+ + + ℹ️ + Send data via MQTT when the device wakes up. +
+ +
+ + + ℹ️ + Send data via ESPNow when the device wakes up. It's very fast to send + data (few milliseconds) and more afficient than WiFi. +
+ +
+ + + ℹ️ + Turn on the display for 3 seconds when the device wakes up. Only for TFT + and OLED displays. +
+ +
+ + +
+ Thresholds Options + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+

These are the thresholds for the display when in low power mode.

+
+ Use +
+ + + ℹ️ + The CO2 threshold will never be used. It is disabled. + + + ℹ️ + The CO2 threshold will always be used. + + + ℹ️ + The CO2 threshold will only be used when the device is in low + power mode. +
+ +
+ Thresholds Options for Display +
+
+ + ℹ️ + The absolute value difference of CO2 in ppm that will + trigger + the + threshold. The display will not be updated until the threshold is met. + +
+
+ + ℹ️ + The percentage difference of CO2 in ppm that will trigger + the + threshold. The display will not be updated until the threshold is met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+ +
+ +
+
+ + ℹ️ + The absolute value difference of temperature in °C that + will + trigger the threshold. The display will not be updated until the threshold is + met. + +
+
+ + ℹ️ + The percentage difference of temperature in °C that will + trigger + the threshold. The display will not be updated until the threshold is + met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+
+ +
+
+ + ℹ️ + The absolute value difference of humidity in %rH that + will + trigger + the threshold. The display will not be updated until the threshold is + met. + +
+
+ + ℹ️ + The percentage difference of humidity in %rH that will + trigger + the threshold. The display will not be updated until the threshold is + met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+
+
+
+ +
+

These are the thresholds for the Bluetooth functionality when in low power mode.

+
+ Use +
+ + ℹ️ + The CO2 threshold will never be used. It is disabled. + + + ℹ️ + The CO2 threshold will always be used. + + + ℹ️ + The CO2 threshold will only be used when the device is in low + power mode. + +
+
+
+ Thresholds Options for Bluetooth +
+
+ + ℹ️ + The absolute value difference of CO2 in ppm that will + trigger + the + threshold. The value will not be sent by bluetooth until the threshold is + met. + +
+
+ + ℹ️ + The percentage difference of CO2 in ppm that will trigger + the + threshold. The value will not be sent by bluetooth until the threshold is + met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+
+ +
+
+ + ℹ️ + The absolute value difference of temperature in °C that + will + trigger the threshold. The value will not be sent by bluetooth until the + threshold + is + met. + +
+
+ + ℹ️ + The percentage difference of temperature in °C that will + trigger + the threshold. The value will not be sent by bluetooth until the threshold is + met. + +
+
+ + + + ℹ️ + + + ℹ️ +
+
+ +
+
+ + ℹ️ + The absolute value difference of humidity in %rH that + will + trigger + the threshold. The value will not be sent by bluetooth until the threshold is + met. + +
+
+ + ℹ️ + The percentage difference of humidity in %rH that will + trigger + the threshold. The value will not be sent by bluetooth until the threshold is + met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+
+
+
+ +
+

These are the thresholds for the MQTT functionality when in low power mode.

+
+ Use +
+ + ℹ️ + The CO2 threshold will never be used. It is disabled. + + + ℹ️ + The CO2 threshold will always be used. + + + ℹ️ + The CO2 threshold will only be used when the device is in low + power mode. + +
+
+
+ Thresholds Options for MQTT +
+
+ + ℹ️ + The absolute value difference of CO2 in ppm that will + trigger + the + threshold. The value will not be sent by MQTT until the threshold is met. + +
+
+ + ℹ️ + The percentage difference of CO2 in ppm that will trigger + the + threshold. The value will not be sent by MQTT until the threshold is met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+
+ +
+
+ + ℹ️ + The absolute value difference of temperature in °C that + will + trigger the threshold. The value will not be sent by MQTT until the threshold is + met. + +
+
+ + ℹ️ + The percentage difference of temperature in °C that will + trigger + the threshold. The value will not be sent by MQTT until the threshold is + met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+
+ +
+
+ + ℹ️ + The absolute value difference of humidity in %rH that + will + trigger + the threshold. The value will not be sent by MQTT until the threshold is + met. + +
+
+ + ℹ️ + The percentage difference of humidity in %rH that will + trigger + the threshold. The value will not be sent by MQTT until the threshold is + met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+
+
+
+ + +
+

These are the thresholds for the ESPNOW functionality.

+
+ Use +
+ + ℹ️ + The CO2 threshold will never be used. It is disabled. + + + ℹ️ + The CO2 threshold will always be used. + + + ℹ️ + The CO2 threshold will only be used when the device is in low + power mode. + +
+
+
+ Thresholds Options for ESPNOW +
+
+ + ℹ️ + The absolute value difference of CO2 in ppm that will + trigger + the + threshold. The value will not be sent by ESPNOW until the threshold is + met. + +
+
+ + ℹ️ + The percentage difference of CO2 in ppm that will trigger + the + threshold. The value will not be sent by ESPNOW until the threshold is + met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+
+ +
+
+ + ℹ️ + The absolute value difference of temperature in °C that + will + trigger the threshold. The value will not be sent by ESPNOW until the threshold + is + met. + +
+
+ + ℹ️ + The percentage difference of temperature in °C that will + trigger + the threshold. The value will not be sent by ESPNOW until the threshold is + met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+
+ +
+
+ + ℹ️ + The absolute value difference of humidity in %rH that + will + trigger + the threshold. The value will not be sent by ESPNOW until the threshold is + met. + +
+
+ + ℹ️ + The percentage difference of humidity in %rH that will + trigger + the threshold. The value will not be sent by ESPNOW until the threshold is + met. + +
+
+ + + + ℹ️ + Both conditions must be met to trigger the + threshold. + + + ℹ️ + At least one condition must be met to trigger the + threshold. +
+
+
+ +
+ + +
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/data/preferences.html b/data/preferences.html index 2e379c2f..57fe211b 100644 --- a/data/preferences.html +++ b/data/preferences.html @@ -18,6 +18,7 @@ Home Preferences Status + Thresholds
diff --git a/data/status.html b/data/status.html index e4a163e0..04358169 100644 --- a/data/status.html +++ b/data/status.html @@ -16,6 +16,7 @@ Home Preferences Status + Thresholds
diff --git a/data/style.css b/data/style.css index 6e4acd87..7bb97868 100644 --- a/data/style.css +++ b/data/style.css @@ -343,3 +343,51 @@ button:hover { opacity: 0; } } + +.tab-container { + margin-top: 20px; +} + +.tab { + display: inline-block; + padding: 10px 15px; + border: 1px solid #ccc; + border-radius: 4px 4px 0 0; + background-color: var(--bg-color); + color: var(--font-color); + cursor: pointer; +} + +.tab.active { + background-color: #f4f4f4; +} + +.tab-content { + display: none; + padding: 10px; + border: 1px solid #ccc; + border-top: none; +} + +.tab-content.active { + display: block; +} + +#buttonContainer button { + margin-top: 10px; +} + +#popup { + display: none; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: #333; + color: #fff; + padding: 15px; + border-radius: 5px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); + z-index: 1000; + animation: fadeInOut 2s ease-in-out; +} \ No newline at end of file