Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make robotic vacuum cleaner spec compliant #37718

Merged
merged 9 commits into from
Feb 24, 2025
38 changes: 38 additions & 0 deletions examples/chef/common/chef-rvc-mode-delegate.cpp
Original file line number Diff line number Diff line change
@@ -29,11 +29,21 @@ using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::T

#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
#include <chef-rvc-mode-delegate.h>

#ifdef MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER
#include <chef-rvc-operational-state-delegate.h>
#endif // MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER

using namespace chip::app::Clusters::RvcRunMode;

static std::unique_ptr<RvcRunModeDelegate> gRvcRunModeDelegate;
static std::unique_ptr<ModeBase::Instance> gRvcRunModeInstance;

chip::app::Clusters::ModeBase::Instance * getRvcRunModeInstance()
{
return gRvcRunModeInstance.get();
}

CHIP_ERROR RvcRunModeDelegate::Init()
{
return CHIP_NO_ERROR;
@@ -51,7 +61,35 @@ void RvcRunModeDelegate::HandleChangeToMode(uint8_t NewMode, ModeBase::Commands:
return;
}

#ifdef MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER
OperationalState::GenericOperationalError err(to_underlying(OperationalState::ErrorStateEnum::kNoError));
if (NewMode == RvcRunMode::ModeIdle)
{
if (currentMode != RvcRunMode::ModeIdle)
{ // Stop existing cycle when going from cleaning/mapping to idle.
ChipLogProgress(DeviceLayer, "Stopping RVC cycle: %d", currentMode);
getRvcOperationalStateDelegate()->HandleStopStateCallback(err);
}
}
else
{
if (currentMode == RvcRunMode::ModeIdle)
{ // Start a new cycle when going from idle to clening/mapping.
ChipLogProgress(DeviceLayer, "Starting new RVC cycle: %d", NewMode);
getRvcOperationalStateDelegate()->HandleStartStateCallback(err);
}
}
if (err.IsEqual(OperationalState::GenericOperationalError(to_underlying(OperationalState::ErrorStateEnum::kNoError))))
{
response.status = to_underlying(ModeBase::StatusCode::kSuccess);
}
else
{
response.status = to_underlying(ModeBase::StatusCode::kGenericFailure);
}
#else
response.status = to_underlying(ModeBase::StatusCode::kSuccess);
#endif // MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER
}

CHIP_ERROR RvcRunModeDelegate::GetModeLabelByIndex(uint8_t modeIndex, chip::MutableCharSpan & label)
5 changes: 4 additions & 1 deletion examples/chef/common/chef-rvc-mode-delegate.h
Original file line number Diff line number Diff line change
@@ -42,6 +42,7 @@ class RvcRunModeDelegate : public ModeBase::Delegate
using ModeTagStructType = detail::Structs::ModeTagStruct::Type;
ModeTagStructType ModeTagsIdle[1] = { { .value = to_underlying(ModeTag::kIdle) } };
ModeTagStructType ModeTagsCleaning[1] = { { .value = to_underlying(ModeTag::kCleaning) } };
ModeTagStructType ModeTagsMapping[1] = { { .value = to_underlying(ModeTag::kMapping) } };

const detail::Structs::ModeOptionStruct::Type kModeOptions[3] = {
detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Idle"),
@@ -52,7 +53,7 @@ class RvcRunModeDelegate : public ModeBase::Delegate
.modeTags = DataModel::List<const ModeTagStructType>(ModeTagsCleaning) },
detail::Structs::ModeOptionStruct::Type{ .label = CharSpan::fromCharString("Mapping"),
.mode = ModeMapping,
.modeTags = DataModel::List<const ModeTagStructType>(ModeTagsIdle) },
.modeTags = DataModel::List<const ModeTagStructType>(ModeTagsMapping) },
};

CHIP_ERROR Init() override;
@@ -122,6 +123,8 @@ void Shutdown();
} // namespace chip

#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
chip::app::Clusters::ModeBase::Instance * getRvcRunModeInstance();

chip::Protocols::InteractionModel::Status chefRvcRunModeWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
const EmberAfAttributeMetadata * attributeMetadata,
uint8_t * buffer);
18 changes: 18 additions & 0 deletions examples/chef/common/chef-rvc-operational-state-delegate.cpp
Original file line number Diff line number Diff line change
@@ -28,9 +28,18 @@ using namespace chip::app::Clusters::OperationalState;
using namespace chip::app::Clusters::RvcOperationalState;
using chip::Protocols::InteractionModel::Status;

#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
#include <chef-rvc-mode-delegate.h>
#endif // MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER

static std::unique_ptr<RvcOperationalStateDelegate> gRvcOperationalStateDelegate;
static std::unique_ptr<RvcOperationalState::Instance> gRvcOperationalStateInstance;

RvcOperationalStateDelegate * getRvcOperationalStateDelegate()
{
return gRvcOperationalStateDelegate.get();
}

static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data);

DataModel::Nullable<uint32_t> RvcOperationalStateDelegate::GetCountdownTime()
@@ -176,6 +185,11 @@ static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data
OperationalState::OperationalStateEnum state =
static_cast<OperationalState::OperationalStateEnum>(instance->GetCurrentOperationalState());

if (state == OperationalState::OperationalStateEnum::kStopped) // Do not continue the timer when RVC has stopped.
{
return;
}

if (gRvcOperationalStateDelegate->mCountdownTime.IsNull())
{
if (state == OperationalState::OperationalStateEnum::kRunning)
@@ -223,6 +237,10 @@ static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data
gRvcOperationalStateDelegate->mRunningTime = 0;
gRvcOperationalStateDelegate->mPausedTime = 0;
gRvcOperationalStateDelegate->mCountdownTime.SetNull();

#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
getRvcRunModeInstance()->UpdateCurrentMode(RvcRunMode::ModeIdle);
#endif // MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
}
}
}
2 changes: 2 additions & 0 deletions examples/chef/common/chef-rvc-operational-state-delegate.h
Original file line number Diff line number Diff line change
@@ -122,6 +122,8 @@ void Shutdown();
} // namespace app
} // namespace chip

chip::app::Clusters::RvcOperationalState::RvcOperationalStateDelegate * getRvcOperationalStateDelegate();

chip::Protocols::InteractionModel::Status chefRvcOperationalStateWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
const EmberAfAttributeMetadata * attributeMetadata,
uint8_t * buffer);