mirror of
https://github.com/ruvnet/RuView.git
synced 2026-10-18 21:00:22 -05:00
Follow-up to the review on #1797. The CRITICAL -> THROTTLED edge was unconditional: any reading below critical_c dropped the state immediately, so a node sitting on the critical boundary flapped between TXP_MIN and TXP_STEP2 indefinitely. Every oscillation moves that node's RSSI at both ends, which a reader cannot distinguish from an obstruction -- exactly the failure the hysteresis on the other edges was added to prevent. Now every falling edge requires cooling a full hysteresis band below the threshold it crossed on the way up; rising edges stay immediate, because heat is a reason to act now. Verified by dithering across the boundary: six readings either side of 80 C previously produced five state changes, now zero. The decision moved into thermal.h as a pure function, following the convention edge_processing.h already uses for edge_evidence_person_count -- a host test then exercises the exact function the device build runs rather than a copy free to drift. BEHAVIOUR CHANGE worth calling out, beyond what the review asked for. The old `recover` point was a single global threshold (throttle_c - hyst) that every state fell back through, so leaving WARN required cooling to 64 C -- a bound derived from the throttle threshold, not WARN's own. Hysteresis is now relative to each state's own entry point, so WARN releases at 57 C instead. Leaving THROTTLED is unchanged at 64 C. Kconfig help updated, since it described the old throttle-relative semantics. One consequence the test pins explicitly: with the default constants the critical exit point (80 - 8 = 72) coincides exactly with the throttle threshold, so a node cool enough to leave CRITICAL is already below THROTTLED's entry and lands in WARN. THROTTLED is unreachable descending from CRITICAL at hysteresis 8. That falls out of the chosen constants rather than the logic, and the test covers hysteresis 4 as well to show the intermediate step reappears when the bands do not coincide. My first version of the test asserted THROTTLED there and was simply wrong -- running it caught that. Verified in espressif/idf:v5.4: against the unfixed transition the test fails five checks including the dither, passes with the fix, and the C6 firmware builds. Still no hardware evidence for this PR -- a real boot log is coming before merge, as promised earlier in the thread. Co-Authored-By: claude-flow <ruv@ruv.net>