mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 13:52:15 +01:00
The three places that act on the sun and wind each set different targets for a tilt-only shade: the sun timer moved its lift, the no-sun and wind timers moved tilt and lift, a group's sun flag moved its lift and only a remote's sun flag moved its tilt. They now share sensorTargets(): a tilt-only shade moves its tilt to the favorite tilt (or fully) and back to 0, and every other shade its lift, as Up and Down already do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
91 lines
2.8 KiB
C++
91 lines
2.8 KiB
C++
#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;
|
|
}
|
|
SensorTargets sensorTargets(SensorMove move, tilt_types tilt, float myPos, float myTiltPos) {
|
|
SensorTargets t;
|
|
if(move == SensorMove::none) return t;
|
|
const bool extend = move == SensorMove::extend;
|
|
if(tilt == tilt_types::tiltonly) {
|
|
t.setTilt = true;
|
|
t.tilt = extend ? (myTiltPos >= 0 ? myTiltPos : 100.0f) : 0.0f;
|
|
}
|
|
else {
|
|
t.setLift = true;
|
|
t.lift = extend ? (myPos >= 0 ? myPos : 100.0f) : 0.0f;
|
|
}
|
|
return t;
|
|
}
|
|
bool ShadeSensors::windBlocksDown(uint32_t now) const {
|
|
return this->windLast != 0 && now - this->windLast < SOMFY_NO_WIND_REMOTE_TIMEOUT;
|
|
}
|