Enable chef robotic vacuum cleaner device (#33258)

* Enable chef robotic vacuum cleaner device

* Restyled by whitespace

* Restyled by clang-format

* remove old rvc feature

* Restyled by clang-format

* update return status

* Restyled by whitespace

* Restyled by clang-format

* add back ifdef; remove old feature flag

* Restyled by clang-format

* write read attributes into buffer

* Restyled by clang-format

* update readCallback write buffer

* Restyled by whitespace

* update buffer read in read call back

* Restyled by clang-format

* use static instance

* Restyled by clang-format

* write attribute into buffer in callback

* use unique_ptr

* Restyled by clang-format

---------

Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/examples/chef/common/chef-rvc-mode-delegate.cpp b/examples/chef/common/chef-rvc-mode-delegate.cpp
index 20f3afb..32b4cad 100644
--- a/examples/chef/common/chef-rvc-mode-delegate.cpp
+++ b/examples/chef/common/chef-rvc-mode-delegate.cpp
@@ -18,17 +18,20 @@
 #include <app-common/zap-generated/attributes/Accessors.h>
 #include <app/util/config.h>
 
+using namespace chip;
+using namespace chip::app;
 using namespace chip::app::Clusters;
 using chip::Protocols::InteractionModel::Status;
 template <typename T>
 using List              = chip::app::DataModel::List<T>;
 using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type;
 
-#ifdef ZCL_USING_RVC_RUN_MODE_CLUSTER_SERVER
+#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
 #include <chef-rvc-mode-delegate.h>
 using namespace chip::app::Clusters::RvcRunMode;
-static RvcRunModeDelegate * gRvcRunModeDelegate = nullptr;
-static ModeBase::Instance * gRvcRunModeInstance = nullptr;
+
+static std::unique_ptr<RvcRunModeDelegate> gRvcRunModeDelegate;
+static std::unique_ptr<ModeBase::Instance> gRvcRunModeInstance;
 
 CHIP_ERROR RvcRunModeDelegate::Init()
 {
@@ -87,40 +90,82 @@
     return CHIP_NO_ERROR;
 }
 
-ModeBase::Instance * RvcRunMode::Instance()
-{
-    return gRvcRunModeInstance;
-}
-
 void RvcRunMode::Shutdown()
 {
-    if (gRvcRunModeInstance != nullptr)
+    gRvcRunModeInstance.reset();
+    gRvcRunModeDelegate.reset();
+}
+
+chip::Protocols::InteractionModel::Status chefRvcRunModeWriteCallback(chip::EndpointId endpointId, chip::ClusterId clusterId,
+                                                                      const EmberAfAttributeMetadata * attributeMetadata,
+                                                                      uint8_t * buffer)
+{
+    VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1
+    VerifyOrDie(gRvcRunModeInstance != nullptr);
+    chip::Protocols::InteractionModel::Status ret;
+    chip::AttributeId attributeId = attributeMetadata->attributeId;
+
+    switch (attributeId)
     {
-        delete gRvcRunModeInstance;
-        gRvcRunModeInstance = nullptr;
+    case chip::app::Clusters::RvcRunMode::Attributes::CurrentMode::Id: {
+        uint8_t m = static_cast<uint8_t>(buffer[0]);
+        ret       = gRvcRunModeInstance->UpdateCurrentMode(m);
+        if (chip::Protocols::InteractionModel::Status::Success != ret)
+        {
+            ChipLogError(DeviceLayer, "Invalid Attribute Update status: %d", static_cast<int>(ret));
+        }
     }
-    if (gRvcRunModeDelegate != nullptr)
+    break;
+    default:
+        ret = chip::Protocols::InteractionModel::Status::UnsupportedWrite;
+        ChipLogError(DeviceLayer, "Unsupported Writng Attribute ID: %d", static_cast<int>(attributeId));
+        break;
+    }
+
+    return ret;
+}
+
+chip::Protocols::InteractionModel::Status chefRvcRunModeReadCallback(chip::EndpointId endpointId, chip::ClusterId clusterId,
+                                                                     const EmberAfAttributeMetadata * attributeMetadata,
+                                                                     uint8_t * buffer, uint16_t maxReadLength)
+{
+    chip::Protocols::InteractionModel::Status ret = chip::Protocols::InteractionModel::Status::Success;
+    chip::AttributeId attributeId                 = attributeMetadata->attributeId;
+
+    switch (attributeId)
     {
-        delete gRvcRunModeDelegate;
-        gRvcRunModeDelegate = nullptr;
+    case chip::app::Clusters::RvcRunMode::Attributes::CurrentMode::Id: {
+        *buffer = gRvcRunModeInstance->GetCurrentMode();
+        ChipLogDetail(DeviceLayer, "Reading RunMode CurrentMode : %d", static_cast<int>(attributeId));
     }
+    break;
+    default:
+        ret = chip::Protocols::InteractionModel::Status::UnsupportedRead;
+        ChipLogDetail(DeviceLayer, "Unsupported attributeId %d from reading RvcRunMode", static_cast<int>(attributeId));
+        break;
+    }
+
+    return ret;
 }
 
 void emberAfRvcRunModeClusterInitCallback(chip::EndpointId endpointId)
 {
     VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1.
-    VerifyOrDie(gRvcRunModeDelegate == nullptr && gRvcRunModeInstance == nullptr);
-    gRvcRunModeDelegate = new RvcRunMode::RvcRunModeDelegate;
-    gRvcRunModeInstance =
-        new ModeBase::Instance(gRvcRunModeDelegate, 0x1, RvcRunMode::Id, chip::to_underlying(RvcRunMode::Feature::kOnOff));
+    VerifyOrDie(!gRvcRunModeDelegate && !gRvcRunModeInstance);
+
+    gRvcRunModeDelegate = std::make_unique<RvcRunModeDelegate>();
+    gRvcRunModeInstance = std::make_unique<ModeBase::Instance>(gRvcRunModeDelegate.get(), endpointId, RvcRunMode::Id,
+                                                               chip::to_underlying(RvcRunMode::Feature::kNoFeatures));
     gRvcRunModeInstance->Init();
 }
 
-#ifdef ZCL_USING_RVC_CLEAN_MODE_CLUSTER_SERVER
+#endif // MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
+
+#ifdef MATTER_DM_PLUGIN_RVC_CLEAN_MODE_SERVER
 #include <chef-rvc-mode-delegate.h>
 using namespace chip::app::Clusters::RvcCleanMode;
-static RvcCleanModeDelegate * gRvcCleanModeDelegate = nullptr;
-static ModeBase::Instance * gRvcCleanModeInstance   = nullptr;
+static std::unique_ptr<RvcCleanModeDelegate> gRvcCleanModeDelegate;
+static std::unique_ptr<ModeBase::Instance> gRvcCleanModeInstance;
 
 CHIP_ERROR RvcCleanModeDelegate::Init()
 {
@@ -178,33 +223,75 @@
     return CHIP_NO_ERROR;
 }
 
-ModeBase::Instance * RvcCleanMode::Instance()
-{
-    return gRvcCleanModeInstance;
-}
-
 void RvcCleanMode::Shutdown()
 {
-    if (gRvcCleanModeInstance != nullptr)
+    gRvcCleanModeInstance.reset();
+    gRvcCleanModeDelegate.reset();
+}
+
+chip::Protocols::InteractionModel::Status chefRvcCleanModeWriteCallback(chip::EndpointId endpointId, chip::ClusterId clusterId,
+                                                                        const EmberAfAttributeMetadata * attributeMetadata,
+                                                                        uint8_t * buffer)
+{
+    VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1
+    VerifyOrDie(gRvcCleanModeInstance != nullptr);
+    chip::Protocols::InteractionModel::Status ret;
+    chip::AttributeId attributeId = attributeMetadata->attributeId;
+
+    switch (attributeId)
     {
-        delete gRvcCleanModeInstance;
-        gRvcCleanModeInstance = nullptr;
+    case chip::app::Clusters::RvcCleanMode::Attributes::CurrentMode::Id: {
+        uint8_t m = static_cast<uint8_t>(buffer[0]);
+        ret       = gRvcCleanModeInstance->UpdateCurrentMode(m);
+        if (chip::Protocols::InteractionModel::Status::Success != ret)
+        {
+            ChipLogError(DeviceLayer, "Invalid Attribute Update status: %d", static_cast<int>(ret));
+        }
     }
-    if (gRvcCleanModeDelegate != nullptr)
+    break;
+    default:
+        ret = chip::Protocols::InteractionModel::Status::UnsupportedWrite;
+        ChipLogError(DeviceLayer, "Unsupported Attribute ID: %d", static_cast<int>(attributeId));
+        break;
+    }
+
+    return ret;
+}
+
+chip::Protocols::InteractionModel::Status chefRvcCleanModeReadCallback(chip::EndpointId endpointId, chip::ClusterId clusterId,
+                                                                       const EmberAfAttributeMetadata * attributeMetadata,
+                                                                       uint8_t * buffer, uint16_t maxReadLength)
+{
+    VerifyOrReturnValue(maxReadLength > 0, chip::Protocols::InteractionModel::Status::ResourceExhausted);
+    buffer[0] = gRvcCleanModeInstance->GetCurrentMode();
+
+    chip::Protocols::InteractionModel::Status ret = chip::Protocols::InteractionModel::Status::Success;
+    chip::AttributeId attributeId                 = attributeMetadata->attributeId;
+
+    switch (attributeId)
     {
-        delete gRvcCleanModeDelegate;
-        gRvcCleanModeDelegate = nullptr;
+    case chip::app::Clusters::RvcCleanMode::Attributes::CurrentMode::Id: {
+        *buffer = gRvcCleanModeInstance->GetCurrentMode();
+        ChipLogDetail(DeviceLayer, "Reading CleanMode CurrentMode : %d", static_cast<int>(attributeId));
     }
+    break;
+    default:
+        ret = chip::Protocols::InteractionModel::Status::UnsupportedRead;
+        ChipLogDetail(DeviceLayer, "Unsupported attributeId %d from reading RvcCleanMode", static_cast<int>(attributeId));
+        break;
+    }
+
+    return ret;
 }
 
 void emberAfRvcCleanModeClusterInitCallback(chip::EndpointId endpointId)
 {
     VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1.
-    VerifyOrDie(gRvcCleanModeDelegate == nullptr && gRvcCleanModeInstance == nullptr);
-    gRvcCleanModeDelegate = new RvcCleanMode::RvcCleanModeDelegate;
-    gRvcCleanModeInstance =
-        new ModeBase::Instance(gRvcCleanModeDelegate, 0x1, RvcCleanMode::Id, chip::to_underlying(RvcCleanMode::Feature::kOnOff));
+    VerifyOrDie(!gRvcCleanModeDelegate && !gRvcCleanModeInstance);
+
+    gRvcCleanModeDelegate = std::make_unique<RvcCleanModeDelegate>();
+    gRvcCleanModeInstance = std::make_unique<ModeBase::Instance>(gRvcCleanModeDelegate.get(), endpointId, RvcCleanMode::Id,
+                                                                 chip::to_underlying(RvcCleanMode::Feature::kNoFeatures));
     gRvcCleanModeInstance->Init();
 }
-#endif // ZCL_USING_RVC_CLEAN_MODE_CLUSTER_SERVER
-#endif // ZCL_USING_RVC_RUN_MODE_CLUSTER_SERVER
+#endif // MATTER_DM_PLUGIN_RVC_CLEAN_MODE_SERVER
diff --git a/examples/chef/common/chef-rvc-mode-delegate.h b/examples/chef/common/chef-rvc-mode-delegate.h
index 5f96957..359c90c 100644
--- a/examples/chef/common/chef-rvc-mode-delegate.h
+++ b/examples/chef/common/chef-rvc-mode-delegate.h
@@ -23,6 +23,8 @@
 #include <cstring>
 #include <utility>
 
+using chip::Protocols::InteractionModel::Status;
+
 namespace chip {
 namespace app {
 namespace Clusters {
@@ -118,3 +120,21 @@
 } // namespace Clusters
 } // namespace app
 } // namespace chip
+
+#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
+chip::Protocols::InteractionModel::Status chefRvcRunModeWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
+                                                                      const EmberAfAttributeMetadata * attributeMetadata,
+                                                                      uint8_t * buffer);
+chip::Protocols::InteractionModel::Status chefRvcRunModeReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
+                                                                     const EmberAfAttributeMetadata * attributeMetadata,
+                                                                     uint8_t * buffer, uint16_t maxReadLength);
+#endif // MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
+
+#ifdef MATTER_DM_PLUGIN_RVC_CLEAN_MODE_SERVER
+chip::Protocols::InteractionModel::Status chefRvcCleanModeWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
+                                                                        const EmberAfAttributeMetadata * attributeMetadata,
+                                                                        uint8_t * buffer);
+chip::Protocols::InteractionModel::Status chefRvcCleanModeReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
+                                                                       const EmberAfAttributeMetadata * attributeMetadata,
+                                                                       uint8_t * buffer, uint16_t maxReadLength);
+#endif // MATTER_DM_PLUGIN_RVC_CLEAN_MODE_SERVER
diff --git a/examples/chef/common/chef-rvc-operational-state-delegate.cpp b/examples/chef/common/chef-rvc-operational-state-delegate.cpp
index 9ea4e61..36ff3e8 100644
--- a/examples/chef/common/chef-rvc-operational-state-delegate.cpp
+++ b/examples/chef/common/chef-rvc-operational-state-delegate.cpp
@@ -17,17 +17,31 @@
  */
 #include <app-common/zap-generated/attributes/Accessors.h>
 #include <app/util/config.h>
-
-#ifdef ZCL_USING_OPERATIONAL_STATE_RVC_CLUSTER_SERVER
 #include <chef-rvc-operational-state-delegate.h>
+#include <platform/CHIPDeviceLayer.h>
 
+#ifdef MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER
 using namespace chip;
 using namespace chip::app;
 using namespace chip::app::Clusters;
 using namespace chip::app::Clusters::OperationalState;
 using namespace chip::app::Clusters::RvcOperationalState;
+using chip::Protocols::InteractionModel::Status;
 
-CHIP_ERROR GenericOperationalStateDelegateImpl::GetOperationalStateAtIndex(size_t index, GenericOperationalState & operationalState)
+static std::unique_ptr<RvcOperationalStateDelegate> gRvcOperationalStateDelegate;
+static std::unique_ptr<RvcOperationalState::Instance> gRvcOperationalStateInstance;
+
+static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data);
+
+DataModel::Nullable<uint32_t> RvcOperationalStateDelegate::GetCountdownTime()
+{
+    if (mRunningTime > mPhaseDuration.Value())
+        return DataModel::NullNullable;
+
+    return DataModel::MakeNullable((uint32_t) (mPhaseDuration.Value() - mRunningTime));
+}
+
+CHIP_ERROR RvcOperationalStateDelegate::GetOperationalStateAtIndex(size_t index, GenericOperationalState & operationalState)
 {
     if (index >= mOperationalStateList.size())
     {
@@ -37,7 +51,7 @@
     return CHIP_NO_ERROR;
 }
 
-CHIP_ERROR GenericOperationalStateDelegateImpl::GetOperationalPhaseAtIndex(size_t index, MutableCharSpan & operationalPhase)
+CHIP_ERROR RvcOperationalStateDelegate::GetOperationalPhaseAtIndex(size_t index, MutableCharSpan & operationalPhase)
 {
     if (index >= mOperationalPhaseList.size())
     {
@@ -46,125 +60,203 @@
     return CopyCharSpanToMutableCharSpan(mOperationalPhaseList[index], operationalPhase);
 }
 
-void GenericOperationalStateDelegateImpl::HandlePauseStateCallback(GenericOperationalError & err)
+void RvcOperationalStateDelegate::HandlePauseStateCallback(GenericOperationalError & err)
 {
     // placeholder implementation
     auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused));
     if (error == CHIP_NO_ERROR)
     {
-        err.Set(to_underlying(ErrorStateEnum::kNoError));
+        err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
     }
     else
     {
-        err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation));
+        err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation));
     }
 }
 
-void GenericOperationalStateDelegateImpl::HandleResumeStateCallback(GenericOperationalError & err)
+void RvcOperationalStateDelegate::HandleResumeStateCallback(GenericOperationalError & err)
 {
     // placeholder implementation
-    auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning));
+    auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning));
     if (error == CHIP_NO_ERROR)
     {
-        err.Set(to_underlying(ErrorStateEnum::kNoError));
+        err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
     }
     else
     {
-        err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation));
+        err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation));
     }
 }
 
-void GenericOperationalStateDelegateImpl::HandleStartStateCallback(GenericOperationalError & err)
+void RvcOperationalStateDelegate::HandleStartStateCallback(GenericOperationalError & err)
+{
+    OperationalState::GenericOperationalError current_err(to_underlying(OperationalState::ErrorStateEnum::kNoError));
+    GetInstance()->GetCurrentOperationalError(current_err);
+
+    if (current_err.errorStateID != to_underlying(OperationalState::ErrorStateEnum::kNoError))
+    {
+        err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToStartOrResume));
+        return;
+    }
+
+    // placeholder implementation
+    auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning));
+    if (error == CHIP_NO_ERROR)
+    {
+        (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, this);
+        err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
+    }
+    else
+    {
+        err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation));
+    }
+}
+
+void RvcOperationalStateDelegate::HandleStopStateCallback(GenericOperationalError & err)
 {
     // placeholder implementation
-    auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning));
+    auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped));
     if (error == CHIP_NO_ERROR)
     {
-        err.Set(to_underlying(ErrorStateEnum::kNoError));
+        (void) DeviceLayer::SystemLayer().CancelTimer(onOperationalStateTimerTick, this);
+
+        OperationalState::GenericOperationalError current_err(to_underlying(OperationalState::ErrorStateEnum::kNoError));
+        GetInstance()->GetCurrentOperationalError(current_err);
+
+        Optional<DataModel::Nullable<uint32_t>> totalTime((DataModel::Nullable<uint32_t>(mRunningTime + mPausedTime)));
+        Optional<DataModel::Nullable<uint32_t>> pausedTime((DataModel::Nullable<uint32_t>(mPausedTime)));
+
+        GetInstance()->OnOperationCompletionDetected(static_cast<uint8_t>(current_err.errorStateID), totalTime, pausedTime);
+
+        mRunningTime = 0;
+        mPausedTime  = 0;
+        err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError));
     }
     else
     {
-        err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation));
+        err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation));
     }
 }
-
-void GenericOperationalStateDelegateImpl::HandleStopStateCallback(GenericOperationalError & err)
+static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data)
 {
-    // placeholder implementation
-    auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kStopped));
-    if (error == CHIP_NO_ERROR)
+    RvcOperationalStateDelegate * delegate = reinterpret_cast<RvcOperationalStateDelegate *>(data);
+
+    OperationalState::Instance * instance = gRvcOperationalStateInstance.get();
+    OperationalState::OperationalStateEnum state =
+        static_cast<OperationalState::OperationalStateEnum>(instance->GetCurrentOperationalState());
+
+    auto countdown_time = delegate->GetCountdownTime();
+
+    if (countdown_time.ValueOr(1) > 0)
     {
-        err.Set(to_underlying(ErrorStateEnum::kNoError));
+        if (state == OperationalState::OperationalStateEnum::kRunning)
+        {
+            delegate->mRunningTime++;
+        }
+        else if (state == OperationalState::OperationalStateEnum::kPaused)
+        {
+            delegate->mPausedTime++;
+        }
+    }
+
+    if (state == OperationalState::OperationalStateEnum::kRunning || state == OperationalState::OperationalStateEnum::kPaused)
+    {
+        (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, delegate);
     }
     else
     {
-        err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation));
+        (void) DeviceLayer::SystemLayer().CancelTimer(onOperationalStateTimerTick, delegate);
     }
 }
 
-// Init Operational State cluster
-
-static OperationalState::Instance * gOperationalStateInstance = nullptr;
-static OperationalStateDelegate * gOperationalStateDelegate   = nullptr;
-
-void OperationalState::Shutdown()
-{
-    if (gOperationalStateInstance != nullptr)
-    {
-        delete gOperationalStateInstance;
-        gOperationalStateInstance = nullptr;
-    }
-    if (gOperationalStateDelegate != nullptr)
-    {
-        delete gOperationalStateDelegate;
-        gOperationalStateDelegate = nullptr;
-    }
-}
-
-void emberAfOperationalStateClusterInitCallback(chip::EndpointId endpointId)
-{
-    VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1.
-    VerifyOrDie(gOperationalStateInstance == nullptr && gOperationalStateDelegate == nullptr);
-
-    gOperationalStateDelegate           = new OperationalStateDelegate;
-    EndpointId operationalStateEndpoint = 0x01;
-    gOperationalStateInstance           = new OperationalState::Instance(gOperationalStateDelegate, operationalStateEndpoint);
-
-    gOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped));
-
-    gOperationalStateInstance->Init();
-}
-
-// Init RVC Operational State cluster
-
-static RvcOperationalState::Instance * gRvcOperationalStateInstance = nullptr;
-static RvcOperationalStateDelegate * gRvcOperationalStateDelegate   = nullptr;
-
 void RvcOperationalState::Shutdown()
 {
-    if (gRvcOperationalStateInstance != nullptr)
+    gRvcOperationalStateInstance.reset();
+    gRvcOperationalStateDelegate.reset();
+}
+
+chip::Protocols::InteractionModel::Status chefRvcOperationalStateWriteCallback(chip::EndpointId endpointId,
+                                                                               chip::ClusterId clusterId,
+                                                                               const EmberAfAttributeMetadata * attributeMetadata,
+                                                                               uint8_t * buffer)
+{
+    chip::Protocols::InteractionModel::Status ret = chip::Protocols::InteractionModel::Status::Success;
+    VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1.
+    VerifyOrDie(gRvcOperationalStateInstance != nullptr);
+    chip::AttributeId attributeId = attributeMetadata->attributeId;
+
+    switch (attributeId)
     {
-        delete gRvcOperationalStateInstance;
-        gRvcOperationalStateInstance = nullptr;
+    case chip::app::Clusters::RvcOperationalState::Attributes::CurrentPhase::Id: {
+        uint8_t m = static_cast<uint8_t>(buffer[0]);
+        DataModel::Nullable<uint8_t> aPhase(m);
+        CHIP_ERROR err = gRvcOperationalStateInstance->SetCurrentPhase(aPhase);
+        if (CHIP_NO_ERROR == err)
+        {
+            break;
+        }
+        ret = chip::Protocols::InteractionModel::Status::ConstraintError;
+        ChipLogError(DeviceLayer, "Invalid Attribute Update status: %" CHIP_ERROR_FORMAT, err.Format());
     }
-    if (gRvcOperationalStateDelegate != nullptr)
+    break;
+    case chip::app::Clusters::RvcOperationalState::Attributes::OperationalState::Id: {
+        uint8_t m      = static_cast<uint8_t>(buffer[0]);
+        CHIP_ERROR err = gRvcOperationalStateInstance->SetOperationalState(m);
+        if (CHIP_NO_ERROR == err)
+        {
+            break;
+        }
+        ret = chip::Protocols::InteractionModel::Status::ConstraintError;
+        ChipLogError(DeviceLayer, "Invalid Attribute Update status: %" CHIP_ERROR_FORMAT, err.Format());
+    }
+    break;
+    default:
+        ret = chip::Protocols::InteractionModel::Status::UnsupportedAttribute;
+        ChipLogError(DeviceLayer, "Unsupported Attribute ID: %d", static_cast<int>(attributeId));
+        break;
+    }
+
+    return ret;
+}
+
+chip::Protocols::InteractionModel::Status chefRvcOperationalStateReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
+                                                                              const EmberAfAttributeMetadata * attributeMetadata,
+                                                                              uint8_t * buffer, uint16_t maxReadLength)
+{
+    chip::Protocols::InteractionModel::Status ret = chip::Protocols::InteractionModel::Status::Success;
+    chip::AttributeId attributeId                 = attributeMetadata->attributeId;
+    switch (attributeId)
     {
-        delete gRvcOperationalStateDelegate;
-        gRvcOperationalStateDelegate = nullptr;
+    case chip::app::Clusters::RvcOperationalState::Attributes::CurrentPhase::Id: {
+
+        app::DataModel::Nullable<uint8_t> currentPhase = gRvcOperationalStateInstance->GetCurrentPhase();
+        if (currentPhase.IsNull())
+        {
+            ret = chip::Protocols::InteractionModel::Status::UnsupportedAttribute;
+            break;
+        }
+        *buffer = currentPhase.Value();
     }
+    break;
+    case chip::app::Clusters::RvcOperationalState::Attributes::OperationalState::Id: {
+        *buffer = gRvcOperationalStateInstance->GetCurrentOperationalState();
+    }
+    break;
+    default:
+        ChipLogError(DeviceLayer, "Unsupported Attribute ID: %d", static_cast<int>(attributeId));
+        break;
+    }
+
+    return ret;
 }
 
 void emberAfRvcOperationalStateClusterInitCallback(chip::EndpointId endpointId)
 {
     VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1.
-    VerifyOrDie(gRvcOperationalStateInstance == nullptr && gRvcOperationalStateDelegate == nullptr);
+    VerifyOrDie(!gRvcOperationalStateDelegate && !gRvcOperationalStateInstance);
 
-    gRvcOperationalStateDelegate        = new RvcOperationalStateDelegate;
-    EndpointId operationalStateEndpoint = 0x01;
-    gRvcOperationalStateInstance        = new RvcOperationalState::Instance(gRvcOperationalStateDelegate, operationalStateEndpoint);
-
-    gRvcOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped));
-
+    gRvcOperationalStateDelegate = std::make_unique<RvcOperationalStateDelegate>();
+    gRvcOperationalStateInstance = std::make_unique<RvcOperationalState::Instance>(gRvcOperationalStateDelegate.get(), endpointId);
     gRvcOperationalStateInstance->Init();
 }
 #endif // MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER
diff --git a/examples/chef/common/chef-rvc-operational-state-delegate.h b/examples/chef/common/chef-rvc-operational-state-delegate.h
index f487e38..33b01d5 100644
--- a/examples/chef/common/chef-rvc-operational-state-delegate.h
+++ b/examples/chef/common/chef-rvc-operational-state-delegate.h
@@ -23,21 +23,26 @@
 
 #include <protocols/interaction_model/StatusCode.h>
 
+#ifdef MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER
+using chip::Protocols::InteractionModel::Status;
+
 namespace chip {
 namespace app {
 namespace Clusters {
 
-namespace OperationalState {
+namespace RvcOperationalState {
 
 // This is an application level delegate to handle operational state commands according to the specific business logic.
-class GenericOperationalStateDelegateImpl : public Delegate
+class RvcOperationalStateDelegate : public RvcOperationalState::Delegate
 {
 public:
+    RvcOperationalStateDelegate() { mOperationalStateList = Span<const OperationalState::GenericOperationalState>(rvcOpStateList); }
+
     /**
      * Get the countdown time. This attribute is not used in this application.
      * @return The current countdown time.
      */
-    app::DataModel::Nullable<uint32_t> GetCountdownTime() override { return {}; };
+    app::DataModel::Nullable<uint32_t> GetCountdownTime() override;
 
     /**
      * Fills in the provided GenericOperationalState with the state at index `index` if there is one,
@@ -47,7 +52,7 @@
      * @param index The index of the state, with 0 representing the first state.
      * @param operationalState  The GenericOperationalState is filled.
      */
-    CHIP_ERROR GetOperationalStateAtIndex(size_t index, GenericOperationalState & operationalState) override;
+    CHIP_ERROR GetOperationalStateAtIndex(size_t index, OperationalState::GenericOperationalState & operationalState) override;
 
     /**
      * Fills in the provided MutableCharSpan with the phase at index `index` if there is one,
@@ -68,59 +73,34 @@
      * Handle Command Callback in application: Pause
      * @param[out] get operational error after callback.
      */
-    void HandlePauseStateCallback(GenericOperationalError & err) override;
+    void HandlePauseStateCallback(OperationalState::GenericOperationalError & err) override;
 
     /**
      * Handle Command Callback in application: Resume
      * @param[out] get operational error after callback.
      */
-    void HandleResumeStateCallback(GenericOperationalError & err) override;
+    void HandleResumeStateCallback(OperationalState::GenericOperationalError & err) override;
 
     /**
      * Handle Command Callback in application: Start
      * @param[out] get operational error after callback.
      */
-    void HandleStartStateCallback(GenericOperationalError & err) override;
+    void HandleStartStateCallback(OperationalState::GenericOperationalError & err) override;
 
     /**
      * Handle Command Callback in application: Stop
      * @param[out] get operational error after callback.
      */
-    void HandleStopStateCallback(GenericOperationalError & err) override;
+    void HandleStopStateCallback(OperationalState::GenericOperationalError & err) override;
 
-protected:
-    Span<const GenericOperationalState> mOperationalStateList;
+    uint32_t mRunningTime = 0;
+    uint32_t mPausedTime  = 0;
+    app::DataModel::Nullable<uint32_t> mPhaseDuration;
+
+private:
+    Span<const OperationalState::GenericOperationalState> mOperationalStateList;
     Span<const CharSpan> mOperationalPhaseList;
-};
 
-// This is an application level delegate to handle operational state commands according to the specific business logic.
-class OperationalStateDelegate : public GenericOperationalStateDelegateImpl
-{
-private:
-    const GenericOperationalState opStateList[4] = {
-        GenericOperationalState(to_underlying(OperationalStateEnum::kStopped)),
-        GenericOperationalState(to_underlying(OperationalStateEnum::kRunning)),
-        GenericOperationalState(to_underlying(OperationalStateEnum::kPaused)),
-        GenericOperationalState(to_underlying(OperationalStateEnum::kError)),
-    };
-
-public:
-    OperationalStateDelegate()
-    {
-        GenericOperationalStateDelegateImpl::mOperationalStateList = Span<const GenericOperationalState>(opStateList);
-    }
-};
-
-void Shutdown();
-
-} // namespace OperationalState
-
-namespace RvcOperationalState {
-
-// This is an application level delegate to handle operational state commands according to the specific business logic.
-class RvcOperationalStateDelegate : public OperationalState::GenericOperationalStateDelegateImpl
-{
-private:
     const OperationalState::GenericOperationalState rvcOpStateList[7] = {
         OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)),
         OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)),
@@ -131,13 +111,6 @@
         OperationalState::GenericOperationalState(to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kCharging)),
         OperationalState::GenericOperationalState(to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kDocked)),
     };
-
-public:
-    RvcOperationalStateDelegate()
-    {
-        GenericOperationalStateDelegateImpl::mOperationalStateList =
-            Span<const OperationalState::GenericOperationalState>(rvcOpStateList);
-    }
 };
 
 void Shutdown();
@@ -146,3 +119,11 @@
 } // namespace Clusters
 } // namespace app
 } // namespace chip
