Skip to content

Commit

Permalink
open command start
Browse files Browse the repository at this point in the history
  • Loading branch information
cecille committed Sep 16, 2024
1 parent 02906e1 commit 71fb16c
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,15 @@ CHIP_ERROR ClusterLogic::HandleOpenCommand(std::optional<DataModel::Nullable<Ela
return CHIP_NO_ERROR;
}

void ClusterLogic::HandleCloseInternal()
CHIP_ERROR ClusterLogic::HandleCloseCommand()
{
VerifyOrReturnError(mInitialized, CHIP_ERROR_INCORRECT_STATE);
DeviceLayer::SystemLayer().CancelTimer(HandleUpdateRemainingDuration, this);
return HandleCloseInternal();
}

CHIP_ERROR ClusterLogic::HandleCloseInternal()
{
// TODO: call the delegate and add to tests
CHIP_ERROR err;
BitMask<ValveFaultBitmap> faults;
if (mConformance.HasFeature(Feature::kLevel))
Expand Down Expand Up @@ -497,6 +503,7 @@ void ClusterLogic::HandleCloseInternal()
mState.SetTargetLevel(DataModel::NullNullable);
mState.SetTargetState(DataModel::NullNullable);
mState.SetAutoCloseTime(DataModel::NullNullable);
return err;
}

void ClusterLogic::HandleUpdateRemainingDuration(System::Layer * systemLayer, void * context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ class ClusterLogic
// Calls delegate HandleOpen function after validating the parameters
CHIP_ERROR HandleOpenCommand(std::optional<DataModel::Nullable<ElapsedS>> openDuration, std::optional<Percent> targetLevel);

// Return CHIP_ERROR_INCORRECT_STATE if the class has not been initialized.
// Calls delegate HandleClose function after validating the parameters and stops any open duration timers.
CHIP_ERROR HandleCloseCommand();

private:
// Determines if the level value is allowed per the level step.
bool ValueCompliesWithLevelStep(const uint8_t value);
Expand All @@ -193,7 +197,7 @@ class ClusterLogic
void HandleUpdateRemainingDurationInternal();
// Internal function called by HandleUpdateRemainingDuration to call the close function in the delegate and
// set all the attributes back to their closed state.
void HandleCloseInternal();
CHIP_ERROR HandleCloseInternal();

bool mInitialized = false;
System::Clock::Milliseconds64 mDurationStarted = System::Clock::Milliseconds64(0);
Expand Down
168 changes: 163 additions & 5 deletions src/app/tests/TestValveConfigurationAndControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1947,9 +1947,168 @@ TEST_F(TestValveConfigurationAndControlClusterLogic, TestCloseCalledAtOpenDurati
//=========================================================================================
// Tests for handling close commands
//=========================================================================================
// while remaining duration is null and valve is open
// while remaining duration is not null and valve is open

TEST_F(TestValveConfigurationAndControlClusterLogic, TestCloseCommandOpenValveDurationLevel)
{
TestDelegateLevel delegate;
TestPersistentStorageDelegate storageDelegate;
EndpointId endpoint = 0;
MockedMatterContext context(endpoint, storageDelegate);
ClusterLogic logic(delegate, context);

ClusterConformance conformance = { .featureMap = to_underlying(Feature::kLevel) | to_underlying(Feature::kTimeSync),
.supportsDefaultOpenLevel = true,
.supportsValveFault = true,
.supportsLevelStep = true };
EXPECT_EQ(logic.Init(conformance), CHIP_NO_ERROR);

gSystemLayerAndClock.SetMonotonic(0_ms64);
gSystemLayerAndClock.Clear();
DataModel::Nullable<ElapsedS> openDuration;
openDuration.SetNonNull(2u);
EXPECT_EQ(logic.HandleOpenCommand(std::make_optional(openDuration), std::nullopt), CHIP_NO_ERROR);
EXPECT_TRUE(HasAttributeChanges(context.GetDirtyList(), Attributes::OpenDuration::Id));
EXPECT_EQ(delegate.numHandleCloseValveCalls, 0);

gSystemLayerAndClock.AdvanceMonotonic(1000_ms64);
EXPECT_EQ(logic.HandleCloseCommand(), CHIP_NO_ERROR);
EXPECT_EQ(delegate.numHandleCloseValveCalls, 1);

// Ensure the timer was cancelled
gSystemLayerAndClock.AdvanceMonotonic(1000_ms64);
EXPECT_EQ(delegate.numHandleCloseValveCalls, 1);
}

TEST_F(TestValveConfigurationAndControlClusterLogic, TestCloseCommandOpenValveDurationNoLevel)
{
TestDelegateNoLevel delegate;
TestPersistentStorageDelegate storageDelegate;
EndpointId endpoint = 0;
MockedMatterContext context(endpoint, storageDelegate);
ClusterLogic logic(delegate, context);

ClusterConformance conformance = {
.featureMap = 0, .supportsDefaultOpenLevel = false, .supportsValveFault = true, .supportsLevelStep = false
};
EXPECT_EQ(logic.Init(conformance), CHIP_NO_ERROR);

gSystemLayerAndClock.SetMonotonic(0_ms64);
gSystemLayerAndClock.Clear();
DataModel::Nullable<ElapsedS> openDuration;
openDuration.SetNonNull(2u);
EXPECT_EQ(logic.HandleOpenCommand(std::make_optional(openDuration), std::nullopt), CHIP_NO_ERROR);
EXPECT_TRUE(HasAttributeChanges(context.GetDirtyList(), Attributes::OpenDuration::Id));
EXPECT_EQ(delegate.numHandleCloseValveCalls, 0);

gSystemLayerAndClock.AdvanceMonotonic(2000_ms64);
EXPECT_EQ(delegate.numHandleCloseValveCalls, 1);

gSystemLayerAndClock.AdvanceMonotonic(1000_ms64);
EXPECT_EQ(logic.HandleCloseCommand(), CHIP_NO_ERROR);
EXPECT_EQ(delegate.numHandleCloseValveCalls, 1);

// Ensure the timer was cancelled
gSystemLayerAndClock.AdvanceMonotonic(1000_ms64);
EXPECT_EQ(delegate.numHandleCloseValveCalls, 1);
}

// while remaining duration is null and valve is open
TEST_F(TestValveConfigurationAndControlClusterLogic, TestCloseCommandOpenValveNoDurationLevel)
{
TestDelegateLevel delegate;
TestPersistentStorageDelegate storageDelegate;
EndpointId endpoint = 0;
MockedMatterContext context(endpoint, storageDelegate);
ClusterLogic logic(delegate, context);

ClusterConformance conformance = { .featureMap = to_underlying(Feature::kLevel) | to_underlying(Feature::kTimeSync),
.supportsDefaultOpenLevel = true,
.supportsValveFault = true,
.supportsLevelStep = true };
EXPECT_EQ(logic.Init(conformance), CHIP_NO_ERROR);

gSystemLayerAndClock.SetMonotonic(0_ms64);
gSystemLayerAndClock.Clear();
EXPECT_EQ(logic.HandleOpenCommand(std::nullopt, std::nullopt), CHIP_NO_ERROR);
EXPECT_TRUE(HasAttributeChanges(context.GetDirtyList(), Attributes::OpenDuration::Id));
EXPECT_EQ(delegate.numHandleCloseValveCalls, 0);

gSystemLayerAndClock.AdvanceMonotonic(1000_ms64);
EXPECT_EQ(logic.HandleCloseCommand(), CHIP_NO_ERROR);
EXPECT_EQ(delegate.numHandleCloseValveCalls, 1);
}

TEST_F(TestValveConfigurationAndControlClusterLogic, TestCloseCommandOpenValveNoDurationNoLevel)
{
TestDelegateNoLevel delegate;
TestPersistentStorageDelegate storageDelegate;
EndpointId endpoint = 0;
MockedMatterContext context(endpoint, storageDelegate);
ClusterLogic logic(delegate, context);

ClusterConformance conformance = {
.featureMap = 0, .supportsDefaultOpenLevel = false, .supportsValveFault = true, .supportsLevelStep = false
};
EXPECT_EQ(logic.Init(conformance), CHIP_NO_ERROR);

gSystemLayerAndClock.SetMonotonic(0_ms64);
gSystemLayerAndClock.Clear();
EXPECT_EQ(logic.HandleOpenCommand(std::nullopt, std::nullopt), CHIP_NO_ERROR);
EXPECT_TRUE(HasAttributeChanges(context.GetDirtyList(), Attributes::OpenDuration::Id));
EXPECT_EQ(delegate.numHandleCloseValveCalls, 0);

gSystemLayerAndClock.AdvanceMonotonic(2000_ms64);
EXPECT_EQ(delegate.numHandleCloseValveCalls, 1);

gSystemLayerAndClock.AdvanceMonotonic(1000_ms64);
EXPECT_EQ(logic.HandleCloseCommand(), CHIP_NO_ERROR);
EXPECT_EQ(delegate.numHandleCloseValveCalls, 1);
}

// while valve is closed
TEST_F(TestValveConfigurationAndControlClusterLogic, TestCloseCommandClosedLevel)
{
TestDelegateLevel delegate;
TestPersistentStorageDelegate storageDelegate;
EndpointId endpoint = 0;
MockedMatterContext context(endpoint, storageDelegate);
ClusterLogic logic(delegate, context);

ClusterConformance conformance = { .featureMap = to_underlying(Feature::kLevel) | to_underlying(Feature::kTimeSync),
.supportsDefaultOpenLevel = true,
.supportsValveFault = true,
.supportsLevelStep = true };
EXPECT_EQ(logic.Init(conformance), CHIP_NO_ERROR);

gSystemLayerAndClock.SetMonotonic(0_ms64);
gSystemLayerAndClock.Clear();

EXPECT_EQ(logic.HandleCloseCommand(), CHIP_NO_ERROR);
EXPECT_EQ(delegate.numHandleCloseValveCalls, 1);
}

TEST_F(TestValveConfigurationAndControlClusterLogic, TestCloseCommandClosedNoLevel)
{
TestDelegateNoLevel delegate;
TestPersistentStorageDelegate storageDelegate;
EndpointId endpoint = 0;
MockedMatterContext context(endpoint, storageDelegate);
ClusterLogic logic(delegate, context);

ClusterConformance conformance = {
.featureMap = 0, .supportsDefaultOpenLevel = false, .supportsValveFault = true, .supportsLevelStep = false
};
EXPECT_EQ(logic.Init(conformance), CHIP_NO_ERROR);

gSystemLayerAndClock.SetMonotonic(0_ms64);
gSystemLayerAndClock.Clear();

EXPECT_EQ(logic.HandleCloseCommand(), CHIP_NO_ERROR);
EXPECT_EQ(delegate.numHandleCloseValveCalls, 1);
}
// Before init
// simulated failures return error

//=========================================================================================
// Tests for timing for async read updates to current / target level and state
Expand All @@ -1972,10 +2131,9 @@ TEST_F(TestValveConfigurationAndControlClusterLogic, TestCloseCalledAtOpenDurati
//=========================================================================================
// Tests for attribute callbacks from delegates
//=========================================================================================
// TODO: Should the delegate call the cluster logic class direclty, or should this be piped through the delegate class so the app
// layer ONLY has to interact with the delegate?
// Test setter for valve fault Test attribute change notifications are sent out and not
// sent out when the attribute is change do the same value - add in prior
// TODO: Should the delegate call the cluster logic class direclty, or should this be piped through the delegate class so the
// app layer ONLY has to interact with the delegate? Test setter for valve fault Test attribute change notifications are sent
// out and not sent out when the attribute is change do the same value - add in prior

//=========================================================================================
// Tests for attribute callbacks from delegates
Expand Down

0 comments on commit 71fb16c

Please sign in to comment.