diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index ad7cb56245f2bd..95590d1f1fa7a5 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -3420,6 +3420,8 @@ cluster RvcOperationalState = 97 { command Start(): OperationalCommandResponse = 2; /** Upon receipt, the device SHALL resume its operation from the point it was at when it received the Pause command, or from the point when it was paused by means outside of this cluster (for example by manual button press). */ command Resume(): OperationalCommandResponse = 3; + /** On receipt of this command, the device SHALL start seeking the charging dock, if possible in the current state of the device. */ + command GoHome(): OperationalCommandResponse = 128; } /** Attributes and commands for scene configuration and manipulation. */ @@ -7786,6 +7788,7 @@ endpoint 1 { handle command Pause; handle command Resume; handle command OperationalCommandResponse; + handle command GoHome; } server cluster ScenesManagement { diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index 9013ea3140e6db..45499b5d44ce3e 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -11262,6 +11262,14 @@ "source": "server", "isIncoming": 0, "isEnabled": 1 + }, + { + "name": "GoHome", + "code": 128, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ diff --git a/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h b/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h index c8d63c2bb6efc2..0bcb76f324a1da 100644 --- a/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h +++ b/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h @@ -111,38 +111,11 @@ class OperationalStateDelegate : public GenericOperationalStateDelegateImpl } }; -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)), - OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)), - OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kError)), - OperationalState::GenericOperationalState( - to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kSeekingCharger)), - OperationalState::GenericOperationalState(to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kCharging)), - OperationalState::GenericOperationalState(to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kDocked)), - }; - -public: - RvcOperationalStateDelegate() - { - GenericOperationalStateDelegateImpl::mOperationalStateList = - Span(rvcOpStateList); - } -}; +Instance * GetOperationalStateInstance(); void Shutdown(); -} // namespace RvcOperationalState +} // namespace OperationalState } // namespace Clusters } // namespace app } // namespace chip diff --git a/examples/all-clusters-app/ameba/main/include/OperationalStateManager.h b/examples/all-clusters-app/all-clusters-common/include/rvc-operational-state-delegate-impl.h similarity index 64% rename from examples/all-clusters-app/ameba/main/include/OperationalStateManager.h rename to examples/all-clusters-app/all-clusters-common/include/rvc-operational-state-delegate-impl.h index 2183e92078e6c7..89a3e69c5b8bed 100644 --- a/examples/all-clusters-app/ameba/main/include/OperationalStateManager.h +++ b/examples/all-clusters-app/all-clusters-common/include/rvc-operational-state-delegate-impl.h @@ -23,20 +23,34 @@ #include #include -void getOperationalStateSet(u8 state); - namespace chip { namespace app { namespace Clusters { -namespace OperationalState { - -Instance * GetOperationalStateInstance(); +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 Delegate { +private: + const Clusters::OperationalState::GenericOperationalState rvcOpStateList[7] = { + OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)), + OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)), + OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)), + OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kError)), + OperationalState::GenericOperationalState( + to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kSeekingCharger)), + OperationalState::GenericOperationalState(to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kCharging)), + OperationalState::GenericOperationalState(to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kDocked)), + }; + + Span mOperationalStateList = + Span(rvcOpStateList); + Span mOperationalPhaseList; + public: + RvcOperationalStateDelegate() {} + /** * Get the countdown time. This attribute is not used in this application. * @return The current countdown time. @@ -51,19 +65,15 @@ class GenericOperationalStateDelegateImpl : public Delegate * @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, + * Fills in the provided GenericOperationalPhase with the phase at index `index` if there is one, * or returns CHIP_ERROR_NOT_FOUND if the index is out of range for the list of phases. - * - * If CHIP_ERROR_NOT_FOUND is returned for index 0, that indicates that the PhaseList attribute is null - * (there are no phases defined at all). - * * Note: This is used by the SDK to populate the phase list attribute. If the contents of this list changes, the * device SHALL call the Instance's ReportPhaseListChange method to report that this attribute has changed. * @param index The index of the phase, with 0 representing the first phase. - * @param operationalPhase The MutableCharSpan is filled. + * @param operationalPhase The GenericOperationalPhase is filled. */ CHIP_ERROR GetOperationalPhaseAtIndex(size_t index, MutableCharSpan & operationalPhase) override; @@ -72,82 +82,37 @@ class GenericOperationalStateDelegateImpl : public Delegate * 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; - -protected: - Span mOperationalStateList; - Span 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)), - }; + void HandleStopStateCallback(OperationalState::GenericOperationalError & err) override; -public: - OperationalStateDelegate() - { - GenericOperationalStateDelegateImpl::mOperationalStateList = Span(opStateList); - } + /** + * Handle the GoHome command. + * @param err + */ + void HandleGoHomeCommandCallback(OperationalState::GenericOperationalError & err) override; }; void Shutdown(); -} // namespace OperationalState - -namespace RvcOperationalState { - Instance * GetRvcOperationalStateInstance(); -// 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)), - OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)), - OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kError)), - OperationalState::GenericOperationalState( - to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kSeekingCharger)), - OperationalState::GenericOperationalState(to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kCharging)), - OperationalState::GenericOperationalState(to_underlying(Clusters::RvcOperationalState::OperationalStateEnum::kDocked)), - }; - -public: - RvcOperationalStateDelegate() - { - GenericOperationalStateDelegateImpl::mOperationalStateList = - Span(rvcOpStateList); - } -}; - -void Shutdown(); - } // namespace RvcOperationalState } // namespace Clusters } // namespace app diff --git a/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp b/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp index c78f34e9a8f31f..9297cd79960b89 100644 --- a/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp @@ -1,3 +1,20 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include using namespace chip::app::Clusters; diff --git a/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp b/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp index 02bcd4a775a07e..3370d75bd65f35 100644 --- a/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp @@ -103,6 +103,11 @@ void GenericOperationalStateDelegateImpl::HandleStopStateCallback(GenericOperati static OperationalState::Instance * gOperationalStateInstance = nullptr; static OperationalStateDelegate * gOperationalStateDelegate = nullptr; +OperationalState::Instance * OperationalState::GetOperationalStateInstance() +{ + return gOperationalStateInstance; +} + void OperationalState::Shutdown() { if (gOperationalStateInstance != nullptr) @@ -130,36 +135,3 @@ void emberAfOperationalStateClusterInitCallback(chip::EndpointId endpointId) gOperationalStateInstance->Init(); } - -// Init RVC Operational State cluster - -static OperationalState::Instance * gRvcOperationalStateInstance = nullptr; -static RvcOperationalStateDelegate * gRvcOperationalStateDelegate = nullptr; - -void RvcOperationalState::Shutdown() -{ - if (gRvcOperationalStateInstance != nullptr) - { - delete gRvcOperationalStateInstance; - gRvcOperationalStateInstance = nullptr; - } - if (gRvcOperationalStateDelegate != nullptr) - { - delete gRvcOperationalStateDelegate; - gRvcOperationalStateDelegate = nullptr; - } -} - -void emberAfRvcOperationalStateClusterInitCallback(chip::EndpointId endpointId) -{ - VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. - VerifyOrDie(gRvcOperationalStateInstance == nullptr && gRvcOperationalStateDelegate == nullptr); - - gRvcOperationalStateDelegate = new RvcOperationalStateDelegate; - EndpointId operationalStateEndpoint = 0x01; - gRvcOperationalStateInstance = new RvcOperationalState::Instance(gRvcOperationalStateDelegate, operationalStateEndpoint); - - gRvcOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)); - - gRvcOperationalStateInstance->Init(); -} diff --git a/examples/all-clusters-app/ameba/main/OperationalStateManager.cpp b/examples/all-clusters-app/all-clusters-common/src/rvc-operational-state-delegate-impl.cpp similarity index 53% rename from examples/all-clusters-app/ameba/main/OperationalStateManager.cpp rename to examples/all-clusters-app/all-clusters-common/src/rvc-operational-state-delegate-impl.cpp index 8dbeda60d75526..946110bb18906c 100644 --- a/examples/all-clusters-app/ameba/main/OperationalStateManager.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/rvc-operational-state-delegate-impl.cpp @@ -15,15 +15,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; -using namespace chip::app::Clusters::OperationalState; using namespace chip::app::Clusters::RvcOperationalState; -CHIP_ERROR GenericOperationalStateDelegateImpl::GetOperationalStateAtIndex(size_t index, GenericOperationalState & operationalState) +CHIP_ERROR RvcOperationalStateDelegate::GetOperationalStateAtIndex(size_t index, + OperationalState::GenericOperationalState & operationalState) { if (index >= mOperationalStateList.size()) { @@ -33,7 +33,7 @@ CHIP_ERROR GenericOperationalStateDelegateImpl::GetOperationalStateAtIndex(size_ 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()) { @@ -42,98 +42,76 @@ CHIP_ERROR GenericOperationalStateDelegateImpl::GetOperationalPhaseAtIndex(size_ return CopyCharSpanToMutableCharSpan(mOperationalPhaseList[index], operationalPhase); } -void GenericOperationalStateDelegateImpl::HandlePauseStateCallback(GenericOperationalError & err) +void RvcOperationalStateDelegate::HandlePauseStateCallback(OperationalState::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(OperationalState::GenericOperationalError & err) { - auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); + // placeholder implementation + 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(OperationalState::GenericOperationalError & err) { - auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); + // placeholder implementation + 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::HandleStopStateCallback(GenericOperationalError & err) +void RvcOperationalStateDelegate::HandleStopStateCallback(OperationalState::GenericOperationalError & err) { - auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kStopped)); + // placeholder implementation + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)); 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)); } } -// Init Operational State cluster - -static OperationalState::Instance * gOperationalStateInstance = nullptr; -static OperationalStateDelegate * gOperationalStateDelegate = nullptr; - -void OperationalState::Shutdown() +void RvcOperationalStateDelegate::HandleGoHomeCommandCallback(OperationalState::GenericOperationalError & err) { - if (gOperationalStateInstance != nullptr) + // placeholder implementation + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kSeekingCharger)); + if (error == CHIP_NO_ERROR) { - delete gOperationalStateInstance; - gOperationalStateInstance = nullptr; + err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError)); } - if (gOperationalStateDelegate != nullptr) + else { - delete gOperationalStateDelegate; - gOperationalStateDelegate = nullptr; + err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation)); } } -OperationalState::Instance * OperationalState::GetOperationalStateInstance() -{ - return gOperationalStateInstance; -} - -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; diff --git a/examples/all-clusters-app/ameba/chip_main.cmake b/examples/all-clusters-app/ameba/chip_main.cmake index 66528a9941141a..6cc76ad25e7dd8 100755 --- a/examples/all-clusters-app/ameba/chip_main.cmake +++ b/examples/all-clusters-app/ameba/chip_main.cmake @@ -166,13 +166,14 @@ list( ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/rvc-operational-state-delegate-impl.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/chipinterface.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/BindingHandler.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/DeviceCallbacks.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/CHIPDeviceManager.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/Globals.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/LEDWidget.cpp - ${chip_dir}/examples/all-clusters-app/ameba/main/OperationalStateManager.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp ${chip_dir}/examples/all-clusters-app/ameba/main/SmokeCOAlarmManager.cpp diff --git a/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h b/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h index 5d4373597a2d00..fc2825576e6b72 100644 --- a/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h +++ b/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h @@ -18,7 +18,8 @@ #include "controller/InvokeInteraction.h" #include "controller/ReadInteraction.h" -#include +#include "operational-state-delegate-impl.h" +#include "rvc-operational-state-delegate-impl.h" #if CONFIG_ENABLE_CHIP_SHELL #include "lib/shell/Engine.h" diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index 8b031d769773e4..3b93e7605d5c65 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -39,6 +39,7 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/oven-modes.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-delegates.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/rvc-modes.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/rvc-operational-state-delegate-impl.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index 49ee513ca33f95..a3040c39d0d175 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -30,6 +30,7 @@ #include "oven-modes.h" #include "resource-monitoring-delegates.h" #include "rvc-modes.h" +#include "rvc-operational-state-delegate-impl.h" #include "tcc-mode.h" #include #include diff --git a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter index cea46e31fad3fc..fa836fe8b0c5e2 100644 --- a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter +++ b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter @@ -1178,6 +1178,8 @@ cluster RvcOperationalState = 97 { command Start(): OperationalCommandResponse = 2; /** Upon receipt, the device SHALL resume its operation from the point it was at when it received the Pause command, or from the point when it was paused by means outside of this cluster (for example by manual button press). */ command Resume(): OperationalCommandResponse = 3; + /** On receipt of this command, the device SHALL start seeking the charging dock, if possible in the current state of the device. */ + command GoHome(): OperationalCommandResponse = 128; } endpoint 0 { diff --git a/examples/rvc-app/rvc-common/include/rvc-operational-state-delegate.h b/examples/rvc-app/rvc-common/include/rvc-operational-state-delegate.h index d69843d6de8fb8..400dfd67910234 100644 --- a/examples/rvc-app/rvc-common/include/rvc-operational-state-delegate.h +++ b/examples/rvc-app/rvc-common/include/rvc-operational-state-delegate.h @@ -34,7 +34,7 @@ typedef void (RvcDevice::*HandleOpStateCommand)(Clusters::OperationalState::Gene namespace RvcOperationalState { // This is an application level delegate to handle operational state commands according to the specific business logic. -class RvcOperationalStateDelegate : public OperationalState::Delegate +class RvcOperationalStateDelegate : public RvcOperationalState::Delegate { private: const Clusters::OperationalState::GenericOperationalState mOperationalStateList[7] = { diff --git a/examples/rvc-app/rvc-common/rvc-app.matter b/examples/rvc-app/rvc-common/rvc-app.matter index 6db104d8eac315..2579d7253054fb 100644 --- a/examples/rvc-app/rvc-common/rvc-app.matter +++ b/examples/rvc-app/rvc-common/rvc-app.matter @@ -1101,6 +1101,8 @@ cluster RvcOperationalState = 97 { command Start(): OperationalCommandResponse = 2; /** Upon receipt, the device SHALL resume its operation from the point it was at when it received the Pause command, or from the point when it was paused by means outside of this cluster (for example by manual button press). */ command Resume(): OperationalCommandResponse = 3; + /** On receipt of this command, the device SHALL start seeking the charging dock, if possible in the current state of the device. */ + command GoHome(): OperationalCommandResponse = 128; } endpoint 0 { @@ -1352,6 +1354,7 @@ endpoint 1 { handle command Pause; handle command Resume; handle command OperationalCommandResponse; + handle command GoHome; } } diff --git a/examples/rvc-app/rvc-common/rvc-app.zap b/examples/rvc-app/rvc-common/rvc-app.zap index 9f4f43bc793e3a..7519e3a2c0c488 100644 --- a/examples/rvc-app/rvc-common/rvc-app.zap +++ b/examples/rvc-app/rvc-common/rvc-app.zap @@ -17,6 +17,12 @@ } ], "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" + }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", @@ -24,12 +30,6 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" - }, - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "version": "chip-v1" } ], "endpointTypes": [ @@ -2608,6 +2608,14 @@ "source": "server", "isIncoming": 0, "isEnabled": 1 + }, + { + "name": "GoHome", + "code": 128, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ diff --git a/src/app/clusters/operational-state-server/operational-state-server.cpp b/src/app/clusters/operational-state-server/operational-state-server.cpp index a76d14e20d350b..896cc0ca3856b6 100644 --- a/src/app/clusters/operational-state-server/operational-state-server.cpp +++ b/src/app/clusters/operational-state-server/operational-state-server.cpp @@ -263,6 +263,10 @@ void Instance::InvokeCommand(HandlerContext & handlerContext) HandleCommand(handlerContext, [this](HandlerContext & ctx, const auto & req) { HandleStopState(ctx, req); }); break; + default: + ChipLogDetail(Zcl, "OperationalState: Entering handling derived cluster commands"); + + InvokeDerivedClusterCommand(handlerContext); } } @@ -291,7 +295,6 @@ CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValu break; case OperationalState::Attributes::OperationalState::Id: { - ChipLogError(Zcl, "OperationalState: H1"); ReturnErrorOnFailure(aEncoder.Encode(GetCurrentOperationalState())); } break; @@ -460,3 +463,42 @@ bool RvcOperationalState::Instance::IsDerivedClusterStateResumeCompatible(uint8_ return (aState == to_underlying(RvcOperationalState::OperationalStateEnum::kCharging) || aState == to_underlying(RvcOperationalState::OperationalStateEnum::kDocked)); } + +// This function is called by the base operational state cluster when a command in the derived cluster number-space is received. +void RvcOperationalState::Instance::InvokeDerivedClusterCommand(chip::app::CommandHandlerInterface::HandlerContext & handlerContext) +{ + ChipLogDetail(Zcl, "RvcOperationalState: InvokeDerivedClusterCommand"); + switch (handlerContext.mRequestPath.mCommandId) + { + case RvcOperationalState::Commands::GoHome::Id: + ChipLogDetail(Zcl, "RvcOperationalState: Entering handling GoHome command"); + + CommandHandlerInterface::HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & req) { HandleGoHomeCommand(ctx, req); }); + break; + } +} + +void RvcOperationalState::Instance::HandleGoHomeCommand(HandlerContext & ctx, const Commands::GoHome::DecodableType & req) +{ + ChipLogDetail(Zcl, "RvcOperationalState: HandleGoHomeCommand"); + + GenericOperationalError err(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + uint8_t opState = GetCurrentOperationalState(); + + // Handle the case of the device being in an invalid state + if (opState == to_underlying(OperationalStateEnum::kCharging) || opState == to_underlying(OperationalStateEnum::kDocked)) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState)); + } + + if (err.errorStateID == 0 && opState != to_underlying(OperationalStateEnum::kSeekingCharger)) + { + mDelegate->HandleGoHomeCommandCallback(err); + } + + Commands::OperationalCommandResponse::Type response; + response.commandResponseState = err; + + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); +} diff --git a/src/app/clusters/operational-state-server/operational-state-server.h b/src/app/clusters/operational-state-server/operational-state-server.h index ed0993ea7aed31..e4ab6d981ca75a 100644 --- a/src/app/clusters/operational-state-server/operational-state-server.h +++ b/src/app/clusters/operational-state-server/operational-state-server.h @@ -185,6 +185,14 @@ class Instance : public CommandHandlerInterface, public AttributeAccessInterface */ virtual bool IsDerivedClusterStateResumeCompatible(uint8_t aState) { return false; }; + /** + * Handles the invocation of derived cluster commands. + * If a derived cluster defines its own commands, this method SHALL be implemented by the derived cluster's class + * to handle the derived cluster's specific commands. + * @param handlerContext The command handler context containing information about the received command. + */ + virtual void InvokeDerivedClusterCommand(HandlerContext & handlerContext) { return; }; + private: Delegate * mDelegate; @@ -196,7 +204,13 @@ class Instance : public CommandHandlerInterface, public AttributeAccessInterface uint8_t mOperationalState = 0; // assume 0 for now. GenericOperationalError mOperationalError = to_underlying(ErrorStateEnum::kNoError); - // Inherited from CommandHandlerInterface + /** + * This method is inherited from CommandHandlerInterface. + * This reimplementation does not check that the cluster ID in the HandlerContext (the cluster the command relates to) + * matches the cluster ID of the RequestT type. + * These cluster IDs may be different in the case where a command defined in the base cluster is intended for a + * derived cluster. + */ template void HandleCommand(HandlerContext & handlerContext, FuncT func); @@ -324,6 +338,15 @@ class Delegate namespace RvcOperationalState { +class Delegate : public OperationalState::Delegate +{ +public: + virtual void HandleGoHomeCommandCallback(OperationalState::GenericOperationalError & err) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnknownEnumValue)); + }; +}; + class Instance : public OperationalState::Instance { public: @@ -336,8 +359,8 @@ class Instance : public OperationalState::Instance * Note: the caller must ensure that the delegate lives throughout the instance's lifetime. * @param aEndpointId The endpoint on which this cluster exists. This must match the zap configuration. */ - Instance(OperationalState::Delegate * aDelegate, EndpointId aEndpointId) : - OperationalState::Instance(aDelegate, aEndpointId, Id) + Instance(Delegate * aDelegate, EndpointId aEndpointId) : + OperationalState::Instance(aDelegate, aEndpointId, Id), mDelegate(aDelegate) {} protected: @@ -356,6 +379,20 @@ class Instance : public OperationalState::Instance * @return true if aState is pause-compatible, false otherwise. */ bool IsDerivedClusterStateResumeCompatible(uint8_t aState) override; + + /** + * Handles the invocation of RvcOperationalState specific commands + * @param handlerContext The command handler context containing information about the received command. + */ + void InvokeDerivedClusterCommand(HandlerContext & handlerContext) override; + +private: + Delegate * mDelegate; + + /** + * Handle Command: GoHome + */ + void HandleGoHomeCommand(HandlerContext & ctx, const Commands::GoHome::DecodableType & req); }; } // namespace RvcOperationalState diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml index 8f19a21cf1bc59..41a0c64e4af169 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml @@ -81,6 +81,10 @@ both values from this cluster and from the base cluster. + + On receipt of this command, the device SHALL start seeking the charging dock, if possible in the current state of the device. + + OperationalError diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 5f550b620b8006..bc8127ac45ba28 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -3721,6 +3721,8 @@ cluster RvcOperationalState = 97 { command Start(): OperationalCommandResponse = 2; /** Upon receipt, the device SHALL resume its operation from the point it was at when it received the Pause command, or from the point when it was paused by means outside of this cluster (for example by manual button press). */ command Resume(): OperationalCommandResponse = 3; + /** On receipt of this command, the device SHALL start seeking the charging dock, if possible in the current state of the device. */ + command GoHome(): OperationalCommandResponse = 128; } /** Attributes and commands for scene configuration and manipulation. */ diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 8eb7fcdcee4b3a..8cd5cc11e54cc8 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -25491,6 +25491,32 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, value, timedInvokeTimeoutMs); } + public void goHome(OperationalCommandResponseCallback callback) { + goHome(callback, 0); + } + + public void goHome(OperationalCommandResponseCallback callback, int timedInvokeTimeoutMs) { + final long commandId = 128L; + + ArrayList elements = new ArrayList<>(); + StructType value = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long commandResponseStateFieldID = 0L; + ChipStructs.RvcOperationalStateClusterErrorStateStruct commandResponseState = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == commandResponseStateFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.Struct) { + StructType castingValue = element.value(StructType.class); + commandResponseState = ChipStructs.RvcOperationalStateClusterErrorStateStruct.decodeTlv(castingValue); + } + } + } + callback.onSuccess(commandResponseState); + }}, commandId, value, timedInvokeTimeoutMs); + } + public interface OperationalCommandResponseCallback extends BaseClusterCallback { void onSuccess(ChipStructs.RvcOperationalStateClusterErrorStateStruct commandResponseState); } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index a1be6ce8ae6bd1..2c7843a639d268 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -8227,7 +8227,8 @@ public enum Command { Pause(0L), Stop(1L), Start(2L), - Resume(3L),; + Resume(3L), + GoHome(128L),; private final long id; Command(long id) { this.id = id; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 10007746d7dd7b..8bd7d3a7a265f9 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -22843,6 +22843,18 @@ public Map> getCommandMap() { ); rvcOperationalStateClusterInteractionInfoMap.put("resume", rvcOperationalStateresumeInteractionInfo); + Map rvcOperationalStategoHomeCommandParams = new LinkedHashMap(); + InteractionInfo rvcOperationalStategoHomeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.RvcOperationalStateCluster) cluster) + .goHome((ChipClusters.RvcOperationalStateCluster.OperationalCommandResponseCallback) callback + ); + }, + () -> new DelegatedRvcOperationalStateClusterOperationalCommandResponseCallback(), + rvcOperationalStategoHomeCommandParams + ); + rvcOperationalStateClusterInteractionInfoMap.put("goHome", rvcOperationalStategoHomeInteractionInfo); + commandMap.put("rvcOperationalState", rvcOperationalStateClusterInteractionInfoMap); Map scenesManagementClusterInteractionInfoMap = new LinkedHashMap<>(); diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/RvcOperationalStateCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/RvcOperationalStateCluster.kt index 0513f78d1b0e38..d2a53548665600 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/RvcOperationalStateCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/RvcOperationalStateCluster.kt @@ -310,6 +310,48 @@ class RvcOperationalStateCluster( return OperationalCommandResponse(commandResponseState_decoded) } + suspend fun goHome(timedInvokeTimeout: Duration? = null): OperationalCommandResponse { + val commandId: UInt = 128u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_COMMAND_RESPONSE_STATE: Int = 0 + var commandResponseState_decoded: RvcOperationalStateClusterErrorStateStruct? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_COMMAND_RESPONSE_STATE)) { + commandResponseState_decoded = + RvcOperationalStateClusterErrorStateStruct.fromTlv(tag, tlvReader) + } else { + tlvReader.skipElement() + } + } + + if (commandResponseState_decoded == null) { + throw IllegalStateException("commandResponseState not found in TLV") + } + + tlvReader.exitContainer() + + return OperationalCommandResponse(commandResponseState_decoded) + } + suspend fun readPhaseListAttribute(): PhaseListAttribute { val ATTRIBUTE_ID: UInt = 0u diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 2c5cfc50944076..afe5190e8f96b9 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -5737,6 +5737,12 @@ class ChipClusters: "args": { }, }, + 0x00000080: { + "commandId": 0x00000080, + "commandName": "GoHome", + "args": { + }, + }, }, "attributes": { 0x00000000: { diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 6cfb1520eb2936..4a1c6a0c8400ec 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -20068,6 +20068,19 @@ def descriptor(cls) -> ClusterObjectDescriptor: commandResponseState: 'RvcOperationalState.Structs.ErrorStateStruct' = field(default_factory=lambda: RvcOperationalState.Structs.ErrorStateStruct()) + @dataclass + class GoHome(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000061 + command_id: typing.ClassVar[int] = 0x00000080 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'OperationalCommandResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ]) + class Attributes: @dataclass class PhaseList(ClusterAttributeDescriptor): diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 1c3298fb15b308..a3c5fc32992c07 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -6544,6 +6544,14 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) - (void)resumeWithParams:(MTRRVCOperationalStateClusterResumeParams * _Nullable)params completion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (void)resumeWithCompletion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); +/** + * Command GoHome + * + * On receipt of this command, the device SHALL start seeking the charging dock, if possible in the current state of the device. + */ +- (void)goHomeWithParams:(MTRRVCOperationalStateClusterGoHomeParams * _Nullable)params completion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)goHomeWithCompletion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributePhaseListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (void)subscribeAttributePhaseListWithParams:(MTRSubscribeParams *)params diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index 1bda7cb36cd7bf..2f8a21416af04d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -46620,6 +46620,34 @@ - (void)resumeWithParams:(MTRRVCOperationalStateClusterResumeParams * _Nullable) queue:self.callbackQueue completion:responseHandler]; } +- (void)goHomeWithCompletion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self goHomeWithParams:nil completion:completion]; +} +- (void)goHomeWithParams:(MTRRVCOperationalStateClusterGoHomeParams * _Nullable)params completion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRRVCOperationalStateClusterGoHomeParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = RvcOperationalState::Commands::GoHome::Type; + [self.device _invokeKnownCommandWithEndpointID:@(self.endpoint) + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRRVCOperationalStateClusterOperationalCommandResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} - (void)readAttributePhaseListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 77e169df653784..4f9fdb33c6cd0a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -6170,6 +6170,7 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterRVCOperationalStateCommandStartID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, MTRCommandIDTypeClusterRVCOperationalStateCommandResumeID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = 0x00000003, MTRCommandIDTypeClusterRVCOperationalStateCommandOperationalCommandResponseID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = 0x00000004, + MTRCommandIDTypeClusterRVCOperationalStateCommandGoHomeID MTR_PROVISIONALLY_AVAILABLE = 0x00000080, // Cluster ScenesManagement commands MTRCommandIDTypeClusterScenesManagementCommandAddSceneID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 6fcea80c35673e..c1d6782c518c59 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -3113,6 +3113,9 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) - (void)resumeWithParams:(MTRRVCOperationalStateClusterResumeParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (void)resumeWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); +- (void)goHomeWithParams:(MTRRVCOperationalStateClusterGoHomeParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)goHomeWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion + MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributePhaseListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 7f79d6452d3415..bff98afd6ab590 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -8281,6 +8281,37 @@ - (void)resumeWithParams:(MTRRVCOperationalStateClusterResumeParams * _Nullable) completion:responseHandler]; } +- (void)goHomeWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + [self goHomeWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; +} +- (void)goHomeWithParams:(MTRRVCOperationalStateClusterGoHomeParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRRVCOperationalStateClusterGoHomeParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = RvcOperationalState::Commands::GoHome::Type; + [self.device _invokeKnownCommandWithEndpointID:@(self.endpoint) + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRRVCOperationalStateClusterOperationalCommandResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + - (NSDictionary * _Nullable)readAttributePhaseListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:@(self.endpoint) clusterID:@(MTRClusterIDTypeRVCOperationalStateID) attributeID:@(MTRAttributeIDTypeClusterRVCOperationalStateAttributePhaseListID) params:params]; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index d5b65a7fbc4feb..f617ffcd65e400 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -4724,6 +4724,34 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) error:(NSError * __autoreleasing *)error MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRRVCOperationalStateClusterGoHomeParams : NSObject +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRScenesManagementClusterAddSceneParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index b5472ad77833a3..2a4863997b5143 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -12871,6 +12871,79 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::RvcOpera @end +@implementation MTRRVCOperationalStateClusterGoHomeParams +- (instancetype)init +{ + if (self = [super init]) { + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRRVCOperationalStateClusterGoHomeParams alloc] init]; + + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: >", NSStringFromClass([self class])]; + return descriptionString; +} + +@end + +@implementation MTRRVCOperationalStateClusterGoHomeParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::RvcOperationalState::Commands::GoHome::Type encodableStruct; + ListFreer listFreer; + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + @implementation MTRScenesManagementClusterAddSceneParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index 42d8a17450841a..7b33d80c72c54b 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -868,6 +868,12 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRRVCOperationalStateClusterGoHomeParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + @interface MTRScenesManagementClusterAddSceneParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index e4988fdd696cd1..3e7412349926bb 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -12284,6 +12284,26 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace OperationalCommandResponse. +namespace GoHome { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + } +} +} // namespace GoHome. } // namespace Commands namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index e41a226edfbdaa..69683f07a7006e 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -17737,6 +17737,11 @@ struct Type; struct DecodableType; } // namespace OperationalCommandResponse +namespace GoHome { +struct Type; +struct DecodableType; +} // namespace GoHome + } // namespace Commands namespace Commands { @@ -17884,6 +17889,34 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace OperationalCommandResponse +namespace GoHome { +enum class Fields : uint8_t +{ +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::GoHome::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::RvcOperationalState::Id; } + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::RvcOperationalState::Commands::OperationalCommandResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::GoHome::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::RvcOperationalState::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace GoHome } // namespace Commands namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index 46626e62f0751e..76ed4e215d1092 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h @@ -808,6 +808,10 @@ namespace OperationalCommandResponse { static constexpr CommandId Id = 0x00000004; } // namespace OperationalCommandResponse +namespace GoHome { +static constexpr CommandId Id = 0x00000080; +} // namespace GoHome + } // namespace Commands } // namespace RvcOperationalState diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index c1e1d69f59d802..df306407c81780 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -5667,6 +5667,7 @@ class OperationalStateResume : public ClusterCommand | * Stop | 0x01 | | * Start | 0x02 | | * Resume | 0x03 | +| * GoHome | 0x80 | |------------------------------------------------------------------------------| | Attributes: | | | * PhaseList | 0x0000 | @@ -5831,6 +5832,42 @@ class RvcOperationalStateResume : public ClusterCommand chip::app::Clusters::RvcOperationalState::Commands::Resume::Type mRequest; }; +/* + * Command GoHome + */ +class RvcOperationalStateGoHome : public ClusterCommand +{ +public: + RvcOperationalStateGoHome(CredentialIssuerCommands * credsIssuerConfig) : ClusterCommand("go-home", credsIssuerConfig) + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::RvcOperationalState::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::RvcOperationalState::Commands::GoHome::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::RvcOperationalState::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::RvcOperationalState::Commands::GoHome::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::RvcOperationalState::Commands::GoHome::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster ScenesManagement | 0x0062 | |------------------------------------------------------------------------------| @@ -19359,6 +19396,7 @@ void registerClusterRvcOperationalState(Commands & commands, CredentialIssuerCom make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // // // Attributes // diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 49fd07683ab36e..674714905aada3 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -68434,6 +68434,7 @@ class SubscribeAttributeOperationalStateClusterRevision : public SubscribeAttrib | * Stop | 0x01 | | * Start | 0x02 | | * Resume | 0x03 | +| * GoHome | 0x80 | |------------------------------------------------------------------------------| | Attributes: | | | * PhaseList | 0x0000 | @@ -68658,6 +68659,59 @@ class RvcOperationalStateResume : public ClusterCommand { private: }; +#if MTR_ENABLE_PROVISIONAL +/* + * Command GoHome + */ +class RvcOperationalStateGoHome : public ClusterCommand { +public: + RvcOperationalStateGoHome() + : ClusterCommand("go-home") + { + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::RvcOperationalState::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::RvcOperationalState::Commands::GoHome::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterRVCOperationalState alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRRVCOperationalStateClusterGoHomeParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster goHomeWithParams:params completion: + ^(MTRRVCOperationalStateClusterOperationalCommandResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::RvcOperationalState::Commands::OperationalCommandResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::RvcOperationalState::Commands::OperationalCommandResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: +}; + +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute PhaseList */ @@ -180816,6 +180870,9 @@ void registerClusterRvcOperationalState(Commands & commands) make_unique(), // #endif // MTR_ENABLE_PROVISIONAL make_unique(), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(Id), // make_unique(Id), // make_unique(Id), //