diff --git a/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp index e6e18ab9edb32a..4b1e883a6b7d17 100644 --- a/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp @@ -44,15 +44,11 @@ void EndSelfTestingEventHandler(System::Layer * systemLayer, void * appState) ChipLogProgress(Support, "[Smoke-CO-Alarm] => Self test complete"); } -bool emberAfPluginSmokeCoAlarmSelfTestRequestCommand(EndpointId endpointId) +void emberAfPluginSmokeCoAlarmSelfTestRequestCommand(EndpointId endpointId) { - SmokeCoAlarmServer::Instance().SetTestInProgress(1, true); - ChipLogProgress(Support, "[Smoke-CO-Alarm] => Self test running"); DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds32(kSelfTestingTimeoutSec), EndSelfTestingEventHandler, nullptr); - - return true; } bool HandleSmokeCOTestEventTrigger(uint64_t eventTrigger) diff --git a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp index e3118377d51772..b94e3177d67ae1 100644 --- a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp +++ b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -286,6 +287,9 @@ void AllClustersAppCommandHandler::OnSwitchLongPressedHandler(uint8_t newPositio ChipLogDetail(NotSpecified, "The new position when the momentary switch has been pressed for a long time:%d", newPosition); Clusters::SwitchServer::Instance().OnLongPress(endpoint, newPosition); + + // Long press to trigger smokeco self-test + SmokeCoAlarmServer::Instance().RequestSelfTest(endpoint); } void AllClustersAppCommandHandler::OnSwitchShortReleasedHandler(uint8_t previousPosition) diff --git a/examples/smoke-co-alarm-app/silabs/include/SmokeCoAlarmManager.h b/examples/smoke-co-alarm-app/silabs/include/SmokeCoAlarmManager.h index be1b38a8bb5e3a..b44bbf102be8b4 100644 --- a/examples/smoke-co-alarm-app/silabs/include/SmokeCoAlarmManager.h +++ b/examples/smoke-co-alarm-app/silabs/include/SmokeCoAlarmManager.h @@ -31,89 +31,23 @@ class SmokeCoAlarmManager { public: - using ExpressedStateEnum = chip::app::Clusters::SmokeCoAlarm::ExpressedStateEnum; - - enum TriggeredEvent_t - { - kTriggeredEvent_WarningSmokeAlarm = 0xffffffff00000090, - kTriggeredEvent_CriticalSmokeAlarm = 0xffffffff0000009c, - kTriggeredEvent_SmokeAlarmClear = 0xffffffff000000a0, - kTriggeredEvent_WarningCOAlarm = 0xffffffff00000091, - kTriggeredEvent_CriticalCOAlarm = 0xffffffff0000009d, - kTriggeredEvent_COAlarmClear = 0xffffffff000000a1, - kTriggeredEvent_WarningBatteryAlert = 0xffffffff00000095, - kTriggeredEvent_CriticalBatteryAlert = 0xffffffff0000009e, - kTriggeredEvent_BatteryAlertClear = 0xffffffff000000a5, - kTriggeredEvent_HardwareFaultAlert = 0xffffffff00000093, - kTriggeredEvent_HardwareFaultAlertClear = 0xffffffff000000a3, - kTriggeredEvent_EndofServiceAlert = 0xffffffff0000009a, - kTriggeredEvent_EndofServiceAlertClear = 0xffffffff000000aa, - kTriggeredEvent_DeviceMute = 0xffffffff0000009b, - kTriggeredEvent_DeviceMuteClear = 0xffffffff000000ab, - kTriggeredEvent_InterconnectSmokeAlarm = 0xffffffff00000092, - kTriggeredEvent_InterconnectSmokeAlarmClear = 0xffffffff000000a2, - kTriggeredEvent_InterconnectCOAlarm = 0xffffffff00000094, - kTriggeredEvent_InterconnectCOAlarmClear = 0xffffffff000000a4, - kTriggeredEvent_ContaminationStateHigh = 0xffffffff00000096, - kTriggeredEvent_ContaminationStateLow = 0xffffffff00000097, - kTriggeredEvent_ContaminationStateClear = 0xffffffff000000a6, - kTriggeredEvent_SensitivityLevelHigh = 0xffffffff00000098, - kTriggeredEvent_SensitivityLevelLow = 0xffffffff00000099, - kTriggeredEvent_SensitivityLevelClear = 0xffffffff000000a8, - } TriggeredEvent; - CHIP_ERROR Init(); /** - * @brief Execute the self-test process and attribute changes - * - */ - bool OnSelfTesting(); - - /** - * @brief Execute the self-test process manually - * - */ - bool ManualSelfTesting(); - - /** - * @brief Execute the HandleEventTrigger process - * - */ - bool OnEventTriggerHandle(uint64_t eventTrigger); - - /** - * @brief Updates the expressed state with new value + * @brief Execute the self-test process * - * @param endpointId ID of the endpoint - * @param expressedState expressed state - * @param isSet true on set, false on unset - * @return true on success, false on failure */ - bool SetExpressedState(chip::EndpointId endpointId, ExpressedStateEnum expressedState, bool isSet); + void SelfTestingEventHandler(); private: friend SmokeCoAlarmManager & AlarmMgr(void); - /** - * @brief Record expressed state in decreasing priority - * - */ - std::array mExpressedStatePriority; - - /** - * @brief Expression status record values - * - */ - int mExpressedStateMask = 1; - bool mEndSelfTesting; void CancelTimer(void); void StartTimer(uint32_t aTimeoutMs); static void TimerEventHandler(TimerHandle_t xTimer); - static void SelfTestingEventHandler(AppEvent * aEvent); static void EndSelfTestingEventHandler(AppEvent * aEvent); static SmokeCoAlarmManager sAlarm; diff --git a/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp b/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp index 4e2341e3b7ef45..153f2e7073bcb7 100644 --- a/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp +++ b/examples/smoke-co-alarm-app/silabs/src/AppTask.cpp @@ -140,7 +140,9 @@ void AppTask::AppTaskMain(void * pvParameter) void AppTask::ButtonActionEventHandler(AppEvent * aEvent) { - bool success = AlarmMgr().ManualSelfTesting(); + chip::DeviceLayer::PlatformMgr().LockChipStack(); + bool success = SmokeCoAlarmServer::Instance().RequestSelfTest(1); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); if (!success) { SILABS_LOG("Manual self-test failed"); diff --git a/examples/smoke-co-alarm-app/silabs/src/SmokeCoAlarmManager.cpp b/examples/smoke-co-alarm-app/silabs/src/SmokeCoAlarmManager.cpp index 3fd076689d4e14..85c8bca2193a67 100644 --- a/examples/smoke-co-alarm-app/silabs/src/SmokeCoAlarmManager.cpp +++ b/examples/smoke-co-alarm-app/silabs/src/SmokeCoAlarmManager.cpp @@ -21,24 +21,25 @@ #include "AppTask.h" #include +#include #include using namespace chip; -using namespace ::chip::app::Clusters::SmokeCoAlarm; -using namespace ::chip::DeviceLayer; +using namespace chip::app::Clusters::SmokeCoAlarm; +using namespace chip::DeviceLayer; SmokeCoAlarmManager SmokeCoAlarmManager::sAlarm; TimerHandle_t sAlarmTimer; +static std::array sPriorityOrder = { + ExpressedStateEnum::kSmokeAlarm, ExpressedStateEnum::kInterconnectSmoke, ExpressedStateEnum::kCOAlarm, + ExpressedStateEnum::kInterconnectCO, ExpressedStateEnum::kHardwareFault, ExpressedStateEnum::kTesting, + ExpressedStateEnum::kEndOfService, ExpressedStateEnum::kBatteryAlert +}; + CHIP_ERROR SmokeCoAlarmManager::Init() { - mExpressedStatePriority = { - ExpressedStateEnum::kTesting, ExpressedStateEnum::kEndOfService, ExpressedStateEnum::kSmokeAlarm, - ExpressedStateEnum::kCOAlarm, ExpressedStateEnum::kInterconnectSmoke, ExpressedStateEnum::kInterconnectCO, - ExpressedStateEnum::kHardwareFault, ExpressedStateEnum::kBatteryAlert, ExpressedStateEnum::kNormal - }; - // Create FreeRTOS sw timer for alarm timer. sAlarmTimer = xTimerCreate("alarmTmr", // Just a text name, not used by the RTOS kernel pdMS_TO_TICKS(1), // == default timer period @@ -55,47 +56,7 @@ CHIP_ERROR SmokeCoAlarmManager::Init() // read current State on endpoint one chip::DeviceLayer::PlatformMgr().LockChipStack(); - ExpressedStateEnum currentExpressedState; - bool success = SmokeCoAlarmServer::Instance().GetExpressedState(1, currentExpressedState); - if (success) - { - mExpressedStateMask |= (1 << to_underlying(currentExpressedState)); - } - - AlarmStateEnum currentSmokeState; - success = SmokeCoAlarmServer::Instance().GetSmokeState(1, currentSmokeState); - if (success && (currentSmokeState != AlarmStateEnum::kNormal)) - { - mExpressedStateMask |= (1 << to_underlying(ExpressedStateEnum::kSmokeAlarm)); - } - - AlarmStateEnum currentCOState; - success = SmokeCoAlarmServer::Instance().GetCOState(1, currentCOState); - if (success && (currentCOState != AlarmStateEnum::kNormal)) - { - mExpressedStateMask |= (1 << to_underlying(ExpressedStateEnum::kCOAlarm)); - } - - AlarmStateEnum currentBatteryAlert; - success = SmokeCoAlarmServer::Instance().GetBatteryAlert(1, currentBatteryAlert); - if (success && (currentBatteryAlert != AlarmStateEnum::kNormal)) - { - mExpressedStateMask |= (1 << to_underlying(ExpressedStateEnum::kBatteryAlert)); - } - - bool currentHardwareFaultAlert; - success = SmokeCoAlarmServer::Instance().GetHardwareFaultAlert(1, currentHardwareFaultAlert); - if (success && (currentHardwareFaultAlert != false)) - { - mExpressedStateMask |= (1 << to_underlying(ExpressedStateEnum::kHardwareFault)); - } - - EndOfServiceEnum currentEndOfServiceAlert; - success = SmokeCoAlarmServer::Instance().GetEndOfServiceAlert(1, currentEndOfServiceAlert); - if (success && (currentEndOfServiceAlert != EndOfServiceEnum::kNormal)) - { - mExpressedStateMask |= (1 << to_underlying(ExpressedStateEnum::kEndOfService)); - } + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); chip::DeviceLayer::PlatformMgr().UnlockChipStack(); mEndSelfTesting = false; @@ -148,18 +109,8 @@ void SmokeCoAlarmManager::TimerEventHandler(TimerHandle_t xTimer) AppTask::GetAppTask().PostEvent(&event); } -void SmokeCoAlarmManager::SelfTestingEventHandler(AppEvent * aEvent) +void SmokeCoAlarmManager::SelfTestingEventHandler() { - chip::DeviceLayer::PlatformMgr().LockChipStack(); - bool success = SmokeCoAlarmServer::Instance().SetTestInProgress(1, true); - chip::DeviceLayer::PlatformMgr().UnlockChipStack(); - - if (!success) - { - SILABS_LOG("Start self-testing failed"); - return; - } - SILABS_LOG("Start self-testing!"); AlarmMgr().mEndSelfTesting = true; @@ -171,194 +122,140 @@ void SmokeCoAlarmManager::EndSelfTestingEventHandler(AppEvent * aEvent) AlarmMgr().mEndSelfTesting = false; chip::DeviceLayer::PlatformMgr().LockChipStack(); - bool success = SmokeCoAlarmServer::Instance().SetTestInProgress(1, false); - if (success) - { - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kTesting, false); - SILABS_LOG("End self-testing!"); - } + SmokeCoAlarmServer::Instance().SetTestInProgress(1, false); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); chip::DeviceLayer::PlatformMgr().UnlockChipStack(); -} -bool SmokeCoAlarmManager::OnSelfTesting() -{ - AppEvent event; - event.Handler = SelfTestingEventHandler; - AppTask::GetAppTask().PostEvent(&event); - - return true; -} - -bool SmokeCoAlarmManager::ManualSelfTesting() -{ - bool success = false; - - if ((mExpressedStateMask & 0b110010110) == 0) - { - chip::DeviceLayer::PlatformMgr().LockChipStack(); - success = AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kTesting, true); - chip::DeviceLayer::PlatformMgr().UnlockChipStack(); - - if (success) - { - success = OnSelfTesting(); - } - } - - return success; + SILABS_LOG("End self-testing!"); } -bool SmokeCoAlarmManager::OnEventTriggerHandle(uint64_t eventTrigger) +bool emberAfHandleEventTrigger(uint64_t eventTrigger) { - bool isValidCommand = true; + SmokeCOTrigger trigger = static_cast(eventTrigger); - switch (eventTrigger) + switch (trigger) { - case kTriggeredEvent_WarningSmokeAlarm: + 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); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kSmokeAlarm, true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); break; - - case kTriggeredEvent_CriticalSmokeAlarm: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetSmokeState(1, AlarmStateEnum::kCritical), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kSmokeAlarm, true); + 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 kTriggeredEvent_SmokeAlarmClear: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetSmokeState(1, AlarmStateEnum::kNormal), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kSmokeAlarm, false); + 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 kTriggeredEvent_WarningCOAlarm: + case SmokeCOTrigger::kForceCOWarning: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force CO (warning)"); VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetCOState(1, AlarmStateEnum::kWarning), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kCOAlarm, true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); break; - - case kTriggeredEvent_CriticalCOAlarm: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetCOState(1, AlarmStateEnum::kCritical), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kCOAlarm, true); + 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 kTriggeredEvent_COAlarmClear: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetCOState(1, AlarmStateEnum::kNormal), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kCOAlarm, false); + case SmokeCOTrigger::kForceSmokeContaminationHigh: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke contamination (critical)"); + SmokeCoAlarmServer::Instance().SetContaminationState(1, ContaminationStateEnum::kCritical); break; - - case kTriggeredEvent_WarningBatteryAlert: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetBatteryAlert(1, AlarmStateEnum::kWarning), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kBatteryAlert, true); + case SmokeCOTrigger::kForceSmokeContaminationLow: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke contamination (warning)"); + SmokeCoAlarmServer::Instance().SetContaminationState(1, ContaminationStateEnum::kLow); break; - - case kTriggeredEvent_CriticalBatteryAlert: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetBatteryAlert(1, AlarmStateEnum::kCritical), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kBatteryAlert, true); + case SmokeCOTrigger::kForceSmokeSensitivityHigh: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke sensistivity (high)"); + SmokeCoAlarmServer::Instance().SetSmokeSensitivityLevel(1, SensitivityEnum::kHigh); break; - - case kTriggeredEvent_BatteryAlertClear: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetBatteryAlert(1, AlarmStateEnum::kNormal), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kBatteryAlert, false); + case SmokeCOTrigger::kForceSmokeSensitivityLow: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force smoke sensitivity (low)"); + SmokeCoAlarmServer::Instance().SetSmokeSensitivityLevel(1, SensitivityEnum::kLow); break; - - case kTriggeredEvent_HardwareFaultAlert: + case SmokeCOTrigger::kForceMalfunction: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force malfunction"); VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetHardwareFaultAlert(1, true), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kHardwareFault, true); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); break; - - case kTriggeredEvent_HardwareFaultAlertClear: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetHardwareFaultAlert(1, false), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kHardwareFault, false); + 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 kTriggeredEvent_EndofServiceAlert: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetEndOfServiceAlert(1, EndOfServiceEnum::kExpired), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kEndOfService, true); + 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 kTriggeredEvent_EndofServiceAlertClear: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetEndOfServiceAlert(1, EndOfServiceEnum::kNormal), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kEndOfService, false); + 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 kTriggeredEvent_DeviceMute: + case SmokeCOTrigger::kForceSilence: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force silence"); SmokeCoAlarmServer::Instance().SetDeviceMuted(1, MuteStateEnum::kMuted); break; - - case kTriggeredEvent_DeviceMuteClear: - SmokeCoAlarmServer::Instance().SetDeviceMuted(1, MuteStateEnum::kNotMuted); + 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 kTriggeredEvent_InterconnectSmokeAlarm: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetInterconnectSmokeAlarm(1, AlarmStateEnum::kWarning), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kInterconnectSmoke, true); + 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 kTriggeredEvent_InterconnectSmokeAlarmClear: + case SmokeCOTrigger::kClearSmokeInterconnect: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear smoke interconnect"); VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetInterconnectSmokeAlarm(1, AlarmStateEnum::kNormal), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kInterconnectSmoke, false); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); break; - - case kTriggeredEvent_InterconnectCOAlarm: - VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetInterconnectCOAlarm(1, AlarmStateEnum::kWarning), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kInterconnectCO, true); - break; - - case kTriggeredEvent_InterconnectCOAlarmClear: + case SmokeCOTrigger::kClearCOInterconnect: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear CO interconnect"); VerifyOrReturnValue(SmokeCoAlarmServer::Instance().SetInterconnectCOAlarm(1, AlarmStateEnum::kNormal), true); - AlarmMgr().SetExpressedState(1, ExpressedStateEnum::kInterconnectCO, false); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); break; - - case kTriggeredEvent_ContaminationStateHigh: - SmokeCoAlarmServer::Instance().SetContaminationState(1, ContaminationStateEnum::kWarning); + 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 kTriggeredEvent_ContaminationStateLow: - SmokeCoAlarmServer::Instance().SetContaminationState(1, ContaminationStateEnum::kLow); + 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 kTriggeredEvent_ContaminationStateClear: - SmokeCoAlarmServer::Instance().SetContaminationState(1, ContaminationStateEnum::kNormal); + case SmokeCOTrigger::kClearSilence: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear silence"); + SmokeCoAlarmServer::Instance().SetDeviceMuted(1, MuteStateEnum::kNotMuted); break; - - case kTriggeredEvent_SensitivityLevelHigh: - SmokeCoAlarmServer::Instance().SetSmokeSensitivityLevel(1, SensitivityEnum::kHigh); + 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 kTriggeredEvent_SensitivityLevelLow: - SmokeCoAlarmServer::Instance().SetSmokeSensitivityLevel(1, SensitivityEnum::kLow); + case SmokeCOTrigger::kClearContamination: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Force SmokeContamination (warning)"); + SmokeCoAlarmServer::Instance().SetContaminationState(1, ContaminationStateEnum::kNormal); break; - - case kTriggeredEvent_SensitivityLevelClear: + case SmokeCOTrigger::kClearSensitivity: + ChipLogProgress(Support, "[Smoke-CO-Alarm-Test-Event] => Clear Smoke Sensitivity"); SmokeCoAlarmServer::Instance().SetSmokeSensitivityLevel(1, SensitivityEnum::kStandard); break; - default: - isValidCommand = false; - } - - return isValidCommand; -} - -bool SmokeCoAlarmManager::SetExpressedState(EndpointId endpointId, ExpressedStateEnum expressedState, bool isSet) -{ - bool success = false; - if (isSet) - { - mExpressedStateMask |= (1 << to_underlying(expressedState)); - } - else - { - mExpressedStateMask &= ~(1 << to_underlying(expressedState)); + return false; } - for (auto it : mExpressedStatePriority) - { - if (mExpressedStateMask & (1 << to_underlying(it))) - { - success = SmokeCoAlarmServer::Instance().SetExpressedState(endpointId, it); - break; - } - } - - return success; + return true; } diff --git a/examples/smoke-co-alarm-app/silabs/src/ZclCallbacks.cpp b/examples/smoke-co-alarm-app/silabs/src/ZclCallbacks.cpp index 49050b80d6675c..d4e807acb28bdb 100644 --- a/examples/smoke-co-alarm-app/silabs/src/ZclCallbacks.cpp +++ b/examples/smoke-co-alarm-app/silabs/src/ZclCallbacks.cpp @@ -23,14 +23,13 @@ #include "AppConfig.h" #include "SmokeCoAlarmManager.h" -#include "SilabsTestEventTriggerDelegate.h" #include #include #include #include -using namespace ::chip; -using namespace ::chip::app::Clusters; +using namespace chip; +using namespace chip::app::Clusters; void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, uint8_t * value) @@ -62,12 +61,7 @@ void emberAfSmokeCoAlarmClusterInitCallback(EndpointId endpoint) // TODO: implement any additional Cluster Server init actions } -bool emberAfPluginSmokeCoAlarmSelfTestRequestCommand(EndpointId endpointId) +void emberAfPluginSmokeCoAlarmSelfTestRequestCommand(EndpointId endpointId) { - return AlarmMgr().OnSelfTesting(); -} - -bool emberAfHandleEventTrigger(uint64_t eventTrigger) -{ - return AlarmMgr().OnEventTriggerHandle(eventTrigger); + AlarmMgr().SelfTestingEventHandler(); } diff --git a/examples/smoke-co-alarm-app/telink/include/SmokeCoAlarmManager.h b/examples/smoke-co-alarm-app/telink/include/SmokeCoAlarmManager.h index fa441082743b78..8d19d7340a7981 100644 --- a/examples/smoke-co-alarm-app/telink/include/SmokeCoAlarmManager.h +++ b/examples/smoke-co-alarm-app/telink/include/SmokeCoAlarmManager.h @@ -30,16 +30,14 @@ class SmokeCoAlarmManager CHIP_ERROR Init(); /** - * @brief Execute the self-test process and attribute changes + * @brief Execute the self-test process * */ - bool StartSelfTesting(); + void StartSelfTesting(); private: friend SmokeCoAlarmManager & AlarmMgr(void); - chip::app::Clusters::SmokeCoAlarm::ExpressedStateEnum mExpressedState; - static SmokeCoAlarmManager sAlarm; }; diff --git a/examples/smoke-co-alarm-app/telink/src/AppTask.cpp b/examples/smoke-co-alarm-app/telink/src/AppTask.cpp index 71f495fca26bf8..86ffb247965ae6 100644 --- a/examples/smoke-co-alarm-app/telink/src/AppTask.cpp +++ b/examples/smoke-co-alarm-app/telink/src/AppTask.cpp @@ -50,7 +50,13 @@ CHIP_ERROR AppTask::Init(void) void AppTask::SelfTestHandler(AppEvent * aEvent) { - AlarmMgr().StartSelfTesting(); + chip::DeviceLayer::PlatformMgr().LockChipStack(); + bool success = SmokeCoAlarmServer::Instance().RequestSelfTest(1); + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + if (!success) + { + LOG_ERR("Manual self-test failed"); + } } void AppTask::SelfTestEventHandler(AppEvent * aEvent) diff --git a/examples/smoke-co-alarm-app/telink/src/SmokeCoAlarmManager.cpp b/examples/smoke-co-alarm-app/telink/src/SmokeCoAlarmManager.cpp index 7f7c3a678773d5..e97d6e95d3cafc 100644 --- a/examples/smoke-co-alarm-app/telink/src/SmokeCoAlarmManager.cpp +++ b/examples/smoke-co-alarm-app/telink/src/SmokeCoAlarmManager.cpp @@ -27,30 +27,24 @@ LOG_MODULE_DECLARE(COsensor, CONFIG_CHIP_APP_LOG_LEVEL); SmokeCoAlarmManager SmokeCoAlarmManager::sAlarm; +static std::array sPriorityOrder = { + ExpressedStateEnum::kSmokeAlarm, ExpressedStateEnum::kInterconnectSmoke, ExpressedStateEnum::kCOAlarm, + ExpressedStateEnum::kInterconnectCO, ExpressedStateEnum::kHardwareFault, ExpressedStateEnum::kTesting, + ExpressedStateEnum::kEndOfService, ExpressedStateEnum::kBatteryAlert +}; + CHIP_ERROR SmokeCoAlarmManager::Init() { - mExpressedState = ExpressedStateEnum::kNormal; - return CHIP_NO_ERROR; } -bool SmokeCoAlarmManager::StartSelfTesting() +void SmokeCoAlarmManager::StartSelfTesting() { LOG_INF("Start self-testing!"); - bool success = SmokeCoAlarmServer::Instance().SetTestInProgress(1, true); - - if (success) - { - LOG_INF("Start self-testing success!"); - } - else - { - LOG_INF("Start self-testing fail!"); - } - - SmokeCoAlarmServer::Instance().SetExpressedState(1, mExpressedState); + + // It will take some time here + SmokeCoAlarmServer::Instance().SetTestInProgress(1, false); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); LOG_INF("End self-testing!"); - - return success; } diff --git a/examples/smoke-co-alarm-app/telink/src/ZclCallbacks.cpp b/examples/smoke-co-alarm-app/telink/src/ZclCallbacks.cpp index 28c84a6b206e8d..0d1261fb925af1 100644 --- a/examples/smoke-co-alarm-app/telink/src/ZclCallbacks.cpp +++ b/examples/smoke-co-alarm-app/telink/src/ZclCallbacks.cpp @@ -61,7 +61,7 @@ void emberAfSmokeCoAlarmClusterInitCallback(EndpointId endpoint) // TODO: implement any additional Cluster Server init actions } -bool emberAfPluginSmokeCoAlarmSelfTestRequestCommand(EndpointId endpointId) +void emberAfPluginSmokeCoAlarmSelfTestRequestCommand(EndpointId endpointId) { - return AlarmMgr().StartSelfTesting(); + AlarmMgr().StartSelfTesting(); } diff --git a/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.cpp b/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.cpp index 19f1da4f8a8d76..67c927c202730d 100644 --- a/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.cpp +++ b/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.cpp @@ -29,6 +29,7 @@ using namespace chip; using namespace chip::app; using namespace chip::app::Clusters::SmokeCoAlarm; +using namespace chip::app::Clusters::SmokeCoAlarm::Attributes; using chip::Protocols::InteractionModel::Status; SmokeCoAlarmServer SmokeCoAlarmServer::sInstance; @@ -42,25 +43,6 @@ SmokeCoAlarmServer & SmokeCoAlarmServer::Instance() return sInstance; } -bool SmokeCoAlarmServer::SetExpressedState(EndpointId endpointId, ExpressedStateEnum newExpressedState) -{ - ExpressedStateEnum expressedState; - bool success = GetAttribute(endpointId, Attributes::ExpressedState::Id, Attributes::ExpressedState::Get, expressedState); - - if (success && (expressedState != newExpressedState)) - { - success = SetAttribute(endpointId, Attributes::ExpressedState::Id, Attributes::ExpressedState::Set, newExpressedState); - - if (success && (newExpressedState == ExpressedStateEnum::kNormal)) - { - Events::AllClear::Type event{}; - SendEvent(endpointId, event); - } - } - - return success; -} - void SmokeCoAlarmServer::SetExpressedStateByPriority(EndpointId endpointId, const std::array & priorityOrder) { @@ -102,379 +84,322 @@ void SmokeCoAlarmServer::SetExpressedStateByPriority(EndpointId endpointId, if ((alarmState != AlarmStateEnum::kNormal) || (endOfServiceState != EndOfServiceEnum::kNormal) || active) { - VerifyOrDo(SetExpressedState(endpointId, priority), ChipLogError(NotSpecified, "Set ExpressedState failed")); + SetExpressedState(endpointId, priority); return; } } - VerifyOrDo(SetExpressedState(endpointId, ExpressedStateEnum::kNormal), ChipLogError(NotSpecified, "Set ExpressedState failed")); + SetExpressedState(endpointId, ExpressedStateEnum::kNormal); } -bool SmokeCoAlarmServer::SetSmokeState(EndpointId endpointId, AlarmStateEnum newSmokeState) +bool SmokeCoAlarmServer::RequestSelfTest(EndpointId endpointId) { - AlarmStateEnum smokeState; - bool success = GetAttribute(endpointId, Attributes::SmokeState::Id, Attributes::SmokeState::Get, smokeState); + ExpressedStateEnum expressedState; + VerifyOrReturnValue(GetExpressedState(endpointId, expressedState), false); - if (success && (smokeState != newSmokeState)) + // If the value is busy then return busy + if (expressedState == ExpressedStateEnum::kSmokeAlarm || expressedState == ExpressedStateEnum::kCOAlarm || + expressedState == ExpressedStateEnum::kTesting || expressedState == ExpressedStateEnum::kInterconnectSmoke || + expressedState == ExpressedStateEnum::kInterconnectCO) { - success = SetAttribute(endpointId, Attributes::SmokeState::Id, Attributes::SmokeState::Set, newSmokeState); + return false; + } - if (success && (newSmokeState == AlarmStateEnum::kWarning || newSmokeState == AlarmStateEnum::kCritical)) - { - Events::SmokeAlarm::Type event{ newSmokeState }; - SendEvent(endpointId, event); - } + VerifyOrReturnValue(SetTestInProgress(endpointId, true), false); + SetExpressedState(endpointId, ExpressedStateEnum::kTesting); - if (success && (newSmokeState == AlarmStateEnum::kCritical)) - { - SetDeviceMuted(endpointId, MuteStateEnum::kNotMuted); - } + emberAfPluginSmokeCoAlarmSelfTestRequestCommand(endpointId); + + return true; +} + +bool SmokeCoAlarmServer::SetSmokeState(EndpointId endpointId, AlarmStateEnum newSmokeState) +{ + AlarmStateEnum alarmState; + VerifyOrReturnValue(GetAttribute(endpointId, SmokeState::Id, SmokeState::Get, alarmState), false); + VerifyOrReturnValue(alarmState != newSmokeState, true); + + VerifyOrReturnValue(SetAttribute(endpointId, SmokeState::Id, SmokeState::Set, newSmokeState), false); + if (newSmokeState == AlarmStateEnum::kWarning || newSmokeState == AlarmStateEnum::kCritical) + { + Events::SmokeAlarm::Type event{ newSmokeState }; + SendEvent(endpointId, event); } - return success; + if (newSmokeState == AlarmStateEnum::kCritical) + { + SetDeviceMuted(endpointId, MuteStateEnum::kNotMuted); + } + + return true; } bool SmokeCoAlarmServer::SetCOState(EndpointId endpointId, AlarmStateEnum newCOState) { - AlarmStateEnum coState; - bool success = GetAttribute(endpointId, Attributes::COState::Id, Attributes::COState::Get, coState); + AlarmStateEnum alarmState; + VerifyOrReturnValue(GetAttribute(endpointId, COState::Id, COState::Get, alarmState), false); + VerifyOrReturnValue(alarmState != newCOState, true); - if (success && (coState != newCOState)) + VerifyOrReturnValue(SetAttribute(endpointId, COState::Id, COState::Set, newCOState), false); + if (newCOState == AlarmStateEnum::kWarning || newCOState == AlarmStateEnum::kCritical) { - success = SetAttribute(endpointId, Attributes::COState::Id, Attributes::COState::Set, newCOState); - - if (success && (newCOState == AlarmStateEnum::kWarning || newCOState == AlarmStateEnum::kCritical)) - { - Events::COAlarm::Type event{ newCOState }; - SendEvent(endpointId, event); - } + Events::COAlarm::Type event{ newCOState }; + SendEvent(endpointId, event); + } - if (success && (newCOState == AlarmStateEnum::kCritical)) - { - SetDeviceMuted(endpointId, MuteStateEnum::kNotMuted); - } + if (newCOState == AlarmStateEnum::kCritical) + { + SetDeviceMuted(endpointId, MuteStateEnum::kNotMuted); } - return success; + return true; } bool SmokeCoAlarmServer::SetBatteryAlert(EndpointId endpointId, AlarmStateEnum newBatteryAlert) { - AlarmStateEnum batteryAlert; - bool success = GetAttribute(endpointId, Attributes::BatteryAlert::Id, Attributes::BatteryAlert::Get, batteryAlert); + AlarmStateEnum alarmState; + VerifyOrReturnValue(GetAttribute(endpointId, BatteryAlert::Id, BatteryAlert::Get, alarmState), false); + VerifyOrReturnValue(alarmState != newBatteryAlert, true); - if (success && (batteryAlert != newBatteryAlert)) + VerifyOrReturnValue(SetAttribute(endpointId, BatteryAlert::Id, BatteryAlert::Set, newBatteryAlert), false); + if (newBatteryAlert == AlarmStateEnum::kWarning || newBatteryAlert == AlarmStateEnum::kCritical) { - success = SetAttribute(endpointId, Attributes::BatteryAlert::Id, Attributes::BatteryAlert::Set, newBatteryAlert); - - if (success && (newBatteryAlert == AlarmStateEnum::kWarning || newBatteryAlert == AlarmStateEnum::kCritical)) - { - Events::LowBattery::Type event{ newBatteryAlert }; - SendEvent(endpointId, event); - } + Events::LowBattery::Type event{ newBatteryAlert }; + SendEvent(endpointId, event); + } - if (success && (newBatteryAlert == AlarmStateEnum::kCritical)) - { - SetDeviceMuted(endpointId, MuteStateEnum::kNotMuted); - } + if (newBatteryAlert == AlarmStateEnum::kCritical) + { + SetDeviceMuted(endpointId, MuteStateEnum::kNotMuted); } - return success; + return true; } bool SmokeCoAlarmServer::SetDeviceMuted(EndpointId endpointId, MuteStateEnum newDeviceMuted) { MuteStateEnum deviceMuted; - bool success = GetAttribute(endpointId, Attributes::DeviceMuted::Id, Attributes::DeviceMuted::Get, deviceMuted); + VerifyOrReturnValue(GetAttribute(endpointId, DeviceMuted::Id, DeviceMuted::Get, deviceMuted), false); + VerifyOrReturnValue(deviceMuted != newDeviceMuted, true); - if (success && (deviceMuted != newDeviceMuted)) + if (newDeviceMuted == MuteStateEnum::kMuted) { - if (newDeviceMuted == MuteStateEnum::kMuted) - { - AlarmStateEnum alarmState; - success = GetAttribute(endpointId, Attributes::SmokeState::Id, Attributes::SmokeState::Get, alarmState); - if (success && (alarmState == AlarmStateEnum::kCritical)) - { - success = false; - } - - if (success) - { - success = GetAttribute(endpointId, Attributes::COState::Id, Attributes::COState::Get, alarmState); - if (success && (alarmState == AlarmStateEnum::kCritical)) - { - success = false; - } - } - - if (success) - { - success = GetAttribute(endpointId, Attributes::BatteryAlert::Id, Attributes::BatteryAlert::Get, alarmState); - if (success && (alarmState == AlarmStateEnum::kCritical)) - { - success = false; - } - } - - if (success) - { - success = GetAttribute(endpointId, Attributes::InterconnectSmokeAlarm::Id, Attributes::InterconnectSmokeAlarm::Get, - alarmState); - if (success && (alarmState == AlarmStateEnum::kCritical)) - { - success = false; - } - } - - if (success) - { - success = - GetAttribute(endpointId, Attributes::InterconnectCOAlarm::Id, Attributes::InterconnectCOAlarm::Get, alarmState); - if (success && (alarmState == AlarmStateEnum::kCritical)) - { - success = false; - } - } - } + AlarmStateEnum alarmState; - if (success) - { - success = SetAttribute(endpointId, Attributes::DeviceMuted::Id, Attributes::DeviceMuted::Set, newDeviceMuted); - } + VerifyOrReturnValue(GetAttribute(endpointId, SmokeState::Id, SmokeState::Get, alarmState), false); + VerifyOrReturnValue(alarmState != AlarmStateEnum::kCritical, false); - if (success) - { - if (newDeviceMuted == MuteStateEnum::kMuted) - { - Events::AlarmMuted::Type event{}; - SendEvent(endpointId, event); - } - else if (newDeviceMuted == MuteStateEnum::kNotMuted) - { - Events::MuteEnded::Type event{}; - SendEvent(endpointId, event); - } - } + VerifyOrReturnValue(GetAttribute(endpointId, COState::Id, COState::Get, alarmState), false); + VerifyOrReturnValue(alarmState != AlarmStateEnum::kCritical, false); + + VerifyOrReturnValue(GetAttribute(endpointId, BatteryAlert::Id, BatteryAlert::Get, alarmState), false); + VerifyOrReturnValue(alarmState != AlarmStateEnum::kCritical, false); + + VerifyOrReturnValue(GetAttribute(endpointId, InterconnectSmokeAlarm::Id, InterconnectSmokeAlarm::Get, alarmState), false); + VerifyOrReturnValue(alarmState != AlarmStateEnum::kCritical, false); + + VerifyOrReturnValue(GetAttribute(endpointId, InterconnectCOAlarm::Id, InterconnectCOAlarm::Get, alarmState), false); + VerifyOrReturnValue(alarmState != AlarmStateEnum::kCritical, false); } - return success; + VerifyOrReturnValue(SetAttribute(endpointId, DeviceMuted::Id, DeviceMuted::Set, newDeviceMuted), false); + if (newDeviceMuted == MuteStateEnum::kMuted) + { + Events::AlarmMuted::Type event{}; + SendEvent(endpointId, event); + } + else if (newDeviceMuted == MuteStateEnum::kNotMuted) + { + Events::MuteEnded::Type event{}; + SendEvent(endpointId, event); + } + + return true; } bool SmokeCoAlarmServer::SetTestInProgress(EndpointId endpointId, bool newTestInProgress) { - bool testInProgress; - bool success = GetAttribute(endpointId, Attributes::TestInProgress::Id, Attributes::TestInProgress::Get, testInProgress); + bool active; + VerifyOrReturnValue(GetAttribute(endpointId, TestInProgress::Id, TestInProgress::Get, active), false); + VerifyOrReturnValue(active != newTestInProgress, true); - if (success && (testInProgress != newTestInProgress)) + VerifyOrReturnValue(SetAttribute(endpointId, TestInProgress::Id, TestInProgress::Set, newTestInProgress), false); + if (!newTestInProgress) { - success = SetAttribute(endpointId, Attributes::TestInProgress::Id, Attributes::TestInProgress::Set, newTestInProgress); - - if (success && !newTestInProgress) - { - Events::SelfTestComplete::Type event{}; - SendEvent(endpointId, event); - } + Events::SelfTestComplete::Type event{}; + SendEvent(endpointId, event); } - return success; + return true; } bool SmokeCoAlarmServer::SetHardwareFaultAlert(EndpointId endpointId, bool newHardwareFaultAlert) { - bool hardwareFaultAlert; - bool success = - GetAttribute(endpointId, Attributes::HardwareFaultAlert::Id, Attributes::HardwareFaultAlert::Get, hardwareFaultAlert); + bool active; + VerifyOrReturnValue(GetAttribute(endpointId, HardwareFaultAlert::Id, HardwareFaultAlert::Get, active), false); + VerifyOrReturnValue(active != newHardwareFaultAlert, true); - if (success && (hardwareFaultAlert != newHardwareFaultAlert)) + VerifyOrReturnValue(SetAttribute(endpointId, HardwareFaultAlert::Id, HardwareFaultAlert::Set, newHardwareFaultAlert), false); + if (newHardwareFaultAlert) { - success = SetAttribute(endpointId, Attributes::HardwareFaultAlert::Id, Attributes::HardwareFaultAlert::Set, - newHardwareFaultAlert); - - if (success && newHardwareFaultAlert) - { - Events::HardwareFault::Type event{}; - SendEvent(endpointId, event); - } + Events::HardwareFault::Type event{}; + SendEvent(endpointId, event); } - return success; + return true; } bool SmokeCoAlarmServer::SetEndOfServiceAlert(EndpointId endpointId, EndOfServiceEnum newEndOfServiceAlert) { - EndOfServiceEnum endOfServiceAlert; - bool success = - GetAttribute(endpointId, Attributes::EndOfServiceAlert::Id, Attributes::EndOfServiceAlert::Get, endOfServiceAlert); + EndOfServiceEnum endOfServiceState; + VerifyOrReturnValue(GetAttribute(endpointId, EndOfServiceAlert::Id, EndOfServiceAlert::Get, endOfServiceState), false); + VerifyOrReturnValue(endOfServiceState != newEndOfServiceAlert, true); - if (success && (endOfServiceAlert != newEndOfServiceAlert)) + VerifyOrReturnValue(SetAttribute(endpointId, EndOfServiceAlert::Id, EndOfServiceAlert::Set, newEndOfServiceAlert), false); + if (newEndOfServiceAlert == EndOfServiceEnum::kExpired) { - success = - SetAttribute(endpointId, Attributes::EndOfServiceAlert::Id, Attributes::EndOfServiceAlert::Set, newEndOfServiceAlert); - - if (success && (newEndOfServiceAlert == EndOfServiceEnum::kExpired)) - { - Events::EndOfService::Type event{}; - SendEvent(endpointId, event); - } + Events::EndOfService::Type event{}; + SendEvent(endpointId, event); } - return success; + return true; } bool SmokeCoAlarmServer::SetInterconnectSmokeAlarm(EndpointId endpointId, AlarmStateEnum newInterconnectSmokeAlarm) { - AlarmStateEnum interconnectSmokeAlarm; - bool success = GetAttribute(endpointId, Attributes::InterconnectSmokeAlarm::Id, Attributes::InterconnectSmokeAlarm::Get, - interconnectSmokeAlarm); + AlarmStateEnum alarmState; + VerifyOrReturnValue(GetAttribute(endpointId, InterconnectSmokeAlarm::Id, InterconnectSmokeAlarm::Get, alarmState), false); + VerifyOrReturnValue(alarmState != newInterconnectSmokeAlarm, true); - if (success && (interconnectSmokeAlarm != newInterconnectSmokeAlarm)) + VerifyOrReturnValue( + SetAttribute(endpointId, InterconnectSmokeAlarm::Id, InterconnectSmokeAlarm::Set, newInterconnectSmokeAlarm), false); + if (newInterconnectSmokeAlarm == AlarmStateEnum::kWarning || newInterconnectSmokeAlarm == AlarmStateEnum::kCritical) { - success = SetAttribute(endpointId, Attributes::InterconnectSmokeAlarm::Id, Attributes::InterconnectSmokeAlarm::Set, - newInterconnectSmokeAlarm); - - if (success && - (newInterconnectSmokeAlarm == AlarmStateEnum::kWarning || newInterconnectSmokeAlarm == AlarmStateEnum::kCritical)) - { - Events::InterconnectSmokeAlarm::Type event{ newInterconnectSmokeAlarm }; - SendEvent(endpointId, event); - } + Events::InterconnectSmokeAlarm::Type event{ newInterconnectSmokeAlarm }; + SendEvent(endpointId, event); + } - if (success && (newInterconnectSmokeAlarm == AlarmStateEnum::kCritical)) - { - SetDeviceMuted(endpointId, MuteStateEnum::kNotMuted); - } + if (newInterconnectSmokeAlarm == AlarmStateEnum::kCritical) + { + SetDeviceMuted(endpointId, MuteStateEnum::kNotMuted); } - return success; + return true; } bool SmokeCoAlarmServer::SetInterconnectCOAlarm(EndpointId endpointId, AlarmStateEnum newInterconnectCOAlarm) { - AlarmStateEnum interconnectCOAlarm; - bool success = - GetAttribute(endpointId, Attributes::InterconnectCOAlarm::Id, Attributes::InterconnectCOAlarm::Get, interconnectCOAlarm); + AlarmStateEnum alarmState; + VerifyOrReturnValue(GetAttribute(endpointId, InterconnectCOAlarm::Id, InterconnectCOAlarm::Get, alarmState), false); + VerifyOrReturnValue(alarmState != newInterconnectCOAlarm, true); - if (success && (interconnectCOAlarm != newInterconnectCOAlarm)) + VerifyOrReturnValue(SetAttribute(endpointId, InterconnectCOAlarm::Id, InterconnectCOAlarm::Set, newInterconnectCOAlarm), false); + if (newInterconnectCOAlarm == AlarmStateEnum::kWarning || newInterconnectCOAlarm == AlarmStateEnum::kCritical) { - success = SetAttribute(endpointId, Attributes::InterconnectCOAlarm::Id, Attributes::InterconnectCOAlarm::Set, - newInterconnectCOAlarm); - - if (success && (newInterconnectCOAlarm == AlarmStateEnum::kWarning || newInterconnectCOAlarm == AlarmStateEnum::kCritical)) - { - Events::InterconnectCOAlarm::Type event{ newInterconnectCOAlarm }; - SendEvent(endpointId, event); - } + Events::InterconnectCOAlarm::Type event{ newInterconnectCOAlarm }; + SendEvent(endpointId, event); + } - if (success && (newInterconnectCOAlarm == AlarmStateEnum::kCritical)) - { - SetDeviceMuted(endpointId, MuteStateEnum::kNotMuted); - } + if (newInterconnectCOAlarm == AlarmStateEnum::kCritical) + { + SetDeviceMuted(endpointId, MuteStateEnum::kNotMuted); } - return success; + return true; } bool SmokeCoAlarmServer::SetContaminationState(EndpointId endpointId, ContaminationStateEnum newContaminationState) { ContaminationStateEnum contaminationState; - bool success = - GetAttribute(endpointId, Attributes::ContaminationState::Id, Attributes::ContaminationState::Get, contaminationState); + VerifyOrReturnValue(GetAttribute(endpointId, ContaminationState::Id, ContaminationState::Get, contaminationState), false); + VerifyOrReturnValue(contaminationState != newContaminationState, true); - if (success && (contaminationState != newContaminationState)) - { - success = SetAttribute(endpointId, Attributes::ContaminationState::Id, Attributes::ContaminationState::Set, - newContaminationState); - } + VerifyOrReturnValue(SetAttribute(endpointId, ContaminationState::Id, ContaminationState::Set, newContaminationState), false); - return success; + return true; } bool SmokeCoAlarmServer::SetSmokeSensitivityLevel(EndpointId endpointId, SensitivityEnum newSmokeSensitivityLevel) { - SensitivityEnum smokeSensitivityLevel; - bool success = GetAttribute(endpointId, Attributes::SmokeSensitivityLevel::Id, Attributes::SmokeSensitivityLevel::Get, - smokeSensitivityLevel); + SensitivityEnum sensitivity; + VerifyOrReturnValue(GetAttribute(endpointId, SmokeSensitivityLevel::Id, SmokeSensitivityLevel::Get, sensitivity), false); + VerifyOrReturnValue(sensitivity != newSmokeSensitivityLevel, true); - if (success && (smokeSensitivityLevel != newSmokeSensitivityLevel)) - { - success = SetAttribute(endpointId, Attributes::SmokeSensitivityLevel::Id, Attributes::SmokeSensitivityLevel::Set, - newSmokeSensitivityLevel); - } + VerifyOrReturnValue(SetAttribute(endpointId, SmokeSensitivityLevel::Id, SmokeSensitivityLevel::Set, newSmokeSensitivityLevel), + false); - return success; + return true; } bool SmokeCoAlarmServer::GetExpressedState(chip ::EndpointId endpointId, ExpressedStateEnum & expressedState) { - return GetAttribute(endpointId, Attributes::ExpressedState::Id, Attributes::ExpressedState::Get, expressedState); + return GetAttribute(endpointId, ExpressedState::Id, ExpressedState::Get, expressedState); } bool SmokeCoAlarmServer::GetSmokeState(EndpointId endpointId, AlarmStateEnum & smokeState) { - return GetAttribute(endpointId, Attributes::SmokeState::Id, Attributes::SmokeState::Get, smokeState); + return GetAttribute(endpointId, SmokeState::Id, SmokeState::Get, smokeState); } bool SmokeCoAlarmServer::GetCOState(EndpointId endpointId, AlarmStateEnum & coState) { - return GetAttribute(endpointId, Attributes::COState::Id, Attributes::COState::Get, coState); + return GetAttribute(endpointId, COState::Id, COState::Get, coState); } bool SmokeCoAlarmServer::GetBatteryAlert(EndpointId endpointId, AlarmStateEnum & batteryAlert) { - return GetAttribute(endpointId, Attributes::BatteryAlert::Id, Attributes::BatteryAlert::Get, batteryAlert); + return GetAttribute(endpointId, BatteryAlert::Id, BatteryAlert::Get, batteryAlert); } bool SmokeCoAlarmServer::GetDeviceMuted(EndpointId endpointId, MuteStateEnum & deviceMuted) { - return GetAttribute(endpointId, Attributes::DeviceMuted::Id, Attributes::DeviceMuted::Get, deviceMuted); + return GetAttribute(endpointId, DeviceMuted::Id, DeviceMuted::Get, deviceMuted); } bool SmokeCoAlarmServer::GetTestInProgress(EndpointId endpointId, bool & testInProgress) { - return GetAttribute(endpointId, Attributes::TestInProgress::Id, Attributes::TestInProgress::Get, testInProgress); + return GetAttribute(endpointId, TestInProgress::Id, TestInProgress::Get, testInProgress); } bool SmokeCoAlarmServer::GetHardwareFaultAlert(EndpointId endpointId, bool & hardwareFaultAlert) { - return GetAttribute(endpointId, Attributes::HardwareFaultAlert::Id, Attributes::HardwareFaultAlert::Get, hardwareFaultAlert); + return GetAttribute(endpointId, HardwareFaultAlert::Id, HardwareFaultAlert::Get, hardwareFaultAlert); } bool SmokeCoAlarmServer::GetEndOfServiceAlert(EndpointId endpointId, EndOfServiceEnum & endOfServiceAlert) { - return GetAttribute(endpointId, Attributes::EndOfServiceAlert::Id, Attributes::EndOfServiceAlert::Get, endOfServiceAlert); + return GetAttribute(endpointId, EndOfServiceAlert::Id, EndOfServiceAlert::Get, endOfServiceAlert); } bool SmokeCoAlarmServer::GetInterconnectSmokeAlarm(EndpointId endpointId, AlarmStateEnum & interconnectSmokeAlarm) { - return GetAttribute(endpointId, Attributes::InterconnectSmokeAlarm::Id, Attributes::InterconnectSmokeAlarm::Get, - interconnectSmokeAlarm); + return GetAttribute(endpointId, InterconnectSmokeAlarm::Id, InterconnectSmokeAlarm::Get, interconnectSmokeAlarm); } bool SmokeCoAlarmServer::GetInterconnectCOAlarm(EndpointId endpointId, AlarmStateEnum & interconnectCOAlarm) { - return GetAttribute(endpointId, Attributes::InterconnectCOAlarm::Id, Attributes::InterconnectCOAlarm::Get, interconnectCOAlarm); + return GetAttribute(endpointId, InterconnectCOAlarm::Id, InterconnectCOAlarm::Get, interconnectCOAlarm); } bool SmokeCoAlarmServer::GetContaminationState(EndpointId endpointId, ContaminationStateEnum & contaminationState) { - return GetAttribute(endpointId, Attributes::ContaminationState::Id, Attributes::ContaminationState::Get, contaminationState); + return GetAttribute(endpointId, ContaminationState::Id, ContaminationState::Get, contaminationState); } bool SmokeCoAlarmServer::GetSmokeSensitivityLevel(EndpointId endpointId, SensitivityEnum & smokeSensitivityLevel) { - return GetAttribute(endpointId, Attributes::SmokeSensitivityLevel::Id, Attributes::SmokeSensitivityLevel::Get, - smokeSensitivityLevel); + return GetAttribute(endpointId, SmokeSensitivityLevel::Id, SmokeSensitivityLevel::Get, smokeSensitivityLevel); } bool SmokeCoAlarmServer::GetExpiryDate(EndpointId endpointId, uint32_t & expiryDate) { - return GetAttribute(endpointId, Attributes::ExpiryDate::Id, Attributes::ExpiryDate::Get, expiryDate); + return GetAttribute(endpointId, ExpiryDate::Id, ExpiryDate::Get, expiryDate); } chip::BitFlags SmokeCoAlarmServer::GetFeatures(EndpointId endpointId) { chip::BitFlags featureMap; - if (!GetAttribute(endpointId, Attributes::FeatureMap::Id, Attributes::FeatureMap::Get, *featureMap.RawStorage())) + if (!GetAttribute(endpointId, FeatureMap::Id, FeatureMap::Get, *featureMap.RawStorage())) { ChipLogError(Zcl, "Unable to get the Smoke CO Alarm feature map: attribute read error"); featureMap.ClearAll(); @@ -486,41 +411,42 @@ chip::BitFlags SmokeCoAlarmServer::GetFeatures(EndpointId endpointId) * SmokeCoAlarmServer private methods *********************************************************/ -bool SmokeCoAlarmServer::HandleRemoteSelfTestRequest(CommandHandler * commandObj, const ConcreteCommandPath & commandPath) +void SmokeCoAlarmServer::SetExpressedState(EndpointId endpointId, ExpressedStateEnum newExpressedState) { - EndpointId endpointId = commandPath.mEndpointId; - Status status = Status::Success; - ExpressedStateEnum expressedState; - bool success = GetExpressedState(endpointId, expressedState); + VerifyOrReturn(GetAttribute(endpointId, ExpressedState::Id, ExpressedState::Get, expressedState)); + VerifyOrReturn(expressedState != newExpressedState); - if (success) + VerifyOrReturn(SetAttribute(endpointId, ExpressedState::Id, ExpressedState::Set, newExpressedState)); + if (newExpressedState == ExpressedStateEnum::kNormal) { - // If the value is busy then return busy - if (expressedState == ExpressedStateEnum::kSmokeAlarm || expressedState == ExpressedStateEnum::kCOAlarm || - expressedState == ExpressedStateEnum::kTesting || expressedState == ExpressedStateEnum::kInterconnectSmoke || - expressedState == ExpressedStateEnum::kInterconnectCO) - { - status = Status::Busy; - } - else - { - success = SetExpressedState(endpointId, ExpressedStateEnum::kTesting); - - if (success) - { - success = emberAfPluginSmokeCoAlarmSelfTestRequestCommand(endpointId); - } - } + Events::AllClear::Type event{}; + SendEvent(endpointId, event); } +} - if (!success) +void SmokeCoAlarmServer::HandleRemoteSelfTestRequest(CommandHandler * commandObj, const ConcreteCommandPath & commandPath) +{ + EndpointId endpointId = commandPath.mEndpointId; + + ExpressedStateEnum expressedState; + VerifyOrReturn(GetExpressedState(endpointId, expressedState), commandObj->AddStatus(commandPath, Status::Failure)); + + // If the value is busy then return busy + if (expressedState == ExpressedStateEnum::kSmokeAlarm || expressedState == ExpressedStateEnum::kCOAlarm || + expressedState == ExpressedStateEnum::kTesting || expressedState == ExpressedStateEnum::kInterconnectSmoke || + expressedState == ExpressedStateEnum::kInterconnectCO) { - status = Status::Failure; + commandObj->AddStatus(commandPath, Status::Busy); + return; } - commandObj->AddStatus(commandPath, status); - return true; + VerifyOrReturn(SetTestInProgress(endpointId, true), commandObj->AddStatus(commandPath, Status::Failure)); + SetExpressedState(endpointId, ExpressedStateEnum::kTesting); + + emberAfPluginSmokeCoAlarmSelfTestRequestCommand(endpointId); + + commandObj->AddStatus(commandPath, Status::Success); } template @@ -573,7 +499,8 @@ bool SmokeCoAlarmServer::SetAttribute(EndpointId endpointId, AttributeId attribu bool emberAfSmokeCoAlarmClusterSelfTestRequestCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::SelfTestRequest::DecodableType & commandData) { - return SmokeCoAlarmServer::Instance().HandleRemoteSelfTestRequest(commandObj, commandPath); + SmokeCoAlarmServer::Instance().HandleRemoteSelfTestRequest(commandObj, commandPath); + return true; } void MatterSmokeCoAlarmPluginServerInitCallback() {} diff --git a/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h b/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h index 0df9583371b67a..9a41c88f282831 100644 --- a/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h +++ b/src/app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h @@ -47,27 +47,23 @@ class SmokeCoAlarmServer using SensitivityEnum = chip::app::Clusters::SmokeCoAlarm::SensitivityEnum; /** - * For all the functions below, the return value is true on success, false on failure + * @brief Set the highest level of Expressed State according to priorityOrder + * @param endpointId ID of the endpoint + * @param priorityOrder Priority order of expressed state from highest to lowest */ + void SetExpressedStateByPriority(chip::EndpointId endpointId, + const std::array & priorityOrder); /** - * @brief Updates the expressed state with new value - * - * @note If the value of ExpressedState is not Normal, the attribute corresponding to the value should not be Normal. - * + * @brief Set the highest level of Expressed State according to priorityOrder * @param endpointId ID of the endpoint - * @param newExpressedState new expressed state * @return true on success, false on failure */ - bool SetExpressedState(chip::EndpointId endpointId, ExpressedStateEnum newExpressedState); + bool RequestSelfTest(chip::EndpointId endpointId); /** - * @brief Set the highest level of Expressed State according to priorityOrder - * @param endpointId ID of the endpoint - * @param priorityOrder Priority order of expressed state from highest to lowest + * For all the functions below, the return value is true on success, false on failure */ - void SetExpressedStateByPriority(chip::EndpointId endpointId, - const std::array & priorityOrder); bool SetSmokeState(chip::EndpointId endpointId, AlarmStateEnum newSmokeState); bool SetCOState(chip::EndpointId endpointId, AlarmStateEnum newCOState); @@ -102,15 +98,23 @@ class SmokeCoAlarmServer inline bool SupportsCOAlarm(chip::EndpointId endpointId) { return GetFeatures(endpointId).Has(Feature::kCoAlarm); } private: + /** + * @brief Updates the expressed state with new value + * + * @note If the value of ExpressedState is not Normal, the attribute corresponding to the value should not be Normal. + * + * @param endpointId ID of the endpoint + * @param newExpressedState new expressed state + */ + void SetExpressedState(chip::EndpointId endpointId, ExpressedStateEnum newExpressedState); + /** * @brief Common handler for SelfTestRequest commands * * @param commandObj original command context * @param commandPath original command path - * @return true if successful - * @return false if error happened */ - bool HandleRemoteSelfTestRequest(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath); + void HandleRemoteSelfTestRequest(chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath); /** * @brief Send generic event @@ -170,8 +174,5 @@ class SmokeCoAlarmServer * @note The application must set the ExpressedState to "Testing" * * @param endpointId endpoint for which SelfTestRequest command is called - * - * @retval true on success - * @retval false if error happened (err should be set to appropriate error code) */ -bool emberAfPluginSmokeCoAlarmSelfTestRequestCommand(chip::EndpointId endpointId); +void emberAfPluginSmokeCoAlarmSelfTestRequestCommand(chip::EndpointId endpointId);