Skip to content

Commit

Permalink
First versionof DEM 1-1
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterC1965 committed Aug 20, 2024
1 parent 1e0db09 commit 8f63c49
Showing 1 changed file with 216 additions and 0 deletions.
216 changes: 216 additions & 0 deletions src/python_testing/TC_DEM_1_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
#
# Copyright (c) 2024 Project CHIP Authors
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# pylint: disable=invalid-name

# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments
# for details about the block below.
#
# === BEGIN CI TEST ARGUMENTS ===
# test-runner-runs: run1
# test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP}
# test-runner-run/run1/factoryreset: True
# test-runner-run/run1/quiet: True
# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x23
# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto
# === END CI TEST ARGUMENTS ===

"""Define Matter test case TC_DEM_1_1."""


import logging

import chip.clusters as Clusters
from chip.interaction_model import Status
from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from mobly import asserts
from TC_DEMTestBase import DEMTestBase

logger = logging.getLogger(__name__)


class TC_DEM_1_1(MatterBaseTest, DEMTestBase):
"""Implementation of test case TC_DEM_1_1."""

def desc_TC_DEM_1_1(self) -> str:
"""Return a description of this test."""
return "4.1.3. [TC-DEM-2.5] Forecast Adjustment with Power Forecast Reporting feature functionality with DUT as Server"

def pics_TC_DEM_1_1(self):
"""Return the PICS definitions associated with this test."""
pics = [
# Depends on Feature 05 (ForecastAdjustment) & Feature 01 (PowerForecastReporting)
"DEM.S.F05", "DEM.S.F01"
]
return pics

def steps_TC_DEM_1_1(self) -> list[TestStep]:
"""Execute the test steps."""
steps = [
TestStep("1", "Commission DUT to TH (can be skipped if done in a preceding test)."),
TestStep("2", "TH reads from the DUT the ClusterRevision attribute.",
"Verify that the DUT response contains the ClusterRevision attribute and has the value 3."),
TestStep("3", "TH reads from the DUT the FeatureMap attribute.",
"Verify that the DUT response contains the FeatureMap attribute and have the following bit set:\n- bit 0: SHALL be 1 if and only if DEM.S.F00(PowerAdjustment).\n- bit 1: SHALL be 1 if and only if DEM.S.F01(PowerForecastReporting).\n- bit 2: SHALL be 1 if and only if DEM.S.F02(StateForecastReporting).\n- bit 3: SHALL be 1 if and only if DEM.S.F03(StartTimeAdjustment).\n- bit 4: SHALL be 1 if and only if DEM.S.F04(Pausable).\nAll remaining bits SHALL be 0. Provisional features DEM.S.F05(ForecastAdjustment) and DEM.S.F06(ConstraintBasedAdjustment) must not be supported."),
TestStep("4", "TH reads from the DUT the AttributeList attribute.",
"Verify that the DUT response contains the AttributeList attribute and have the list of supported attributes:\nThe list SHALL include all the mandatory entries: +\n0x0000, 0x0001, 0x0002, 0x0003, 0x0004\n0xfff8, 0xfff9, 0xfffb, 0xfffc and 0xfffd.\nThe list includes entries based on feature support: +\n- 0x0005: SHALL be included if and only if DEM.S.F00(PowerAdjustment).\nDEM.S.F02(StateForecastReporting).\n- 0x0007: SHALL be included if and only if DEM.S.F00(PowerAdjustment)"),
TestStep("5", "TH reads from the DUT the EventList attribute.",
"Verify that the DUT response contains the EventList attribute and have the list of supported events:\nThe list includes entries based on feature support: +\n- 0x00, 0x01: SHALL be included if and only if DEM.S.F00(PowerAdjustment).\n- 0x02, 0x03: SHALL be included if and only if DEM.S.F04(Pausable)."),
TestStep("6", "TH reads from the DUT the AcceptedCommandList attribute.",
"Verify that the DUT response contains the AcceptedCommandList attribute and have the list of Accepted Command:\nThe list includes entries based on feature support: +\n- 0x00, 0x01: SHALL be included if and only if DEM.S.F00(PowerAdjustment).\n- 0x02: SHALL be included if and only if DEM.S.F03(StartTimeAdjustment).\n- 0x03, 0x04: SHALL be included if and only if DEM.S.F04(Pausable).\n- 0x05: SHALL be included if and only if DEM.S.F05(ForecastAdjustment).\n- 0x06: SHALL be included if and only if DEM.S.F06(ConstraintBasedAdjustment).\n- 0x07: SHALL be included if and only if DEM.S.F03(StartTimeAdjustment)"),
TestStep("7", "TH reads from the DUT the GeneratedCommandList attribute.",
"Verify that the DUT response contains the GeneratedCommandList attribute and have the list of Generated Command:\nThis cluster has no entries in the standard or scoped range. +"),
]

