Skip to content

Commit 03d3595

Browse files
authored
Chef RVC: Add support for GoHome command (#38083)
* RVC HandleGoHomeCommand and fixes in reporting countdown time. * Changes to this attribute merely due to the normal passage of time with no other dynamic change of device state SHALL NOT be reported. * Fix compilation * Fix compilation * Fix compilation * Fix compilation * Remove redundant UpdateCountdownTimeFromDelegate * Enable GoHome in ZAP and .matter * Call UpdateCountdownTimeFromDelegate every time countdown time changes. The update function decides whether the new value must be reported * fix compilation
1 parent 3e9b41b commit 03d3595

4 files changed

+111
-7
lines changed

examples/chef/common/chef-rvc-operational-state-delegate.cpp

+97-7
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,18 @@ void RvcOperationalStateDelegate::HandlePauseStateCallback(GenericOperationalErr
8686
return;
8787
}
8888

89+
if (state != OperationalState::OperationalStateEnum::kRunning)
90+
{
91+
ChipLogDetail(DeviceLayer, "HandlePauseStateCallback: RVC not running. Current state = %d. Returning.",
92+
to_underlying(state));
93+
err.Set(to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState));
94+
return;
95+
}
96+
8997
// placeholder implementation
9098
auto error = gRvcOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused));
9199
if (error == CHIP_NO_ERROR)
92100
{
93-
(void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, GetInstance());
94-
GetInstance()->UpdateCountdownTimeFromDelegate();
95101
err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
96102
}
97103
else
@@ -111,12 +117,18 @@ void RvcOperationalStateDelegate::HandleResumeStateCallback(GenericOperationalEr
111117
return;
112118
}
113119

120+
if (state != OperationalState::OperationalStateEnum::kPaused)
121+
{
122+
ChipLogDetail(DeviceLayer, "HandleResumeStateCallback: RVC not in paused state. Current state = %d. Returning.",
123+
to_underlying(state));
124+
err.Set(to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState));
125+
return;
126+
}
127+
114128
// placeholder implementation
115129
auto error = gRvcOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning));
116130
if (error == CHIP_NO_ERROR)
117131
{
118-
(void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, GetInstance());
119-
GetInstance()->UpdateCountdownTimeFromDelegate();
120132
err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
121133
}
122134
else
@@ -136,12 +148,34 @@ void RvcOperationalStateDelegate::HandleStartStateCallback(GenericOperationalErr
136148
return;
137149
}
138150

151+
RvcOperationalState::OperationalStateEnum current_state =
152+
static_cast<RvcOperationalState::OperationalStateEnum>(gRvcOperationalStateInstance->GetCurrentOperationalState());
153+
154+
if (current_state == RvcOperationalState::OperationalStateEnum::kRunning ||
155+
current_state == RvcOperationalState::OperationalStateEnum::kPaused)
156+
{
157+
ChipLogDetail(DeviceLayer, "HandleStartStateCallback: RVC is already started. Current state = %d. Returning.",
158+
to_underlying(current_state));
159+
err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
160+
return;
161+
}
162+
163+
if (to_underlying(current_state) != to_underlying(RvcOperationalState::OperationalStateEnum::kCharging) &&
164+
to_underlying(current_state) != to_underlying(RvcOperationalState::OperationalStateEnum::kStopped))
165+
{
166+
ChipLogError(
167+
DeviceLayer,
168+
"HandleStartStateCallback: RVC must be in either charging or stopped state before starting. current state = %d",
169+
to_underlying(current_state));
170+
err.Set(to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState));
171+
return;
172+
}
139173
// placeholder implementation
140174
auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning));
141175
if (error == CHIP_NO_ERROR)
142176
{
177+
// Start RVC run cycle.
143178
(void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, GetInstance());
144-
GetInstance()->UpdateCountdownTimeFromDelegate();
145179
err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
146180
}
147181
else
@@ -152,12 +186,23 @@ void RvcOperationalStateDelegate::HandleStartStateCallback(GenericOperationalErr
152186

153187
void RvcOperationalStateDelegate::HandleStopStateCallback(GenericOperationalError & err)
154188
{
189+
190+
RvcOperationalState::OperationalStateEnum current_state =
191+
static_cast<RvcOperationalState::OperationalStateEnum>(gRvcOperationalStateInstance->GetCurrentOperationalState());
192+
193+
if (current_state != RvcOperationalState::OperationalStateEnum::kRunning &&
194+
current_state != RvcOperationalState::OperationalStateEnum::kPaused)
195+
{
196+
ChipLogDetail(DeviceLayer, "HandleStopStateCallback: RVC not started. Current state = %d. Returning.",
197+
to_underlying(current_state));
198+
err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
199+
return;
200+
}
155201
// placeholder implementation
156202
auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped));
157203
if (error == CHIP_NO_ERROR)
158204
{
159205
(void) DeviceLayer::SystemLayer().CancelTimer(onOperationalStateTimerTick, this);
160-
GetInstance()->UpdateCountdownTimeFromDelegate();
161206

162207
OperationalState::GenericOperationalError current_err(to_underlying(OperationalState::ErrorStateEnum::kNoError));
163208
GetInstance()->GetCurrentOperationalError(current_err);
@@ -171,12 +216,41 @@ void RvcOperationalStateDelegate::HandleStopStateCallback(GenericOperationalErro
171216
mPausedTime = 0;
172217
mCountdownTime.SetNull();
173218
err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
219+
GetInstance()->UpdateCountdownTimeFromDelegate();
174220
}
175221
else
176222
{
177223
err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation));
178224
}
179225
}
226+
227+
void RvcOperationalStateDelegate::HandleGoHomeCommandCallback(OperationalState::GenericOperationalError & err)
228+
{
229+
230+
RvcOperationalState::OperationalStateEnum current_state =
231+
static_cast<RvcOperationalState::OperationalStateEnum>(gRvcOperationalStateInstance->GetCurrentOperationalState());
232+
233+
if (current_state == RvcOperationalState::OperationalStateEnum::kRunning ||
234+
current_state == RvcOperationalState::OperationalStateEnum::kPaused)
235+
{
236+
ChipLogDetail(DeviceLayer, "HandleGoHomeCommandCallback: RVC was started, current state = %d. Stopping RVC.",
237+
to_underlying(current_state));
238+
gRvcOperationalStateDelegate->HandleStopStateCallback(err);
239+
}
240+
241+
// Skip SeekingCharger and Docking states and directly go into charging.
242+
auto error =
243+
gRvcOperationalStateInstance->SetOperationalState(to_underlying(RvcOperationalState::OperationalStateEnum::kCharging));
244+
if (error == CHIP_NO_ERROR)
245+
{
246+
err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
247+
}
248+
else
249+
{
250+
err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation));
251+
}
252+
}
253+
180254
static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data)
181255
{
182256
RvcOperationalStateDelegate * delegate = reinterpret_cast<RvcOperationalStateDelegate *>(data);
@@ -185,7 +259,8 @@ static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data
185259
OperationalState::OperationalStateEnum state =
186260
static_cast<OperationalState::OperationalStateEnum>(instance->GetCurrentOperationalState());
187261

188-
if (state == OperationalState::OperationalStateEnum::kStopped) // Do not continue the timer when RVC has stopped.
262+
if (state != OperationalState::OperationalStateEnum::kRunning &&
263+
state != OperationalState::OperationalStateEnum::kPaused) // Timer shouldn't run when RVC is not in Running or Paused.
189264
{
190265
return;
191266
}
@@ -198,6 +273,12 @@ static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data
198273
static_cast<uint32_t>(gRvcOperationalStateDelegate->kExampleCountDown));
199274
gRvcOperationalStateDelegate->mRunningTime = 0;
200275
gRvcOperationalStateDelegate->mPausedTime = 0;
276+
instance->UpdateCountdownTimeFromDelegate();
277+
}
278+
else
279+
{ // kPaused
280+
ChipLogError(DeviceLayer, "RVC timer tick: Invalid state. Device is in kPaused but mCountdownTime is NULL.");
281+
return;
201282
}
202283
}
203284

