From 898870e174f3bcda22ae579bfb2d4a2b11689dcf Mon Sep 17 00:00:00 2001 From: pankore <86098180+pankore@users.noreply.github.com> Date: Sat, 21 Oct 2023 06:13:30 +0800 Subject: [PATCH] [Ameba] Additional Ameba Implementation (#29720) * [Ameba] added implementation for manual operation of several clusters (dishwasher alarm, refrigerator alarm, operational state, rvc operational state, rvc runmode, and rvc cleanmode), test event trigger for smoke alarm, shutdown function of CHIPDeviceManager, and init laundrywashercontrolserver * [Ameba] Run restyle-diff.sh, and modified cmake configuration to add additional implementation * [Ameba] Added CONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER macro * [Ameba] added CONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER define flag at cmake * [Ameba] Updated switch case at ManualOperationalStateCommand.h and updated raise and lower alarm function at ManualDishWasherAlarmCommand.h * [Ameba] Updated RvcOperationalState::ErrorStateEnum::kUnknownEnumValue to OperationalState::ErrorStateEnum::kUnknownEnumValue because it was removed, and added minor comments. --- .../all-clusters-app/ameba/chip_main.cmake | 12 +- .../ameba/main/CHIPDeviceManager.cpp | 6 + .../ameba/main/ManualOperationCommand.cpp | 159 +++++++++++++++ .../ameba/main/OperationalStateManager.cpp | 173 ++++++++++++++++ .../ameba/main/SmokeCOAlarmManager.cpp | 171 ++++++++++++++++ .../ameba/main/chipinterface.cpp | 32 +++ .../ameba/main/include/CHIPDeviceManager.h | 2 + .../include/ManualDishWasherAlarmCommand.h | 172 ++++++++++++++++ .../main/include/ManualOperationCommand.h | 26 +++ .../include/ManualOperationalStateCommand.h | 185 ++++++++++++++++++ .../main/include/ManualRVCModesCommand.h | 135 +++++++++++++ .../include/ManualRefrigeratorAlarmCommand.h | 160 +++++++++++++++ .../main/include/OperationalStateManager.h | 162 +++++++++++++++ .../ameba/main/include/SmokeCOAlarmManager.h | 47 +++++ .../AmebaTestEventTriggerDelegate.cpp | 37 ++++ .../AmebaTestEventTriggerDelegate.h | 61 ++++++ 16 files changed, 1538 insertions(+), 2 deletions(-) create mode 100644 examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp create mode 100644 examples/all-clusters-app/ameba/main/OperationalStateManager.cpp create mode 100644 examples/all-clusters-app/ameba/main/SmokeCOAlarmManager.cpp create mode 100644 examples/all-clusters-app/ameba/main/include/ManualDishWasherAlarmCommand.h create mode 100644 examples/all-clusters-app/ameba/main/include/ManualOperationCommand.h create mode 100644 examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h create mode 100644 examples/all-clusters-app/ameba/main/include/ManualRVCModesCommand.h create mode 100644 examples/all-clusters-app/ameba/main/include/ManualRefrigeratorAlarmCommand.h create mode 100644 examples/all-clusters-app/ameba/main/include/OperationalStateManager.h create mode 100644 examples/all-clusters-app/ameba/main/include/SmokeCOAlarmManager.h create mode 100644 examples/platform/ameba/test_event_trigger/AmebaTestEventTriggerDelegate.cpp create mode 100644 examples/platform/ameba/test_event_trigger/AmebaTestEventTriggerDelegate.h diff --git a/examples/all-clusters-app/ameba/chip_main.cmake b/examples/all-clusters-app/ameba/chip_main.cmake index f105d3efe41a44..07052e123757cd 100755 --- a/examples/all-clusters-app/ameba/chip_main.cmake +++ b/examples/all-clusters-app/ameba/chip_main.cmake @@ -154,10 +154,12 @@ list( APPEND ${list_chip_main_sources} ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp - ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp - ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/concentration-measurement-instances.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/fan-stub.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/resource-monitoring-delegates.cpp + ${chip_dir}/examples/all-clusters-app/all-clusters-common/src/rvc-modes.cpp ${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 @@ -167,10 +169,15 @@ list( ${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 ${chip_dir}/examples/platform/ameba/route_hook/ameba_route_hook.c ${chip_dir}/examples/platform/ameba/route_hook/ameba_route_table.c + ${chip_dir}/examples/platform/ameba/test_event_trigger/AmebaTestEventTriggerDelegate.cpp + ${chip_dir}/examples/providers/DeviceInfoProviderImpl.cpp ) @@ -263,6 +270,7 @@ list( -DMBEDTLS_CONFIG_FILE= -DCHIP_SHELL_MAX_TOKENS=11 -DCONFIG_ENABLE_AMEBA_FACTORY_DATA=0 + -DCONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER=0 ) if (matter_enable_persistentstorage_audit) diff --git a/examples/all-clusters-app/ameba/main/CHIPDeviceManager.cpp b/examples/all-clusters-app/ameba/main/CHIPDeviceManager.cpp index 50e6d11db53c25..7b178060a6fff2 100644 --- a/examples/all-clusters-app/ameba/main/CHIPDeviceManager.cpp +++ b/examples/all-clusters-app/ameba/main/CHIPDeviceManager.cpp @@ -93,6 +93,12 @@ CHIP_ERROR CHIPDeviceManager::Init(CHIPDeviceManagerCallbacks * cb) exit: return err; } + +void CHIPDeviceManager::Shutdown() +{ + PlatformMgr().Shutdown(); +} + } // namespace DeviceManager } // namespace chip diff --git a/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp b/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp new file mode 100644 index 00000000000000..feb346b892f6bb --- /dev/null +++ b/examples/all-clusters-app/ameba/main/ManualOperationCommand.cpp @@ -0,0 +1,159 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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 "ManualOperationCommand.h" +#include "ManualDishWasherAlarmCommand.h" +#include "ManualOperationalStateCommand.h" +#include "ManualRVCModesCommand.h" +#include "ManualRefrigeratorAlarmCommand.h" + +#include "app/server/Server.h" +#include "platform/CHIPDeviceLayer.h" +#include + +#if CONFIG_ENABLE_CHIP_SHELL +#include "lib/shell/Engine.h" +#include "lib/shell/commands/Help.h" +#endif // ENABLE_CHIP_SHELL + +using namespace chip; +using namespace chip::app; + +#if CONFIG_ENABLE_CHIP_SHELL +using Shell::Engine; +using Shell::shell_command_t; +using Shell::streamer_get; +using Shell::streamer_printf; + +Engine sShellManualOperationSubCommands; +#endif // defined(ENABLE_CHIP_SHELL) + +namespace { +#if CONFIG_ENABLE_CHIP_SHELL + +/******************************************************** + * Manual Operation shell functions + *********************************************************/ + +CHIP_ERROR ManualOperationHelpHandler(int argc, char ** argv) +{ + sShellManualOperationSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ManualOperationCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return ManualOperationHelpHandler(argc, argv); + } + + return sShellManualOperationSubCommands.ExecCommand(argc, argv); +} + +/** + * @brief configures switch matter shell + * + */ +static void RegisterManualOperationCommands() +{ + + static const shell_command_t sManualOperationSubCommands[] = { + { &ManualOperationHelpHandler, "help", "Usage: manual " }, + { &ManualOperationalStateCommandHandler, "opstate", " Usage: manual opstate " }, + { &ManualRVCCommandHandler, "rvc", " Usage: manual rvc " }, + { &ManualRefrigeratorAlarmCommandHandler, "refalm", " Usage: manual refalm " }, + { &ManualDishWasherAlarmCommandHandler, "dishalm", " Usage: manual dishalm " }, + }; + + static const shell_command_t sManualOperationalStateSubCommands[] = { + { &ManualOperationalStateCommandHelpHandler, "help", "Usage: manual opstate " }, + { &ManualOperationalStateSetStateCommandHandler, "set-state", "set-state Usage: manual opstate set-state " }, + { &ManualOperationalStateSetErrorCommandHandler, "set-error", "set-error Usage: manual opstate set-error " }, + }; + + static const shell_command_t sManualRVCSubCommands[] = { + { &ManualRVCCommandHelpHandler, "help", "Usage: manual rvc " }, + { &ManualRVCOperationalStateCommandHandler, "opstate", "Usage: manual rvc opstate " }, + { &ManualRVCRunModeCommandHandler, "runmode", "Usage: manual rvc runmode " }, + { &ManualRVCCleanModeCommandHandler, "cleanmode", "Usage: manual rvc cleanmode " }, + }; + + static const shell_command_t sManualRVCOperationalStateSubCommands[] = { + { &ManualRVCOperationalStateCommandHelpHandler, "help", "Usage: manual rvc opstate " }, + { &ManualRVCOperationalStateSetStateCommandHandler, "set-state", "set-state Usage: manual rvc opstate set-state " }, + { &ManualRVCOperationalStateSetErrorCommandHandler, "set-error", "set-error Usage: manual rvc opstate set-error " }, + }; + + static const shell_command_t sManualRVCRunModeSubCommands[] = { + { &ManualRVCRunModeCommandHelpHandler, "help", "Usage: manual rvc runmode " }, + { &ManualRVCRunModeSetModeCommandHandler, "set-mode", "set-mode Usage: manual rvc runmode set-mode " }, + }; + + static const shell_command_t sManualRVCCleanModeSubCommands[] = { + { &ManualRVCCleanModeCommandHelpHandler, "help", "Usage: manual rvc cleanmode " }, + { &ManualRVCCleanModeSetModeCommandHandler, "set-mode", "set-mode Usage: manual rvc cleanmode set-mode " }, + }; + + static const shell_command_t sManualRefrigeratorAlarmStateSubCommands[] = { + { &ManualRefrigeratorAlarmCommandHelpHandler, "help", "Usage: manual refalm " }, + { &ManualRefrigeratorAlarmDoorOpenCommandHandler, "door-open", "door-open Usage: manual refalm door-open" }, + { &ManualRefrigeratorAlarmDoorCloseCommandHandler, "door-close", "door-close Usage: manual refalm door-close" }, + { &ManualRefrigeratorAlarmSuppressCommandHandler, "suppress-alarm", "suppress-alarm Usage: manual refalm suppress-alarm" }, + }; + + static const shell_command_t sManualDishWasherAlarmSubCommands[] = { + { &ManualDishWasherAlarmCommandHelpHandler, "help", "Usage: manual dishalm " }, + { &ManualDishWasherAlarmSetRaiseCommandHandler, "raise", "raise Usage: manual dishalm raise" }, + { &ManualDishWasherAlarmSetLowerCommandHandler, "lower", "lower Usage: manual dishalm lower" }, + }; + + static const shell_command_t sManualOperationCommand = { &ManualOperationCommandHandler, "manual", + "Manual Operation commands. Usage: manual " }; + + // Register commands + sShellManualOperationSubCommands.RegisterCommands(sManualOperationSubCommands, ArraySize(sManualOperationSubCommands)); + sShellManualOperationalStateSubCommands.RegisterCommands(sManualOperationalStateSubCommands, + ArraySize(sManualOperationalStateSubCommands)); + sShellManualRVCSubCommands.RegisterCommands(sManualRVCSubCommands, ArraySize(sManualRVCSubCommands)); + sShellManualRVCOperationalStateSubCommands.RegisterCommands(sManualRVCOperationalStateSubCommands, + ArraySize(sManualRVCOperationalStateSubCommands)); + sShellManualRVCRunModeSubCommands.RegisterCommands(sManualRVCRunModeSubCommands, ArraySize(sManualRVCRunModeSubCommands)); + sShellManualRVCCleanModeSubCommands.RegisterCommands(sManualRVCCleanModeSubCommands, ArraySize(sManualRVCCleanModeSubCommands)); + sShellManualRefrigeratorAlarmStateSubCommands.RegisterCommands(sManualRefrigeratorAlarmStateSubCommands, + ArraySize(sManualRefrigeratorAlarmStateSubCommands)); + sShellManualDishWasherAlarmStateSubCommands.RegisterCommands(sManualDishWasherAlarmSubCommands, + ArraySize(sManualDishWasherAlarmSubCommands)); + + Engine::Root().RegisterCommands(&sManualOperationCommand, 1); +} +#endif // ENABLE_CHIP_SHELL + +} // namespace + +/******************************************************** + * Switch functions + *********************************************************/ + +CHIP_ERROR InitManualOperation() +{ +#if CONFIG_ENABLE_CHIP_SHELL + RegisterManualOperationCommands(); +#endif + return CHIP_NO_ERROR; +} diff --git a/examples/all-clusters-app/ameba/main/OperationalStateManager.cpp b/examples/all-clusters-app/ameba/main/OperationalStateManager.cpp new file mode 100644 index 00000000000000..9e4001e7d24e2d --- /dev/null +++ b/examples/all-clusters-app/ameba/main/OperationalStateManager.cpp @@ -0,0 +1,173 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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; +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) +{ + if (index >= mOperationalStateList.size()) + { + return CHIP_ERROR_NOT_FOUND; + } + operationalState = mOperationalStateList[index]; + return CHIP_NO_ERROR; +} + +CHIP_ERROR GenericOperationalStateDelegateImpl::GetOperationalPhaseAtIndex(size_t index, GenericOperationalPhase & operationalPhase) +{ + if (index >= mOperationalPhaseList.size()) + { + return CHIP_ERROR_NOT_FOUND; + } + operationalPhase = mOperationalPhaseList[index]; + return CHIP_NO_ERROR; +} + +void GenericOperationalStateDelegateImpl::HandlePauseStateCallback(GenericOperationalError & err) +{ + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +void GenericOperationalStateDelegateImpl::HandleResumeStateCallback(GenericOperationalError & err) +{ + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +void GenericOperationalStateDelegateImpl::HandleStartStateCallback(GenericOperationalError & err) +{ + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +void GenericOperationalStateDelegateImpl::HandleStopStateCallback(GenericOperationalError & err) +{ + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kStopped)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +// 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; + } +} + +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 Instance(gOperationalStateDelegate, operationalStateEndpoint, Clusters::OperationalState::Id); + + gOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)); + + gOperationalStateInstance->Init(); +} + +// Init RVC Operational State cluster + +static OperationalState::Instance * gRvcOperationalStateInstance = nullptr; +static RvcOperationalStateDelegate * gRvcOperationalStateDelegate = nullptr; + +OperationalState::Instance * OperationalState::GetRVCOperationalStateInstance() +{ + return gRvcOperationalStateInstance; +} + +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 Instance(gRvcOperationalStateDelegate, operationalStateEndpoint, Clusters::RvcOperationalState::Id); + + gRvcOperationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)); + + gRvcOperationalStateInstance->Init(); +} diff --git a/examples/all-clusters-app/ameba/main/SmokeCOAlarmManager.cpp b/examples/all-clusters-app/ameba/main/SmokeCOAlarmManager.cpp new file mode 100644 index 00000000000000..bede2bcf537a76 --- /dev/null +++ b/examples/all-clusters-app/ameba/main/SmokeCOAlarmManager.cpp @@ -0,0 +1,171 @@ +/* + * + * 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 "SmokeCOAlarmManager.h" +#include +#include + +using namespace chip; +using namespace chip::app::Clusters::SmokeCoAlarm; +using namespace chip::DeviceLayer; + +static std::array sPriorityOrder = { + ExpressedStateEnum::kSmokeAlarm, ExpressedStateEnum::kInterconnectSmoke, ExpressedStateEnum::kCOAlarm, + ExpressedStateEnum::kInterconnectCO, ExpressedStateEnum::kHardwareFault, ExpressedStateEnum::kTesting, + ExpressedStateEnum::kEndOfService, ExpressedStateEnum::kBatteryAlert +}; + +CHIP_ERROR SmokeCoAlarmManager::Init() +{ + return CHIP_NO_ERROR; +} + +void SmokeCoAlarmManager::StartSelfTesting() +{ + // Currently selftest is not implemented +} + +bool emberAfHandleEventTrigger(uint64_t eventTrigger) +{ + SmokeCOTrigger trigger = static_cast(eventTrigger); + + switch (trigger) + { + case SmokeCOTrigger::kForceSmokeCritical: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke (critical)"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetSmokeState(1, AlarmStateEnum::kCritical), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kForceSmokeWarning: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke (warning)"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetSmokeState(1, AlarmStateEnum::kWarning), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kForceSmokeInterconnect: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke interconnect (warning)"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetInterconnectSmokeAlarm(1, AlarmStateEnum::kWarning), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kForceCOCritical: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force CO (critical)"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetCOState(1, AlarmStateEnum::kCritical), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kForceCOWarning: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force CO (warning)"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetCOState(1, AlarmStateEnum::kWarning), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kForceCOInterconnect: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force CO (warning)"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetInterconnectCOAlarm(1, AlarmStateEnum::kWarning), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kForceSmokeContaminationHigh: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke contamination (critical)"); + SmokeCoAlarmServer::Instance().SetContaminationState(1, ContaminationStateEnum::kCritical); + break; + case SmokeCOTrigger::kForceSmokeContaminationLow: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke contamination (warning)"); + SmokeCoAlarmServer::Instance().SetContaminationState(1, ContaminationStateEnum::kLow); + break; + case SmokeCOTrigger::kForceSmokeSensitivityHigh: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke sensistivity (high)"); + SmokeCoAlarmServer::Instance().SetSmokeSensitivityLevel(1, SensitivityEnum::kHigh); + break; + case SmokeCOTrigger::kForceSmokeSensitivityLow: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke sensitivity (low)"); + SmokeCoAlarmServer::Instance().SetSmokeSensitivityLevel(1, SensitivityEnum::kLow); + break; + case SmokeCOTrigger::kForceMalfunction: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force malfunction"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetHardwareFaultAlert(1, true), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kForceLowBatteryWarning: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force low battery (warning)"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetBatteryAlert(1, AlarmStateEnum::kWarning), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kForceLowBatteryCritical: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force low battery (critical)"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetBatteryAlert(1, AlarmStateEnum::kCritical), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kForceEndOfLife: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force end-of-life"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetEndOfServiceAlert(1, EndOfServiceEnum::kExpired), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kForceSilence: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force silence"); + SmokeCoAlarmServer::Instance().SetDeviceMuted(1, MuteStateEnum::kMuted); + break; + case SmokeCOTrigger::kClearSmoke: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear smoke"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetSmokeState(1, AlarmStateEnum::kNormal), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kClearCO: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear CO"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetCOState(1, AlarmStateEnum::kNormal), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kClearSmokeInterconnect: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear smoke interconnect"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetInterconnectSmokeAlarm(1, AlarmStateEnum::kNormal), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kClearCOInterconnect: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear CO interconnect"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetInterconnectCOAlarm(1, AlarmStateEnum::kNormal), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kClearMalfunction: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear malfunction"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetHardwareFaultAlert(1, false), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kClearEndOfLife: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear end-of-life"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetEndOfServiceAlert(1, EndOfServiceEnum::kNormal), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kClearSilence: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear silence"); + SmokeCoAlarmServer::Instance().SetDeviceMuted(1, MuteStateEnum::kNotMuted); + break; + case SmokeCOTrigger::kClearBatteryLevelLow: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear low battery"); + VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetBatteryAlert(1, AlarmStateEnum::kNormal), true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + break; + case SmokeCOTrigger::kClearContamination: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force SmokeContamination (warning)"); + SmokeCoAlarmServer::Instance().SetContaminationState(1, ContaminationStateEnum::kNormal); + break; + case SmokeCOTrigger::kClearSensitivity: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear Smoke Sensitivity"); + SmokeCoAlarmServer::Instance().SetSmokeSensitivityLevel(1, SensitivityEnum::kStandard); + break; + default: + + return false; + } + + return true; +} diff --git a/examples/all-clusters-app/ameba/main/chipinterface.cpp b/examples/all-clusters-app/ameba/main/chipinterface.cpp index ac3426f4b438cc..21280c676154be 100644 --- a/examples/all-clusters-app/ameba/main/chipinterface.cpp +++ b/examples/all-clusters-app/ameba/main/chipinterface.cpp @@ -22,15 +22,18 @@ #include "DeviceCallbacks.h" #include "Globals.h" #include "LEDWidget.h" +#include "ManualOperationCommand.h" #include "chip_porting.h" #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -39,6 +42,9 @@ #include #include #include +#if CONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER +#include +#endif #if CONFIG_ENABLE_PW_RPC #include @@ -123,11 +129,23 @@ Identify gIdentify1 = { static DeviceCallbacks EchoCallbacks; chip::DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; +#if CONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER +uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; +#endif + static void InitServer(intptr_t context) { // Init ZCL Data Model and CHIP App Server static chip::CommonCaseDeviceServerInitParams initParams; + +#if CONFIG_ENABLE_AMEBA_TEST_EVENT_TRIGGER + static AmebaTestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(sTestEventTriggerEnableKey) }; + initParams.testEventTriggerDelegate = &testEventTriggerDelegate; +#endif + initParams.InitializeStaticResourcesBeforeServerInit(); + chip::Server::GetInstance().Init(initParams); gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage()); // TODO: Use our own DeviceInfoProvider @@ -143,6 +161,7 @@ static void InitServer(intptr_t context) #if CONFIG_ENABLE_CHIP_SHELL InitBindingHandler(); + InitManualOperation(); #endif app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); } @@ -175,7 +194,20 @@ extern "C" void ChipTest(void) #endif } +extern "C" void ChipTestShutdown(void) +{ + ChipLogProgress(DeviceLayer, "All Clusters Demo! Shutdown Now!"); + CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance(); + deviceMgr.Shutdown(); +} + bool lowPowerClusterSleep() { return true; } + +using namespace chip::app::Clusters::LaundryWasherControls; +void emberAfLaundryWasherControlsClusterInitCallback(EndpointId endpoint) +{ + LaundryWasherControlsServer::SetDefaultDelegate(endpoint, &LaundryWasherControlDelegate::getLaundryWasherControlDelegate()); +} diff --git a/examples/all-clusters-app/ameba/main/include/CHIPDeviceManager.h b/examples/all-clusters-app/ameba/main/include/CHIPDeviceManager.h index 4ceddc65e7085e..03588bee0d02c6 100644 --- a/examples/all-clusters-app/ameba/main/include/CHIPDeviceManager.h +++ b/examples/all-clusters-app/ameba/main/include/CHIPDeviceManager.h @@ -103,6 +103,8 @@ class DLL_EXPORT CHIPDeviceManager */ CHIP_ERROR Init(CHIPDeviceManagerCallbacks * cb); + void Shutdown(); + /** * @brief * Fetch a pointer to the registered CHIPDeviceManagerCallbacks object. diff --git a/examples/all-clusters-app/ameba/main/include/ManualDishWasherAlarmCommand.h b/examples/all-clusters-app/ameba/main/include/ManualDishWasherAlarmCommand.h new file mode 100644 index 00000000000000..c1a37be41d385a --- /dev/null +++ b/examples/all-clusters-app/ameba/main/include/ManualDishWasherAlarmCommand.h @@ -0,0 +1,172 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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 "controller/InvokeInteraction.h" +#include "controller/ReadInteraction.h" +#include + +#if CONFIG_ENABLE_CHIP_SHELL +#include "lib/shell/Engine.h" +#include "lib/shell/commands/Help.h" +#endif // ENABLE_CHIP_SHELL + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::DishwasherAlarm; + +#if CONFIG_ENABLE_CHIP_SHELL +using Shell::Engine; +using Shell::shell_command_t; +using Shell::streamer_get; +using Shell::streamer_printf; + +Engine sShellManualDishWasherAlarmStateSubCommands; +#endif // defined(ENABLE_CHIP_SHELL) + +#if CONFIG_ENABLE_CHIP_SHELL + +CHIP_ERROR ManualDishWasherAlarmCommandHelpHandler(int argc, char ** argv) +{ + sShellManualDishWasherAlarmStateSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ManualDishWasherAlarmCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return ManualDishWasherAlarmCommandHelpHandler(argc, argv); + } + + return sShellManualDishWasherAlarmStateSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR ManualDishWasherAlarmSetRaiseCommandHandler(int argc, char ** argv) +{ + if (argc != 0) + { + return ManualDishWasherAlarmCommandHelpHandler(argc, argv); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + EmberAfStatus status; + DishwasherAlarmServer & serverInstance = DishwasherAlarmServer::Instance(); + + BitMask supported; // Set dishwasher alarm supported value + supported.SetField(AlarmMap::kInflowError, 1); // 0x01, 1 + supported.SetField(AlarmMap::kDrainError, 1); // 0x02, 2 + supported.SetField(AlarmMap::kDoorError, 1); // 0x04, 4 + supported.SetField(AlarmMap::kTempTooLow, 1); // 0x08, 8 + supported.SetField(AlarmMap::kWaterLevelError, 1); // 0x20, 32 + + BitMask mask; // Set dishwasher alarm mask value + mask.SetField(AlarmMap::kInflowError, 1); // 0x01, 1 + mask.SetField(AlarmMap::kDrainError, 1); // 0x02, 2 + mask.SetField(AlarmMap::kDoorError, 1); // 0x04, 4 + mask.SetField(AlarmMap::kTempTooLow, 1); // 0x08, 8 + mask.SetField(AlarmMap::kWaterLevelError, 1); // 0x20, 32 + + BitMask state; // Set dishwasher alarm state value + state.SetField(AlarmMap::kDrainError, 1); // 0x02, 2 + state.SetField(AlarmMap::kDoorError, 1); // 0x04, 4 + state.SetField(AlarmMap::kTempTooLow, 1); // 0x08, 8 + + status = serverInstance.SetSupportedValue(1, supported); // 0x2F, 47 + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + + status = serverInstance.SetMaskValue(1, mask); // 0x2F, 47 + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + + status = serverInstance.SetStateValue(1, state); // 0x0E, 14 + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "ManualDishWasherAlarmSetRaiseCommandHandler Failed!\r\n"); + } + + return err; +} + +CHIP_ERROR ManualDishWasherAlarmSetLowerCommandHandler(int argc, char ** argv) +{ + if (argc != 0) + { + return ManualDishWasherAlarmCommandHelpHandler(argc, argv); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + EmberAfStatus status; + DishwasherAlarmServer & serverInstance = DishwasherAlarmServer::Instance(); + + BitMask supported; // Set dishwasher alarm supported value + supported.SetField(AlarmMap::kInflowError, 1); // 0x01, 1 + supported.SetField(AlarmMap::kDrainError, 1); // 0x02, 2 + supported.SetField(AlarmMap::kDoorError, 1); // 0x04, 4 + supported.SetField(AlarmMap::kTempTooLow, 1); // 0x08, 8 + supported.SetField(AlarmMap::kWaterLevelError, 1); // 0x20, 32 + + BitMask mask; // Set dishwasher alarm mask value + mask.SetField(AlarmMap::kInflowError, 1); // 0x01, 1 + mask.SetField(AlarmMap::kDrainError, 1); // 0x02, 2 + mask.SetField(AlarmMap::kDoorError, 1); // 0x04, 4 + mask.SetField(AlarmMap::kTempTooLow, 1); // 0x08, 8 + mask.SetField(AlarmMap::kWaterLevelError, 1); // 0x20, 32 + + status = serverInstance.SetSupportedValue(1, supported); // 0x2F, 47 + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + + status = serverInstance.SetMaskValue(1, mask); // 0x2F, 47 + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + + status = serverInstance.SetStateValue(1, 0); // Set dishwasher alarm state value 0x00, 0 + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "ManualDishWasherAlarmSetLowerCommandHandler Failed!\r\n"); + } + + return err; +} +#endif // CONFIG_ENABLE_CHIP_SHELL diff --git a/examples/all-clusters-app/ameba/main/include/ManualOperationCommand.h b/examples/all-clusters-app/ameba/main/include/ManualOperationCommand.h new file mode 100644 index 00000000000000..418d0aea6f498e --- /dev/null +++ b/examples/all-clusters-app/ameba/main/include/ManualOperationCommand.h @@ -0,0 +1,26 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#pragma once + +#include "app-common/zap-generated/ids/Attributes.h" +#include "app-common/zap-generated/ids/Clusters.h" +#include "app-common/zap-generated/ids/Commands.h" +#include "lib/core/CHIPError.h" + +CHIP_ERROR InitManualOperation(); diff --git a/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h b/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h new file mode 100644 index 00000000000000..1f6d899b59e828 --- /dev/null +++ b/examples/all-clusters-app/ameba/main/include/ManualOperationalStateCommand.h @@ -0,0 +1,185 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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 "controller/InvokeInteraction.h" +#include "controller/ReadInteraction.h" +#include + +#if CONFIG_ENABLE_CHIP_SHELL +#include "lib/shell/Engine.h" +#include "lib/shell/commands/Help.h" +#endif // ENABLE_CHIP_SHELL + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::OperationalState; + +#if CONFIG_ENABLE_CHIP_SHELL +using Shell::Engine; +using Shell::shell_command_t; +using Shell::streamer_get; +using Shell::streamer_printf; + +Engine sShellManualOperationalStateSubCommands; +Engine sShellManualRVCOperationalStateSubCommands; +#endif // defined(ENABLE_CHIP_SHELL) + +#if CONFIG_ENABLE_CHIP_SHELL +/******************************************************** + * Operational State Functions + *********************************************************/ + +CHIP_ERROR ManualOperationalStateCommandHelpHandler(int argc, char ** argv) +{ + sShellManualOperationalStateSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ManualOperationalStateCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return ManualOperationalStateCommandHelpHandler(argc, argv); + } + + return sShellManualOperationalStateSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR ManualOperationalStateSetStateCommandHandler(int argc, char ** argv) +{ + if (argc != 1) + { + return ManualOperationalStateCommandHelpHandler(argc, argv); + } + uint32_t state = atoi(argv[0]); + + CHIP_ERROR err; + err = GetOperationalStateInstance()->SetOperationalState(state); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "ManualOperationalStateSetStateCommandHandler Failed!\r\n"); + } + + return err; +} + +CHIP_ERROR ManualOperationalStateSetErrorCommandHandler(int argc, char ** argv) +{ + if (argc != 1) + { + return ManualOperationalStateCommandHelpHandler(argc, argv); + } + + GenericOperationalError err(to_underlying(ErrorStateEnum::kNoError)); + uint32_t error = atoi(argv[0]); + + switch (error) + { + case to_underlying(OperationalState::ErrorStateEnum::kNoError): // 0x00, 0 + case to_underlying(OperationalState::ErrorStateEnum::kUnableToStartOrResume): // 0x01, 1 + case to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation): // 0x02, 2 + case to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState): // 0x03, 3 + err.errorStateID = error; + break; + default: + err.errorStateID = to_underlying(OperationalState::ErrorStateEnum::kUnknownEnumValue); // 0x04, 4 + break; + } + + GetOperationalStateInstance()->OnOperationalErrorDetected(err); + + return CHIP_NO_ERROR; +} + +/******************************************************** + * RVC Operational State Functions + *********************************************************/ + +CHIP_ERROR ManualRVCOperationalStateCommandHelpHandler(int argc, char ** argv) +{ + sShellManualRVCOperationalStateSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ManualRVCOperationalStateCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return ManualRVCOperationalStateCommandHelpHandler(argc, argv); + } + + return sShellManualRVCOperationalStateSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR ManualRVCOperationalStateSetStateCommandHandler(int argc, char ** argv) +{ + if (argc != 1) + { + return ManualRVCOperationalStateCommandHelpHandler(argc, argv); + } + uint32_t state = atoi(argv[0]); + + CHIP_ERROR err; + err = GetRVCOperationalStateInstance()->SetOperationalState(state); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "ManualRVCOperationalStateSetStateCommandHandler Failed!\r\n"); + } + + return err; +} + +CHIP_ERROR ManualRVCOperationalStateSetErrorCommandHandler(int argc, char ** argv) +{ + if (argc != 1) + { + return ManualRVCOperationalStateCommandHelpHandler(argc, argv); + } + + GenericOperationalError err(to_underlying(ErrorStateEnum::kNoError)); + uint32_t error = atoi(argv[0]); + + switch (error) + { + case to_underlying(OperationalState::ErrorStateEnum::kNoError): // 0x00, 0 + case to_underlying(OperationalState::ErrorStateEnum::kUnableToStartOrResume): // 0x01, 1 + case to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation): // 0x02, 2 + case to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState): // 0x03, 3 + case to_underlying(RvcOperationalState::ErrorStateEnum::kFailedToFindChargingDock): // 0x40, 64 + case to_underlying(RvcOperationalState::ErrorStateEnum::kStuck): // 0x41, 65 + case to_underlying(RvcOperationalState::ErrorStateEnum::kDustBinMissing): // 0x42, 66 + case to_underlying(RvcOperationalState::ErrorStateEnum::kDustBinFull): // 0x43, 67 + case to_underlying(RvcOperationalState::ErrorStateEnum::kWaterTankEmpty): // 0x44, 68 + case to_underlying(RvcOperationalState::ErrorStateEnum::kWaterTankMissing): // 0x45, 69 + case to_underlying(RvcOperationalState::ErrorStateEnum::kWaterTankLidOpen): // 0x46, 70 + case to_underlying(RvcOperationalState::ErrorStateEnum::kMopCleaningPadMissing): // 0x47, 71 + err.errorStateID = error; + break; + default: + err.errorStateID = to_underlying(OperationalState::ErrorStateEnum::kUnknownEnumValue); // 0x04, 4 + break; + } + + GetRVCOperationalStateInstance()->OnOperationalErrorDetected(err); + + return CHIP_NO_ERROR; +} +#endif // CONFIG_ENABLE_CHIP_SHELL diff --git a/examples/all-clusters-app/ameba/main/include/ManualRVCModesCommand.h b/examples/all-clusters-app/ameba/main/include/ManualRVCModesCommand.h new file mode 100644 index 00000000000000..b020141c5df7a9 --- /dev/null +++ b/examples/all-clusters-app/ameba/main/include/ManualRVCModesCommand.h @@ -0,0 +1,135 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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 "controller/InvokeInteraction.h" +#include "controller/ReadInteraction.h" +#include + +#if CONFIG_ENABLE_CHIP_SHELL +#include "lib/shell/Engine.h" +#include "lib/shell/commands/Help.h" +#endif // ENABLE_CHIP_SHELL + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; + +#if CONFIG_ENABLE_CHIP_SHELL +using Shell::Engine; +using Shell::shell_command_t; +using Shell::streamer_get; +using Shell::streamer_printf; + +Engine sShellManualRVCSubCommands; +Engine sShellManualRVCRunModeSubCommands; +Engine sShellManualRVCCleanModeSubCommands; +#endif // defined(ENABLE_CHIP_SHELL) + +#if CONFIG_ENABLE_CHIP_SHELL +/******************************************************** + * RVC + *********************************************************/ + +CHIP_ERROR ManualRVCCommandHelpHandler(int argc, char ** argv) +{ + sShellManualRVCSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ManualRVCCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return ManualRVCCommandHelpHandler(argc, argv); + } + return sShellManualRVCSubCommands.ExecCommand(argc, argv); +} + +/******************************************************** + * RVC Run Mode + *********************************************************/ + +CHIP_ERROR ManualRVCRunModeCommandHelpHandler(int argc, char ** argv) +{ + sShellManualRVCRunModeSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ManualRVCRunModeCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return ManualRVCRunModeCommandHelpHandler(argc, argv); + } + + return sShellManualRVCRunModeSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR ManualRVCRunModeSetModeCommandHandler(int argc, char ** argv) +{ + if (argc != 1) + { + return ManualRVCRunModeCommandHelpHandler(argc, argv); + } + Protocols::InteractionModel::Status status; + status = RvcRunMode::Instance()->UpdateCurrentMode((uint8_t) atoi(argv[0])); + if (status != Protocols::InteractionModel::Status::Success) + { + ChipLogError(DeviceLayer, "ManualRVCRunModeSetModeCommandHandler Error!"); + return CHIP_ERROR_INTERNAL; + } + return CHIP_NO_ERROR; +} + +/******************************************************** + * RVC Clean Mode + *********************************************************/ + +CHIP_ERROR ManualRVCCleanModeCommandHelpHandler(int argc, char ** argv) +{ + sShellManualRVCCleanModeSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ManualRVCCleanModeCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return ManualRVCCleanModeCommandHelpHandler(argc, argv); + } + + return sShellManualRVCCleanModeSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR ManualRVCCleanModeSetModeCommandHandler(int argc, char ** argv) +{ + if (argc != 1) + { + return ManualRVCCleanModeCommandHelpHandler(argc, argv); + } + Protocols::InteractionModel::Status status; + status = RvcCleanMode::Instance()->UpdateCurrentMode((uint8_t) atoi(argv[0])); + if (status != Protocols::InteractionModel::Status::Success) + { + ChipLogError(DeviceLayer, "ManualRVCCleanModeSetModeCommandHandler Error!"); + return CHIP_ERROR_INTERNAL; + } + return CHIP_NO_ERROR; +} + +#endif // CONFIG_ENABLE_CHIP_SHELL diff --git a/examples/all-clusters-app/ameba/main/include/ManualRefrigeratorAlarmCommand.h b/examples/all-clusters-app/ameba/main/include/ManualRefrigeratorAlarmCommand.h new file mode 100644 index 00000000000000..d2ec4224a5332f --- /dev/null +++ b/examples/all-clusters-app/ameba/main/include/ManualRefrigeratorAlarmCommand.h @@ -0,0 +1,160 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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 "controller/InvokeInteraction.h" +#include "controller/ReadInteraction.h" +#include + +#if CONFIG_ENABLE_CHIP_SHELL +#include "lib/shell/Engine.h" +#include "lib/shell/commands/Help.h" +#endif // ENABLE_CHIP_SHELL + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::RefrigeratorAlarm; + +#if CONFIG_ENABLE_CHIP_SHELL +using Shell::Engine; +using Shell::shell_command_t; +using Shell::streamer_get; +using Shell::streamer_printf; + +Engine sShellManualRefrigeratorAlarmStateSubCommands; +#endif // defined(ENABLE_CHIP_SHELL) + +#if CONFIG_ENABLE_CHIP_SHELL + +CHIP_ERROR ManualRefrigeratorAlarmCommandHelpHandler(int argc, char ** argv) +{ + sShellManualRefrigeratorAlarmStateSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ManualRefrigeratorAlarmCommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return ManualRefrigeratorAlarmCommandHelpHandler(argc, argv); + } + + return sShellManualRefrigeratorAlarmStateSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR ManualRefrigeratorAlarmDoorOpenCommandHandler(int argc, char ** argv) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EmberAfStatus status; + RefrigeratorAlarmServer & serverInstance = RefrigeratorAlarmServer::Instance(); + + status = serverInstance.SetMaskValue(1, 0); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + + status = serverInstance.SetStateValue(1, 1); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + + status = serverInstance.SetSupportedValue(1, 0); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "ManualRefrigeratorAlarmDoorOpenCommandHandler Failed!\r\n"); + } + + return err; +} + +CHIP_ERROR ManualRefrigeratorAlarmDoorCloseCommandHandler(int argc, char ** argv) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EmberAfStatus status; + RefrigeratorAlarmServer & serverInstance = RefrigeratorAlarmServer::Instance(); + + status = serverInstance.SetMaskValue(1, 1); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + + status = serverInstance.SetStateValue(1, 0); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + + status = serverInstance.SetSupportedValue(1, 1); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "ManualRefrigeratorAlarmDoorCloseCommandHandler Failed!\r\n"); + } + + return err; +} + +CHIP_ERROR ManualRefrigeratorAlarmSuppressCommandHandler(int argc, char ** argv) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + EmberAfStatus status; + RefrigeratorAlarmServer & serverInstance = RefrigeratorAlarmServer::Instance(); + + status = serverInstance.SetSupportedValue(1, 1); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + + status = serverInstance.SetStateValue(1, 0); + if (status != EMBER_ZCL_STATUS_SUCCESS) + { + err = CHIP_ERROR_INTERNAL; + goto exit; + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "ManualRefrigeratorAlarmDoorCloseCommandHandler Failed!\r\n"); + } + + return err; +} +#endif // CONFIG_ENABLE_CHIP_SHELL diff --git a/examples/all-clusters-app/ameba/main/include/OperationalStateManager.h b/examples/all-clusters-app/ameba/main/include/OperationalStateManager.h new file mode 100644 index 00000000000000..e98d32171328ac --- /dev/null +++ b/examples/all-clusters-app/ameba/main/include/OperationalStateManager.h @@ -0,0 +1,162 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +void getOperationalStateSet(u8 state); + +namespace chip { +namespace app { +namespace Clusters { + +namespace OperationalState { + +Instance * GetOperationalStateInstance(); +Instance * GetRVCOperationalStateInstance(); + +// This is an application level delegate to handle operational state commands according to the specific business logic. +class GenericOperationalStateDelegateImpl : public Delegate +{ +public: + /** + * Get the countdown time. This attribute is not used in this application. + * @return The current countdown time. + */ + app::DataModel::Nullable GetCountdownTime() override { return {}; }; + + /** + * Fills in the provided GenericOperationalState with the state at index `index` if there is one, + * or returns CHIP_ERROR_NOT_FOUND if the index is out of range for the list of states. + * Note: This is used by the SDK to populate the operational state list attribute. If the contents of this list changes, + * the device SHALL call the Instance's ReportOperationalStateListChange method to report that this attribute has changed. + * @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; + + /** + * 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. + * 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 GenericOperationalPhase is filled. + */ + CHIP_ERROR GetOperationalPhaseAtIndex(size_t index, GenericOperationalPhase & operationalPhase) override; + + // command callback + /** + * Handle Command Callback in application: Pause + * @param[out] get operational error after callback. + */ + void HandlePauseStateCallback(GenericOperationalError & err) override; + + /** + * Handle Command Callback in application: Resume + * @param[out] get operational error after callback. + */ + void HandleResumeStateCallback(GenericOperationalError & err) override; + + /** + * Handle Command Callback in application: Start + * @param[out] get operational error after callback. + */ + void HandleStartStateCallback(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)), + }; + + const GenericOperationalPhase opPhaseList[1] = { + // Phase List is null + GenericOperationalPhase(DataModel::Nullable()), + }; + +public: + OperationalStateDelegate() + { + GenericOperationalStateDelegateImpl::mOperationalStateList = Span(opStateList); + GenericOperationalStateDelegateImpl::mOperationalPhaseList = Span(opPhaseList); + } +}; + +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)), + }; + + const OperationalState::GenericOperationalPhase rvcOpPhaseList[1] = { + // Phase List is null + OperationalState::GenericOperationalPhase(DataModel::Nullable()), + }; + +public: + RvcOperationalStateDelegate() + { + GenericOperationalStateDelegateImpl::mOperationalStateList = + Span(rvcOpStateList); + GenericOperationalStateDelegateImpl::mOperationalPhaseList = + Span(rvcOpPhaseList); + } +}; + +void Shutdown(); + +} // namespace RvcOperationalState +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/ameba/main/include/SmokeCOAlarmManager.h b/examples/all-clusters-app/ameba/main/include/SmokeCOAlarmManager.h new file mode 100644 index 00000000000000..390ee679d0d255 --- /dev/null +++ b/examples/all-clusters-app/ameba/main/include/SmokeCOAlarmManager.h @@ -0,0 +1,47 @@ +/* + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +bool emberAfHandleEventTrigger(uint64_t eventTrigger); + +class SmokeCoAlarmManager +{ +public: + CHIP_ERROR Init(); + + /** + * @brief Execute the self-test process + * + */ + void StartSelfTesting(); + +private: + friend SmokeCoAlarmManager & AlarmMgr(void); + + static SmokeCoAlarmManager sAlarm; +}; + +inline SmokeCoAlarmManager & AlarmMgr(void) +{ + return SmokeCoAlarmManager::sAlarm; +} diff --git a/examples/platform/ameba/test_event_trigger/AmebaTestEventTriggerDelegate.cpp b/examples/platform/ameba/test_event_trigger/AmebaTestEventTriggerDelegate.cpp new file mode 100644 index 00000000000000..9cfddd6f3de9fa --- /dev/null +++ b/examples/platform/ameba/test_event_trigger/AmebaTestEventTriggerDelegate.cpp @@ -0,0 +1,37 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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 "AmebaTestEventTriggerDelegate.h" +#include "SmokeCOAlarmManager.h" + +using namespace ::chip::DeviceLayer; + +namespace chip { + +bool AmebaTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const +{ + return !mEnableKey.empty() && mEnableKey.data_equal(enableKey); +} + +CHIP_ERROR AmebaTestEventTriggerDelegate::HandleEventTrigger(uint64_t eventTrigger) +{ + bool success = emberAfHandleEventTrigger(eventTrigger); + return success ? CHIP_NO_ERROR : CHIP_ERROR_INVALID_ARGUMENT; +} + +} // namespace chip diff --git a/examples/platform/ameba/test_event_trigger/AmebaTestEventTriggerDelegate.h b/examples/platform/ameba/test_event_trigger/AmebaTestEventTriggerDelegate.h new file mode 100644 index 00000000000000..d461194de9b642 --- /dev/null +++ b/examples/platform/ameba/test_event_trigger/AmebaTestEventTriggerDelegate.h @@ -0,0 +1,61 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * 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. + */ + +#pragma once + +#include "SmokeCOAlarmManager.h" +#include + +namespace chip { + +class AmebaTestEventTriggerDelegate : public TestEventTriggerDelegate +{ +public: + explicit AmebaTestEventTriggerDelegate(const ByteSpan & enableKey) : mEnableKey(enableKey) {} + + /** + * @brief Checks to see if `enableKey` provided matches value chosen by the manufacturer. + * @param enableKey Buffer of the key to verify. + * @return True or False. + */ + bool DoesEnableKeyMatch(const ByteSpan & enableKey) const override; + + /** + * @brief User handler for handling the test event trigger based on `eventTrigger` provided. + * @param eventTrigger Event trigger to handle. + * @return CHIP_NO_ERROR on success or CHIP_ERROR_INVALID_ARGUMENT on failure. + */ + CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override; + +private: + ByteSpan mEnableKey; +}; + +} // namespace chip + +/** + * @brief User handler for handling the test event trigger + * + * @note If TestEventTrigger is enabled, it needs to be implemented in the app + * + * @param eventTrigger Event trigger to handle + * + * @retval true on success + * @retval false if error happened + */ +bool emberAfHandleEventTrigger(uint64_t eventTrigger);