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 66f86e5b28ab99..e6e18ab9edb32a 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 @@ -15,9 +15,173 @@ * limitations under the License. */ -#include +#include +#include -bool emberAfPluginSmokeCoAlarmSelfTestRequestCommand(chip::EndpointId endpointId) +#include + +using namespace chip; +using namespace chip::app::Clusters::SmokeCoAlarm; +using namespace chip::DeviceLayer; + +namespace { + +constexpr const uint16_t kSelfTestingTimeoutSec = 10; + +} // namespace + +static std::array sPriorityOrder = { + ExpressedStateEnum::kSmokeAlarm, ExpressedStateEnum::kInterconnectSmoke, ExpressedStateEnum::kCOAlarm, + ExpressedStateEnum::kInterconnectCO, ExpressedStateEnum::kHardwareFault, ExpressedStateEnum::kTesting, + ExpressedStateEnum::kEndOfService, ExpressedStateEnum::kBatteryAlert +}; + +void EndSelfTestingEventHandler(System::Layer * systemLayer, void * appState) +{ + SmokeCoAlarmServer::Instance().SetTestInProgress(1, false); + SmokeCoAlarmServer::Instance().SetExpressedStateByPriority(1, sPriorityOrder); + + ChipLogProgress(Support, "[Smoke-CO-Alarm] => Self test complete"); +} + +bool 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) +{ + 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/linux/args.gni b/examples/all-clusters-app/linux/args.gni index c4c9a18cec9cf5..1bcd86f18843b8 100644 --- a/examples/all-clusters-app/linux/args.gni +++ b/examples/all-clusters-app/linux/args.gni @@ -27,3 +27,4 @@ chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ] matter_enable_tracing_support = true matter_log_json_payload_decode_full = true matter_log_json_payload_hex = true +chip_enable_smoke_co_trigger = true diff --git a/examples/all-clusters-app/tizen/BUILD.gn b/examples/all-clusters-app/tizen/BUILD.gn index 484732400b64f1..8bf7f00152148f 100644 --- a/examples/all-clusters-app/tizen/BUILD.gn +++ b/examples/all-clusters-app/tizen/BUILD.gn @@ -34,6 +34,7 @@ source_set("chip-all-clusters-common") { deps = [ "${chip_root}/examples/all-clusters-app/all-clusters-common", + "${chip_root}/examples/platform/tizen:app-main", "${chip_root}/src/lib/shell:shell_core", ] diff --git a/examples/all-clusters-minimal-app/tizen/BUILD.gn b/examples/all-clusters-minimal-app/tizen/BUILD.gn index 5485fdd469d223..99f857e86303ea 100644 --- a/examples/all-clusters-minimal-app/tizen/BUILD.gn +++ b/examples/all-clusters-minimal-app/tizen/BUILD.gn @@ -31,6 +31,7 @@ source_set("chip-all-clusters-common") { deps = [ "${chip_root}/examples/all-clusters-minimal-app/all-clusters-common", + "${chip_root}/examples/platform/tizen:app-main", "${chip_root}/src/lib/shell:shell_core", ] diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index 22ff4d2db71cb6..ea52a49e79634a 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -75,6 +75,9 @@ #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR #include #endif +#if CHIP_DEVICE_CONFIG_ENABLE_SMOKE_CO_TRIGGER +#include +#endif #include #include @@ -522,6 +525,12 @@ void ChipLinuxAppMainLoop(AppMainLoopImplementation * impl) static OTATestEventTriggerDelegate otaTestEventTriggerDelegate{ ByteSpan( LinuxDeviceOptions::GetInstance().testEventTriggerEnableKey) }; otherDelegate = &otaTestEventTriggerDelegate; +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_SMOKE_CO_TRIGGER + static SmokeCOTestEventTriggerDelegate smokeCOTestEventTriggerDelegate{ + ByteSpan(LinuxDeviceOptions::GetInstance().testEventTriggerEnableKey), otherDelegate + }; + otherDelegate = &smokeCOTestEventTriggerDelegate; #endif // For general testing of TestEventTrigger, we have a common "core" event trigger delegate. static SampleTestEventTriggerDelegate testEventTriggerDelegate; diff --git a/examples/platform/linux/BUILD.gn b/examples/platform/linux/BUILD.gn index 8427fe8aa80104..44a96b12c00604 100644 --- a/examples/platform/linux/BUILD.gn +++ b/examples/platform/linux/BUILD.gn @@ -19,6 +19,10 @@ import("${chip_root}/src/lib/core/core.gni") import("${chip_root}/src/lib/lib.gni") import("${chip_root}/src/tracing/tracing_args.gni") +declare_args() { + chip_enable_smoke_co_trigger = false +} + config("app-main-config") { include_dirs = [ "." ] } @@ -29,6 +33,10 @@ source_set("ota-test-event-trigger") { ] } +source_set("smco-test-event-trigger") { + sources = [ "${chip_root}/src/app/clusters/smoke-co-alarm-server/SmokeCOTestEventTriggerDelegate.h" ] +} + source_set("app-main") { defines = [ "ENABLE_TRACING=${matter_enable_tracing_support}" ] sources = [ @@ -51,6 +59,7 @@ source_set("app-main") { ] public_deps = [ + ":smco-test-event-trigger", "${chip_root}/src/lib", "${chip_root}/src/platform/logging:force_stdio", ] @@ -85,6 +94,10 @@ source_set("app-main") { ] } + if (chip_enable_smoke_co_trigger) { + defines += [ "CHIP_DEVICE_CONFIG_ENABLE_SMOKE_CO_TRIGGER=1" ] + } + public_configs = [ ":app-main-config" ] } diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index d484d7ce654e9b..d20e28a83bbee8 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -287,6 +287,13 @@ template("chip_data_model") { "${_app_root}/clusters/${cluster}/resource-monitoring-cluster-objects.cpp", "${_app_root}/clusters/${cluster}/resource-monitoring-cluster-objects.h", ] + } else if (cluster == "smoke-co-alarm-server") { + sources += [ + "${_app_root}/clusters/${cluster}/${cluster}.cpp", + "${_app_root}/clusters/${cluster}/${cluster}.h", + "${_app_root}/clusters/${cluster}/SmokeCOTestEventTriggerDelegate.cpp", + "${_app_root}/clusters/${cluster}/SmokeCOTestEventTriggerDelegate.h", + ] } else { sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp" ] } diff --git a/src/app/clusters/smoke-co-alarm-server/SmokeCOTestEventTriggerDelegate.cpp b/src/app/clusters/smoke-co-alarm-server/SmokeCOTestEventTriggerDelegate.cpp new file mode 100644 index 00000000000000..597737b14bb768 --- /dev/null +++ b/src/app/clusters/smoke-co-alarm-server/SmokeCOTestEventTriggerDelegate.cpp @@ -0,0 +1,42 @@ +/* + * + * 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 "SmokeCOTestEventTriggerDelegate.h" + +using namespace chip::app::Clusters::SmokeCoAlarm; + +namespace chip { + +bool SmokeCOTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const +{ + return !mEnableKey.empty() && mEnableKey.data_equal(enableKey); +} + +CHIP_ERROR SmokeCOTestEventTriggerDelegate::HandleEventTrigger(uint64_t eventTrigger) +{ + if (HandleSmokeCOTestEventTrigger(eventTrigger)) + { + return CHIP_NO_ERROR; + } + if (mOtherDelegate != nullptr) + { + return mOtherDelegate->HandleEventTrigger(eventTrigger); + } + return CHIP_ERROR_INVALID_ARGUMENT; +} + +} // namespace chip diff --git a/src/app/clusters/smoke-co-alarm-server/SmokeCOTestEventTriggerDelegate.h b/src/app/clusters/smoke-co-alarm-server/SmokeCOTestEventTriggerDelegate.h new file mode 100644 index 00000000000000..599eb6ab2fc080 --- /dev/null +++ b/src/app/clusters/smoke-co-alarm-server/SmokeCOTestEventTriggerDelegate.h @@ -0,0 +1,83 @@ +/* + * + * 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 + +namespace chip { + +enum class SmokeCOTrigger : uint64_t +{ + // Force alarm commands + kForceSmokeWarning = 0xffffffff00000090, + kForceCOWarning = 0xffffffff00000091, + kForceSmokeInterconnect = 0xffffffff00000092, + kForceMalfunction = 0xffffffff00000093, + kForceCOInterconnect = 0xffffffff00000094, + kForceLowBatteryWarning = 0xffffffff00000095, + kForceSmokeContaminationHigh = 0xffffffff00000096, + kForceSmokeContaminationLow = 0xffffffff00000097, + kForceSmokeSensitivityHigh = 0xffffffff00000098, + kForceSmokeSensitivityLow = 0xffffffff00000099, + kForceEndOfLife = 0xffffffff0000009a, + kForceSilence = 0xffffffff0000009b, + kForceSmokeCritical = 0xffffffff0000009c, + kForceCOCritical = 0xffffffff0000009d, + kForceLowBatteryCritical = 0xffffffff0000009e, + // Clear alarm commands + kClearSmoke = 0xffffffff000000a0, + kClearCO = 0xffffffff000000a1, + kClearSmokeInterconnect = 0xffffffff000000a2, + kClearMalfunction = 0xffffffff000000a3, + kClearCOInterconnect = 0xffffffff000000a4, + kClearBatteryLevelLow = 0xffffffff000000a5, + kClearContamination = 0xffffffff000000a6, + kClearSensitivity = 0xffffffff000000a8, + kClearEndOfLife = 0xffffffff000000aa, + kClearSilence = 0xffffffff000000ab +}; + +class SmokeCOTestEventTriggerDelegate : public TestEventTriggerDelegate +{ +public: + explicit SmokeCOTestEventTriggerDelegate(const ByteSpan & enableKey, TestEventTriggerDelegate * otherDelegate) : + mEnableKey(enableKey), mOtherDelegate(otherDelegate) + {} + + bool DoesEnableKeyMatch(const ByteSpan & enableKey) const override; + CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override; + +private: + ByteSpan mEnableKey; + TestEventTriggerDelegate * mOtherDelegate; +}; + +} // 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 HandleSmokeCOTestEventTrigger(uint64_t eventTrigger); 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 c5f109fac63a31..19f1da4f8a8d76 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 @@ -22,23 +22,12 @@ */ #include "smoke-co-alarm-server.h" + #include -#include -#include #include -#include -#include -#include -#include - -#include -#include -#include -#include using namespace chip; using namespace chip::app; -using namespace chip::app::DataModel; using namespace chip::app::Clusters::SmokeCoAlarm; using chip::Protocols::InteractionModel::Status; @@ -72,6 +61,55 @@ bool SmokeCoAlarmServer::SetExpressedState(EndpointId endpointId, ExpressedState return success; } +void SmokeCoAlarmServer::SetExpressedStateByPriority(EndpointId endpointId, + const std::array & priorityOrder) +{ + AlarmStateEnum alarmState = AlarmStateEnum::kNormal; + EndOfServiceEnum endOfServiceState = EndOfServiceEnum::kNormal; + bool active = false; + + for (ExpressedStateEnum priority : priorityOrder) + { + switch (priority) + { + case ExpressedStateEnum::kSmokeAlarm: + VerifyOrReturn(GetSmokeState(endpointId, alarmState)); + break; + case ExpressedStateEnum::kCOAlarm: + VerifyOrReturn(GetCOState(endpointId, alarmState)); + break; + case ExpressedStateEnum::kBatteryAlert: + VerifyOrReturn(GetBatteryAlert(endpointId, alarmState)); + break; + case ExpressedStateEnum::kTesting: + VerifyOrReturn(GetTestInProgress(endpointId, active)); + break; + case ExpressedStateEnum::kHardwareFault: + VerifyOrReturn(GetHardwareFaultAlert(endpointId, active)); + break; + case ExpressedStateEnum::kEndOfService: + VerifyOrReturn(GetEndOfServiceAlert(endpointId, endOfServiceState)); + break; + case ExpressedStateEnum::kInterconnectSmoke: + VerifyOrReturn(GetInterconnectSmokeAlarm(endpointId, alarmState)); + break; + case ExpressedStateEnum::kInterconnectCO: + VerifyOrReturn(GetInterconnectCOAlarm(endpointId, alarmState)); + break; + default: + break; + } + + if ((alarmState != AlarmStateEnum::kNormal) || (endOfServiceState != EndOfServiceEnum::kNormal) || active) + { + VerifyOrDo(SetExpressedState(endpointId, priority), ChipLogError(NotSpecified, "Set ExpressedState failed")); + return; + } + } + + VerifyOrDo(SetExpressedState(endpointId, ExpressedStateEnum::kNormal), ChipLogError(NotSpecified, "Set ExpressedState failed")); +} + bool SmokeCoAlarmServer::SetSmokeState(EndpointId endpointId, AlarmStateEnum newSmokeState) { AlarmStateEnum smokeState; 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 529df2ed766807..0df9583371b67a 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 @@ -25,10 +25,7 @@ #include #include -#include #include -#include -#include /** * @brief Smoke CO Alarm Server Plugin class @@ -38,6 +35,9 @@ class SmokeCoAlarmServer public: static SmokeCoAlarmServer & Instance(); + /* Expected byte size of the PriorityOrder */ + static constexpr size_t kPriorityOrderLength = 8; + using AlarmStateEnum = chip::app::Clusters::SmokeCoAlarm::AlarmStateEnum; using ContaminationStateEnum = chip::app::Clusters::SmokeCoAlarm::ContaminationStateEnum; using EndOfServiceEnum = chip::app::Clusters::SmokeCoAlarm::EndOfServiceEnum; @@ -61,6 +61,14 @@ class SmokeCoAlarmServer */ bool SetExpressedState(chip::EndpointId endpointId, ExpressedStateEnum newExpressedState); + /** + * @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); + bool SetSmokeState(chip::EndpointId endpointId, AlarmStateEnum newSmokeState); bool SetCOState(chip::EndpointId endpointId, AlarmStateEnum newCOState); bool SetBatteryAlert(chip::EndpointId endpointId, AlarmStateEnum newBatteryAlert);