+
+chip::Protocols::InteractionModel::Status chefRvcOperationalStateWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
+                                                                               const EmberAfAttributeMetadata * attributeMetadata,
+                                                                               uint8_t * buffer);
+chip::Protocols::InteractionModel::Status chefRvcOperationalStateReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId,
+                                                                              const EmberAfAttributeMetadata * attributeMetadata,
+                                                                              uint8_t * buffer, uint16_t maxReadLength);
+#endif // MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER
diff --git a/examples/chef/common/stubs.cpp b/examples/chef/common/stubs.cpp
index 437dfe9..c0935df 100644
--- a/examples/chef/common/stubs.cpp
+++ b/examples/chef/common/stubs.cpp
@@ -19,6 +19,14 @@
 #include "chef-concentration-measurement.h"
 #endif
 
+#if defined(MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER) || defined(MATTER_DM_PLUGIN_RVC_CLEAN_MODE_SERVER)
+#include "chef-rvc-mode-delegate.h"
+#endif
+
+#ifdef MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER
+#include "chef-rvc-operational-state-delegate.h"
+#endif
+
 using chip::app::DataModel::Nullable;
 
 using namespace chip;
@@ -57,6 +65,18 @@
     case chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id:
         return chefConcentrationMeasurementReadCallback(endpoint, clusterId, attributeMetadata, buffer, maxReadLength);
 #endif
+#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
+    case chip::app::Clusters::RvcRunMode::Id:
+        return chefRvcRunModeReadCallback(endpoint, clusterId, attributeMetadata, buffer, maxReadLength);
+#endif
+#ifdef MATTER_DM_PLUGIN_RVC_CLEAN_MODE_SERVER
+    case chip::app::Clusters::RvcCleanMode::Id:
+        return chefRvcCleanModeReadCallback(endpoint, clusterId, attributeMetadata, buffer, maxReadLength);
+#endif
+#ifdef MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER
+    case chip::app::Clusters::RvcOperationalState::Id:
+        return chefRvcOperationalStateReadCallback(endpoint, clusterId, attributeMetadata, buffer, maxReadLength);
+#endif
     default:
         break;
     }
@@ -105,6 +125,18 @@
     case chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id:
         return chefConcentrationMeasurementWriteCallback(endpoint, clusterId, attributeMetadata, buffer);
 #endif
+#ifdef MATTER_DM_PLUGIN_RVC_RUN_MODE_SERVER
+    case chip::app::Clusters::RvcRunMode::Id:
+        return chefRvcRunModeWriteCallback(endpoint, clusterId, attributeMetadata, buffer);
+#endif
+#ifdef MATTER_DM_PLUGIN_RVC_CLEAN_MODE_SERVER
+    case chip::app::Clusters::RvcCleanMode::Id:
+        return chefRvcCleanModeWriteCallback(endpoint, clusterId, attributeMetadata, buffer);
+#endif
+#ifdef MATTER_DM_PLUGIN_RVC_OPERATIONAL_STATE_SERVER
+    case chip::app::Clusters::RvcOperationalState::Id:
+        return chefRvcOperationalStateWriteCallback(endpoint, clusterId, attributeMetadata, buffer);
+#endif
     default:
         break;
     }
diff --git a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter
index f2ab0c3..0d5013c 100644
--- a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter
+++ b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter
@@ -333,6 +333,265 @@
   command MfgSpecificPing(): DefaultSuccess = 0;
 }
 
+/** This cluster is used to describe the configuration and capabilities of a physical power source that provides power to the Node. */
+cluster PowerSource = 47 {
+  revision 1; // NOTE: Default/not specifically set
+
+  enum BatApprovedChemistryEnum : enum16 {
+    kUnspecified = 0;
+    kAlkaline = 1;
+    kLithiumCarbonFluoride = 2;
+    kLithiumChromiumOxide = 3;
+    kLithiumCopperOxide = 4;
+    kLithiumIronDisulfide = 5;
+    kLithiumManganeseDioxide = 6;
+    kLithiumThionylChloride = 7;
+    kMagnesium = 8;
+    kMercuryOxide = 9;
+    kNickelOxyhydride = 10;
+    kSilverOxide = 11;
+    kZincAir = 12;
+    kZincCarbon = 13;
+    kZincChloride = 14;
+    kZincManganeseDioxide = 15;
+    kLeadAcid = 16;
+    kLithiumCobaltOxide = 17;
+    kLithiumIon = 18;
+    kLithiumIonPolymer = 19;
+    kLithiumIronPhosphate = 20;
+    kLithiumSulfur = 21;
+    kLithiumTitanate = 22;
+    kNickelCadmium = 23;
+    kNickelHydrogen = 24;
+    kNickelIron = 25;
+    kNickelMetalHydride = 26;
+    kNickelZinc = 27;
+    kSilverZinc = 28;
+    kSodiumIon = 29;
+    kSodiumSulfur = 30;
+    kZincBromide = 31;
+    kZincCerium = 32;
+  }
+
+  enum BatChargeFaultEnum : enum8 {
+    kUnspecified = 0;
+    kAmbientTooHot = 1;
+    kAmbientTooCold = 2;
+    kBatteryTooHot = 3;
+    kBatteryTooCold = 4;
+    kBatteryAbsent = 5;
+    kBatteryOverVoltage = 6;
+    kBatteryUnderVoltage = 7;
+    kChargerOverVoltage = 8;
+    kChargerUnderVoltage = 9;
+    kSafetyTimeout = 10;
+  }
+
+  enum BatChargeLevelEnum : enum8 {
+    kOK = 0;
+    kWarning = 1;
+    kCritical = 2;
+  }
+
+  enum BatChargeStateEnum : enum8 {
+    kUnknown = 0;
+    kIsCharging = 1;
+    kIsAtFullCharge = 2;
+    kIsNotCharging = 3;
+  }
+
+  enum BatCommonDesignationEnum : enum16 {
+    kUnspecified = 0;
+    kAAA = 1;
+    kAA = 2;
+    kC = 3;
+    kD = 4;
+    k4v5 = 5;
+    k6v0 = 6;
+    k9v0 = 7;
+    k12AA = 8;
+    kAAAA = 9;
+    kA = 10;
+    kB = 11;
+    kF = 12;
+    kN = 13;
+    kNo6 = 14;
+    kSubC = 15;
+    kA23 = 16;
+    kA27 = 17;
+    kBA5800 = 18;
+    kDuplex = 19;
+    k4SR44 = 20;
+    k523 = 21;
+    k531 = 22;
+    k15v0 = 23;
+    k22v5 = 24;
+    k30v0 = 25;
+    k45v0 = 26;
+    k67v5 = 27;
+    kJ = 28;
+    kCR123A = 29;
+    kCR2 = 30;
+    k2CR5 = 31;
+    kCRP2 = 32;
+    kCRV3 = 33;
+    kSR41 = 34;
+    kSR43 = 35;
+    kSR44 = 36;
+    kSR45 = 37;
+    kSR48 = 38;
+    kSR54 = 39;
+    kSR55 = 40;
+    kSR57 = 41;
+    kSR58 = 42;
+    kSR59 = 43;
+    kSR60 = 44;
+    kSR63 = 45;
+    kSR64 = 46;
+    kSR65 = 47;
+    kSR66 = 48;
+    kSR67 = 49;
+    kSR68 = 50;
+    kSR69 = 51;
+    kSR516 = 52;
+    kSR731 = 53;
+    kSR712 = 54;
+    kLR932 = 55;
+    kA5 = 56;
+    kA10 = 57;
+    kA13 = 58;
+    kA312 = 59;
+    kA675 = 60;
+    kAC41E = 61;
+    k10180 = 62;
+    k10280 = 63;
+    k10440 = 64;
+    k14250 = 65;
+    k14430 = 66;
+    k14500 = 67;
+    k14650 = 68;
+    k15270 = 69;
+    k16340 = 70;
+    kRCR123A = 71;
+    k17500 = 72;
+    k17670 = 73;
+    k18350 = 74;
+    k18500 = 75;
+    k18650 = 76;
+    k19670 = 77;
+    k25500 = 78;
+    k26650 = 79;
+    k32600 = 80;
+  }
+
+  enum BatFaultEnum : enum8 {
+    kUnspecified = 0;
+    kOverTemp = 1;
+    kUnderTemp = 2;
+  }
+
+  enum BatReplaceabilityEnum : enum8 {
+    kUnspecified = 0;
+    kNotReplaceable = 1;
+    kUserReplaceable = 2;
+    kFactoryReplaceable = 3;
+  }
+
+  enum PowerSourceStatusEnum : enum8 {
+    kUnspecified = 0;
+    kActive = 1;
+    kStandby = 2;
+    kUnavailable = 3;
+  }
+
+  enum WiredCurrentTypeEnum : enum8 {
+    kAC = 0;
+    kDC = 1;
+  }
+
+  enum WiredFaultEnum : enum8 {
+    kUnspecified = 0;
+    kOverVoltage = 1;
+    kUnderVoltage = 2;
+  }
+
+  bitmap Feature : bitmap32 {
+    kWired = 0x1;
+    kBattery = 0x2;
+    kRechargeable = 0x4;
+    kReplaceable = 0x8;
+  }
+
+  struct BatChargeFaultChangeType {
+    BatChargeFaultEnum current[] = 0;
+    BatChargeFaultEnum previous[] = 1;
+  }
+
+  struct BatFaultChangeType {
+    BatFaultEnum current[] = 0;
+    BatFaultEnum previous[] = 1;
+  }
+
+  struct WiredFaultChangeType {
+    WiredFaultEnum current[] = 0;
+    WiredFaultEnum previous[] = 1;
+  }
+
+  info event WiredFaultChange = 0 {
+    WiredFaultEnum current[] = 0;
+    WiredFaultEnum previous[] = 1;
+  }
+
+  info event BatFaultChange = 1 {
+    BatFaultEnum current[] = 0;
+    BatFaultEnum previous[] = 1;
+  }
+
+  info event BatChargeFaultChange = 2 {
+    BatChargeFaultEnum current[] = 0;
+    BatChargeFaultEnum previous[] = 1;
+  }
+
+  readonly attribute PowerSourceStatusEnum status = 0;
+  readonly attribute int8u order = 1;
+  readonly attribute char_string<60> description = 2;
+  readonly attribute optional nullable int32u wiredAssessedInputVoltage = 3;
+  readonly attribute optional nullable int16u wiredAssessedInputFrequency = 4;
+  readonly attribute optional WiredCurrentTypeEnum wiredCurrentType = 5;
+  readonly attribute optional nullable int32u wiredAssessedCurrent = 6;
+  readonly attribute optional int32u wiredNominalVoltage = 7;
+  readonly attribute optional int32u wiredMaximumCurrent = 8;
+  readonly attribute optional boolean wiredPresent = 9;
+  readonly attribute optional WiredFaultEnum activeWiredFaults[] = 10;
+  readonly attribute optional nullable int32u batVoltage = 11;
+  readonly attribute optional nullable int8u batPercentRemaining = 12;
+  readonly attribute optional nullable int32u batTimeRemaining = 13;
+  readonly attribute optional BatChargeLevelEnum batChargeLevel = 14;
+  readonly attribute optional boolean batReplacementNeeded = 15;
+  readonly attribute optional BatReplaceabilityEnum batReplaceability = 16;
+  readonly attribute optional boolean batPresent = 17;
+  readonly attribute optional BatFaultEnum activeBatFaults[] = 18;
+  readonly attribute optional char_string<60> batReplacementDescription = 19;
+  readonly attribute optional BatCommonDesignationEnum batCommonDesignation = 20;
+  readonly attribute optional char_string<20> batANSIDesignation = 21;
+  readonly attribute optional char_string<20> batIECDesignation = 22;
+  readonly attribute optional BatApprovedChemistryEnum batApprovedChemistry = 23;
+  readonly attribute optional int32u batCapacity = 24;
+  readonly attribute optional int8u batQuantity = 25;
+  readonly attribute optional BatChargeStateEnum batChargeState = 26;
+  readonly attribute optional nullable int32u batTimeToFullCharge = 27;
+  readonly attribute optional boolean batFunctionalWhileCharging = 28;
+  readonly attribute optional nullable int32u batChargingCurrent = 29;
+  readonly attribute optional BatChargeFaultEnum activeBatChargeFaults[] = 30;
+  readonly attribute endpoint_no endpointList[] = 31;
+  readonly attribute command_id generatedCommandList[] = 65528;
+  readonly attribute command_id acceptedCommandList[] = 65529;
+  readonly attribute event_id eventList[] = 65530;
+  readonly attribute attrib_id attributeList[] = 65531;
+  readonly attribute bitmap32 featureMap = 65532;
+  readonly attribute int16u clusterRevision = 65533;
+}
+
 /** This cluster is used to manage global aspects of the Commissioning flow. */
 cluster GeneralCommissioning = 48 {
   revision 1; // NOTE: Default/not specifically set
@@ -1366,6 +1625,7 @@
   }
 }
 endpoint 1 {
+  device type ma_powersource = 17, version 1;
   device type ma_robotic_vacuum_cleaner = 116, version 1;
 
 
@@ -1417,6 +1677,22 @@
     callback attribute clusterRevision;
   }
 
+  server cluster PowerSource {
+    ram      attribute status;
+    ram      attribute order;
+    ram      attribute description;
+    ram      attribute batPercentRemaining default = 95;
+    ram      attribute batPresent default = 1;
+    ram      attribute batChargeState default = 4;
+    callback attribute endpointList;
+    callback attribute generatedCommandList;
+    callback attribute acceptedCommandList;
+    callback attribute eventList;
+    callback attribute attributeList;
+    ram      attribute featureMap default = 0;
+    ram      attribute clusterRevision default = 1;
+  }
+
   server cluster RvcRunMode {
     callback attribute supportedModes;
     callback attribute currentMode;
diff --git a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.zap b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.zap
index 3c058e9..15c155d 100644
--- a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.zap
+++ b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.zap
@@ -1,6 +1,6 @@
 {
   "fileFormat": 2,
-  "featureLevel": 100,
+  "featureLevel": 102,
   "creator": "zap",
   "keyValuePairs": [
     {
@@ -29,6 +29,7 @@
       "pathRelativity": "relativeToZap",
       "path": "../../../src/app/zap-templates/app-templates.json",
       "type": "gen-templates-json",
+      "category": "matter",
       "version": "chip-v1"
     }
   ],
@@ -1924,13 +1925,19 @@
       "id": 2,
       "name": "Anonymous Endpoint Type",
       "deviceTypeRef": {
-        "code": 116,
+        "code": 17,
         "profileId": 259,
-        "label": "MA-robotic-vacuum-cleaner",
-        "name": "MA-robotic-vacuum-cleaner"
+        "label": "MA-powersource",
+        "name": "MA-powersource"
       },
       "deviceTypes": [
         {
+          "code": 17,
+          "profileId": 259,
+          "label": "MA-powersource",
+          "name": "MA-powersource"
+        },
+        {
           "code": 116,
           "profileId": 259,
           "label": "MA-robotic-vacuum-cleaner",
@@ -1938,13 +1945,15 @@
         }
       ],
       "deviceVersions": [
+        1,
         1
       ],
       "deviceIdentifiers": [
+        17,
         116
       ],
-      "deviceTypeName": "MA-robotic-vacuum-cleaner",
-      "deviceTypeCode": 116,
+      "deviceTypeName": "MA-powersource",
+      "deviceTypeCode": 17,
       "deviceTypeProfileId": 259,
       "clusters": [
         {
@@ -2342,7 +2351,7 @@
               "singleton": 0,
               "bounded": 0,
               "defaultValue": null,
-              "reportable": 1,
+              "reportable": 0,
               "minInterval": 1,
               "maxInterval": 65534,
               "reportableChange": 0
@@ -2358,7 +2367,7 @@
               "singleton": 0,
               "bounded": 0,
               "defaultValue": null,
-              "reportable": 1,
+              "reportable": 0,
               "minInterval": 1,
               "maxInterval": 65534,
               "reportableChange": 0
@@ -2374,7 +2383,7 @@
               "singleton": 0,
               "bounded": 0,
               "defaultValue": null,
-              "reportable": 1,
+              "reportable": 0,
               "minInterval": 1,
               "maxInterval": 65534,
               "reportableChange": 0
@@ -2478,6 +2487,224 @@
           ]
         },
         {
+          "name": "Power Source",
+          "code": 47,
+          "mfgCode": null,
+          "define": "POWER_SOURCE_CLUSTER",
+          "side": "server",
+          "enabled": 1,
+          "attributes": [
+            {
+              "name": "Status",
+              "code": 0,
+              "mfgCode": null,
+              "side": "server",
+              "type": "PowerSourceStatusEnum",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "Order",
+              "code": 1,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int8u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "Description",
+              "code": 2,
+              "mfgCode": null,
+              "side": "server",
+              "type": "char_string",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "BatPercentRemaining",
+              "code": 12,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int8u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "95",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "BatPresent",
+              "code": 17,
+              "mfgCode": null,
+              "side": "server",
+              "type": "boolean",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "BatChargeState",
+              "code": 26,
+              "mfgCode": null,
+              "side": "server",
+              "type": "BatChargeStateEnum",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "4",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EndpointList",
+              "code": 31,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": null,
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "GeneratedCommandList",
+              "code": 65528,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": null,
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AcceptedCommandList",
+              "code": 65529,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": null,
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "EventList",
+              "code": 65530,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": null,
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "AttributeList",
+              "code": 65531,
+              "mfgCode": null,
+              "side": "server",
+              "type": "array",
+              "included": 1,
+              "storageOption": "External",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": null,
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "FeatureMap",
+              "code": 65532,
+              "mfgCode": null,
+              "side": "server",
+              "type": "bitmap32",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "0",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            },
+            {
+              "name": "ClusterRevision",
+              "code": 65533,
+              "mfgCode": null,
+              "side": "server",
+              "type": "int16u",
+              "included": 1,
+              "storageOption": "RAM",
+              "singleton": 0,
+              "bounded": 0,
+              "defaultValue": "1",
+              "reportable": 1,
+              "minInterval": 1,
+              "maxInterval": 65534,
+              "reportableChange": 0
+            }
+          ]
+        },
+        {
           "name": "RVC Run Mode",
           "code": 84,
           "mfgCode": null,
diff --git a/integrations/cloudbuild/chef.yaml b/integrations/cloudbuild/chef.yaml
index 7ff067f..95cba5a 100644
--- a/integrations/cloudbuild/chef.yaml
+++ b/integrations/cloudbuild/chef.yaml
@@ -29,7 +29,7 @@
       args:
           - >-
               perl -i -pe 's/^gdbgui==/# gdbgui==/' /opt/espressif/esp-idf/requirements.txt &&
-              ./examples/chef/chef.py --build_all --build_exclude noip\|roboticvacuumcleaner
+              ./examples/chef/chef.py --build_all
       id: CompileAll
       waitFor:
           - Bootstrap