Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 34 additions & 28 deletions Integrations/ESPHome/Core.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
substitutions:
version: "26.7.9.1"
version: "26.7.14.1"
device_description: ${name} made by Apollo Automation - version ${version}.
# Default OTA password. Override in your device YAML by re-declaring
# `substitutions: { ota_password: !secret <name>_ota_password }` so each
Expand Down Expand Up @@ -401,22 +401,24 @@ sensor:
id: sys_esp_temperature
filters:
- lambda: |-
static float last_reported_value = 0.0;
static float last_reported_value = NAN;
static uint32_t last_report_time = 0;
float current_value = x;

// Check if the reduce_db_reporting switch is on
// Reduce DB Reporting: report on a meaningful change, but at least hourly so the sensor never looks frozen
if (id(reduce_db_reporting).state) {
// Apply delta filter: only report if the value has changed by 2 or more
if (abs(current_value - last_reported_value) >= 5.0) {
last_reported_value = current_value; // Update the last reported value
uint32_t now = millis();
if (isnan(last_reported_value) ||
abs(current_value - last_reported_value) >= 5.0 ||
(now - last_report_time) >= 3600000UL) {
Comment on lines +411 to +413

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Handle NAN values gracefully to avoid error-hiding and database spam.

The current logic has a significant flaw when the sensor fails and returns NAN:

  1. If the sensor drops offline and starts returning NAN while operating normally, abs(NAN - last) >= threshold evaluates to false. The error is suppressed until the hourly heartbeat fires, hiding the sensor failure from the system for up to an hour.
  2. Once the heartbeat fires, last_reported_value becomes NAN. On subsequent polls, isnan(last_reported_value) stays true, causing EVERY NAN reading to bypass the checks and report immediately. This spams the database with errors, defeating the "Reduce DB Reporting" intent.

To fix this, check explicitly if this is the first publish or if the NAN state has changed (i.e., newly failed or newly recovered) instead of checking only if the last value was NAN.

  • Integrations/ESPHome/Core.yaml#L411-L413: Apply the robust state-change check for ESP Temperature.
  • Integrations/ESPHome/Core.yaml#L629-L631: Apply the robust state-change check for LTR390 Light.
  • Integrations/ESPHome/Core.yaml#L654-L656: Apply the robust state-change check for LTR390 UV.
🛠️ Proposed fix for `sys_esp_temperature` (lines 411-413)
-              if (isnan(last_reported_value) ||
-                  abs(current_value - last_reported_value) >= 5.0 ||
-                  (now - last_report_time) >= 3600000UL) {
+              bool is_first_publish = last_report_time == 0;
+              bool state_changed = isnan(current_value) != isnan(last_reported_value);
+              if (is_first_publish || state_changed ||
+                  abs(current_value - last_reported_value) >= 5.0 ||
+                  (now - last_report_time) >= 3600000UL) {

(Apply the equivalent change with >= 20.0 for the LTR390 sensors at lines 629-631 and 654-656)

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (isnan(last_reported_value) ||
abs(current_value - last_reported_value) >= 5.0 ||
(now - last_report_time) >= 3600000UL) {
bool is_first_publish = last_report_time == 0;
bool state_changed = isnan(current_value) != isnan(last_reported_value);
if (is_first_publish || state_changed ||
abs(current_value - last_reported_value) >= 5.0 ||
(now - last_report_time) >= 3600000UL) {
📍 Affects 1 file
  • Integrations/ESPHome/Core.yaml#L411-L413 (this comment)
  • Integrations/ESPHome/Core.yaml#L629-L631
  • Integrations/ESPHome/Core.yaml#L654-L656
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Integrations/ESPHome/Core.yaml` around lines 411 - 413, Update the reporting
conditions for sys_esp_temperature at Integrations/ESPHome/Core.yaml lines
411-413, LTR390 Light at lines 629-631, and LTR390 UV at lines 654-656 to report
only on the first publish or when the current NAN state differs from the
previous NAN state, while preserving the hourly heartbeat and existing
thresholds (5.0 for temperature, 20.0 for LTR390 sensors); apply the equivalent
state-change logic at all three sites.

last_reported_value = current_value;
last_report_time = now;
return current_value;
} else {
// Return the last reported value without updating if change is less than 2
return {}; // Discard the update
}
return {}; // Within delta and under the hourly heartbeat -> discard
} else {
// If reduce_db_reporting is off, report the current value normally
last_reported_value = current_value;
last_report_time = millis();
return current_value;
}

Expand Down Expand Up @@ -617,45 +619,49 @@ sensor:
id: ltr390light
filters:
- lambda: |-
static float last_reported_value = 0.0;
static float last_reported_value = NAN;
static uint32_t last_report_time = 0;
float current_value = x;

// Check if the reduce_db_reporting switch is on
// Reduce DB Reporting: report on a meaningful change, but at least hourly so the sensor never looks frozen
if (id(reduce_db_reporting).state) {
// Apply delta filter: only report if the value has changed by 2 or more
if (abs(current_value - last_reported_value) >= 20.0) {
last_reported_value = current_value; // Update the last reported value
uint32_t now = millis();
if (isnan(last_reported_value) ||
abs(current_value - last_reported_value) >= 20.0 ||
(now - last_report_time) >= 3600000UL) {
last_reported_value = current_value;
last_report_time = now;
return current_value;
} else {
// Return the last reported value without updating if change is less than 2
return {}; // Discard the update
}
return {}; // Within delta and under the hourly heartbeat -> discard
} else {
// If reduce_db_reporting is off, report the current value normally
last_reported_value = current_value;
last_report_time = millis();
return current_value;
}
uv_index:
name: "LTR390 UV Index"
id: ltr390uvindex
filters:
- lambda: |-
static float last_reported_value = 0.0;
static float last_reported_value = NAN;
static uint32_t last_report_time = 0;
float current_value = x;

// Check if the reduce_db_reporting switch is on
// Reduce DB Reporting: report on a meaningful change, but at least hourly so the sensor never looks frozen
if (id(reduce_db_reporting).state) {
// Apply delta filter: only report if the value has changed by 2 or more
if (abs(current_value - last_reported_value) >= 20.0) {
last_reported_value = current_value; // Update the last reported value
uint32_t now = millis();
if (isnan(last_reported_value) ||
abs(current_value - last_reported_value) >= 20.0 ||
(now - last_report_time) >= 3600000UL) {
last_reported_value = current_value;
last_report_time = now;
return current_value;
} else {
// Return the last reported value without updating if change is less than 2
return {}; // Discard the update
}
return {}; // Within delta and under the hourly heartbeat -> discard
} else {
// If reduce_db_reporting is off, report the current value normally
last_reported_value = current_value;
last_report_time = millis();
return current_value;
}

Expand Down
Loading