@@ -154,66 +154,75 @@ void AppTask::ButtonEventHandler(uint8_t button, uint8_t btnAction)
154154
155155void AppTask::ClosureButtonActionEventHandler (AppEvent * aEvent)
156156{
157- CHIP_ERROR err = CHIP_NO_ERROR;
158-
159157 if (aEvent->Type == AppEvent::kEventType_Button )
160158 {
161- // Check if an action is already in progress
162- if (ClosureManager::GetInstance ().IsClosureControlMotionInProgress ())
163- {
164- // Stop the current action
165- auto status = ClosureManager::GetInstance ().OnStopCommand ();
166- if (status != Protocols::InteractionModel::Status::Success)
159+ // Schedule work on the chip stack thread to ensure all CHIP API calls are safe
160+ chip::DeviceLayer::PlatformMgr ().ScheduleWork ([](intptr_t ) {
161+ // Check if an action is already in progress
162+ if (ClosureManager::GetInstance ().IsClosureControlMotionInProgress ())
167163 {
168- ChipLogError (AppServer, " Failed to stop closure action" );
164+ // Stop the current action
165+ auto status = ClosureManager::GetInstance ().GetClosureControlLogic ().HandleStop ();
166+ if (status != Protocols::InteractionModel::Status::Success)
167+ {
168+ ChipLogError (AppServer, " Failed to stop closure action: %u" , to_underlying (status));
169+ }
169170 }
170- }
171- else
172- {
173- // Fetch the complete current state of closure with proper locking
174- chip::DeviceLayer::PlatformMgr ().LockChipStack ();
175- DataModel::Nullable<ClosureControl::GenericOverallCurrentState> currentState;
176- CHIP_ERROR err = ClosureManager::GetInstance ().GetClosureControlCurrentState (currentState);
177- chip::DeviceLayer::PlatformMgr ().UnlockChipStack ();
178-
179- if (err != CHIP_NO_ERROR || currentState.IsNull () || !currentState.Value ().position .HasValue () ||
180- currentState.Value ().position .Value ().IsNull ())
171+ else
181172 {
182- ChipLogError (AppServer, " Failed to get current closure state" );
183- return ;
184- }
185-
186- // Get current position and determine target position (toggle)
187- auto currentPosition = currentState.Value ().position .Value ().Value ();
188- ClosureControl::TargetPositionEnum targetPosition =
173+ DataModel::Nullable<ClosureControl::GenericOverallCurrentState> currentState;
174+ CHIP_ERROR err = ClosureManager::GetInstance ().GetClosureControlLogic ().GetOverallCurrentState (currentState);
175+
176+ if (err != CHIP_NO_ERROR)
177+ {
178+ ChipLogError (AppServer, " Failed to get current closure state: %s" , chip::ErrorStr (err));
179+ return ;
180+ }
181+ if (currentState.IsNull ())
182+ {
183+ ChipLogError (AppServer, " Failed to get current closure state: currentState is null" );
184+ return ;
185+ }
186+ if (!currentState.Value ().position .HasValue () || currentState.Value ().position .Value ().IsNull ())
187+ {
188+ ChipLogError (AppServer, " Failed to get current closure state: position is null" );
189+ return ;
190+ }
191+
192+ // Get current position and determine target position (toggle)
193+ auto currentPosition = currentState.Value ().position .Value ().Value ();
194+ ChipLogProgress (AppServer, " Current state - Position: %d" , to_underlying (currentPosition));
195+
196+ ClosureControl::TargetPositionEnum targetPosition =
189197 (currentPosition == ClosureControl::CurrentPositionEnum::kFullyOpened )
190198 ? ClosureControl::TargetPositionEnum::kMoveToFullyClosed
191199 : ClosureControl::TargetPositionEnum::kMoveToFullyOpen ;
192-
193- // Get latch and speed from current state to preserve them in target state
194- Optional<bool > latch = chip::NullOptional;
195- if (currentState.Value ().latch .HasValue () && !currentState.Value ().latch .Value ().IsNull ())
196- {
197- latch = MakeOptional (currentState.Value ().latch .Value ().Value ());
198- }
199-
200- Optional<Globals::ThreeLevelAutoEnum> speed = NullOptional;
201- if (currentState.Value ().speed .HasValue ())
202- {
203- speed = chip::MakeOptional (currentState.Value ().speed .Value ());
200+ ChipLogProgress (AppServer, " Target position: %d" , to_underlying (targetPosition));
201+
202+ Optional<bool > latch = chip::NullOptional;
203+ if (currentState.Value ().latch .HasValue () && !currentState.Value ().latch .Value ().IsNull ())
204+ {
205+ latch = MakeOptional (false );
206+ }
207+
208+ Optional<Globals::ThreeLevelAutoEnum> speed = NullOptional;
209+ if (currentState.Value ().speed .HasValue ())
210+ {
211+ speed = chip::MakeOptional (currentState.Value ().speed .Value ());
212+ }
213+
214+ // Move to the target position with latch set to false and preserved speed value
215+ auto status = ClosureManager::GetInstance ().GetClosureControlLogic ().HandleMoveTo (
216+ MakeOptional (targetPosition), latch, speed);
217+ if (status != Protocols::InteractionModel::Status::Success)
218+ {
219+ ChipLogError (AppServer, " Failed to move closure to target position: %u" , to_underlying (status));
220+ }
204221 }
205-
206- // Move to the target position with preserved latch and speed values
207- auto status = ClosureManager::GetInstance ().OnMoveToCommand (MakeOptional (targetPosition), latch, speed);
208- if (status != Protocols::InteractionModel::Status::Success)
209- {
210- ChipLogError (AppServer, " Failed to move closure to target position" );
211- }
212- }
222+ }, 0 );
213223 }
214224 else
215225 {
216- err = APP_ERROR_UNHANDLED_EVENT;
217226 ChipLogError (AppServer, " Unhandled event type in ClosureButtonActionEventHandler" );
218227 }
219228}
0 commit comments