mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 13:52:15 +01:00
fix: default a set-favorite request's tilt to the favorite tilt
/setMyPosition filled in a missing tilt with the lift favorite, so a request without a tilt set the favorite tilt to the lift's. It also took the stored position as a display one, which flipped it twice on a shade with flipPosition. requestedFavoriteTilt() now gives the favorite tilt as displayed. Home Assistant never calls /setMyPosition and the web UI always sends a tilt, so only other API callers see the change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
377a1217a6
commit
1128431e8c
5 changed files with 34 additions and 17 deletions
|
|
@ -115,16 +115,3 @@ Sending a command reads the next rolling code, queues the frame, then commits th
|
|||
|
||||
- Same root cause as [Concurrent mutation during chunked `/controller` response](#concurrent-mutation-during-chunked-controller-response): the web server task changes the shade model that `loop()` owns.
|
||||
- `/linkRemote` sets a linked remote's rolling code on the web server task, while `loop()` updates the same code when it receives a frame from that remote. The last write wins, so a received frame can undo the code just set.
|
||||
|
||||
## `/setMyPosition` without a tilt uses the lift favorite
|
||||
|
||||
**Status:** open
|
||||
**Location:** the `/setMyPosition` handlers in [src/Web.cpp](../src/Web.cpp). This was already in the code before the radio task work.
|
||||
|
||||
### Summary
|
||||
|
||||
When a request for a shade with tilt leaves out `tilt`, the handler fills it in with `shade->myPos`, the lift favorite, where `shade->myTiltPos` looks intended. The favorite tilt is then set to the favorite lift position. The web UI always sends `tilt`, so only API callers that leave it out see this.
|
||||
|
||||
### Fix
|
||||
|
||||
Use `shade->myTiltPos` in both handlers, after checking that no API client depends on the current behaviour.
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ int8_t displayPosition(float pos, bool flip) {
|
|||
if(pos < 0) return -1;
|
||||
return static_cast<int8_t>(flip && pos >= 0.00f ? floor(100.0f - pos) : floor(pos));
|
||||
}
|
||||
int8_t requestedFavoriteTilt(int8_t requestTilt, tilt_types tilt, float myTiltPos, bool flip) {
|
||||
if(tilt == tilt_types::none) return -1;
|
||||
if(requestTilt >= 0) return requestTilt;
|
||||
return displayPosition(myTiltPos, flip);
|
||||
}
|
||||
float limitTarget(int8_t dir) { return dir > 0 ? 100.0f : 0.0f; }
|
||||
bool stepPosition(float pos, int8_t dir, uint32_t travelMs, uint16_t stepSize, uint8_t frameStepSize, float &out) {
|
||||
if(travelMs == 0 || stepSize == 0) return false;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ float travelPosition(float startPos, int8_t dir, uint32_t elapsedMs, int32_t tra
|
|||
// A position as reported to clients: -1 when unset, otherwise the whole
|
||||
// percentage, counted from the other end when flipped.
|
||||
int8_t displayPosition(float pos, bool flip);
|
||||
// The tilt a request to set the favorite asks for, as a display position: the
|
||||
// requested tilt, or the favorite tilt when the request leaves it out. -1 for
|
||||
// a shade without tilt or with no favorite tilt.
|
||||
int8_t requestedFavoriteTilt(int8_t requestTilt, tilt_types tilt, float myTiltPos, bool flip);
|
||||
// Where a shade (or its tilt) moving in dir ends up when nothing stops it.
|
||||
float limitTarget(int8_t dir);
|
||||
// Where a step command moves a shade (or its tilt) from pos, in out. dir > 0
|
||||
|
|
|
|||
|
|
@ -1733,8 +1733,7 @@ void Web::begin() {
|
|||
}
|
||||
SomfyShade* shade = somfy.getShadeById(shadeId);
|
||||
if(shade) {
|
||||
if(tilt < 0) tilt = shade->myPos;
|
||||
if(shade->tiltType == tilt_types::none) tilt = -1;
|
||||
tilt = requestedFavoriteTilt(tilt, shade->tiltType, shade->myTiltPos, shade->flipPosition);
|
||||
if(pos >= 0 && pos <= 100)
|
||||
if(!queueSetMyPosition(request, shade, shade->transformPosition(pos), shade->transformPosition(tilt))) return;
|
||||
AsyncJsonResp resp;
|
||||
|
|
@ -1760,8 +1759,7 @@ void Web::begin() {
|
|||
else { request->send(500, _encoding_json, F("{\"status\":\"ERROR\",\"desc\":\"No shade object supplied.\"}")); return; }
|
||||
SomfyShade* shade = somfy.getShadeById(shadeId);
|
||||
if(shade) {
|
||||
if(tilt < 0) tilt = shade->myPos;
|
||||
if(shade->tiltType == tilt_types::none) tilt = -1;
|
||||
tilt = requestedFavoriteTilt(tilt, shade->tiltType, shade->myTiltPos, shade->flipPosition);
|
||||
if(pos >= 0 && pos <= 100)
|
||||
if(!queueSetMyPosition(request, shade, shade->transformPosition(pos), shade->transformPosition(tilt))) return;
|
||||
AsyncJsonResp resp;
|
||||
|
|
|
|||
|
|
@ -285,6 +285,25 @@ static void test_stepTargets_without_a_travel_time_or_step_size_is_ignored() {
|
|||
ASSERT_ACTION(StepAction::ignore, stepOf(tilt_types::none, DOWN, 100, 0, 1, 20000, 10000, 5000, 0).action);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* requestedFavoriteTilt
|
||||
********************************************************************/
|
||||
static void test_favorite_tilt_keeps_the_requested_tilt() {
|
||||
TEST_ASSERT_EQUAL_INT8(25, requestedFavoriteTilt(25, tilt_types::integrated, 70.0f, false));
|
||||
}
|
||||
static void test_favorite_tilt_defaults_to_the_favorite_tilt() {
|
||||
// Not the lift favorite: that was the old default.
|
||||
TEST_ASSERT_EQUAL_INT8(70, requestedFavoriteTilt(-1, tilt_types::tiltmotor, 70.0f, false));
|
||||
// The request is in display positions, so a flipped shade gets its favorite flipped.
|
||||
TEST_ASSERT_EQUAL_INT8(30, requestedFavoriteTilt(-1, tilt_types::tiltmotor, 70.0f, true));
|
||||
}
|
||||
static void test_favorite_tilt_without_a_favorite_is_unset() {
|
||||
TEST_ASSERT_EQUAL_INT8(-1, requestedFavoriteTilt(-1, tilt_types::integrated, -1.0f, false));
|
||||
}
|
||||
static void test_favorite_tilt_of_a_shade_without_tilt_is_unset() {
|
||||
TEST_ASSERT_EQUAL_INT8(-1, requestedFavoriteTilt(25, tilt_types::none, 70.0f, false));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
|
@ -312,6 +331,10 @@ int main(int argc, char **argv) {
|
|||
RUN_TEST(test_stepTargets_integrated_at_both_ends_is_ignored);
|
||||
RUN_TEST(test_stepTargets_without_a_travel_time_or_step_size_is_ignored);
|
||||
RUN_TEST(test_displayPosition);
|
||||
RUN_TEST(test_favorite_tilt_keeps_the_requested_tilt);
|
||||
RUN_TEST(test_favorite_tilt_defaults_to_the_favorite_tilt);
|
||||
RUN_TEST(test_favorite_tilt_without_a_favorite_is_unset);
|
||||
RUN_TEST(test_favorite_tilt_of_a_shade_without_tilt_is_unset);
|
||||
RUN_TEST(test_flipCommand_swaps_directions);
|
||||
RUN_TEST(test_flipCommand_keeps_the_rest);
|
||||
RUN_TEST(test_txhold_idle_shade_is_held);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue