From 91726e4d6fa3e3acaffd6b75a37a1e9db221ff5a Mon Sep 17 00:00:00 2001 From: Brandon Harvey <8107750+bharvey88@users.noreply.github.com> Date: Wed, 15 Jul 2026 09:44:15 -0500 Subject: [PATCH] Add SEN54/NOX check to AIR-1 factory test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SEN5x component drops the NOX sensor when the chip reports itself as a SEN54, so a mislabeled or wrong-part unit ships with no NOX data and nothing in the factory test catches it. testScript now waits up to 30s for a NOX reading after the DPS310 check and only lights the LED green when NOX reports a value. A unit whose NOX stays NaN flashes red and logs "SEN55 is reporting as SEN54" for the flash station. Bumps version to 26.7.15.1. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- Integrations/ESPHome/Core.yaml | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/Integrations/ESPHome/Core.yaml b/Integrations/ESPHome/Core.yaml index 1250e1d..ab3d82a 100644 --- a/Integrations/ESPHome/Core.yaml +++ b/Integrations/ESPHome/Core.yaml @@ -1,6 +1,6 @@ substitutions: name: apollo-air-1 - version: "26.7.1.1" + version: "26.7.15.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 _ota_password }` so each @@ -71,6 +71,10 @@ globals: restore_value: no type: bool initial_value: "false" + - id: noxPassed + restore_value: no + type: bool + initial_value: "false" i2c: @@ -575,6 +579,7 @@ script: then: - lambda: "id(runTest) = false;" - lambda: "id(testCycleCount) = 0;" + - lambda: "id(noxPassed) = false;" - while: condition: - lambda: "return id(testCycleCount) < 5;" @@ -597,11 +602,33 @@ script: - lambda: "id(runTest) = false;" - delay: 1s - lambda: "id(testCycleCount) += 1;" - + + # SEN54 detection: when the SEN5x chip reports itself as a SEN54 the + # component nulls the NOX sensor, so its state stays NaN forever. A + # healthy SEN55 publishes a NOX index within a couple of update cycles, + # so wait up to 30s for a value before deciding. + - wait_until: + condition: + - lambda: "return !isnan(id(sen55_nox).state);" + timeout: 30s + - if: + condition: + - lambda: "return !isnan(id(sen55_nox).state);" + then: + - lambda: "id(noxPassed) = true;" + - logger.log: + format: "TEST: NOX OK - SEN55 confirmed (nox index %.1f)" + args: ["id(sen55_nox).state"] + level: INFO + else: + - logger.log: + format: "TEST FAIL: NOX unavailable - SEN55 is reporting as SEN54" + level: ERROR + #Check If Test Passed To Trigger Lights - if: condition: - - lambda: "return id(dps310Passed);" + - lambda: "return id(dps310Passed) && id(noxPassed);" then: - lambda: "id(runTest) = false;" - light.turn_on: