Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for SmokeCO TC's in chip-all-clusters-app #28548

Merged
merged 12 commits into from
Aug 10, 2023
168 changes: 166 additions & 2 deletions examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,173 @@
* limitations under the License.
*/

#include <lib/core/DataModelTypes.h>
#include <app/clusters/smoke-co-alarm-server/SmokeCOTestEventTriggerDelegate.h>
#include <app/clusters/smoke-co-alarm-server/smoke-co-alarm-server.h>

bool emberAfPluginSmokeCoAlarmSelfTestRequestCommand(chip::EndpointId endpointId)
#include <platform/CHIPDeviceLayer.h>

using namespace chip;
using namespace chip::app::Clusters::SmokeCoAlarm;
using namespace chip::DeviceLayer;

namespace {

constexpr const uint16_t kSelfTestingTimeoutSec = 10;

} // namespace

static std::array<ExpressedStateEnum, SmokeCoAlarmServer::kPriorityOrderLength> 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<SmokeCOTrigger>(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;
}
1 change: 1 addition & 0 deletions examples/all-clusters-app/linux/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions examples/all-clusters-app/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]

Expand Down
1 change: 1 addition & 0 deletions examples/all-clusters-minimal-app/tizen/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]

Expand Down
9 changes: 9 additions & 0 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@
#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR
#include <app/clusters/ota-requestor/OTATestEventTriggerDelegate.h>
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_SMOKE_CO_TRIGGER
#include <app/clusters/smoke-co-alarm-server/SmokeCOTestEventTriggerDelegate.h>
#endif
#include <app/TestEventTriggerDelegate.h>

#include <signal.h>
Expand Down Expand Up @@ -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;
Expand Down
13 changes: 13 additions & 0 deletions examples/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
ericzijian1994 marked this conversation as resolved.
Show resolved Hide resolved

config("app-main-config") {
include_dirs = [ "." ]
}
Expand All @@ -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 = [
Expand All @@ -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",
]
Expand Down Expand Up @@ -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" ]
}

Expand Down
7 changes: 7 additions & 0 deletions src/app/chip_data_model.gni
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,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" ]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
*
* 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)
{
VerifyOrReturnValue(HandleSmokeCOTestEventTrigger(eventTrigger),
(mOtherDelegate != nullptr) ? mOtherDelegate->HandleEventTrigger(eventTrigger)
: CHIP_ERROR_INVALID_ARGUMENT);

return CHIP_NO_ERROR;
ericzijian1994 marked this conversation as resolved.
Show resolved Hide resolved
}

} // namespace chip
Original file line number Diff line number Diff line change
@@ -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 <app-common/zap-generated/cluster-objects.h>
#include <app/TestEventTriggerDelegate.h>

namespace chip {

enum class SmokeCOTrigger : uint64_t
andy31415 marked this conversation as resolved.
Show resolved Hide resolved
{
// 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);
Loading
Loading