@@ -213,6 +294,14 @@ static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data
213294
uint32_t mPausedTime = gRvcOperationalStateDelegate->mPausedTime;
214295
uint32_t mRunningTime = gRvcOperationalStateDelegate->mRunningTime;
215296

297+
ChipLogDetail(DeviceLayer, "RVC timer tick: Current state = %d. CountdownTime = %d. PauseTime = %d. RunningTime = %d.",
298+
to_underlying(state), gRvcOperationalStateDelegate->mCountdownTime.Value(), mPausedTime, mRunningTime);
299+
if (state == OperationalState::OperationalStateEnum::kRunning)
300+
{
301+
// Reported CountDownTime is the remaining time to run = mCountdownTime.Value() - mRunningTime.
302+
instance->UpdateCountdownTimeFromDelegate();
303+
}
304+
216305
if (gRvcOperationalStateDelegate->mCountdownTime.Value() > mRunningTime)
217306
{
218307
(void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, delegate);
@@ -237,6 +326,7 @@ static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data
237326
gRvcOperationalStateDelegate->mRunningTime = 0;
238327
gRvcOperationalStateDelegate->mPausedTime = 0;
239328
gRvcOperationalStateDelegate->mCountdownTime.SetNull();
329+
instance->UpdateCountdownTimeFromDelegate();
240330

241331
#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
242332
getRvcRunModeInstance()->UpdateCurrentMode(RvcRunMode::ModeIdle);

examples/chef/common/chef-rvc-operational-state-delegate.h

+5
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ class RvcOperationalStateDelegate : public RvcOperationalState::Delegate
9494
*/
9595
void HandleStopStateCallback(OperationalState::GenericOperationalError & err) override;
9696

97+
/**
98+
* Handle Command Callback in application: GoHome
99+
*/
100+
void HandleGoHomeCommandCallback(OperationalState::GenericOperationalError & err) override;
101+
97102
uint32_t mRunningTime = 0;
98103
uint32_t mPausedTime = 0;
99104
app::DataModel::Nullable<uint32_t> mCountdownTime;

examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter

+1
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,7 @@ endpoint 1 {
20972097
handle command Pause;
20982098
handle command Resume;
20992099
handle command OperationalCommandResponse;
2100+
handle command GoHome;
21002101
}
21012102
}
21022103

examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.zap

+8
Original file line numberDiff line numberDiff line change
@@ -2956,6 +2956,14 @@
29562956
"source": "server",
29572957
"isIncoming": 0,
29582958
"isEnabled": 1
2959+
},
2960+
{
2961+
"name": "GoHome",
2962+
"code": 128,
2963+
"mfgCode": null,
2964+
"source": "client",
2965+
"isIncoming": 1,
2966+
"isEnabled": 1
29592967
}
29602968
],
29612969
"attributes": [

0 commit comments

Comments
 (0)