refactor: move sun and wind automation into ShadeSensors

The sun and wind timers were spread over processFrame, checkMovement and
processInternalCommand. ShadeSensors now holds them and decides when the
weather extends or retracts a shade, when turning the sun flag on moves
it, and when wind blocks a remote Down. Each caller still sets the targets
itself, so no shade moves differently yet.

The timers are now 32-bit like millis(). As 64-bit values holding a 32-bit
millis() they fired at once after the rollover every 49.7 days. The debug
logs of each timer go: they were compiled out at CORE_DEBUG_LEVEL 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-13 21:12:34 +02:00
parent 0eb0e63631
commit 8276c1c3cd
6 changed files with 319 additions and 129 deletions

77
src/ShadeSensors.cpp Normal file
View file

@ -0,0 +1,77 @@
#include "ShadeSensors.h"
// Whether a timer started at start has run timeoutMs by now. The unsigned
// subtraction keeps working across the millis() rollover.
static bool due(uint32_t start, uint32_t now, uint32_t timeoutMs) {
return start != 0 && now - start >= timeoutMs;
}
void ShadeSensors::clear() { *this = ShadeSensors(); }
void ShadeSensors::onSensorFrame(bool wasSunny, bool wasWindy, bool sunny, bool windy, uint32_t now) {
if(sunny) {
this->noSunStart = 0;
this->noSunDone = true;
}
else {
this->sunStart = 0;
this->sunDone = true;
}
if(windy) {
this->noWindStart = 0;
this->noWindDone = true;
this->windLast = now;
}
else {
this->windStart = 0;
this->windDone = true;
}
if(sunny && !wasSunny) {
this->sunStart = now;
this->sunDone = false;
}
else if(!sunny && wasSunny) {
this->noSunStart = now;
this->noSunDone = false;
}
if(windy && !wasWindy) {
this->windStart = now;
this->windDone = false;
}
else if(!windy && wasWindy) {
this->noWindStart = now;
this->noWindDone = false;
}
}
SensorMove ShadeSensors::check(bool sunFlag, bool sunny, bool windy, uint32_t now) {
SensorMove move = SensorMove::none;
if(sunFlag) {
if(sunny && !windy) {
// Sunny and calm, so the shade should be extended.
if(this->noWindDone && !this->sunDone && due(this->sunStart, now, SOMFY_SUN_TIMEOUT)) {
this->sunDone = true;
move = SensorMove::extend;
}
if(!this->noWindDone && due(this->noWindStart, now, SOMFY_NO_WIND_TIMEOUT)) {
this->noWindDone = true;
move = SensorMove::extend;
}
}
if(!sunny && !this->noSunDone && due(this->noSunStart, now, SOMFY_NO_SUN_TIMEOUT)) {
this->noSunDone = true;
move = SensorMove::retract;
}
}
if(windy && !this->windDone && due(this->windStart, now, SOMFY_WIND_TIMEOUT)) {
this->windDone = true;
move = SensorMove::retract;
}
return move;
}
SensorMove ShadeSensors::onSunFlag(bool sunny, bool windy) const {
if(windy) return SensorMove::none;
if(sunny && this->sunDone) return SensorMove::extend;
if(!sunny && this->noSunDone) return SensorMove::retract;
return SensorMove::none;
}
bool ShadeSensors::windBlocksDown(uint32_t now) const {
return this->windLast != 0 && now - this->windLast < SOMFY_NO_WIND_REMOTE_TIMEOUT;
}