return steps

@async_test_body
async def test_TC_DEM_1_1(self):
# pylint: disable=too-many-locals, too-many-statements
"""Run the test steps."""
self.step("1")
# Commission DUT - already done

self.step("2")
await self.check_dem_attribute("ClusterRevision", 4)


self.step("3")
#await self.validate_feature_map([Clusters.DeviceEnergyManagement.Bitmaps.Feature.kForecastAdjustment,
# Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPowerForecastReporting],
# [Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPowerAdjustment,
# Clusters.DeviceEnergyManagement.Bitmaps.Feature.kStateForecastReporting,
# Clusters.DeviceEnergyManagement.Bitmaps.Feature.kStartTimeAdjustment,
# Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPausable,
# Clusters.DeviceEnergyManagement.Bitmaps.Feature.kConstraintBasedAdjustment])

self.step("4")
attribute_list = await self.read_dem_attribute_expect_success(attribute="AttributeList")
logging.info(attribute_list)

mandatory_attributes = [Clusters.DeviceEnergyManagement.Attributes.ESAType.attribute_id,
Clusters.DeviceEnergyManagement.Attributes.ESACanGenerate.attribute_id,
Clusters.DeviceEnergyManagement.Attributes.ESAState.attribute_id,
Clusters.DeviceEnergyManagement.Attributes.AbsMinPower.attribute_id,
Clusters.DeviceEnergyManagement.Attributes.AbsMaxPower.attribute_id]

for mandatory_attribute in mandatory_attributes:
asserts.assert_true(mandatory_attribute in attribute_list,
f"Expected to find mandatory attribute {mandatory_attribute} in attribute_list {attribute_list}")

# Remove the enrty from the list
attribute_list.remove(mandatory_attribute)

# Now check feature dependant attributes
feature_map = await self.read_dem_attribute_expect_success(attribute="FeatureMap")

attribute_id = Clusters.DeviceEnergyManagement.Attributes.PowerAdjustmentCapability.attribute_id
required_features = Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPowerAdjustment
self.check_attribute_valid_and_remove_from_list(attribute_id, feature_map, attribute_list, required_features)

attribute_id = Clusters.DeviceEnergyManagement.Attributes.Forecast.attribute_id
required_features = (Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPowerForecastReporting |
Clusters.DeviceEnergyManagement.Bitmaps.Feature.kStateForecastReporting)
self.check_attribute_valid_and_remove_from_list(attribute_id, feature_map, attribute_list, required_features)

attribute_id = Clusters.DeviceEnergyManagement.Attributes.OptOutState.attribute_id
required_features = (Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPowerAdjustment |
Clusters.DeviceEnergyManagement.Bitmaps.Feature.kStartTimeAdjustment |
Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPausable |
Clusters.DeviceEnergyManagement.Bitmaps.Feature.kForecastAdjustment |
Clusters.DeviceEnergyManagement.Bitmaps.Feature.kConstraintBasedAdjustment)

self.check_attribute_valid_and_remove_from_list(attribute_id, feature_map, attribute_list, required_features)

global_attributes = [Clusters.DeviceEnergyManagement.Attributes.GeneratedCommandList.attribute_id,
Clusters.DeviceEnergyManagement.Attributes.AcceptedCommandList.attribute_id,
Clusters.DeviceEnergyManagement.Attributes.AttributeList.attribute_id,
Clusters.DeviceEnergyManagement.Attributes.FeatureMap.attribute_id,
Clusters.DeviceEnergyManagement.Attributes.ClusterRevision.attribute_id]

for global_attribute in global_attributes:
logging.info(f"global_attribute {global_attribute} global_attributes {global_attributes}")
asserts.assert_true(global_attribute in attribute_list,
f"Expected to find global attribute {global_attribute} in attribute_list {attribute_list}")

