From 4eff50645dc7a11ab021943268bc184928c8920d Mon Sep 17 00:00:00 2001 From: cjkas Date: Fri, 16 Oct 2026 22:40:32 +0200 Subject: [PATCH] fix: update every group's flags after a group's sun flag command A SunFlag or Flag frame makes every group work its flags out again, but the same command from a group only updated that group, so other groups holding the shade kept stale sun flags. The group rule now reports the sensor flags as the frame rule does. Reconcile Q20 in SHADE_BEHAVIOUR_PLAN.md. Co-Authored-By: Claude Opus 5.5 --- docs/SHADE_BEHAVIOUR_PLAN.md | 2 +- src/ShadeBehaviour.cpp | 3 +++ test/test_shadebehaviour/test_shadebehaviour.cpp | 8 +++++--- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/SHADE_BEHAVIOUR_PLAN.md b/docs/SHADE_BEHAVIOUR_PLAN.md index ca06fe6..e669c75 100644 --- a/docs/SHADE_BEHAVIOUR_PLAN.md +++ b/docs/SHADE_BEHAVIOUR_PLAN.md @@ -89,7 +89,7 @@ The decisions are the user's. Each question comes with a recommended answer, and - Up and My on tilt-only shades differ between the web, a remote and a group (`test_today_up_on_tilt_only_*`, `test_today_my_while_tilt_only_moves`). - An integrated tilt sent to a lift target without a tilt turns its slats back with an Up after the stop (`test_today_integrated_tilt_turns_back_after_a_lift_target`). - ~~A remote step uses the step size this shade last *sent*.~~ Fixed (Q19). - - A group's SunFlag or Flag doesn't make other groups work their flags out again (`test_group_sun_flag_needs_a_sensor`). + - ~~A group's SunFlag or Flag doesn't make other groups work their flags out again.~~ Fixed (Q20). - The self-echo (Q5) and merging group commands into the frame rule (Q8). - `lastFrame` doing two jobs (the Q6 revisit). - The 500 ms long-press deadline is compared as `now > await`, which isn't wrap-safe (not tested). diff --git a/src/ShadeBehaviour.cpp b/src/ShadeBehaviour.cpp index 22b1c83..42745b7 100644 --- a/src/ShadeBehaviour.cpp +++ b/src/ShadeBehaviour.cpp @@ -786,6 +786,8 @@ void ShadeBehaviour::onGroupCommand(somfy_commands cmd, uint8_t repeat, uint32_t break; case somfy_commands::Flag: this->p_sunFlag(false); + // Every group works its flags out again, as for a Flag frame. + this->events.onSensorFlags(); if(this->settings.sunSensor) { this->events.onSaveWanted(); this->emitState(); @@ -803,6 +805,7 @@ void ShadeBehaviour::onGroupCommand(somfy_commands cmd, uint8_t repeat, uint32_t this->applySensorMove(this->sensors.onSunFlag(isSunny, isWindy)); this->events.onSaveWanted(); this->emitState(); + this->events.onSensorFlags(); } else ESP_LOGW(TAG, "Shade does not have sensor %d", joinShadeFlags(this->settings, false, this->s.stateFlags)); diff --git a/test/test_shadebehaviour/test_shadebehaviour.cpp b/test/test_shadebehaviour/test_shadebehaviour.cpp index cf4cba8..f8f1fef 100644 --- a/test/test_shadebehaviour/test_shadebehaviour.cpp +++ b/test/test_shadebehaviour/test_shadebehaviour.cpp @@ -522,9 +522,11 @@ static void test_group_sun_flag_needs_a_sensor() { r.b.onGroupCommand(somfy_commands::SunFlag, 1, r.now); TEST_ASSERT_TRUE(r.st().stateFlags & static_cast(somfy_flags_t::SunFlag)); TEST_ASSERT_EQUAL(1, r.events.saves); - // today: unlike the frame rule, the group rule doesn't ask for the group - // flags to be worked out again; SomfyGroup does that for its own group. - TEST_ASSERT_EQUAL(0, r.events.sensorFlags); + // As for a frame, every group works its flags out again. + TEST_ASSERT_EQUAL(1, r.events.sensorFlags); + r.b.onGroupCommand(somfy_commands::Flag, 1, r.now); + TEST_ASSERT_FALSE(r.st().stateFlags & static_cast(somfy_flags_t::SunFlag)); + TEST_ASSERT_EQUAL(2, r.events.sensorFlags); } /*********************************************************************