refactor: share the favorite store, tilt repeats and request timing log

- setMyPosition stored a new favorite the same way in each of its three
  tilt branches; storeMyPosition() now does it.  The plain-lift branch
  now emits its state even when the radio refuses the favorite, which is
  harmless since sendSetMy() has already put the old one back.
- tiltRepeats() replaces the repeated tiltmotor ? TILT_REPEATS : repeats.
- timeRequest's two timing log blocks share logRequestTime().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-13 15:10:34 +02:00
parent bea2f78cb6
commit 0b7c57a9ab
3 changed files with 31 additions and 47 deletions

View file

@ -2411,15 +2411,7 @@ bool SomfyShade::setMyPosition(int8_t pos, int8_t tilt) {
this->settingMyPos = true; this->settingMyPos = true;
} }
} }
else { else return this->storeMyPosition(-1.0f, this->currentTiltPos);
// Set it before sending so processFrame doesn't head for the old one. It
// is only committed once the motor was told about it.
const float oldTiltPos = this->myTiltPos;
this->p_myTiltPos(this->currentTiltPos);
sent = this->sendSetMy(0, this->myPos, oldTiltPos);
this->emitState();
return sent;
}
this->commitMyPosition(); this->commitMyPosition();
this->emitState(); this->emitState();
} }
@ -2444,17 +2436,7 @@ bool SomfyShade::setMyPosition(int8_t pos, int8_t tilt) {
this->settingMyPos = true; this->settingMyPos = true;
} }
} }
else { else return this->storeMyPosition(this->currentPos, this->currentTiltPos);
// Set it before sending so processFrame doesn't head for the old one.
// It is only committed once the motor was told about it.
const float oldPos = this->myPos;
const float oldTiltPos = this->myTiltPos;
this->p_myPos(this->currentPos);
this->p_myTiltPos(this->currentTiltPos);
sent = this->sendSetMy(0, oldPos, oldTiltPos);
this->emitState();
return sent;
}
this->commitMyPosition(); this->commitMyPosition();
this->emitState(); this->emitState();
} }
@ -2478,17 +2460,19 @@ bool SomfyShade::setMyPosition(int8_t pos, int8_t tilt) {
this->settingMyPos = true; this->settingMyPos = true;
} }
} }
else { else sent = this->storeMyPosition(this->currentPos, -1.0f);
// Set it before sending so processFrame doesn't head for the old one. It }
// is only committed once the motor was told about it. return sent;
}
bool SomfyShade::storeMyPosition(float pos, float tiltPos) {
// Set it before sending so processFrame doesn't head for the old one. It is
// only committed once the motor was told about it.
const float oldPos = this->myPos; const float oldPos = this->myPos;
const float oldTiltPos = this->myTiltPos; const float oldTiltPos = this->myTiltPos;
this->p_myPos(this->currentPos); this->p_myPos(pos);
this->p_myTiltPos(-1); this->p_myTiltPos(tiltPos);
sent = this->sendSetMy(0, oldPos, oldTiltPos); const bool sent = this->sendSetMy(0, oldPos, oldTiltPos);
if(sent) this->emitState(); this->emitState();
}
}
return sent; return sent;
} }
bool SomfyShade::moveToMyPosition() { bool SomfyShade::moveToMyPosition() {
@ -2639,14 +2623,14 @@ bool SomfyGroup::sendCommand(somfy_commands cmd, uint8_t repeat, uint8_t stepSiz
this->emitState(); this->emitState();
return true; return true;
} }
uint8_t SomfyShade::tiltRepeats() const { return this->tiltType == tilt_types::tiltmotor ? TILT_REPEATS : this->repeats; }
bool SomfyShade::sendTiltCommand(somfy_commands cmd) { bool SomfyShade::sendTiltCommand(somfy_commands cmd) {
const uint8_t repeat = this->tiltType == tilt_types::tiltmotor ? TILT_REPEATS : this->repeats;
float target; float target;
if(cmd == somfy_commands::Up) target = 0.0f; if(cmd == somfy_commands::Up) target = 0.0f;
else if(cmd == somfy_commands::Down) target = 100.0f; else if(cmd == somfy_commands::Down) target = 100.0f;
else if(cmd == somfy_commands::My) target = this->currentTiltPos; else if(cmd == somfy_commands::My) target = this->currentTiltPos;
else return true; else return true;
if(!SomfyRemote::sendCommand(cmd, repeat)) return false; if(!SomfyRemote::sendCommand(cmd, this->tiltRepeats())) return false;
this->p_tiltTarget(target); this->p_tiltTarget(target);
return true; return true;
} }
@ -2662,7 +2646,7 @@ bool SomfyShade::moveToTiltTarget(float target) {
if(cmd != somfy_commands::My) { if(cmd != somfy_commands::My) {
ESP_LOGI(TAG, "Moving Tilt to %.2f%% from %.2f%% using %s", ESP_LOGI(TAG, "Moving Tilt to %.2f%% from %.2f%% using %s",
target, this->currentTiltPos, translateSomfyCommand(cmd).c_str()); target, this->currentTiltPos, translateSomfyCommand(cmd).c_str());
if(!SomfyRemote::sendCommand(cmd, this->tiltType == tilt_types::tiltmotor ? TILT_REPEATS : this->repeats)) return false; if(!SomfyRemote::sendCommand(cmd, this->tiltRepeats())) return false;
} }
// If the blind is currently moving then the command to stop it // If the blind is currently moving then the command to stop it
// will occur on its own when the tilt target is set. // will occur on its own when the tilt target is set.

View file

@ -216,6 +216,10 @@ class SomfyShade : public SomfyRemote {
ShadeTxState tx; ShadeTxState tx;
bool sendStop(int8_t dir, bool tilt); bool sendStop(int8_t dir, bool tilt);
bool sendSetMy(uint16_t delayMs, float oldPos, float oldTiltPos); bool sendSetMy(uint16_t delayMs, float oldPos, float oldTiltPos);
// Makes pos/tiltPos the favorite and tells the motor to store it.
bool storeMyPosition(float pos, float tiltPos);
// Repeats for a tilt command, more for a separate tilt motor.
uint8_t tiltRepeats() const;
void runToLimit(int8_t dir, bool tilt, uint32_t since); void runToLimit(int8_t dir, bool tilt, uint32_t since);
public: public:
uint8_t roomId = 0; uint8_t roomId = 0;

View file

@ -1282,6 +1282,14 @@ void Web::handleNotFound(AsyncWebServerRequest *request) {
// long the whole exchange took. The total includes chunked bodies like // long the whole exchange took. The total includes chunked bodies like
// /controller that are built while they are sent, after the handler returns. // /controller that are built while they are sent, after the handler returns.
// The server name must be a literal as the disconnect handler keeps it. // The server name must be a literal as the disconnect handler keeps it.
// Logs how long part of a request took, when it is worth logging.
static void logRequestTime(const char *server, AsyncWebServerRequest *request, const IPAddress &ip, const char *part, uint32_t us) {
if(!worthLogging(us)) return;
char what[112];
snprintf(what, sizeof(what), "%s %s %s from %u.%u.%u.%u %s", server, request->methodToString(), request->url().c_str(),
ip[0], ip[1], ip[2], ip[3], part);
logElapsed(TAG, what, us);
}
static void timeRequest(AsyncWebServerRequest *request, ArMiddlewareNext next, const char *server) { static void timeRequest(AsyncWebServerRequest *request, ArMiddlewareNext next, const char *server) {
ElapsedTimer timer; ElapsedTimer timer;
// Taken now as the client may already be gone when the disconnect runs. // Taken now as the client may already be gone when the disconnect runs.
@ -1289,22 +1297,10 @@ static void timeRequest(AsyncWebServerRequest *request, ArMiddlewareNext next, c
// Uploads set their own disconnect handler while the body arrives, before // Uploads set their own disconnect handler while the body arrives, before
// this runs, and replacing it would stop the reboot after an update. // this runs, and replacing it would stop the reboot after an update.
if(!request->multipart()) { if(!request->multipart()) {
request->onDisconnect([request, timer, server, ip]() { request->onDisconnect([request, timer, server, ip]() { logRequestTime(server, request, ip, "total", timer.us()); });
const uint32_t us = timer.us();
if(!worthLogging(us)) return;
char what[112];
snprintf(what, sizeof(what), "%s %s %s from %u.%u.%u.%u total", server, request->methodToString(), request->url().c_str(),
ip[0], ip[1], ip[2], ip[3]);
logElapsed(TAG, what, us);
});
} }
next(); next();
const uint32_t us = timer.us(); logRequestTime(server, request, ip, "handler", timer.us());
if(!worthLogging(us)) return;
char what[112];
snprintf(what, sizeof(what), "%s %s %s from %u.%u.%u.%u handler", server, request->methodToString(), request->url().c_str(),
ip[0], ip[1], ip[2], ip[3]);
logElapsed(TAG, what, us);
} }
void Web::begin() { void Web::begin() {