# Remove the enrty from the list
attribute_list.remove(global_attribute)

# Check there are no unknown attributes left in the list
asserts.assert_equal(len(attribute_list), 0)

self.step("5")
#event_list = await self.read_dem_attribute_expect_success(attribute="EventList")
#logging.info(f"event_list {event_list}")

#n- 0x00, 0x01: SHALL be included if and only if DEM.S.F00(PowerAdjustment).\n- 0x02, 0x03: SHALL be included if and only if DEM.S.F04(Pausable)."),
self.step("6")
accepted_command_list = await self.read_dem_attribute_expect_success(attribute="AcceptedCommandList")
logging.info(f"accepted_command_list {accepted_command_list}")

required_features = Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPowerAdjustment
expected_commands = [Clusters.DeviceEnergyManagement.Commands.PowerAdjustRequest.command_id,
Clusters.DeviceEnergyManagement.Commands.CancelPowerAdjustRequest.command_id]
self.check_expected_commands_in_list(expected_commands, feature_map, accepted_command_list, required_features)

required_features = Clusters.DeviceEnergyManagement.Bitmaps.Feature.kStartTimeAdjustment
expected_commands = [Clusters.DeviceEnergyManagement.Commands.StartTimeAdjustRequest.command_id]
self.check_expected_commands_in_list(expected_commands, feature_map, accepted_command_list, required_features)

required_features = Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPausable
expected_commands = [Clusters.DeviceEnergyManagement.Commands.PauseRequest.command_id,
Clusters.DeviceEnergyManagement.Commands.ResumeRequest.command_id]
self.check_expected_commands_in_list(expected_commands, feature_map, accepted_command_list, required_features)

required_features = Clusters.DeviceEnergyManagement.Bitmaps.Feature.kForecastAdjustment
expected_commands = [Clusters.DeviceEnergyManagement.Commands.ModifyForecastRequest.command_id]
self.check_expected_commands_in_list(expected_commands, feature_map, accepted_command_list, required_features)

required_features = Clusters.DeviceEnergyManagement.Bitmaps.Feature.kConstraintBasedAdjustment
expected_commands = [Clusters.DeviceEnergyManagement.Commands.RequestConstraintBasedForecast.command_id]
self.check_expected_commands_in_list(expected_commands, feature_map, accepted_command_list, required_features)

required_features = (Clusters.DeviceEnergyManagement.Bitmaps.Feature.kStartTimeAdjustment |
Clusters.DeviceEnergyManagement.Bitmaps.Feature.kForecastAdjustment |
Clusters.DeviceEnergyManagement.Bitmaps.Feature.kConstraintBasedAdjustment)
expected_commands = [Clusters.DeviceEnergyManagement.Commands.CancelRequest.command_id]
self.check_expected_commands_in_list(expected_commands, feature_map, accepted_command_list, required_features)

self.step("7")
generated_command_list = await self.read_dem_attribute_expect_success(attribute="GeneratedCommandList")
asserts.assert_equal(len(generated_command_list), 0)

def check_attribute_valid_and_remove_from_list(self, attribute_id, feature_map, attribute_list, required_features):
if feature_map & required_features:
asserts.assert_true(attribute_id in attribute_list,
f"Expected to find attribute {attribute_id} in attribute_list {attribute_list} given feature_map 0x{feature_map:x}")
attribute_list.remove(attribute_id)

else:
asserts.assert_false(attribute_id in attribute_list,
f"Did not expect to find attribute {attribute_id} in attribute_list {attribute_list} given feature_map 0x{feature_map:x}")

def check_expected_commands_in_list(self, expected_commands, feature_map, accepted_command_list, required_features):
if (feature_map & required_features) != 0:
for command in expected_commands:
asserts.assert_true(command in accepted_command_list,
f"Expected command {command} to be in accepted_command_list {accepted_command_list} given required_features {required_features} in feature_map 0x{feature_map:x}")

else:
for command in expected_commands:
asserts.assert_false(command in accepted_command_list,
f"Did not expect command {command} to be in accepted_command_list {accepted_command_list} given required_features {required_features} in feature_map 0x{feature_map:x}")
if __name__ == "__main__":
default_matter_test_main()

0 comments on commit 8f63c49

Please sign in to comment.