From 9d9e6abd2ce3011a19f1474ca7e870be6701c2ea Mon Sep 17 00:00:00 2001 From: pcoleman <pcoleman@geotogether.com> Date: Mon, 8 Jul 2024 14:27:46 +0100 Subject: [PATCH 01/35] Add DEM test scripts --- src/python_testing/DEMTestBase.py | 220 +++++++++++++ src/python_testing/TC_DEM_2_2.py | 325 +++++++++++++++++++ src/python_testing/TC_DEM_2_3.py | 270 +++++++++++++++ src/python_testing/TC_DEM_2_4.py | 316 ++++++++++++++++++ src/python_testing/TC_DEM_2_5.py | 240 ++++++++++++++ src/python_testing/TC_DEM_2_6.py | 227 +++++++++++++ src/python_testing/TC_DEM_2_7.py | 265 +++++++++++++++ src/python_testing/TC_DEM_2_8.py | 247 ++++++++++++++ src/python_testing/TC_DEM_2_9.py | 96 ++++++ src/python_testing/matter_testing_support.py | 18 +- 10 files changed, 2220 insertions(+), 4 deletions(-) create mode 100644 src/python_testing/DEMTestBase.py create mode 100644 src/python_testing/TC_DEM_2_2.py create mode 100644 src/python_testing/TC_DEM_2_3.py create mode 100644 src/python_testing/TC_DEM_2_4.py create mode 100644 src/python_testing/TC_DEM_2_5.py create mode 100644 src/python_testing/TC_DEM_2_6.py create mode 100644 src/python_testing/TC_DEM_2_7.py create mode 100644 src/python_testing/TC_DEM_2_8.py create mode 100644 src/python_testing/TC_DEM_2_9.py diff --git a/src/python_testing/DEMTestBase.py b/src/python_testing/DEMTestBase.py new file mode 100644 index 00000000000000..59477d94e9befd --- /dev/null +++ b/src/python_testing/DEMTestBase.py @@ -0,0 +1,220 @@ +# +# Copyright (c) 2023 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. + + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import InteractionModelError, Status +from mobly import asserts + +logger = logging.getLogger(__name__) + + +class DEMTestBase: + + async def read_dem_attribute_expect_success(self, endpoint: int = None, attribute: str = ""): + cluster = Clusters.Objects.DeviceEnergyManagement + full_attr = getattr(cluster.Attributes, attribute) + logging.info(f"endpoint {endpoint} full_attr {full_attr}") + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=full_attr) + + async def check_dem_attribute(self, attribute, expected_value, endpoint: int = None): + value = await self.read_dem_attribute_expect_success(endpoint=endpoint, attribute=attribute) + asserts.assert_equal(value, expected_value, + f"Unexpected '{attribute}' value - expected {expected_value}, was {value}") + + async def send_power_adjustment_command(self, power: int, duration: int, + cause: Clusters.Objects.DeviceEnergyManagement.Enums.CauseEnum, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.PowerAdjustRequest( + power=power, + duration=duration, + cause=cause), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_cancel_power_adjustment_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.CancelPowerAdjustRequest(), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_start_time_adjust_request_command(self, requestedStartTime: int, + cause: Clusters.Objects.DeviceEnergyManagement.Enums.CauseEnum, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.StartTimeAdjustRequest( + requestedStartTime=requestedStartTime, + cause=cause), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_start_time_adjust_clear_command(self, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.StartTimeAdjustClear(), # StartTimeAdjustmentClear(), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_cancel_request_command(self, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.CancelRequest(), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_pause_request_command(self, duration: int, cause: + Clusters.Objects.DeviceEnergyManagement.Enums.AdjustmentCauseEnum, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.PauseRequest( + duration=duration, + cause=cause), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_resume_request_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.ResumeRequest(), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_modify_forecast_request_command(self, forecastID: int, + slotAdjustments: list[Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct], + cause: Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.ModifyForecastRequest(forecastID=forecastID, + slotAdjustments=slotAdjustments, + cause=cause), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_request_constraint_based_forecast(self, constraintList: list[Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct], + cause: Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.RequestConstraintBasedForecast(constraints=constraintList, + cause=cause), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_test_event_trigger_power_adjustment(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000000) + + async def send_test_event_trigger_power_adjustment_clear(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000001) + + async def send_test_event_trigger_user_opt_out_local(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000002) + + async def send_test_event_trigger_user_opt_out_grid(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000003) + + async def send_test_event_trigger_user_opt_out_clear_all(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000004) + + async def send_test_event_trigger_start_time_adjustment(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000005) + + async def send_test_event_trigger_start_time_adjustment_clear(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000006) + + async def send_test_event_trigger_pausable(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000007) + + async def send_test_event_trigger_pausable_next_slot(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000008) + + async def send_test_event_trigger_pausable_clear(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000009) + + async def send_test_event_trigger_forecast_adjustment(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000A) + + async def send_test_event_trigger_forecast_adjustment_next_slot(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000B) + + async def send_test_event_trigger_forecast_adjustment_clear(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000C) + + async def send_test_event_trigger_constraint_based_adjustment(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000D) + + async def send_test_event_trigger_constraint_based_adjustment_clear(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000E) + + async def send_test_event_trigger_forecast(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000F) + + async def send_test_event_trigger_forecast_clear(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000010) diff --git a/src/python_testing/TC_DEM_2_2.py b/src/python_testing/TC_DEM_2_2.py new file mode 100644 index 00000000000000..a9cafb85c22677 --- /dev/null +++ b/src/python_testing/TC_DEM_2_2.py @@ -0,0 +1,325 @@ +# +# 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 +"""Define Matter test case TC_DEM_2_2.""" + + +import datetime +import logging +import sys +import time + +import chip.clusters as Clusters +from chip.interaction_model import Status +from DEMTestBase import DEMTestBase +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_2(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_2.""" + + def desc_TC_DEM_2_2(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + + def pics_TC_DEM_2_2(self): + """Return the PICS definitions associated with this test.""" + pics = [ + "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + ] + return pics + + def steps_TC_DEM_2_2(self) -> list[TestStep]: + """Execute the test steps.""" + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Power Adjustment Test Event"), + TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=NoAdjustment. Note value for later. Determine the OverallMaxPower and OverallMaxDuration as the largest MaxPower and MaxDuration of the PowerAdjustStructs returned, and similarly the OverallMinPower and OverallMinDuration as the smallest of the MinPower and MinDuration values."), + TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep( + "4", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization. Verify Command response is Success and Event DEM.S.E00(PowerAdjustStart) sent"), + TestStep("4a", "TH reads ESAState attribute. Verify value is 0x04 (PowerAdjustActive)"), + TestStep("4b", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=LocalOptimizationAdjustment."), + TestStep("5", "TH sends CancelPowerAdjustRequest. Verify Command response is Success and Event DEM.S.E01(PowerAdjustEnd) sent with Cause=Cancelled"), + TestStep("5a", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=NoAdjustment."), + TestStep("5b", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("6", "TH sends CancelPowerAdjustRequest. Verify Command response is InvalidInStateError"), + TestStep("7", "TH sends PowerAdjustRequest with Power=OverallMaxPower+1 Duration=OverallMinDuration Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("8", "TH sends PowerAdjustRequest with Power=OverallMinPower Duration=OverallMaxDuration+1 Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("9", "TH sends PowerAdjustRequest with Power=OverallMinPower-1 Duration=OverallMaxDuration Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("10", "TH sends PowerAdjustRequest with Power=OverallMaxPower Duration=OverallMinDuration-1 Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "11", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization. Verify Command response is Success and event DEM.S.E00(PowerAdjustStart) sent"), + TestStep("11a", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=LocalOptimizationAdjustment."), + TestStep( + "12", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=GridOptimization. Verify Command response is Success and no event sent"), + TestStep("12a", "TH reads ESAState attribute. Verify value is 0x04 (PowerAdjustActive)"), + TestStep("12b", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=GridOptimizationAdjustment."), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. No event sent"), + TestStep("13a", "TH reads ESAState attribute. Verify value is 0x04 (PowerAdjustActive)"), + TestStep("13b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), + TestStep( + "14", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("15", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event. Event DEM.S.E01(PowerAdjustEnd) sent with Cause=UserOptOut, Duration= approx time from step 11 to step 15, EnergyUse= a valid value"), + TestStep("15a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("15b", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), + TestStep("15c", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=NoAdjustment."), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), + TestStep("16a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("16b", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep( + "17", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization. Verify Command response is Success and event DEM.S.E00(PowerAdjustStart) sent"), + TestStep("17a", "TH reads ESAState attribute. Verify value is 0x04 (PowerAdjustActive)"), + TestStep("17b", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=LocalOptimizationAdjustment."), + TestStep("18", "Wait 10 seconds. Event DEM.S.E01(PowerAdjustEnd) sent with Cause=NormalCompletion, Duration=10s, EnergyUse= a valid value"), + TestStep("18a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("18b", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=NoAdjustment."), + TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Power Adjustment Test Event Clear"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_2(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + # These values have to correlate with the values configured in + # DeviceEnergyManagementManufacturerImpl::SetTestEventTrigger_PowerAdjustment() + min_power = 5 * 1000 * 1000 + max_power = 30 * 1000 * 1000 + + min_duration = 10 + max_duration = 60 + + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_power_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_greater_equal(len(powerAdjustCapabilityStruct.powerAdjustCapability), 1) + logging.info(powerAdjustCapabilityStruct) + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kNoAdjustment) + + # we should expect powerAdjustCapabilityStruct to have multiple entries with different max powers, min powers, max and min durations + found_min_power = sys.maxsize + found_max_power = 0 + found_min_duration = sys.maxsize + found_max_duration = 0 + + for entry in powerAdjustCapabilityStruct.powerAdjustCapability: + found_min_power = min(found_min_power, entry.minPower) + found_max_power = max(found_max_power, entry.maxPower) + found_min_duration = min(found_min_duration, entry.minDuration) + found_max_duration = max(found_max_duration, entry.maxDuration) + + result = f"found_min_power {found_min_power} found_max_power {found_max_power} found_min_duration {found_min_duration} found_max_duration {found_max_duration}" + logging.info(result) + + asserts.assert_equal(found_min_power, min_power) + asserts.assert_equal(found_max_power, max_power) + asserts.assert_equal(found_min_duration, min_duration) + asserts.assert_equal(found_max_duration, max_duration) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + await self.send_power_adjustment_command(power=max_power, + duration=powerAdjustCapabilityStruct.powerAdjustCapability[0].minDuration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustStart) + + self.step("4a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPowerAdjustActive) + + self.step("4b") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_greater_equal(len(powerAdjustCapabilityStruct.powerAdjustCapability), 1) + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kLocalOptimizationAdjustment) + + self.step("5") + await self.send_cancel_power_adjustment_command() + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustEnd) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kCancelled) + + self.step("5a") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_greater_equal(len(powerAdjustCapabilityStruct.powerAdjustCapability), 1) + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kNoAdjustment) + + self.step("5b") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("6") + await self.send_cancel_power_adjustment_command(expected_status=Status.InvalidInState) + + self.step("7") + await self.send_power_adjustment_command(power=max_power + 1, + duration=min_duration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("8") + await self.send_power_adjustment_command(power=min_power, + duration=max_duration + 1, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("9") + await self.send_power_adjustment_command(power=min_power - 1, + duration=max_duration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("10") + await self.send_power_adjustment_command(power=max_power, + duration=min_duration - 1, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("11") + start = datetime.datetime.now() + await self.send_power_adjustment_command(power=max_power, + duration=min_duration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustStart) + + self.step("11a") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_greater_equal(len(powerAdjustCapabilityStruct.powerAdjustCapability), 1) + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kLocalOptimizationAdjustment) + + self.step("12") + await self.send_power_adjustment_command(power=max_power, + duration=min_duration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization) + + # Wait 5 seconds for an event not to be reported + events_callback.wait_for_event_expect_no_report(5) + + self.step("12a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPowerAdjustActive) + + self.step("12b") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_greater_equal(len(powerAdjustCapabilityStruct.powerAdjustCapability), 1) + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kGridOptimizationAdjustment) + + self.step("13") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("13a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPowerAdjustActive) + + self.step("13b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("14") + await self.send_power_adjustment_command(power=max_power, + duration=max_duration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("15") + await self.send_test_event_trigger_user_opt_out_grid() + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustEnd) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kUserOptOut) + + elapsed = datetime.datetime.now() - start + asserts.assert_less_equal(abs(elapsed.seconds - event_data.duration), 1) + + # TODO: Do a better check on valid energyUse value. + # Value returned here is defined in DeviceEnergyManagementManufacturerImpl::GetEnergyUse() + asserts.assert_greater_equal(event_data.energyUse, 300) + + self.step("15a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("15b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("15c") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kNoAdjustment) + + self.step("16") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("16a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("16b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("17") + await self.send_power_adjustment_command(power=max_power, + duration=min_duration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.Success) + + self.step("17a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPowerAdjustActive) + + self.step("17b") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kLocalOptimizationAdjustment) + + self.step("18") + time.sleep(10) + + self.step("18a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("18b") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kNoAdjustment) + + self.step("19") + await self.send_test_event_trigger_power_adjustment_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py new file mode 100644 index 00000000000000..be62d42c8a6a19 --- /dev/null +++ b/src/python_testing/TC_DEM_2_3.py @@ -0,0 +1,270 @@ +# +# 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. + + +import logging + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_3(MatterBaseTest, DEMTestBase): + + def desc_TC_DEM_2_3(self) -> str: + """Returns a description of this test""" + return "4.1.3. [TC-DEM-2.3] Start Time Adjustment feature functionality with DUT as Server" + + def pics_TC_DEM_2_3(self): + """This test case verifies the primary functionality of the Device Energy Management cluster server with Start Time Adjustment feature.""" + pics = [ + "DEM.S.F03", # Depends on F03(StartTimeAdjustment) + ] + return pics + + def steps_TC_DEM_2_3(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Start Time Adjustment Test Event"), + TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute. Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), + TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event"), + TestStep("4a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("4b", "TH reads OptOutState attribute. Verify value is 0x01 (LocalOptOut)"), + TestStep("5", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime from Forecast, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("5a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("5b", "TH reads Forecast attribute. Value has to be unchanged from step 3b"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), + TestStep("6a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("6b", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep("7", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime from Forecast, Cause=LocalOptimization. Verify Command response is Success"), + TestStep("7a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("7b", "TH reads Forecast attribute. Value has to include EarliestStartTime=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Local Optimization"), + TestStep("8", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event"), + TestStep("8a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("8b", "TH reads OptOutState attribute. Verify value is 0x01 (LocalOptOut)"), + TestStep("8c", "TH reads Forecast attribute. Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), + TestStep("9", "TH sends StartTimeAdjustRequest with RequestedStartTime=StartTime+(LatestEndTime-EndTime) from Forecast, Cause=GridOptimization. Verify Command response is Success"), + TestStep("9a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("9b", "TH reads Forecast attribute. Value has to include EarliestStartTime<=StartTime, LatestEndTime=EndTime, and ForecastUpdateReason=Grid Optimization"), + TestStep("10", "TH sends CancelRequest. Verify Command response is Success"), + TestStep("10a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("10b", "TH reads Forecast attribute. Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), + TestStep("11", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime-1 from Forecast, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("11a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("11b", "TH reads Forecast attribute. Value has to include StartTime and EndTime unchanged from step 10b"), + TestStep("12", "TH sends StartTimeAdjustRequest with RequestedStartTime=StartTime+(LatestEndTime-EndTime)+1 from Forecast, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("12a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("12b", "TH reads Forecast attribute. Value has to include StartTime and EndTime unchanged from step 10b"), + TestStep("13", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Start Time Adjustment Test Event Clear"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_3(self): + + logging.info(Clusters.Objects.DeviceEnergyManagement.Attributes.FeatureMap) + + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_start_time_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + + asserts.assert_not_equal(forecast, NullValue) + if forecast is not NullValue: + asserts.assert_less_equal(forecast.earliestStartTime, forecast.startTime, + f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") + asserts.assert_greater_equal(forecast.latestEndTime, forecast.endTime, + f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, + f"Expected forecast forecastUpdateReason {forecast.forecastUpdateReason} to be == Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization") + for index, slot in enumerate(forecast.slots): + logging.info( + f" [{index}] MinDuration: {slot.minDuration} MaxDuration: {slot.maxDuration} DefaultDuration: {slot.defaultDuration}") + logging.info(f" ElapseSlotTime: {slot.elapsedSlotTime} RemainingSlotTime: {slot.remainingSlotTime}") + logging.info( + f" SlotIsPausable: {slot.slotIsPausable} MinPauseDuration: {slot.minPauseDuration} MaxPauseDuration: {slot.maxPauseDuration}") + logging.info(f" ManufacturerESAState: {slot.manufacturerESAState}") + logging.info(f" NominalPower: {slot.nominalPower} MinPower: {slot.minPower} MaxPower: {slot.maxPower}") + logging.info(f" MinPowerAdjustment: {slot.minPowerAdjustment} MaxPowerAdjustment: {slot.maxPowerAdjustment}") + logging.info( + f" MinDurationAdjustment: {slot.minDurationAdjustment} MaxDurationAdjustment: {slot.maxDurationAdjustment}") + if slot.costs is not None: + for cost_index, cost in enumerate(slot): + logging.info( + f" Cost: [{cost_index}] CostType:{cost.costType} Value: {cost.value} DecimalPoints: {cost.decimalPoints} Currency: {cost.currency}") + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("4a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("4b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("5") + await self.send_start_time_adjust_request_command(requestedStartTime=forecast.earliestStartTime, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("5a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("5b") + forecast2 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast, forecast2, + f"Expected same forcast {forecast} to be == {forecast2}") + + self.step("6") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("6a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("6b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("7") + await self.send_start_time_adjust_request_command(requestedStartTime=forecast.earliestStartTime, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + + self.step("7a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("7b") + forecast3 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast3.earliestStartTime, forecast3.startTime, + f"Expected earliestStartTime {forecast3.earliestStartTime} to be == startTime {forecast3.startTime}") + asserts.assert_greater_equal(forecast3.latestEndTime, forecast3.endTime, + f"Expected latestEndTime {forecast3.latestEndTime} to be >= endTime {forecast3.endTime}") + asserts.assert_equal(forecast3.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization, + f"Expected forecastUpdateReason {forecast3.forecastUpdateReason} to be == LocalOptimization {Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization}") + + self.step("8") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("8a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("8b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("8c") + forecast4 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_less_equal(forecast4.earliestStartTime, forecast4.startTime, + f"Expected earliestStartTime {forecast4.earliestStartTime} to be <= startTime {forecast4.startTime}") + asserts.assert_greater_equal(forecast4.latestEndTime, forecast4.endTime, + f"Expected forecast latestEndTime {forecast4.latestEndTime} to be >= endTime {forecast4.endTime}") + asserts.assert_equal(forecast4.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, + f"Expected forecastUpdateReason {forecast4.forecastUpdateReason} to be == InternalOptimization {Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization}") + + self.step("9") + await self.send_start_time_adjust_request_command(requestedStartTime=forecast4.startTime+forecast4.latestEndTime - forecast4.endTime, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization) + + self.step("9a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("9b") + forecast5 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_less_equal(forecast5.earliestStartTime, forecast5.startTime, + f"Expected earliestStartTime {forecast5.earliestStartTime} to be <= startTime {forecast5.startTime}") + asserts.assert_equal(forecast5.latestEndTime, forecast5.endTime, + f"Expected latestEndTime {forecast5.latestEndTime} to be == endTime {forecast5.endTime}") + asserts.assert_equal(forecast5.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization, + f"Expected forecastUpdateReason {forecast5.forecastUpdateReason} to be == GridOptimization {Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization}") + + self.step("10") + await self.send_cancel_request_command() + + self.step("10a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("10b") + forecast6 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_less_equal(forecast6.earliestStartTime, forecast6.startTime, + f"Expected earliestStartTime {forecast6.earliestStartTime} to be <= startTime {forecast6.startTime}") + asserts.assert_greater_equal(forecast6.latestEndTime, forecast6.endTime, + f"Expected latestEndTime {forecast6.latestEndTime} to be >= endTime {forecast6.endTime}") + asserts.assert_equal(forecast6.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, + f"Expected forecastUpdateReason {forecast6.forecastUpdateReason} to be == InternalOptimization {Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization}") + + self.step("11") + await self.send_start_time_adjust_request_command(requestedStartTime=forecast6.earliestStartTime - 1, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + self.step("11a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("11b") + forecast7 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast6.startTime, forecast7.startTime, + f"Expected old startTime {forecast6.startTime} to be == startTime {forecast7.startTime}") + asserts.assert_equal(forecast6.endTime, forecast7.endTime, + f"Expected old endTime {forecast6.endTime} to be == endTime {forecast7.endTime}") + + self.step("12") + await self.send_start_time_adjust_request_command(requestedStartTime=forecast7.startTime+(forecast7.latestEndTime-forecast7.endTime)+1, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + self.step("12a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("12b") + forecast8 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast7.startTime, forecast8.startTime, + f"Expected old startTime {forecast7.startTime} to be == startTime {forecast8.startTime}") + asserts.assert_equal(forecast7.endTime, forecast8.endTime, + f"Expected old endTime {forecast7.endTime} to be == endTime {forecast8.endTime}") + + self.step("13") + await self.send_cancel_request_command(expected_status=Status.InvalidInState) + + self.step("14") + await self.send_test_event_trigger_start_time_adjustment_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py new file mode 100644 index 00000000000000..66c06dc41bd55a --- /dev/null +++ b/src/python_testing/TC_DEM_2_4.py @@ -0,0 +1,316 @@ +# +# 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. + + +import time +import logging + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_4(MatterBaseTest, DEMTestBase): + + def desc_TC_DEM_2_4(self) -> str: + """Returns a description of this test""" + return "4.1.3. [TC-DEM-2.4] Start Time Adjustment feature functionality with DUT as Server" + + def pics_TC_DEM_2_4(self): + """This test case verifies the primary functionality of the Device Energy Management cluster server with Start Time Adjustment feature.""" + pics = [ + "DEM.S.F03", # Depends on F03(StartTimeAdjustment) + ] + return pics + + def steps_TC_DEM_2_4(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event"), + TestStep("3a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast. Value has to include IsPausable=True, slot[0].SlotIsPausable=True, slot[0].MinPauseDuration>1, slot[0].MaxPauseDuration>1, slot[1].SlotIsPausable=False, ActiveSlotNumber=0, and ForecastUpdateReason=Internal Optimization"), + TestStep("3c", "TH reads OptOutState. Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends PauseRequest with Duration=MinPauseDuration-1 from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), + TestStep("4a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("5", "TH sends PauseRequest with Duration=MaxPauseDuration+1 from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), + TestStep("5a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("6", "DGGEN.S.C00.Rsp(TestEventTrigger). TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event"), + TestStep("6a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("6b", "TH reads OptOutState. Verify value is 0x02 (GridOptOut)"), + TestStep("7", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=GridOptimization. Command rejected"), + TestStep("7a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("8", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), + TestStep("8a", "TH reads ESAState. Verify value is 0x05 (Paused)"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. Event {PICS_S}.E03(Resumed) sent with Cause=3 (UserOptOut)"), + TestStep("9a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("9b", "TH reads OptOutState. Verify value is 0x03 (OptOut)"), + TestStep("9c", "TH reads Forecast. Value has to include ForecastUpdateReason=Internal Optimization"), + TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), + TestStep("10a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("10b", "TH reads OptOutState. Verify value is 0x00 (NoOptOut)"), + TestStep("11", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), + TestStep("11a", "TH reads ESAState. Verify value is 0x05 (Paused)"), + TestStep("11b", "TH reads Forecast. Value has to include ForecastUpdateReason=Local Optimization"), + TestStep("12", "TH sends ResumeRequest. Event {PICS_S}.E03(Resumed) sent with Cause=4 (Cancelled)"), + TestStep("12a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("12b", "TH reads Forecast. Value has to include IsPausable=True, slot[0].SlotIsPausable=True, slot[0].MinPauseDuration>1, slot[0].MaxPauseDuration>1, slot[1].SlotIsPausable=False, ActiveSlotNumber=0, ForecastUpdateReason=Internal Optimization"), + TestStep("13", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), + TestStep("13a", "TH reads ESAState. Verify value is 0x05 (Paused)"), + TestStep("13b", "TH reads Forecast. Value has to include ForecastUpdateReason=Local Optimization"), + TestStep("14", "TH sends ResumeRequest. Event {PICS_S}.E03(Resumed) sent with Cause=4 (Cancelled)"), + TestStep("14a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("15", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), + TestStep("15a", "TH reads ESAState. Verify value is 0x05 (Paused)"), + TestStep("16", "Wait for minPauseDuration. Event {PICS_S}.E03(Resumed) sent with Cause=0 (NormalCompletion)"), + TestStep("16a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("17", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event Next Slot."), + TestStep("17a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("17b", "TH reads Forecast. Value has to include ActiveSlotNumber=1"), + TestStep("18", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), + TestStep("18a", "TH reads ESAState. Verify value is 0x01 (Online)"), + TestStep("19", "TH sends ResumeRequest. Command rejected"), + TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event Clear."), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_4(self): + + logging.info(Clusters.Objects.DeviceEnergyManagement.Attributes.FeatureMap) + + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_pausable() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + + asserts.assert_not_equal(forecast, NullValue) + asserts.assert_equal(forecast.isPausable, True) + asserts.assert_greater(forecast.slots[0].minPauseDuration, 1) + asserts.assert_greater(forecast.slots[0].maxPauseDuration, 1) + asserts.assert_equal(forecast.slots[0].slotIsPausable, True) + asserts.assert_equal(forecast.slots[1].slotIsPausable, False) + asserts.assert_equal(forecast.activeSlotNumber, 0) + + if forecast is not NullValue: + asserts.assert_less_equal(forecast.earliestStartTime, forecast.startTime, + f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") + asserts.assert_greater_equal(forecast.latestEndTime, forecast.endTime, + f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, + f"Expected forecast forecastUpdateReason {forecast.forecastUpdateReason} to be == Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization") + for index, slot in enumerate(forecast.slots): + logging.info( + f" [{index}] MinDuration: {slot.minDuration} MaxDuration: {slot.maxDuration} DefaultDuration: {slot.defaultDuration}") + logging.info(f" ElapseSlotTime: {slot.elapsedSlotTime} RemainingSlotTime: {slot.remainingSlotTime}") + logging.info( + f" SlotIsPausable: {slot.slotIsPausable} MinPauseDuration: {slot.minPauseDuration} MaxPauseDuration: {slot.maxPauseDuration}") + logging.info(f" ManufacturerESAState: {slot.manufacturerESAState}") + logging.info(f" NominalPower: {slot.nominalPower} MinPower: {slot.minPower} MaxPower: {slot.maxPower}") + logging.info(f" MinPowerAdjustment: {slot.minPowerAdjustment} MaxPowerAdjustment: {slot.maxPowerAdjustment}") + logging.info( + f" MinDurationAdjustment: {slot.minDurationAdjustment} MaxDurationAdjustment: {slot.maxDurationAdjustment}") + if slot.costs is not None: + for cost_index, cost in enumerate(slot): + logging.info( + f" Cost: [{cost_index}] CostType:{cost.costType} Value: {cost.value} DecimalPoints: {cost.decimalPoints} Currency: {cost.currency}") + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration - 1, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("4a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("5") + await self.send_pause_request_command(forecast.slots[0].maxPauseDuration + 1, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("5a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("6") + await self.send_test_event_trigger_user_opt_out_grid() + + self.step("6a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("6b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kGridOptOut) + + self.step("7") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, + expected_status=Status.ConstraintError) + + self.step("7a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("8") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Paused) + + self.step("8a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPaused) + + self.step("9") + await self.send_test_event_trigger_user_opt_out_local() + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Resumed) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kUserOptOut) + + self.step("9a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("9b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("9c") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + + asserts.assert_not_equal(forecast, NullValue) + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("10") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("10a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("10b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("11") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Paused) + + self.step("11a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPaused) + + self.step("11b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("12") + await self.send_resume_request_command() + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Resumed) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kCancelled) + + self.step("12a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("12b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.isPausable, True) + asserts.assert_greater(forecast.slots[0].minPauseDuration, 1) + asserts.assert_greater(forecast.slots[0].maxPauseDuration, 1) + asserts.assert_equal(forecast.slots[0].slotIsPausable, True) + asserts.assert_equal(forecast.slots[1].slotIsPausable, False) + asserts.assert_equal(forecast.activeSlotNumber, 0) + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("13") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Paused) + + + self.step("13a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPaused) + + self.step("13b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("14") + await self.send_resume_request_command() + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Resumed) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kCancelled) + + self.step("14a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("15") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Paused) + + self.step("15a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPaused) + + self.step("16") + logging.info(f"Sleeping for forecast.slots[0].minPauseDuration {forecast.slots[0].minPauseDuration}s") + time.sleep(forecast.slots[0].minPauseDuration) + + self.step("16a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("17") + await self.send_test_event_trigger_pausable_next_slot() + + self.step("17a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("17b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + print(forecast) + asserts.assert_equal(forecast.activeSlotNumber, 1) + + self.step("18") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("18a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("19") + await self.send_resume_request_command(expected_status=Status.Failure) + + self.step("20") + await self.send_test_event_trigger_user_opt_out_clear_all() + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py new file mode 100644 index 00000000000000..9c91f18afcdde3 --- /dev/null +++ b/src/python_testing/TC_DEM_2_5.py @@ -0,0 +1,240 @@ +# +# 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 +"""Define Matter test case TC_DEM_2_5.""" + + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_5(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_5.""" + + def desc_TC_DEM_2_5(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + + def pics_TC_DEM_2_5(self): + """Return the PICS definitions associated with this test.""" + pics = [ + "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + ] + return pics + + def steps_TC_DEM_2_5(self) -> list[TestStep]: + """Execute the test steps.""" + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event"), + TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute. Value has to include slots[0].MinPowerAdjustment, slots[0].MaxPowerAdjustment, slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), + TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep("5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep("6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment-1, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep("7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment+1, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep("8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep("9", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep("10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event"), + TestStep("11a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("11b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), + TestStep("12", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), + TestStep("13a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("14", "TH sends CancelRequest. Verify Command response is Success"), + TestStep("14a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), + TestStep("15a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event"), + TestStep("16a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), + TestStep("16b", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=Internal Optimization"), + TestStep("17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), + TestStep("18a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep("19", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is Success"), + TestStep("19a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=LocalOptimization"), + TestStep("20", "TH sends CancelRequest. Verify Command response is Success"), + TestStep("20a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("21", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Next Slot"), + TestStep("22", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("23", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), + TestStep("24", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Clear"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_5(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_forecast_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + + asserts.assert_greater_equal(len(forecast.slots), 2) + + asserts.assert_is_not_none(forecast.slots[0].minPowerAdjustment) + asserts.assert_is_not_none(forecast.slots[0].maxPowerAdjustment) + asserts.assert_is_not_none(forecast.slots[0].minDurationAdjustment) + asserts.assert_is_not_none(forecast.slots[0].maxDurationAdjustment) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID + 1, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("5") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=4, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("6") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment - 1, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("7") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].maxPowerAdjustment + 1, duration=forecast.slots[0].minDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("8") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment + 1)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("9") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].maxPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment - 1)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("10") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment), + Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=4, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("11") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("11a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("11b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("12") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("13") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("13a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("14") + await self.send_cancel_request_command() + + self.step("14a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("15") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] +#### await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("15a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("16") + await self.send_test_event_trigger_user_opt_out_grid() + + self.step("16a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("16b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("17") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("18") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("18a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("19") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) + + self.step("19a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("20") + await self.send_cancel_request_command() + + self.step("20a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("21") + await self.send_test_event_trigger_forecast_adjustment_next_slot() + + self.step("22") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("23") + await self.send_cancel_request_command(expected_status=Status.InvalidInState) + + self.step("24") + await self.send_test_event_trigger_forecast_adjustment_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py new file mode 100644 index 00000000000000..170d3a23cfe084 --- /dev/null +++ b/src/python_testing/TC_DEM_2_6.py @@ -0,0 +1,227 @@ +# +# 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 +"""Define Matter test case TC_DEM_2_6.""" + + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_6(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_6.""" + + def desc_TC_DEM_2_6(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + + def pics_TC_DEM_2_6(self): + """Return the PICS definitions associated with this test.""" + pics = [ + "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + ] + return pics + + def steps_TC_DEM_2_6(self) -> list[TestStep]: + """Execute the test steps.""" + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event"), + TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute. Value has to include slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), + TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep("5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep("6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep("7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep("8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event"), + TestStep("9a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("9b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), + TestStep("10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("11", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), + TestStep("11a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("12", "TH sends CancelRequest. Verify Command response is Success"), + TestStep("12a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), + TestStep("13a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event"), + TestStep("14a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), + TestStep("14b", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=Internal Optimization"), + TestStep("15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), + TestStep("16a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep("17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is Success"), + TestStep("17a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=LocalOptimization"), + TestStep("18", "TH sends CancelRequest. Verify Command response is Success"), + TestStep("18a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Next Slot"), + TestStep("20", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("21", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), + TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Clear"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_6(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_forecast_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_is_not_none(forecast.slots[0].minDurationAdjustment) + asserts.assert_is_not_none(forecast.slots[0].maxDurationAdjustment) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID + 1, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("5") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=4, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("6") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment + 1)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("7") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].minDurationAdjustment - 1)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("8") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment), + Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=4, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("9") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("9a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("9b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("10") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("11") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("11a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + logging.info(forecast) + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("12") + await self.send_cancel_request_command() + + self.step("12a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("13") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("13a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("14") + await self.send_test_event_trigger_user_opt_out_grid() + + self.step("14a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("14b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("15") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("16") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("16a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("17") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].minDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) + + self.step("17a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("18") + await self.send_cancel_request_command() + + self.step("18a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("19") + await self.send_test_event_trigger_forecast_adjustment_next_slot() + + self.step("20") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].minDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("21") + await self.send_cancel_request_command(expected_status=Status.InvalidInState) + + self.step("22") + await self.send_test_event_trigger_forecast_adjustment_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py new file mode 100644 index 00000000000000..5400657b863c50 --- /dev/null +++ b/src/python_testing/TC_DEM_2_7.py @@ -0,0 +1,265 @@ +# +# 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 +"""Define Matter test case TC_DEM_2_7.""" + + +import logging +import datetime + +import chip.clusters as Clusters +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_7(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_7.""" + + def desc_TC_DEM_2_7(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + + def pics_TC_DEM_2_7(self): + """Return the PICS definitions associated with this test.""" + pics = [ + "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + ] + return pics + + def steps_TC_DEM_2_7(self) -> list[TestStep]: + """Execute the test steps.""" + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify value is 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Test Event. Verify Command response is Success"), + TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute. {valincludes} valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), + TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+20, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+40, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+40, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+50, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+50, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("9", "TH reads AbsMaxPower attribute attribute.. Save the value"), + TestStep("9a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMaxPower+1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("10", "TH reads AbsMinPower attribute attribute.. Save the value"), + TestStep("10a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMinPower-1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("11", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower}, Cause=LocalOptimization. Verify Command response is InvalidCommand"), + TestStep("12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is InvalidCommand"), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. Verify Command response is Success"), + TestStep("13a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("13b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), + TestStep("14", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is Success"), + TestStep("15a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), + TestStep("16", "TH sends CancelRequest. Verify Command response is Success"), + TestStep("16a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), + TestStep("17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is Success"), + TestStep("17a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event. Verify Command response is Success"), + TestStep("18a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), + TestStep("18b", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), + TestStep("19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear. Verify Command response is Success"), + TestStep("20a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep("21", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is Success"), + TestStep("21a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=LocalOptimization"), + TestStep("22", "TH sends CancelRequest. Verify Command response is Success"), + TestStep("22a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), + TestStep("23", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), + TestStep("24", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Adjustment Test Event Clear. Verify Command response is Success"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_7(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_constraint_based_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + logging.info(forecast) + asserts.assert_greater(forecast.slots[0].nominalPower, 0) + asserts.assert_greater(forecast.slots[0].minPower, 0) + asserts.assert_greater(forecast.slots[0].maxPower, 0) + asserts.assert_greater(forecast.slots[0].nominalEnergy, 0) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + # Matter UTC is time since 00:00:00 1/1/2000 + now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() - 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("5") + now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 20, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("6") + now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + + self.step("7") + now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("8") + now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("9") + absMaxPower = await self.read_dem_attribute_expect_success(attribute="AbsMaxPower") + + self.step("9a") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=absMaxPower + 1, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("10") + absMinPower = await self.read_dem_attribute_expect_success(attribute="AbsMinPower") + + self.step("10a") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=absMinPower - 1, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("11") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.InvalidCommand) + + self.step("12") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.InvalidCommand) + + self.step("13") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("13a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("13b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("14") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("15") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("15a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("16") + await self.send_cancel_request_command() + + self.step("16a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("17") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("17a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("18") + await self.send_test_event_trigger_user_opt_out_grid() + + self.step("18a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("18b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("19") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("20") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("20a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("21") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) + + self.step("21a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("22") + await self.send_cancel_request_command() + + self.step("22a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("23") + await self.send_cancel_request_command(expected_status=Status.InvalidInState) + + self.step("24") + await self.send_test_event_trigger_constraint_based_adjustment_clear() + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py new file mode 100644 index 00000000000000..17ec309255ad1a --- /dev/null +++ b/src/python_testing/TC_DEM_2_8.py @@ -0,0 +1,247 @@ +# +# 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 +"""Define Matter test case TC_DEM_2_8.""" + + +import logging +import datetime + +import chip.clusters as Clusters +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_8(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_8.""" + + def desc_TC_DEM_2_8(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + + def pics_TC_DEM_2_8(self): + """Return the PICS definitions associated with this test.""" + pics = [ + "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + ] + return pics + + def steps_TC_DEM_2_8(self) -> list[TestStep]: + """Execute the test steps.""" + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify value is 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Test Event. Verify Command response is Success"), + TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute. {valincludes} valid slots[0].ManufacturerESAState"), + TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+20, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+40, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+50, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+30, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("9", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=101}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("10", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=-101}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. Verify Command response is Success"), + TestStep("11a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), + TestStep("11b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), + TestStep("12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("13", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is Success"), + TestStep("13a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), + TestStep("14", "TH sends CancelRequest. Verify Command response is Success"), + TestStep("14a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), + TestStep("15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is Success"), + TestStep("15a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event. Verify Command response is Success"), + TestStep("16a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), + TestStep("16b", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), + TestStep("17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear. Verify Command response is Success"), + TestStep("18a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), + TestStep("19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization. Verify Command response is Success"), + TestStep("19a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=LocalOptimization"), + TestStep("20", "TH sends CancelRequest. Verify Command response is Success"), + TestStep("20a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), + TestStep("21", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), + TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Adjustment Test Event Clear. Verify Command response is Success"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_8(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_constraint_based_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_is_not_none(forecast.slots[0].manufacturerESAState) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + # Matter UTC is time since 00:00:00 1/1/2000 + now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() - 10, duration=20, loadControl=0)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("5") + # Matter UTC is time since 00:00:00 1/1/2000 + now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 20, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, loadControl=0)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("6") + # Matter UTC is time since 00:00:00 1/1/2000 + now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 40, duration=20, loadControl=0)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("7") + now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, loadControl=0)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("8") + now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, loadControl=0)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("9") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=101)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + + self.step("10") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=-101)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("11") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("11a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("11b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("12") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("13") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("13a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("14") + await self.send_cancel_request_command() + + self.step("14a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("15") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("15a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("16") + await self.send_test_event_trigger_user_opt_out_grid() + + self.step("16a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("16b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("17") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("18") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("18a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("19") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) + + self.step("19a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("20") + await self.send_cancel_request_command() + + self.step("20a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("21") + await self.send_cancel_request_command(expected_status=Status.InvalidInState) + + self.step("22") + await self.send_test_event_trigger_constraint_based_adjustment_clear() + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py new file mode 100644 index 00000000000000..87a3b4e32ed515 --- /dev/null +++ b/src/python_testing/TC_DEM_2_9.py @@ -0,0 +1,96 @@ +# +# 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 +"""Define Matter test case TC_DEM_2_9.""" + + +import logging + +import chip.clusters as Clusters +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_9(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_9.""" + + def desc_TC_DEM_2_9(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + + def pics_TC_DEM_2_9(self): + """Return the PICS definitions associated with this test.""" + pics = [ + "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + ] + return pics + + def steps_TC_DEM_2_9(self) -> list[TestStep]: + """Execute the test steps.""" + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Test Event"), + TestStep("3a", "TH reads Forecast attribute. Value has to include a valid slots[0].ManufacturerESAState"), + TestStep("3b", "TH reads Forecast attribute. Value has to include valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Test Event Clear"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_9(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_forecast() + + self.step("3a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_greater_equal(len(forecast.slots), 1) + asserts.assert_is_not_none(forecast.slots[0].manufacturerESAState) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_greater_equal(len(forecast.slots), 1) + + asserts.assert_is_not_none(forecast.slots[0].nominalPower) + asserts.assert_is_not_none(forecast.slots[0].minPower) + asserts.assert_is_not_none(forecast.slots[0].maxPower) + asserts.assert_is_not_none(forecast.slots[0].nominalEnergy) + + self.step("4") + await self.send_test_event_trigger_forecast_clear() + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 796397c57e0458..7430d9eec0fd15 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -253,11 +253,11 @@ def __call__(self, res: EventReadResult, transaction: SubscriptionTransaction): f'Got subscription report for event on cluster {self._expected_cluster}: {res.Data}') self._q.put(res) - def wait_for_event_report(self, expected_event: ClusterObjects.ClusterEvent, timeout: int = 10): - """This function allows a test script to block waiting for the specific event to arrive with a timeout. - It returns the event data so that the values can be checked.""" + def wait_for_event_report(self, expected_event: ClusterObjects.ClusterEvent, timeoutS: int = 10): + """This function allows a test script to block waiting for the specific event to arrive with a timeout + (specified in seconds). It returns the event data so that the values can be checked.""" try: - res = self._q.get(block=True, timeout=timeout) + res = self._q.get(block=True, timeout=timeoutS) except queue.Empty: asserts.fail("Failed to receive a report for the event {}".format(expected_event)) @@ -265,6 +265,16 @@ def wait_for_event_report(self, expected_event: ClusterObjects.ClusterEvent, tim asserts.assert_equal(res.Header.EventId, expected_event.event_id, "Expected event ID not found in event report") return res.Data + def wait_for_event_expect_no_report(self, timeoutS: int = 10): + """This function succceeds/returns if an event does not arrive within the timeout specified in seconds. + If an event does arrive, an assert is called.""" + try: + res = self._q.get(block=True, timeout=timeoutS) + except queue.Empty: + return + + asserts.fail(f"Event reported when not expected {res}") + class InternalTestRunnerHooks(TestRunnerHooks): From 79ab87f13fff9be994b42ec0cf031d69692ed13b Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Mon, 8 Jul 2024 13:37:27 +0000 Subject: [PATCH 02/35] Restyled by autopep8 --- src/python_testing/TC_DEM_2_3.py | 4 +- src/python_testing/TC_DEM_2_4.py | 49 ++++++++++------ src/python_testing/TC_DEM_2_5.py | 98 +++++++++++++++++++++----------- src/python_testing/TC_DEM_2_6.py | 86 ++++++++++++++++++---------- src/python_testing/TC_DEM_2_7.py | 98 +++++++++++++++++++++----------- src/python_testing/TC_DEM_2_8.py | 94 +++++++++++++++++++----------- src/python_testing/TC_DEM_2_9.py | 6 +- 7 files changed, 283 insertions(+), 152 deletions(-) diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py index be62d42c8a6a19..dd7de732e69f7c 100644 --- a/src/python_testing/TC_DEM_2_3.py +++ b/src/python_testing/TC_DEM_2_3.py @@ -111,7 +111,7 @@ async def test_TC_DEM_2_3(self): asserts.assert_not_equal(forecast, NullValue) if forecast is not NullValue: asserts.assert_less_equal(forecast.earliestStartTime, forecast.startTime, - f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") + f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") asserts.assert_greater_equal(forecast.latestEndTime, forecast.endTime, f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, @@ -198,7 +198,7 @@ async def test_TC_DEM_2_3(self): asserts.assert_greater_equal(forecast4.latestEndTime, forecast4.endTime, f"Expected forecast latestEndTime {forecast4.latestEndTime} to be >= endTime {forecast4.endTime}") asserts.assert_equal(forecast4.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, - f"Expected forecastUpdateReason {forecast4.forecastUpdateReason} to be == InternalOptimization {Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization}") + f"Expected forecastUpdateReason {forecast4.forecastUpdateReason} to be == InternalOptimization {Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization}") self.step("9") await self.send_start_time_adjust_request_command(requestedStartTime=forecast4.startTime+forecast4.latestEndTime - forecast4.endTime, diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py index 66c06dc41bd55a..97e76195e6115e 100644 --- a/src/python_testing/TC_DEM_2_4.py +++ b/src/python_testing/TC_DEM_2_4.py @@ -47,45 +47,56 @@ def steps_TC_DEM_2_4(self) -> list[TestStep]: TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event"), TestStep("3a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("3b", "TH reads Forecast. Value has to include IsPausable=True, slot[0].SlotIsPausable=True, slot[0].MinPauseDuration>1, slot[0].MaxPauseDuration>1, slot[1].SlotIsPausable=False, ActiveSlotNumber=0, and ForecastUpdateReason=Internal Optimization"), + TestStep( + "3b", "TH reads Forecast. Value has to include IsPausable=True, slot[0].SlotIsPausable=True, slot[0].MinPauseDuration>1, slot[0].MaxPauseDuration>1, slot[1].SlotIsPausable=False, ActiveSlotNumber=0, and ForecastUpdateReason=Internal Optimization"), TestStep("3c", "TH reads OptOutState. Verify value is 0x00 (NoOptOut)"), - TestStep("4", "TH sends PauseRequest with Duration=MinPauseDuration-1 from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), + TestStep( + "4", "TH sends PauseRequest with Duration=MinPauseDuration-1 from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), TestStep("4a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("5", "TH sends PauseRequest with Duration=MaxPauseDuration+1 from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), + TestStep( + "5", "TH sends PauseRequest with Duration=MaxPauseDuration+1 from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), TestStep("5a", "TH reads ESAState. Verify value is 0x01 (Online)"), TestStep("6", "DGGEN.S.C00.Rsp(TestEventTrigger). TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event"), TestStep("6a", "TH reads ESAState. Verify value is 0x01 (Online)"), TestStep("6b", "TH reads OptOutState. Verify value is 0x02 (GridOptOut)"), - TestStep("7", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=GridOptimization. Command rejected"), + TestStep( + "7", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=GridOptimization. Command rejected"), TestStep("7a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("8", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), + TestStep( + "8", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), TestStep("8a", "TH reads ESAState. Verify value is 0x05 (Paused)"), - TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. Event {PICS_S}.E03(Resumed) sent with Cause=3 (UserOptOut)"), + TestStep( + "9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. Event {PICS_S}.E03(Resumed) sent with Cause=3 (UserOptOut)"), TestStep("9a", "TH reads ESAState. Verify value is 0x01 (Online)"), TestStep("9b", "TH reads OptOutState. Verify value is 0x03 (OptOut)"), TestStep("9c", "TH reads Forecast. Value has to include ForecastUpdateReason=Internal Optimization"), TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), TestStep("10a", "TH reads ESAState. Verify value is 0x01 (Online)"), TestStep("10b", "TH reads OptOutState. Verify value is 0x00 (NoOptOut)"), - TestStep("11", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), + TestStep( + "11", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), TestStep("11a", "TH reads ESAState. Verify value is 0x05 (Paused)"), TestStep("11b", "TH reads Forecast. Value has to include ForecastUpdateReason=Local Optimization"), TestStep("12", "TH sends ResumeRequest. Event {PICS_S}.E03(Resumed) sent with Cause=4 (Cancelled)"), TestStep("12a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("12b", "TH reads Forecast. Value has to include IsPausable=True, slot[0].SlotIsPausable=True, slot[0].MinPauseDuration>1, slot[0].MaxPauseDuration>1, slot[1].SlotIsPausable=False, ActiveSlotNumber=0, ForecastUpdateReason=Internal Optimization"), - TestStep("13", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), + TestStep( + "12b", "TH reads Forecast. Value has to include IsPausable=True, slot[0].SlotIsPausable=True, slot[0].MinPauseDuration>1, slot[0].MaxPauseDuration>1, slot[1].SlotIsPausable=False, ActiveSlotNumber=0, ForecastUpdateReason=Internal Optimization"), + TestStep( + "13", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), TestStep("13a", "TH reads ESAState. Verify value is 0x05 (Paused)"), TestStep("13b", "TH reads Forecast. Value has to include ForecastUpdateReason=Local Optimization"), TestStep("14", "TH sends ResumeRequest. Event {PICS_S}.E03(Resumed) sent with Cause=4 (Cancelled)"), TestStep("14a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("15", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), + TestStep( + "15", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), TestStep("15a", "TH reads ESAState. Verify value is 0x05 (Paused)"), TestStep("16", "Wait for minPauseDuration. Event {PICS_S}.E03(Resumed) sent with Cause=0 (NormalCompletion)"), TestStep("16a", "TH reads ESAState. Verify value is 0x01 (Online)"), TestStep("17", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event Next Slot."), TestStep("17a", "TH reads ESAState. Verify value is 0x01 (Online)"), TestStep("17b", "TH reads Forecast. Value has to include ActiveSlotNumber=1"), - TestStep("18", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), + TestStep( + "18", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), TestStep("18a", "TH reads ESAState. Verify value is 0x01 (Online)"), TestStep("19", "TH sends ResumeRequest. Command rejected"), TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event Clear."), @@ -129,7 +140,7 @@ async def test_TC_DEM_2_4(self): if forecast is not NullValue: asserts.assert_less_equal(forecast.earliestStartTime, forecast.startTime, - f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") + f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") asserts.assert_greater_equal(forecast.latestEndTime, forecast.endTime, f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, @@ -210,7 +221,8 @@ async def test_TC_DEM_2_4(self): forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") asserts.assert_not_equal(forecast, NullValue) - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("10") await self.send_test_event_trigger_user_opt_out_clear_all() @@ -231,7 +243,8 @@ async def test_TC_DEM_2_4(self): self.step("11b") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) self.step("12") await self.send_resume_request_command() @@ -249,20 +262,21 @@ async def test_TC_DEM_2_4(self): asserts.assert_equal(forecast.slots[0].slotIsPausable, True) asserts.assert_equal(forecast.slots[1].slotIsPausable, False) asserts.assert_equal(forecast.activeSlotNumber, 0) - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) self.step("13") await self.send_pause_request_command(forecast.slots[0].minPauseDuration, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Paused) - self.step("13a") await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPaused) self.step("13b") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) self.step("14") await self.send_resume_request_command() @@ -312,5 +326,6 @@ async def test_TC_DEM_2_4(self): self.step("20") await self.send_test_event_trigger_user_opt_out_clear_all() + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py index 9c91f18afcdde3..e57b304fe852b3 100644 --- a/src/python_testing/TC_DEM_2_5.py +++ b/src/python_testing/TC_DEM_2_5.py @@ -49,37 +49,51 @@ def steps_TC_DEM_2_5(self) -> list[TestStep]: TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event"), TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("3b", "TH reads Forecast attribute. Value has to include slots[0].MinPowerAdjustment, slots[0].MaxPowerAdjustment, slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), + TestStep( + "3b", "TH reads Forecast attribute. Value has to include slots[0].MinPowerAdjustment, slots[0].MaxPowerAdjustment, slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep("4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), - TestStep("5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), - TestStep("6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment-1, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep("7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment+1, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep("8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep("9", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep("10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep( + "4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep( + "5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep( + "6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment-1, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep( + "7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment+1, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep( + "8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep( + "9", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep( + "10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event"), TestStep("11a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), TestStep("11b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), - TestStep("12", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), + TestStep( + "12", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), TestStep("13a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), TestStep("14", "TH sends CancelRequest. Verify Command response is Success"), TestStep("14a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), - TestStep("15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), + TestStep( + "15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), TestStep("15a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event"), TestStep("16a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), TestStep("16b", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=Internal Optimization"), - TestStep("17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep( + "17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), TestStep("18a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep("19", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is Success"), + TestStep( + "19", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is Success"), TestStep("19a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=LocalOptimization"), TestStep("20", "TH sends CancelRequest. Verify Command response is Success"), TestStep("20a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), TestStep("21", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Next Slot"), - TestStep("22", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "22", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), TestStep("23", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), TestStep("24", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Clear"), ] @@ -122,27 +136,33 @@ async def test_TC_DEM_2_5(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) self.step("4") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID + 1, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("5") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=4, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=4, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("6") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment - 1, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment - 1, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("7") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].maxPowerAdjustment + 1, duration=forecast.slots[0].minDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].maxPowerAdjustment + 1, duration=forecast.slots[0].minDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("8") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment + 1)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment + 1)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("9") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].maxPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment - 1)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].maxPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment - 1)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("10") @@ -160,32 +180,38 @@ async def test_TC_DEM_2_5(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) self.step("12") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("13") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) self.step("13a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) self.step("14") await self.send_cancel_request_command() self.step("14a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("15") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] -#### await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] +# await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) self.step("15a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) self.step("16") await self.send_test_event_trigger_user_opt_out_grid() @@ -195,10 +221,12 @@ async def test_TC_DEM_2_5(self): self.step("16b") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("17") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("18") @@ -208,25 +236,29 @@ async def test_TC_DEM_2_5(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) self.step("19") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) self.step("19a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) self.step("20") await self.send_cancel_request_command() self.step("20a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("21") await self.send_test_event_trigger_forecast_adjustment_next_slot() self.step("22") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("23") diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index 170d3a23cfe084..6528ecedcaf2ce 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -49,35 +49,47 @@ def steps_TC_DEM_2_6(self) -> list[TestStep]: TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event"), TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("3b", "TH reads Forecast attribute. Value has to include slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), + TestStep( + "3b", "TH reads Forecast attribute. Value has to include slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep("4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), - TestStep("5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), - TestStep("6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep("7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep("8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep( + "4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep( + "5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), + TestStep( + "6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep( + "7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep( + "8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event"), TestStep("9a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), TestStep("9b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), - TestStep("10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("11", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), + TestStep( + "10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "11", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), TestStep("11a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), TestStep("12", "TH sends CancelRequest. Verify Command response is Success"), TestStep("12a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), - TestStep("13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), + TestStep( + "13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), TestStep("13a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event"), TestStep("14a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), TestStep("14b", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=Internal Optimization"), - TestStep("15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep( + "15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), TestStep("16a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep("17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is Success"), + TestStep( + "17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is Success"), TestStep("17a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=LocalOptimization"), TestStep("18", "TH sends CancelRequest. Verify Command response is Success"), TestStep("18a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Next Slot"), - TestStep("20", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "20", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), TestStep("21", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Clear"), ] @@ -97,8 +109,6 @@ async def test_TC_DEM_2_6(self): self.dut_node_id, self.matter_test_config.endpoint) - - self.step("2") await self.check_test_event_triggers_enabled() @@ -117,19 +127,23 @@ async def test_TC_DEM_2_6(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) self.step("4") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID + 1, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("5") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=4, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=4, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("6") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment + 1)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment + 1)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("7") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].minDurationAdjustment - 1)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].minDurationAdjustment - 1)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("8") @@ -147,32 +161,38 @@ async def test_TC_DEM_2_6(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) self.step("10") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("11") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) self.step("11a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") logging.info(forecast) - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) self.step("12") await self.send_cancel_request_command() self.step("12a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("13") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) self.step("13a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) self.step("14") await self.send_test_event_trigger_user_opt_out_grid() @@ -182,10 +202,12 @@ async def test_TC_DEM_2_6(self): self.step("14b") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("15") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("16") @@ -195,25 +217,29 @@ async def test_TC_DEM_2_6(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) self.step("17") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].minDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].minDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) self.step("17a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) self.step("18") await self.send_cancel_request_command() self.step("18a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("19") await self.send_test_event_trigger_forecast_adjustment_next_slot() self.step("20") - slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].minDurationAdjustment)] + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].minDurationAdjustment)] await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("21") diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 5400657b863c50..6def94ccc0f37a 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -50,36 +50,47 @@ def steps_TC_DEM_2_7(self) -> list[TestStep]: TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify value is 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Test Event. Verify Command response is Success"), TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("3b", "TH reads Forecast attribute. {valincludes} valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), + TestStep( + "3b", "TH reads Forecast attribute. {valincludes} valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep("4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), TestStep("5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+20, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+40, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), TestStep("6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+40, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), TestStep("7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+50, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), TestStep("8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+50, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("9", "TH reads AbsMaxPower attribute attribute.. Save the value"), - TestStep("9a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMaxPower+1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep("9", "TH reads AbsMaxPower attribute attribute.. Save the value"), + TestStep( + "9a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMaxPower+1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), TestStep("10", "TH reads AbsMinPower attribute attribute.. Save the value"), - TestStep("10a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMinPower-1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("11", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower}, Cause=LocalOptimization. Verify Command response is InvalidCommand"), - TestStep("12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is InvalidCommand"), + TestStep( + "10a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMinPower-1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "11", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower}, Cause=LocalOptimization. Verify Command response is InvalidCommand"), + TestStep( + "12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is InvalidCommand"), TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. Verify Command response is Success"), TestStep("13a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), TestStep("13b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), - TestStep("14", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is Success"), + TestStep( + "14", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is Success"), TestStep("15a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), TestStep("16", "TH sends CancelRequest. Verify Command response is Success"), TestStep("16a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), - TestStep("17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is Success"), + TestStep( + "17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is Success"), TestStep("17a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event. Verify Command response is Success"), TestStep("18a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), TestStep("18b", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), - TestStep("19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep( + "19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is ConstraintError"), TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear. Verify Command response is Success"), TestStep("20a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep("21", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is Success"), + TestStep( + "21", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is Success"), TestStep("21a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=LocalOptimization"), TestStep("22", "TH sends CancelRequest. Verify Command response is Success"), TestStep("22a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), @@ -102,8 +113,6 @@ async def test_TC_DEM_2_7(self): self.dut_node_id, self.matter_test_config.endpoint) - - self.step("2") await self.check_test_event_triggers_enabled() @@ -128,14 +137,16 @@ async def test_TC_DEM_2_7(self): # Matter UTC is time since 00:00:00 1/1/2000 now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() - 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds( + ) - 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("5") now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 20, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds( + ) + 20, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) @@ -143,14 +154,16 @@ async def test_TC_DEM_2_7(self): now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds( + ) + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] self.step("7") now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds( + ) + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) @@ -158,7 +171,8 @@ async def test_TC_DEM_2_7(self): now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds( + ) + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) @@ -166,22 +180,26 @@ async def test_TC_DEM_2_7(self): absMaxPower = await self.read_dem_attribute_expect_success(attribute="AbsMaxPower") self.step("9a") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=absMaxPower + 1, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=absMaxPower + 1, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("10") absMinPower = await self.read_dem_attribute_expect_success(attribute="AbsMinPower") self.step("10a") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=absMinPower - 1, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=absMinPower - 1, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("11") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.InvalidCommand) self.step("12") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.InvalidCommand) self.step("13") @@ -194,31 +212,37 @@ async def test_TC_DEM_2_7(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) self.step("14") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("15") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) self.step("15a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) self.step("16") await self.send_cancel_request_command() self.step("16a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("17") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) self.step("17a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) self.step("18") await self.send_test_event_trigger_user_opt_out_grid() @@ -228,10 +252,12 @@ async def test_TC_DEM_2_7(self): self.step("18b") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("19") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("20") @@ -241,19 +267,22 @@ async def test_TC_DEM_2_7(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) self.step("21") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) self.step("21a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) self.step("22") await self.send_cancel_request_command() self.step("22a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("23") await self.send_cancel_request_command(expected_status=Status.InvalidInState) @@ -261,5 +290,6 @@ async def test_TC_DEM_2_7(self): self.step("24") await self.send_test_event_trigger_constraint_based_adjustment_clear() + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index 17ec309255ad1a..39860b6da11abb 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -52,30 +52,42 @@ def steps_TC_DEM_2_8(self) -> list[TestStep]: TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), TestStep("3b", "TH reads Forecast attribute. {valincludes} valid slots[0].ManufacturerESAState"), TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep("4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+20, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+40, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+50, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+30, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("9", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=101}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("10", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=-101}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+20, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+40, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+50, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+30, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "9", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=101}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "10", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=-101}, Cause=LocalOptimization. Verify Command response is ConstraintError"), TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. Verify Command response is Success"), TestStep("11a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), TestStep("11b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), - TestStep("12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("13", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is Success"), + TestStep( + "12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization. Verify Command response is ConstraintError"), + TestStep( + "13", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is Success"), TestStep("13a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), TestStep("14", "TH sends CancelRequest. Verify Command response is Success"), TestStep("14a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), - TestStep("15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is Success"), + TestStep( + "15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is Success"), TestStep("15a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event. Verify Command response is Success"), TestStep("16a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), TestStep("16b", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), - TestStep("17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is ConstraintError"), + TestStep( + "17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is ConstraintError"), TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear. Verify Command response is Success"), TestStep("18a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep("19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization. Verify Command response is Success"), + TestStep( + "19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization. Verify Command response is Success"), TestStep("19a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=LocalOptimization"), TestStep("20", "TH sends CancelRequest. Verify Command response is Success"), TestStep("20a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), @@ -98,8 +110,6 @@ async def test_TC_DEM_2_8(self): self.dut_node_id, self.matter_test_config.endpoint) - - self.step("2") await self.check_test_event_triggers_enabled() @@ -120,7 +130,8 @@ async def test_TC_DEM_2_8(self): # Matter UTC is time since 00:00:00 1/1/2000 now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() - 10, duration=20, loadControl=0)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now.total_seconds() - 10, duration=20, loadControl=0)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("5") @@ -128,7 +139,8 @@ async def test_TC_DEM_2_8(self): now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 20, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now.total_seconds() + 20, duration=20, loadControl=0), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, loadControl=0)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) @@ -137,7 +149,8 @@ async def test_TC_DEM_2_8(self): now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now.total_seconds() + 30, duration=20, loadControl=0), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 40, duration=20, loadControl=0)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) @@ -145,7 +158,8 @@ async def test_TC_DEM_2_8(self): now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now.total_seconds() + 10, duration=20, loadControl=0), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, loadControl=0)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) @@ -153,17 +167,19 @@ async def test_TC_DEM_2_8(self): now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now.total_seconds() + 50, duration=20, loadControl=0), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, loadControl=0)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("9") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=101)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=101)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) - self.step("10") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=-101)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=-101)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("11") @@ -176,31 +192,37 @@ async def test_TC_DEM_2_8(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) self.step("12") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("13") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) self.step("13a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) self.step("14") await self.send_cancel_request_command() self.step("14a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("15") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) self.step("15a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) self.step("16") await self.send_test_event_trigger_user_opt_out_grid() @@ -210,10 +232,12 @@ async def test_TC_DEM_2_8(self): self.step("16b") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("17") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) self.step("18") @@ -223,19 +247,22 @@ async def test_TC_DEM_2_8(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) self.step("19") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) self.step("19a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) self.step("20") await self.send_cancel_request_command() self.step("20a") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("21") await self.send_cancel_request_command(expected_status=Status.InvalidInState) @@ -243,5 +270,6 @@ async def test_TC_DEM_2_8(self): self.step("22") await self.send_test_event_trigger_constraint_based_adjustment_clear() + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py index 87a3b4e32ed515..cdae285c6c8a0f 100644 --- a/src/python_testing/TC_DEM_2_9.py +++ b/src/python_testing/TC_DEM_2_9.py @@ -48,7 +48,8 @@ def steps_TC_DEM_2_9(self) -> list[TestStep]: TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Test Event"), TestStep("3a", "TH reads Forecast attribute. Value has to include a valid slots[0].ManufacturerESAState"), - TestStep("3b", "TH reads Forecast attribute. Value has to include valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), + TestStep( + "3b", "TH reads Forecast attribute. Value has to include valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Test Event Clear"), ] @@ -67,8 +68,6 @@ async def test_TC_DEM_2_9(self): self.dut_node_id, self.matter_test_config.endpoint) - - self.step("2") await self.check_test_event_triggers_enabled() @@ -92,5 +91,6 @@ async def test_TC_DEM_2_9(self): self.step("4") await self.send_test_event_trigger_forecast_clear() + if __name__ == "__main__": default_matter_test_main() From f3d60185f2677526222b6519e1d885fe17e536c7 Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Mon, 8 Jul 2024 13:37:28 +0000 Subject: [PATCH 03/35] Restyled by isort --- src/python_testing/TC_DEM_2_3.py | 2 +- src/python_testing/TC_DEM_2_4.py | 4 ++-- src/python_testing/TC_DEM_2_5.py | 2 +- src/python_testing/TC_DEM_2_6.py | 2 +- src/python_testing/TC_DEM_2_7.py | 4 ++-- src/python_testing/TC_DEM_2_8.py | 4 ++-- src/python_testing/TC_DEM_2_9.py | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py index dd7de732e69f7c..58d21d031477a4 100644 --- a/src/python_testing/TC_DEM_2_3.py +++ b/src/python_testing/TC_DEM_2_3.py @@ -20,9 +20,9 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import Status +from DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts -from DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py index 97e76195e6115e..3065afd563c9e4 100644 --- a/src/python_testing/TC_DEM_2_4.py +++ b/src/python_testing/TC_DEM_2_4.py @@ -15,15 +15,15 @@ # limitations under the License. -import time import logging +import time import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import Status +from DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts -from DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py index e57b304fe852b3..90c2c311020f6a 100644 --- a/src/python_testing/TC_DEM_2_5.py +++ b/src/python_testing/TC_DEM_2_5.py @@ -21,9 +21,9 @@ import chip.clusters as Clusters from chip.interaction_model import Status +from DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts -from DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index 6528ecedcaf2ce..d0016009c7d50a 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -21,9 +21,9 @@ import chip.clusters as Clusters from chip.interaction_model import Status +from DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts -from DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 6def94ccc0f37a..9971a2e89b6610 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -17,14 +17,14 @@ """Define Matter test case TC_DEM_2_7.""" -import logging import datetime +import logging import chip.clusters as Clusters from chip.interaction_model import Status +from DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts -from DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index 39860b6da11abb..52042e39ae5a94 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -17,14 +17,14 @@ """Define Matter test case TC_DEM_2_8.""" -import logging import datetime +import logging import chip.clusters as Clusters from chip.interaction_model import Status +from DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts -from DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py index cdae285c6c8a0f..5ea7ab8829d0cc 100644 --- a/src/python_testing/TC_DEM_2_9.py +++ b/src/python_testing/TC_DEM_2_9.py @@ -20,9 +20,9 @@ import logging import chip.clusters as Clusters +from DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts -from DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) From 43e1617d11baaa06868cabcfad10f4155e75dc3c Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 15:19:18 +0100 Subject: [PATCH 04/35] Renamed DEMBaseTest.py to TC_DEMTestBase.py so that it's grouped with the TC_DEM scripts. Also split the expected result in the TestSteps() into 3rd 'expected' arg. Corrected some missing Verification steps. --- .../{DEMTestBase.py => TC_DEMTestBase.py} | 0 src/python_testing/TC_DEM_2_2.py | 127 +++++++++++------- src/python_testing/TC_DEM_2_3.py | 110 ++++++++++----- 3 files changed, 154 insertions(+), 83 deletions(-) rename src/python_testing/{DEMTestBase.py => TC_DEMTestBase.py} (100%) diff --git a/src/python_testing/DEMTestBase.py b/src/python_testing/TC_DEMTestBase.py similarity index 100% rename from src/python_testing/DEMTestBase.py rename to src/python_testing/TC_DEMTestBase.py diff --git a/src/python_testing/TC_DEM_2_2.py b/src/python_testing/TC_DEM_2_2.py index a9cafb85c22677..963fe534418d30 100644 --- a/src/python_testing/TC_DEM_2_2.py +++ b/src/python_testing/TC_DEM_2_2.py @@ -24,7 +24,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from DEMTestBase import DEMTestBase +from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -48,51 +48,86 @@ def pics_TC_DEM_2_2(self): def steps_TC_DEM_2_2(self) -> list[TestStep]: """Execute the test steps.""" steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Power Adjustment Test Event"), - TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("3b", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=NoAdjustment. Note value for later. Determine the OverallMaxPower and OverallMaxDuration as the largest MaxPower and MaxDuration of the PowerAdjustStructs returned, and similarly the OverallMinPower and OverallMinDuration as the smallest of the MinPower and MinDuration values."), - TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep( - "4", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization. Verify Command response is Success and Event DEM.S.E00(PowerAdjustStart) sent"), - TestStep("4a", "TH reads ESAState attribute. Verify value is 0x04 (PowerAdjustActive)"), - TestStep("4b", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=LocalOptimizationAdjustment."), - TestStep("5", "TH sends CancelPowerAdjustRequest. Verify Command response is Success and Event DEM.S.E01(PowerAdjustEnd) sent with Cause=Cancelled"), - TestStep("5a", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=NoAdjustment."), - TestStep("5b", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("6", "TH sends CancelPowerAdjustRequest. Verify Command response is InvalidInStateError"), - TestStep("7", "TH sends PowerAdjustRequest with Power=OverallMaxPower+1 Duration=OverallMinDuration Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("8", "TH sends PowerAdjustRequest with Power=OverallMinPower Duration=OverallMaxDuration+1 Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("9", "TH sends PowerAdjustRequest with Power=OverallMinPower-1 Duration=OverallMaxDuration Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("10", "TH sends PowerAdjustRequest with Power=OverallMaxPower Duration=OverallMinDuration-1 Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "11", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization. Verify Command response is Success and event DEM.S.E00(PowerAdjustStart) sent"), - TestStep("11a", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=LocalOptimizationAdjustment."), - TestStep( - "12", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=GridOptimization. Verify Command response is Success and no event sent"), - TestStep("12a", "TH reads ESAState attribute. Verify value is 0x04 (PowerAdjustActive)"), - TestStep("12b", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=GridOptimizationAdjustment."), - TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. No event sent"), - TestStep("13a", "TH reads ESAState attribute. Verify value is 0x04 (PowerAdjustActive)"), - TestStep("13b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), - TestStep( - "14", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("15", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event. Event DEM.S.E01(PowerAdjustEnd) sent with Cause=UserOptOut, Duration= approx time from step 11 to step 15, EnergyUse= a valid value"), - TestStep("15a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("15b", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), - TestStep("15c", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=NoAdjustment."), - TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), - TestStep("16a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("16b", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep( - "17", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization. Verify Command response is Success and event DEM.S.E00(PowerAdjustStart) sent"), - TestStep("17a", "TH reads ESAState attribute. Verify value is 0x04 (PowerAdjustActive)"), - TestStep("17b", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=LocalOptimizationAdjustment."), - TestStep("18", "Wait 10 seconds. Event DEM.S.E01(PowerAdjustEnd) sent with Cause=NormalCompletion, Duration=10s, EnergyUse= a valid value"), - TestStep("18a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("18b", "TH reads PowerAdjustmentCapability attribute. Value has to include Cause=NoAdjustment."), - TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Power Adjustment Test Event Clear"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Power Adjustment Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=NoAdjustment. Note value for later. Determine the OverallMaxPower and OverallMaxDuration as the largest MaxPower and MaxDuration of the PowerAdjustStructs returned, and similarly the OverallMinPower and OverallMinDuration as the smallest of the MinPower and MinDuration values."), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and Event DEM.S.E00(PowerAdjustStart) sent"), + TestStep("4a", "TH reads ESAState attribute.", + "Verify value is 0x04 (PowerAdjustActive)"), + TestStep("4b", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=LocalOptimizationAdjustment."), + TestStep("5", "TH sends CancelPowerAdjustRequest.", + "Verify DUT responds with status SUCCESS(0x00) and Event DEM.S.E01(PowerAdjustEnd) sent with Cause=Cancelled"), + TestStep("5a", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=NoAdjustment."), + TestStep("5b", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("6", "TH sends CancelPowerAdjustRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("7", "TH sends PowerAdjustRequest with Power=OverallMaxPower+1 Duration=OverallMinDuration Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("8", "TH sends PowerAdjustRequest with Power=OverallMinPower Duration=OverallMaxDuration+1 Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("9", "TH sends PowerAdjustRequest with Power=OverallMinPower-1 Duration=OverallMaxDuration Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("10", "TH sends PowerAdjustRequest with Power=OverallMaxPower Duration=OverallMinDuration-1 Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("11", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E00(PowerAdjustStart) sent"), + TestStep("11a", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=LocalOptimizationAdjustment."), + TestStep("12", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and no event sent"), + TestStep("12a", "TH reads ESAState attribute.", + "Verify value is 0x04 (PowerAdjustActive)"), + TestStep("12b", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=GridOptimizationAdjustment."), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00) and no event sent"), + TestStep("13a", "TH reads ESAState attribute.", + "Verify value is 0x04 (PowerAdjustActive)"), + TestStep("13b", "TH reads OptOutState attribute.", + "Verify value is 0x02 (LocalOptOut)"), + TestStep("14", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("15", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E01(PowerAdjustEnd) sent with Cause=UserOptOut, Duration= approx time from step 11 to step 15, EnergyUse= a valid value"), + TestStep("15a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("15b", "TH reads OptOutState attribute.", + "Verify value is 0x03 (OptOut)"), + TestStep("15c", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=NoAdjustment."), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("16a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("16b", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("17", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E00(PowerAdjustStart) sent"), + TestStep("17a", "TH reads ESAState attribute.", + "Verify value is 0x04 (PowerAdjustActive)"), + TestStep("17b", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=LocalOptimizationAdjustment."), + TestStep("18", "Wait 10 seconds.", + "Event DEM.S.E01(PowerAdjustEnd) sent with Cause=NormalCompletion, Duration=10s, EnergyUse= a valid value"), + TestStep("18a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("18b", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=NoAdjustment."), + TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Power Adjustment Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), ] return steps diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py index 58d21d031477a4..82bb3aabc21be0 100644 --- a/src/python_testing/TC_DEM_2_3.py +++ b/src/python_testing/TC_DEM_2_3.py @@ -20,7 +20,7 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import Status -from DEMTestBase import DEMTestBase +from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -42,42 +42,78 @@ def pics_TC_DEM_2_3(self): def steps_TC_DEM_2_3(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Start Time Adjustment Test Event"), - TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("3b", "TH reads Forecast attribute. Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), - TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event"), - TestStep("4a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("4b", "TH reads OptOutState attribute. Verify value is 0x01 (LocalOptOut)"), - TestStep("5", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime from Forecast, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("5a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("5b", "TH reads Forecast attribute. Value has to be unchanged from step 3b"), - TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), - TestStep("6a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("6b", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep("7", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime from Forecast, Cause=LocalOptimization. Verify Command response is Success"), - TestStep("7a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("7b", "TH reads Forecast attribute. Value has to include EarliestStartTime=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Local Optimization"), - TestStep("8", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event"), - TestStep("8a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("8b", "TH reads OptOutState attribute. Verify value is 0x01 (LocalOptOut)"), - TestStep("8c", "TH reads Forecast attribute. Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), - TestStep("9", "TH sends StartTimeAdjustRequest with RequestedStartTime=StartTime+(LatestEndTime-EndTime) from Forecast, Cause=GridOptimization. Verify Command response is Success"), - TestStep("9a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("9b", "TH reads Forecast attribute. Value has to include EarliestStartTime<=StartTime, LatestEndTime=EndTime, and ForecastUpdateReason=Grid Optimization"), - TestStep("10", "TH sends CancelRequest. Verify Command response is Success"), - TestStep("10a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("10b", "TH reads Forecast attribute. Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), - TestStep("11", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime-1 from Forecast, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("11a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("11b", "TH reads Forecast attribute. Value has to include StartTime and EndTime unchanged from step 10b"), - TestStep("12", "TH sends StartTimeAdjustRequest with RequestedStartTime=StartTime+(LatestEndTime-EndTime)+1 from Forecast, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("12a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("12b", "TH reads Forecast attribute. Value has to include StartTime and EndTime unchanged from step 10b"), - TestStep("13", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), - TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Start Time Adjustment Test Event Clear"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Start Time Adjustment Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("4a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("4b", "TH reads OptOutState attribute.", + "Verify value is 0x01 (LocalOptOut)"), + TestStep("5", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime from Forecast, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("5a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("5b", "TH reads Forecast attribute.", + "Value has to be unchanged from step 3b"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("6a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("6b", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("7", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime from Forecast, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("7a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("7b", "TH reads Forecast attribute.", + "Value has to include EarliestStartTime=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Local Optimization"), + TestStep("8", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("8a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("8b", "TH reads OptOutState attribute.", + "Verify value is 0x01 (LocalOptOut)"), + TestStep("8c", "TH reads Forecast attribute.", + "Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), + TestStep("9", "TH sends StartTimeAdjustRequest with RequestedStartTime=StartTime+(LatestEndTime-EndTime) from Forecast, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("9a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("9b", "TH reads Forecast attribute.", + "Value has to include EarliestStartTime<=StartTime, LatestEndTime=EndTime, and ForecastUpdateReason=Grid Optimization"), + TestStep("10", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("10a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("10b", "TH reads Forecast attribute.", + "Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), + TestStep("11", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime-1 from Forecast, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("11a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("11b", "TH reads Forecast attribute.", + "Value has to include StartTime and EndTime unchanged from step 10b"), + TestStep("12", "TH sends StartTimeAdjustRequest with RequestedStartTime=StartTime+(LatestEndTime-EndTime)+1 from Forecast, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("12a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("12b", "TH reads Forecast attribute.", + "Value has to include StartTime and EndTime unchanged from step 10b"), + TestStep("13", "TH sends CancelRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Start Time Adjustment Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), ] return steps From 7da746fcd0dad53e0da686eae698fc02368e9409 Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 17:32:56 +0100 Subject: [PATCH 05/35] Updated DEM_2.4 with corrections to match latest test plan. Also corrected PICS and description from DEM 2.3 --- src/python_testing/TC_DEM_2_3.py | 3 +- src/python_testing/TC_DEM_2_4.py | 158 +++++++++++++++++++------------ 2 files changed, 99 insertions(+), 62 deletions(-) diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py index 82bb3aabc21be0..1d7c033303aefa 100644 --- a/src/python_testing/TC_DEM_2_3.py +++ b/src/python_testing/TC_DEM_2_3.py @@ -28,13 +28,14 @@ class TC_DEM_2_3(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_3.""" def desc_TC_DEM_2_3(self) -> str: """Returns a description of this test""" return "4.1.3. [TC-DEM-2.3] Start Time Adjustment feature functionality with DUT as Server" def pics_TC_DEM_2_3(self): - """This test case verifies the primary functionality of the Device Energy Management cluster server with Start Time Adjustment feature.""" + """Return the PICS definitions associated with this test.""" pics = [ "DEM.S.F03", # Depends on F03(StartTimeAdjustment) ] diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py index 3065afd563c9e4..9e654ea817dbb8 100644 --- a/src/python_testing/TC_DEM_2_4.py +++ b/src/python_testing/TC_DEM_2_4.py @@ -21,7 +21,7 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import Status -from DEMTestBase import DEMTestBase +from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -29,77 +29,113 @@ class TC_DEM_2_4(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_4.""" def desc_TC_DEM_2_4(self) -> str: """Returns a description of this test""" - return "4.1.3. [TC-DEM-2.4] Start Time Adjustment feature functionality with DUT as Server" + return "4.1.3. [TC-DEM-2.4] Pausable feature functionality with DUT as Server" def pics_TC_DEM_2_4(self): - """This test case verifies the primary functionality of the Device Energy Management cluster server with Start Time Adjustment feature.""" + """Return the PICS definitions associated with this test.""" pics = [ - "DEM.S.F03", # Depends on F03(StartTimeAdjustment) + "DEM.S.F04", # Depends on F04(Pausable) ] return pics def steps_TC_DEM_2_4(self) -> list[TestStep]: steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event"), - TestStep("3a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep( - "3b", "TH reads Forecast. Value has to include IsPausable=True, slot[0].SlotIsPausable=True, slot[0].MinPauseDuration>1, slot[0].MaxPauseDuration>1, slot[1].SlotIsPausable=False, ActiveSlotNumber=0, and ForecastUpdateReason=Internal Optimization"), - TestStep("3c", "TH reads OptOutState. Verify value is 0x00 (NoOptOut)"), - TestStep( - "4", "TH sends PauseRequest with Duration=MinPauseDuration-1 from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), - TestStep("4a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep( - "5", "TH sends PauseRequest with Duration=MaxPauseDuration+1 from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), - TestStep("5a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("6", "DGGEN.S.C00.Rsp(TestEventTrigger). TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event"), - TestStep("6a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("6b", "TH reads OptOutState. Verify value is 0x02 (GridOptOut)"), - TestStep( - "7", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=GridOptimization. Command rejected"), - TestStep("7a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep( - "8", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), - TestStep("8a", "TH reads ESAState. Verify value is 0x05 (Paused)"), - TestStep( - "9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. Event {PICS_S}.E03(Resumed) sent with Cause=3 (UserOptOut)"), - TestStep("9a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("9b", "TH reads OptOutState. Verify value is 0x03 (OptOut)"), - TestStep("9c", "TH reads Forecast. Value has to include ForecastUpdateReason=Internal Optimization"), - TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), - TestStep("10a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("10b", "TH reads OptOutState. Verify value is 0x00 (NoOptOut)"), - TestStep( - "11", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), - TestStep("11a", "TH reads ESAState. Verify value is 0x05 (Paused)"), - TestStep("11b", "TH reads Forecast. Value has to include ForecastUpdateReason=Local Optimization"), - TestStep("12", "TH sends ResumeRequest. Event {PICS_S}.E03(Resumed) sent with Cause=4 (Cancelled)"), - TestStep("12a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep( - "12b", "TH reads Forecast. Value has to include IsPausable=True, slot[0].SlotIsPausable=True, slot[0].MinPauseDuration>1, slot[0].MaxPauseDuration>1, slot[1].SlotIsPausable=False, ActiveSlotNumber=0, ForecastUpdateReason=Internal Optimization"), - TestStep( - "13", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), - TestStep("13a", "TH reads ESAState. Verify value is 0x05 (Paused)"), - TestStep("13b", "TH reads Forecast. Value has to include ForecastUpdateReason=Local Optimization"), - TestStep("14", "TH sends ResumeRequest. Event {PICS_S}.E03(Resumed) sent with Cause=4 (Cancelled)"), - TestStep("14a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep( - "15", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Event {PICS_S}.E02(Paused) sent"), - TestStep("15a", "TH reads ESAState. Verify value is 0x05 (Paused)"), - TestStep("16", "Wait for minPauseDuration. Event {PICS_S}.E03(Resumed) sent with Cause=0 (NormalCompletion)"), - TestStep("16a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("17", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event Next Slot."), - TestStep("17a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("17b", "TH reads Forecast. Value has to include ActiveSlotNumber=1"), - TestStep( - "18", "TH sends PauseRequest with Duration=MinPauseDuration from Forecast for slot[0], Cause=LocalOptimization. Command rejected"), - TestStep("18a", "TH reads ESAState. Verify value is 0x01 (Online)"), - TestStep("19", "TH sends ResumeRequest. Command rejected"), - TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event Clear."), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast.", + "Value has to include IsPausable=True, slot[0].SlotIsPausable=True, slot[0].MinPauseDuration>1, slot[0].MaxPauseDuration>1, slot[1].SlotIsPausable=False, ActiveSlotNumber=0, and ForecastUpdateReason=Internal Optimization"), + TestStep("3c", "TH reads OptOutState.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration-1, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("4a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("5", "TH sends PauseRequest with Duration=Forecast.slots[0].MaxPauseDuration+1, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("5a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("6a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("6b", "TH reads OptOutState.", + "Verify value is 0x02 (GridOptOut)"), + TestStep("7", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("7a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("8", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E02(Paused) sent"), + TestStep("8a", "TH reads ESAState.", + "Verify value is 0x05 (Paused)"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E03(Resumed) sent with Cause=3 (UserOptOut)"), + TestStep("9a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("9b", "TH reads OptOutState.", + "Verify value is 0x03 (OptOut)"), + TestStep("9c", "TH reads Forecast.", + "Value has to include ForecastUpdateReason=Internal Optimization"), + TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("10a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("10b", "TH reads OptOutState.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("11", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E02(Paused) sent"), + TestStep("11a", "TH reads ESAState.", + "Verify value is 0x05 (Paused)"), + TestStep("11b", "TH reads Forecast.", + "Value has to include ForecastUpdateReason=Local Optimization"), + TestStep("12", "TH sends ResumeRequest.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E03(Resumed) sent with Cause=4 (Cancelled)"), + TestStep("12a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("12b", "TH reads Forecast.", + "Value has to include IsPausable=True, slots[0].SlotIsPausable=True, slots[0].MinPauseDuration>1, slots[0].MaxPauseDuration>1, slots[1].SlotIsPausable=False, ActiveSlotNumber=0, ForecastUpdateReason=Internal Optimization"), + TestStep("13", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E02(Paused) sent"), + TestStep("13a", "TH reads ESAState.", + "Verify value is 0x05 (Paused)"), + TestStep("13b", "TH reads Forecast.", + "Value has to include ForecastUpdateReason=Local Optimization"), + TestStep("14", "TH sends ResumeRequest.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E03(Resumed) sent with Cause=4 (Cancelled)"), + TestStep("14a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("15", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E02(Paused) sent"), + TestStep("15a", "TH reads ESAState.", + "Verify value is 0x05 (Paused)"), + TestStep("16", "Wait for minPauseDuration.", + "Event DEM.S.E03(Resumed) sent with Cause=0 (NormalCompletion)"), + TestStep("16a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("17", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event Next Slot.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("17a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("17b", "TH reads Forecast.", + "Value has to include ActiveSlotNumber=1"), + TestStep("18", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=LocalOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("18a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("19", "TH sends ResumeRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event Clear.", + "Verify DUT responds with status SUCCESS(0x00)"), ] return steps From a417ee279df8f7722316f0497b5250f39e623aff Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Wed, 10 Jul 2024 16:34:42 +0000 Subject: [PATCH 06/35] Restyled by isort --- src/python_testing/TC_DEM_2_2.py | 2 +- src/python_testing/TC_DEM_2_3.py | 2 +- src/python_testing/TC_DEM_2_4.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python_testing/TC_DEM_2_2.py b/src/python_testing/TC_DEM_2_2.py index 963fe534418d30..6da870caaedee5 100644 --- a/src/python_testing/TC_DEM_2_2.py +++ b/src/python_testing/TC_DEM_2_2.py @@ -24,9 +24,9 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts +from TC_DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py index 1d7c033303aefa..feab2b035b5845 100644 --- a/src/python_testing/TC_DEM_2_3.py +++ b/src/python_testing/TC_DEM_2_3.py @@ -20,9 +20,9 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import Status -from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts +from TC_DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py index 9e654ea817dbb8..c474be36149353 100644 --- a/src/python_testing/TC_DEM_2_4.py +++ b/src/python_testing/TC_DEM_2_4.py @@ -21,9 +21,9 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import Status -from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts +from TC_DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) From e77e6441630ac53727ad8ede5aa33a8a72037b36 Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 18:19:46 +0100 Subject: [PATCH 07/35] TC_DEM_2_5.py updated with TestSteps and corrections to match latest test plan --- src/python_testing/TC_DEM_2_5.py | 132 ++++++++++++++++++------------- 1 file changed, 78 insertions(+), 54 deletions(-) diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py index 90c2c311020f6a..0576a7bc70af12 100644 --- a/src/python_testing/TC_DEM_2_5.py +++ b/src/python_testing/TC_DEM_2_5.py @@ -21,7 +21,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from DEMTestBase import DEMTestBase +from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -33,69 +33,93 @@ class TC_DEM_2_5(MatterBaseTest, DEMTestBase): def desc_TC_DEM_2_5(self) -> str: """Return a description of this test.""" - return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + return "4.1.3. [TC-DEM-2.5] Forecast Adjustment with Power Forecast Reporting feature functionality with DUT as Server" def pics_TC_DEM_2_5(self): """Return the PICS definitions associated with this test.""" pics = [ - "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + "DEM.S.F05", # Depends on Feature (ForecastAdjustment) + "DEM.S.F01" # & (PowerForecastReporting) ] return pics def steps_TC_DEM_2_5(self) -> list[TestStep]: """Execute the test steps.""" steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event"), - TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep( - "3b", "TH reads Forecast attribute. Value has to include slots[0].MinPowerAdjustment, slots[0].MaxPowerAdjustment, slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), - TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep( - "4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), - TestStep( - "5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), - TestStep( - "6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment-1, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep( - "7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment+1, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep( - "8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep( - "9", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep( - "10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), - TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event"), - TestStep("11a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("11b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), - TestStep( - "12", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), - TestStep("13a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), - TestStep("14", "TH sends CancelRequest. Verify Command response is Success"), - TestStep("14a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), - TestStep( - "15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), - TestStep("15a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), - TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event"), - TestStep("16a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), - TestStep("16b", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=Internal Optimization"), - TestStep( - "17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), - TestStep("18a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep( - "19", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is Success"), - TestStep("19a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=LocalOptimization"), - TestStep("20", "TH sends CancelRequest. Verify Command response is Success"), - TestStep("20a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), - TestStep("21", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Next Slot"), - TestStep( - "22", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("23", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), - TestStep("24", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Clear"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include slots[0].MinPowerAdjustment, slots[0].MaxPowerAdjustment, slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment-1, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment+1, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("9", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("11a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("11b", "TH reads OptOutState attribute.", + "Verify value is 0x02 (LocalOptOut)"), + TestStep("12", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("13a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("14", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("14a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("15a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("16a", "TH reads OptOutState attribute.", + "Verify value is 0x03 (OptOut)"), + TestStep("16b", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=Internal Optimization"), + TestStep("17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("18a", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("19", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("19a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=LocalOptimization"), + TestStep("20", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("20a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("21", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Next Slot", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("22", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("23", "TH sends CancelRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("24", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), ] return steps From a974dc91d806af929d704d4b221f5ae069bec93f Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 21:33:50 +0100 Subject: [PATCH 08/35] Reformatted TC_DEM_2_9.py --- src/python_testing/TC_DEM_2_9.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py index 5ea7ab8829d0cc..941cd7c7bff3b5 100644 --- a/src/python_testing/TC_DEM_2_9.py +++ b/src/python_testing/TC_DEM_2_9.py @@ -20,7 +20,7 @@ import logging import chip.clusters as Clusters -from DEMTestBase import DEMTestBase +from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -32,25 +32,31 @@ class TC_DEM_2_9(MatterBaseTest, DEMTestBase): def desc_TC_DEM_2_9(self) -> str: """Return a description of this test.""" - return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + return "4.1.3. [TC-DEM-2.2] Power or State Forecast Reporting feature functionality with DUT as Server" def pics_TC_DEM_2_9(self): """Return the PICS definitions associated with this test.""" pics = [ - "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + # Depends on Feature 01 (PowerForecastReporting) | Feature 2 (StateForecastReporting) + "DEM.S.F01 | DEM.S.F02", ] return pics def steps_TC_DEM_2_9(self) -> list[TestStep]: """Execute the test steps.""" steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Test Event"), - TestStep("3a", "TH reads Forecast attribute. Value has to include a valid slots[0].ManufacturerESAState"), - TestStep( - "3b", "TH reads Forecast attribute. Value has to include valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), - TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Test Event Clear"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads Forecast attribute.", + "Value has to include a valid slots[0].ManufacturerESAState"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), ] return steps @@ -75,6 +81,7 @@ async def test_TC_DEM_2_9(self): await self.send_test_event_trigger_forecast() self.step("3a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") asserts.assert_greater_equal(len(forecast.slots), 1) asserts.assert_is_not_none(forecast.slots[0].manufacturerESAState) From 937aed00e1fe2c99cbc36464912cabdfa64234df Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 21:50:45 +0100 Subject: [PATCH 09/35] Changed PICS for DEM_2_5.py to have it as a single boolean - unsure on the correct format. --- src/python_testing/TC_DEM_2_5.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py index 0576a7bc70af12..9383bad1b80b24 100644 --- a/src/python_testing/TC_DEM_2_5.py +++ b/src/python_testing/TC_DEM_2_5.py @@ -38,8 +38,8 @@ def desc_TC_DEM_2_5(self) -> str: def pics_TC_DEM_2_5(self): """Return the PICS definitions associated with this test.""" pics = [ - "DEM.S.F05", # Depends on Feature (ForecastAdjustment) - "DEM.S.F01" # & (PowerForecastReporting) + # Depends on Feature 05 (ForecastAdjustment) & Feature 01 (PowerForecastReporting) + "DEM.S.F05 & DEM.S.F01" ] return pics From f410e4777e5e741ebe64790fd19281fdd03d290c Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 21:51:23 +0100 Subject: [PATCH 10/35] Updated DEM_2_6.py test steps in new format and corrected Test description and PICS --- src/python_testing/TC_DEM_2_6.py | 124 ++++++++++++++++++------------- 1 file changed, 74 insertions(+), 50 deletions(-) diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index d0016009c7d50a..85e272b877e8e9 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -21,7 +21,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from DEMTestBase import DEMTestBase +from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -33,65 +33,89 @@ class TC_DEM_2_6(MatterBaseTest, DEMTestBase): def desc_TC_DEM_2_6(self) -> str: """Return a description of this test.""" - return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + return "4.1.3. [TC-DEM-2.2] Forecast Adjustment with State Forecast Reporting feature functionality with DUT as Server" def pics_TC_DEM_2_6(self): """Return the PICS definitions associated with this test.""" pics = [ - "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + # Depends on Feature 05 (ForecastAdjustment) & Feature 01 (StateForecastReporting) + "DEM.S.F05 & DEM.S.F02" ] return pics def steps_TC_DEM_2_6(self) -> list[TestStep]: """Execute the test steps.""" steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event"), - TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep( - "3b", "TH reads Forecast attribute. Value has to include slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), - TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep( - "4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), - TestStep( - "5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), - TestStep( - "6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep( - "7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep( - "8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Failure"), - TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event"), - TestStep("9a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("9b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), - TestStep( - "10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "11", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), - TestStep("11a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), - TestStep("12", "TH sends CancelRequest. Verify Command response is Success"), - TestStep("12a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), - TestStep( - "13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is Success"), - TestStep("13a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=GridOptimization"), - TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event"), - TestStep("14a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), - TestStep("14b", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=Internal Optimization"), - TestStep( - "15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"), - TestStep("16a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep( - "17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is Success"), - TestStep("17a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=LocalOptimization"), - TestStep("18", "TH sends CancelRequest. Verify Command response is Success"), - TestStep("18a", "TH reads Forecast attribute. Value has to include ForecastUpdateReason=InternalOptimization"), - TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Next Slot"), - TestStep( - "20", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("21", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), - TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Clear"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("9a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("9b", "TH reads OptOutState attribute.", + "Verify value is 0x02 (LocalOptOut)"), + TestStep("10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("11", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("11a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("12", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("12a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("13a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("14a", "TH reads OptOutState attribute.", + "Verify value is 0x03 (OptOut)"), + TestStep("14b", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=Internal Optimization"), + TestStep("15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("16a", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("17a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=LocalOptimization"), + TestStep("18", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("18a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Next Slot", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("20", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("21", "TH sends CancelRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), ] return steps From b2b313d3c090dd8e6f66c5797928fc6cbdcf7145 Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 22:01:52 +0100 Subject: [PATCH 11/35] Fixed extra " in DEM_2_6 --- src/python_testing/TC_DEM_2_6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index 85e272b877e8e9..06d95596eedd63 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -96,7 +96,7 @@ def steps_TC_DEM_2_6(self) -> list[TestStep]: "Value has to include ForecastUpdateReason=Internal Optimization"), TestStep("15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), - TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear"", + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear", "Verify DUT responds with status SUCCESS(0x00)"), TestStep("16a", "TH reads OptOutState attribute.", "Verify value is 0x00 (NoOptOut)"), From 556211a647eff8b401118b08e5215a44d39b24b8 Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 22:26:44 +0100 Subject: [PATCH 12/35] Reformatted TC_DEM_2_7.py - corrected PICS and description --- src/python_testing/TC_DEM_2_7.py | 135 +++++++++++++++++++------------ 1 file changed, 82 insertions(+), 53 deletions(-) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 9971a2e89b6610..f182b0ce1b2063 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -22,7 +22,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from DEMTestBase import DEMTestBase +from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -34,68 +34,97 @@ class TC_DEM_2_7(MatterBaseTest, DEMTestBase): def desc_TC_DEM_2_7(self) -> str: """Return a description of this test.""" - return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + return "4.1.3. [TC-DEM-2.7] Constraints-based Adjustment with Power Forecast Reporting feature functionality with DUT as Server" def pics_TC_DEM_2_7(self): """Return the PICS definitions associated with this test.""" pics = [ - "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + # Depends on Feature 06 (ConstraintBasedAdjustment) & Feature 01 (PowerForecastReporting) + "DEM.S.F06 & DEM.S.F01" ] return pics def steps_TC_DEM_2_7(self) -> list[TestStep]: """Execute the test steps.""" steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify value is 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Test Event. Verify Command response is Success"), - TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep( - "3b", "TH reads Forecast attribute. {valincludes} valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), - TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep( - "4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+20, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+40, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+40, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+50, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+50, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("9", "TH reads AbsMaxPower attribute attribute.. Save the value"), - TestStep( - "9a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMaxPower+1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("10", "TH reads AbsMinPower attribute attribute.. Save the value"), - TestStep( - "10a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMinPower-1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "11", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower}, Cause=LocalOptimization. Verify Command response is InvalidCommand"), - TestStep( - "12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is InvalidCommand"), - TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. Verify Command response is Success"), - TestStep("13a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("13b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), - TestStep( - "14", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is Success"), - TestStep("15a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), - TestStep("16", "TH sends CancelRequest. Verify Command response is Success"), - TestStep("16a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), - TestStep( - "17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is Success"), - TestStep("17a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), - TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event. Verify Command response is Success"), - TestStep("18a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), - TestStep("18b", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), - TestStep( - "19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear. Verify Command response is Success"), - TestStep("20a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep( - "21", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization. Verify Command response is Success"), - TestStep("21a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=LocalOptimization"), - TestStep("22", "TH sends CancelRequest. Verify Command response is Success"), - TestStep("22a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), - TestStep("23", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), - TestStep("24", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Adjustment Test Event Clear. Verify Command response is Success"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify value is 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+20, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+40, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+40, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+50, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+50, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("9", "TH reads AbsMaxPower attribute attribute.", + "Save the value"), + TestStep("9a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMaxPower+1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("10", "TH reads AbsMinPower attribute attribute.", + "Save the value"), + TestStep("10a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMinPower-1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("11", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower}, Cause=LocalOptimization.", + "Verify DUT responds with status InvalidCommand"), + TestStep("12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status InvalidCommand"), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("13a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("13b", "TH reads OptOutState attribute.", + "Verify value is 0x02 (LocalOptOut)"), + TestStep("14", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("15a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("16", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("16a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("17a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("18a", "TH reads OptOutState attribute.", + "Verify value is 0x03 (OptOut)"), + TestStep("18b", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("20a", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("21", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("21a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=LocalOptimization"), + TestStep("22", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("22a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("23", "TH sends CancelRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("24", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Adjustment Test Event Clear.", + "Verify DUT responds with status SUCCESS(0x00)"), ] return steps From a45851b3d42d07aab53c238f7f99c85b33d3bd30 Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 22:27:40 +0100 Subject: [PATCH 13/35] Corrected Feature 2 for DEM_2_6 --- src/python_testing/TC_DEM_2_6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index 06d95596eedd63..6803e79d336b24 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -38,7 +38,7 @@ def desc_TC_DEM_2_6(self) -> str: def pics_TC_DEM_2_6(self): """Return the PICS definitions associated with this test.""" pics = [ - # Depends on Feature 05 (ForecastAdjustment) & Feature 01 (StateForecastReporting) + # Depends on Feature 05 (ForecastAdjustment) & Feature 02 (StateForecastReporting) "DEM.S.F05 & DEM.S.F02" ] return pics From 547f03c473e3f697bc5e9335afec62b73aa5d360 Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 22:37:10 +0100 Subject: [PATCH 14/35] Corrected TC number for DEM_2_6 --- src/python_testing/TC_DEM_2_6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index 6803e79d336b24..d1067812bf3071 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -33,7 +33,7 @@ class TC_DEM_2_6(MatterBaseTest, DEMTestBase): def desc_TC_DEM_2_6(self) -> str: """Return a description of this test.""" - return "4.1.3. [TC-DEM-2.2] Forecast Adjustment with State Forecast Reporting feature functionality with DUT as Server" + return "4.1.3. [TC-DEM-2.6] Forecast Adjustment with State Forecast Reporting feature functionality with DUT as Server" def pics_TC_DEM_2_6(self): """Return the PICS definitions associated with this test.""" From 5c3e2cee59d0d4bc7cdecb5acb704874d4644612 Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 10 Jul 2024 22:37:51 +0100 Subject: [PATCH 15/35] Updated TC_DEM_2_8 test steps, description and pics --- src/python_testing/TC_DEM_2_8.py | 124 ++++++++++++++++++------------- 1 file changed, 74 insertions(+), 50 deletions(-) diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index 52042e39ae5a94..659b341bbf958e 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -22,7 +22,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from DEMTestBase import DEMTestBase +from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts @@ -34,65 +34,89 @@ class TC_DEM_2_8(MatterBaseTest, DEMTestBase): def desc_TC_DEM_2_8(self) -> str: """Return a description of this test.""" - return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + return "4.1.3. [TC-DEM-2.8] Constraints-based Adjustment with State Forecast Reporting feature functionality with DUT as Server" def pics_TC_DEM_2_8(self): """Return the PICS definitions associated with this test.""" pics = [ - "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + # Depends on Feature 06 (ConstraintBasedAdjustment) & Feature 02 (StateForecastReporting) + "DEM.S.F06 & DEM.S.F02" ] return pics def steps_TC_DEM_2_8(self) -> list[TestStep]: """Execute the test steps.""" steps = [ - TestStep("1", "Commissioning, already done", is_commissioning=True), - TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster. Verify value is 1 (True)"), - TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Test Event. Verify Command response is Success"), - TestStep("3a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("3b", "TH reads Forecast attribute. {valincludes} valid slots[0].ManufacturerESAState"), - TestStep("3c", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep( - "4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+20, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+40, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+50, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+30, Duration=20, LoadControl=0}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "9", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=101}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "10", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=-101}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event. Verify Command response is Success"), - TestStep("11a", "TH reads ESAState attribute. Verify value is 0x01 (Online)"), - TestStep("11b", "TH reads OptOutState attribute. Verify value is 0x02 (LocalOptOut)"), - TestStep( - "12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization. Verify Command response is ConstraintError"), - TestStep( - "13", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is Success"), - TestStep("13a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), - TestStep("14", "TH sends CancelRequest. Verify Command response is Success"), - TestStep("14a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), - TestStep( - "15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is Success"), - TestStep("15a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=GridOptimization"), - TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event. Verify Command response is Success"), - TestStep("16a", "TH reads OptOutState attribute. Verify value is 0x03 (OptOut)"), - TestStep("16b", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), - TestStep( - "17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization. Verify Command response is ConstraintError"), - TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear. Verify Command response is Success"), - TestStep("18a", "TH reads OptOutState attribute. Verify value is 0x00 (NoOptOut)"), - TestStep( - "19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization. Verify Command response is Success"), - TestStep("19a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=LocalOptimization"), - TestStep("20", "TH sends CancelRequest. Verify Command response is Success"), - TestStep("20a", "TH reads Forecast attribute. {valincludes} ForecastUpdateReason=InternalOptimization"), - TestStep("21", "TH sends CancelRequest. Verify Command response is InvalidInStateError"), - TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Adjustment Test Event Clear. Verify Command response is Success"), + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify value is 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include valid slots[0].ManufacturerESAState"), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, LoadControl=0}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+20, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+40, Duration=20, LoadControl=0}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+50, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+30, Duration=20, LoadControl=0}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("9", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=101}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("10", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=-101}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("11a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("11b", "TH reads OptOutState attribute.", + "Verify value is 0x02 (LocalOptOut)"), + TestStep("12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("13", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("13a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("14", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("14a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("15a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("16a", "TH reads OptOutState attribute.", + "Verify value is 0x03 (OptOut)"), + TestStep("16b", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("18a", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("19a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=LocalOptimization"), + TestStep("20", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("20a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("21", "TH sends CancelRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Adjustment Test Event Clear.", + "Verify DUT responds with status SUCCESS(0x00)"), ] return steps From dfd47b4244aff3015f2b53a0e384ad9f430b61b6 Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Wed, 10 Jul 2024 21:39:03 +0000 Subject: [PATCH 16/35] Restyled by isort --- src/python_testing/TC_DEM_2_5.py | 2 +- src/python_testing/TC_DEM_2_6.py | 2 +- src/python_testing/TC_DEM_2_7.py | 2 +- src/python_testing/TC_DEM_2_8.py | 2 +- src/python_testing/TC_DEM_2_9.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py index 9383bad1b80b24..55e346d74889ea 100644 --- a/src/python_testing/TC_DEM_2_5.py +++ b/src/python_testing/TC_DEM_2_5.py @@ -21,9 +21,9 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts +from TC_DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index d1067812bf3071..5d09d7e5deecb9 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -21,9 +21,9 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts +from TC_DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index f182b0ce1b2063..c57bdb633e152c 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -22,9 +22,9 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts +from TC_DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index 659b341bbf958e..92cdf3ca8644dc 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -22,9 +22,9 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts +from TC_DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py index 941cd7c7bff3b5..c8d8d748a8333a 100644 --- a/src/python_testing/TC_DEM_2_9.py +++ b/src/python_testing/TC_DEM_2_9.py @@ -20,9 +20,9 @@ import logging import chip.clusters as Clusters -from TC_DEMTestBase import DEMTestBase from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts +from TC_DEMTestBase import DEMTestBase logger = logging.getLogger(__name__) From 57d4fdcda4bbf8b24ab8491dd498c7856bc78d2b Mon Sep 17 00:00:00 2001 From: pcoleman <pcoleman@geotogether.com> Date: Thu, 11 Jul 2024 10:15:39 +0100 Subject: [PATCH 17/35] Apply review comments from James Harrow --- src/python_testing/TC_DEMTestBase.py | 17 ++++++++++ src/python_testing/TC_DEM_2_2.py | 50 ++++++++++++---------------- src/python_testing/TC_DEM_2_3.py | 17 ++-------- src/python_testing/TC_DEM_2_4.py | 22 +++--------- 4 files changed, 45 insertions(+), 61 deletions(-) diff --git a/src/python_testing/TC_DEMTestBase.py b/src/python_testing/TC_DEMTestBase.py index 59477d94e9befd..dc615a82c0a670 100644 --- a/src/python_testing/TC_DEMTestBase.py +++ b/src/python_testing/TC_DEMTestBase.py @@ -168,6 +168,23 @@ async def send_request_constraint_based_forecast(self, constraintList: list[Clus except InteractionModelError as e: asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + def print_forecast(self, forecast): + for index, slot in enumerate(forecast.slots): + logging.info( + f" [{index}] MinDuration: {slot.minDuration} MaxDuration: {slot.maxDuration} DefaultDuration: {slot.defaultDuration}") + logging.info(f" ElapseSlotTime: {slot.elapsedSlotTime} RemainingSlotTime: {slot.remainingSlotTime}") + logging.info( + f" SlotIsPausable: {slot.slotIsPausable} MinPauseDuration: {slot.minPauseDuration} MaxPauseDuration: {slot.maxPauseDuration}") + logging.info(f" ManufacturerESAState: {slot.manufacturerESAState}") + logging.info(f" NominalPower: {slot.nominalPower} MinPower: {slot.minPower} MaxPower: {slot.maxPower}") + logging.info(f" MinPowerAdjustment: {slot.minPowerAdjustment} MaxPowerAdjustment: {slot.maxPowerAdjustment}") + logging.info( + f" MinDurationAdjustment: {slot.minDurationAdjustment} MaxDurationAdjustment: {slot.maxDurationAdjustment}") + if slot.costs is not None: + for cost_index, cost in enumerate(slot): + logging.info( + f" Cost: [{cost_index}] CostType:{cost.costType} Value: {cost.value} DecimalPoints: {cost.decimalPoints} Currency: {cost.currency}") + async def send_test_event_trigger_power_adjustment(self): await self.send_test_event_triggers(eventTrigger=0x0098000000000000) diff --git a/src/python_testing/TC_DEM_2_2.py b/src/python_testing/TC_DEM_2_2.py index 6da870caaedee5..e14cdff812f44d 100644 --- a/src/python_testing/TC_DEM_2_2.py +++ b/src/python_testing/TC_DEM_2_2.py @@ -136,11 +136,6 @@ def steps_TC_DEM_2_2(self) -> list[TestStep]: async def test_TC_DEM_2_2(self): # pylint: disable=too-many-locals, too-many-statements """Run the test steps.""" - # These values have to correlate with the values configured in - # DeviceEnergyManagementManufacturerImpl::SetTestEventTrigger_PowerAdjustment() - min_power = 5 * 1000 * 1000 - max_power = 30 * 1000 * 1000 - min_duration = 10 max_duration = 60 @@ -170,25 +165,20 @@ async def test_TC_DEM_2_2(self): Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kNoAdjustment) # we should expect powerAdjustCapabilityStruct to have multiple entries with different max powers, min powers, max and min durations - found_min_power = sys.maxsize - found_max_power = 0 - found_min_duration = sys.maxsize - found_max_duration = 0 + min_power = sys.maxsize + max_power = 0 + min_duration = sys.maxsize + max_duration = 0 for entry in powerAdjustCapabilityStruct.powerAdjustCapability: - found_min_power = min(found_min_power, entry.minPower) - found_max_power = max(found_max_power, entry.maxPower) - found_min_duration = min(found_min_duration, entry.minDuration) - found_max_duration = max(found_max_duration, entry.maxDuration) + min_power = min(min_power, entry.minPower) + max_power = max(max_power, entry.maxPower) + min_duration = min(min_duration, entry.minDuration) + max_duration = max(max_duration, entry.maxDuration) - result = f"found_min_power {found_min_power} found_max_power {found_max_power} found_min_duration {found_min_duration} found_max_duration {found_max_duration}" + result = f"min_power {min_power} max_power {max_power} min_duration {min_duration} max_duration {max_duration}" logging.info(result) - asserts.assert_equal(found_min_power, min_power) - asserts.assert_equal(found_max_power, max_power) - asserts.assert_equal(found_min_duration, min_duration) - asserts.assert_equal(found_max_duration, max_duration) - self.step("3c") await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) @@ -251,7 +241,7 @@ async def test_TC_DEM_2_2(self): self.step("11") start = datetime.datetime.now() - await self.send_power_adjustment_command(power=max_power, + await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxPower, duration=min_duration, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) @@ -264,7 +254,7 @@ async def test_TC_DEM_2_2(self): Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kLocalOptimizationAdjustment) self.step("12") - await self.send_power_adjustment_command(power=max_power, + await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxPower, duration=min_duration, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization) @@ -300,12 +290,10 @@ async def test_TC_DEM_2_2(self): event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustEnd) asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kUserOptOut) + # Allow 3s error margin as the CI build system can run out of CPU time elapsed = datetime.datetime.now() - start - asserts.assert_less_equal(abs(elapsed.seconds - event_data.duration), 1) - - # TODO: Do a better check on valid energyUse value. - # Value returned here is defined in DeviceEnergyManagementManufacturerImpl::GetEnergyUse() - asserts.assert_greater_equal(event_data.energyUse, 300) + asserts.assert_less_equal(abs(elapsed.seconds - event_data.duration), 3) + asserts.assert_greater_equal(event_data.energyUse, 0) self.step("15a") await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) @@ -328,10 +316,11 @@ async def test_TC_DEM_2_2(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) self.step("17") - await self.send_power_adjustment_command(power=max_power, - duration=min_duration, + await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxPower, + duration=powerAdjustCapabilityStruct.powerAdjustCapability[0].minDuration, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustStart) self.step("17a") await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPowerAdjustActive) @@ -344,6 +333,11 @@ async def test_TC_DEM_2_2(self): self.step("18") time.sleep(10) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustEnd) + asserts.assert_equal(event_data.duration, 10) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kNormalCompletion) + asserts.assert_greater(event_data.energyUse, 0) + self.step("18a") await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py index feab2b035b5845..59caf8eb7ab34c 100644 --- a/src/python_testing/TC_DEM_2_3.py +++ b/src/python_testing/TC_DEM_2_3.py @@ -153,21 +153,8 @@ async def test_TC_DEM_2_3(self): f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, f"Expected forecast forecastUpdateReason {forecast.forecastUpdateReason} to be == Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization") - for index, slot in enumerate(forecast.slots): - logging.info( - f" [{index}] MinDuration: {slot.minDuration} MaxDuration: {slot.maxDuration} DefaultDuration: {slot.defaultDuration}") - logging.info(f" ElapseSlotTime: {slot.elapsedSlotTime} RemainingSlotTime: {slot.remainingSlotTime}") - logging.info( - f" SlotIsPausable: {slot.slotIsPausable} MinPauseDuration: {slot.minPauseDuration} MaxPauseDuration: {slot.maxPauseDuration}") - logging.info(f" ManufacturerESAState: {slot.manufacturerESAState}") - logging.info(f" NominalPower: {slot.nominalPower} MinPower: {slot.minPower} MaxPower: {slot.maxPower}") - logging.info(f" MinPowerAdjustment: {slot.minPowerAdjustment} MaxPowerAdjustment: {slot.maxPowerAdjustment}") - logging.info( - f" MinDurationAdjustment: {slot.minDurationAdjustment} MaxDurationAdjustment: {slot.maxDurationAdjustment}") - if slot.costs is not None: - for cost_index, cost in enumerate(slot): - logging.info( - f" Cost: [{cost_index}] CostType:{cost.costType} Value: {cost.value} DecimalPoints: {cost.decimalPoints} Currency: {cost.currency}") + + self.print_forecast(forecast) self.step("3c") await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py index c474be36149353..c43d82dd41c06d 100644 --- a/src/python_testing/TC_DEM_2_4.py +++ b/src/python_testing/TC_DEM_2_4.py @@ -181,21 +181,7 @@ async def test_TC_DEM_2_4(self): f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, f"Expected forecast forecastUpdateReason {forecast.forecastUpdateReason} to be == Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization") - for index, slot in enumerate(forecast.slots): - logging.info( - f" [{index}] MinDuration: {slot.minDuration} MaxDuration: {slot.maxDuration} DefaultDuration: {slot.defaultDuration}") - logging.info(f" ElapseSlotTime: {slot.elapsedSlotTime} RemainingSlotTime: {slot.remainingSlotTime}") - logging.info( - f" SlotIsPausable: {slot.slotIsPausable} MinPauseDuration: {slot.minPauseDuration} MaxPauseDuration: {slot.maxPauseDuration}") - logging.info(f" ManufacturerESAState: {slot.manufacturerESAState}") - logging.info(f" NominalPower: {slot.nominalPower} MinPower: {slot.minPower} MaxPower: {slot.maxPower}") - logging.info(f" MinPowerAdjustment: {slot.minPowerAdjustment} MaxPowerAdjustment: {slot.maxPowerAdjustment}") - logging.info( - f" MinDurationAdjustment: {slot.minDurationAdjustment} MaxDurationAdjustment: {slot.maxDurationAdjustment}") - if slot.costs is not None: - for cost_index, cost in enumerate(slot): - logging.info( - f" Cost: [{cost_index}] CostType:{cost.costType} Value: {cost.value} DecimalPoints: {cost.decimalPoints} Currency: {cost.currency}") + self.print_forecast(forecast) self.step("3c") await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) @@ -333,6 +319,7 @@ async def test_TC_DEM_2_4(self): self.step("16") logging.info(f"Sleeping for forecast.slots[0].minPauseDuration {forecast.slots[0].minPauseDuration}s") time.sleep(forecast.slots[0].minPauseDuration) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Resumed) self.step("16a") await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) @@ -345,19 +332,18 @@ async def test_TC_DEM_2_4(self): self.step("17b") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - print(forecast) asserts.assert_equal(forecast.activeSlotNumber, 1) self.step("18") await self.send_pause_request_command(forecast.slots[0].minPauseDuration, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, - expected_status=Status.ConstraintError) + expected_status=Status.Failure) self.step("18a") await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) self.step("19") - await self.send_resume_request_command(expected_status=Status.Failure) + await self.send_resume_request_command(expected_status=Status.InvalidInState) self.step("20") await self.send_test_event_trigger_user_opt_out_clear_all() From 430232466f4290c122f0a5e7b2062fafe9618ade Mon Sep 17 00:00:00 2001 From: pcoleman <pcoleman@geotogether.com> Date: Thu, 11 Jul 2024 11:38:01 +0100 Subject: [PATCH 18/35] Apply review comments from James Harrow --- src/python_testing/TC_DEM_2_5.py | 7 +++-- src/python_testing/TC_DEM_2_6.py | 6 ++--- src/python_testing/TC_DEM_2_7.py | 44 +++++++++++++++----------------- src/python_testing/TC_DEM_2_9.py | 28 ++++++++++++-------- 4 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py index 55e346d74889ea..519f6b43fefa21 100644 --- a/src/python_testing/TC_DEM_2_5.py +++ b/src/python_testing/TC_DEM_2_5.py @@ -162,12 +162,12 @@ async def test_TC_DEM_2_5(self): self.step("4") slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] - await self.send_modify_forecast_request_command(forecast.forecastID + 1, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + await self.send_modify_forecast_request_command(forecast.forecastID + 1, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) self.step("5") slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( slotIndex=4, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] - await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) self.step("6") slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( @@ -192,7 +192,7 @@ async def test_TC_DEM_2_5(self): self.step("10") slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment), Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=4, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] - await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) self.step("11") await self.send_test_event_trigger_user_opt_out_local() @@ -229,7 +229,6 @@ async def test_TC_DEM_2_5(self): self.step("15") slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] -# await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) self.step("15a") diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index 5d09d7e5deecb9..1b4506f69bface 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -153,12 +153,12 @@ async def test_TC_DEM_2_6(self): self.step("4") slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] - await self.send_modify_forecast_request_command(forecast.forecastID + 1, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + await self.send_modify_forecast_request_command(forecast.forecastID + 1, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) self.step("5") slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( slotIndex=4, duration=forecast.slots[0].maxDurationAdjustment)] - await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) self.step("6") slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( @@ -173,7 +173,7 @@ async def test_TC_DEM_2_6(self): self.step("8") slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment), Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=4, duration=forecast.slots[0].maxDurationAdjustment)] - await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) self.step("9") await self.send_test_event_trigger_user_opt_out_local() diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index c57bdb633e152c..62088479857a5b 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -22,7 +22,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main, utc_time_in_matter_epoch from mobly import asserts from TC_DEMTestBase import DEMTestBase @@ -164,45 +164,41 @@ async def test_TC_DEM_2_7(self): self.step("4") # Matter UTC is time since 00:00:00 1/1/2000 - now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds( - ) - 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now - 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("5") - now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds( - ) + 20, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 20, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("6") - now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds( - ) + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("7") - now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds( - ) + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("8") - now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds( - ) + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("9") diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py index c8d8d748a8333a..42448742216484 100644 --- a/src/python_testing/TC_DEM_2_9.py +++ b/src/python_testing/TC_DEM_2_9.py @@ -81,19 +81,25 @@ async def test_TC_DEM_2_9(self): await self.send_test_event_trigger_forecast() self.step("3a") - - forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_greater_equal(len(forecast.slots), 1) - asserts.assert_is_not_none(forecast.slots[0].manufacturerESAState) + feature_map = await self.read_dem_attribute_expect_success(attribute="FeatureMap") + if feature_map & Clusters.DeviceEnergyManagement.Bitmaps.Feature.kStateForecastReporting: + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_greater_equal(len(forecast.slots), 1) + asserts.assert_is_not_none(forecast.slots[0].manufacturerESAState) + else: + logging.info('Device does not support StateForecastReporting. Skipping step 3a') self.step("3b") - forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_greater_equal(len(forecast.slots), 1) - - asserts.assert_is_not_none(forecast.slots[0].nominalPower) - asserts.assert_is_not_none(forecast.slots[0].minPower) - asserts.assert_is_not_none(forecast.slots[0].maxPower) - asserts.assert_is_not_none(forecast.slots[0].nominalEnergy) + if feature_map & Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPowerForecastReporting: + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_greater_equal(len(forecast.slots), 1) + + asserts.assert_is_not_none(forecast.slots[0].nominalPower) + asserts.assert_is_not_none(forecast.slots[0].minPower) + asserts.assert_is_not_none(forecast.slots[0].maxPower) + asserts.assert_is_not_none(forecast.slots[0].nominalEnergy) + else: + logging.info('Device does not support StateForecastReporting. Skipping step 3b') self.step("4") await self.send_test_event_trigger_forecast_clear() From 9ff0c61528fef49b23e7a9c2d195b43770ec8abb Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Thu, 11 Jul 2024 10:38:43 +0000 Subject: [PATCH 19/35] Restyled by autopep8 --- src/python_testing/TC_DEM_2_7.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 62088479857a5b..5f6583d548da56 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -166,14 +166,16 @@ async def test_TC_DEM_2_7(self): # Matter UTC is time since 00:00:00 1/1/2000 now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now - 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now - 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("5") now = int(utc_time_in_matter_epoch()/1000000) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 20, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now + 20, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) @@ -181,7 +183,8 @@ async def test_TC_DEM_2_7(self): now = int(utc_time_in_matter_epoch()/1000000) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) @@ -189,7 +192,8 @@ async def test_TC_DEM_2_7(self): now = int(utc_time_in_matter_epoch()/1000000) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) @@ -197,7 +201,8 @@ async def test_TC_DEM_2_7(self): now = int(utc_time_in_matter_epoch()/1000000) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) From f66efd93fd8103fd245d083f1ef2d333ca12fd51 Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Thu, 11 Jul 2024 10:38:44 +0000 Subject: [PATCH 20/35] Restyled by isort --- src/python_testing/TC_DEM_2_7.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 5f6583d548da56..090f9dc77f1747 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -22,7 +22,8 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main, utc_time_in_matter_epoch +from matter_testing_support import (EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main, + utc_time_in_matter_epoch) from mobly import asserts from TC_DEMTestBase import DEMTestBase From 48bd1cbd02d70470a4a4c6a444bc4936ffe36b36 Mon Sep 17 00:00:00 2001 From: pcoleman <pcoleman@geotogether.com> Date: Thu, 11 Jul 2024 11:48:59 +0100 Subject: [PATCH 21/35] Apply review comments from James Harrow --- src/python_testing/TC_DEM_2_7.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 090f9dc77f1747..86256db4cc9cb3 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -201,10 +201,12 @@ async def test_TC_DEM_2_7(self): self.step("8") now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=now + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, + duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, + duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, + duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("9") From 4b579fea93ba105f36e58f5d369c38e62be4f6fa Mon Sep 17 00:00:00 2001 From: pcoleman <pcoleman@geotogether.com> Date: Thu, 11 Jul 2024 12:10:32 +0100 Subject: [PATCH 22/35] Fix python lint error --- src/python_testing/TC_DEM_2_7.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 86256db4cc9cb3..4a642285089004 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -17,7 +17,6 @@ """Define Matter test case TC_DEM_2_7.""" -import datetime import logging import chip.clusters as Clusters From 36487520fadfa6e2e78c22d14e14b436f1b9a8b6 Mon Sep 17 00:00:00 2001 From: pcoleman <pcoleman@geotogether.com> Date: Thu, 11 Jul 2024 13:24:37 +0100 Subject: [PATCH 23/35] Apply review comments from James Harrow --- src/python_testing/TC_DEM_2_7.py | 46 ++++++++++++++++------------- src/python_testing/TC_DEM_2_8.py | 50 ++++++++++++++------------------ 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 4a642285089004..487eecc86fbc4d 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -166,46 +166,52 @@ async def test_TC_DEM_2_7(self): # Matter UTC is time since 00:00:00 1/1/2000 now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=now - 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now - 10, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("5") now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=now + 20, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 20, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("6") now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("7") now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("8") now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, - duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, - duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, - duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("9") diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index 92cdf3ca8644dc..e220f674b5b5bd 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -17,12 +17,12 @@ """Define Matter test case TC_DEM_2_8.""" -import datetime import logging import chip.clusters as Clusters from chip.interaction_model import Status -from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from matter_testing_support import (EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main, + utc_time_in_matter_epoch) from mobly import asserts from TC_DEMTestBase import DEMTestBase @@ -152,58 +152,52 @@ async def test_TC_DEM_2_8(self): self.step("4") # Matter UTC is time since 00:00:00 1/1/2000 - now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + now = int(utc_time_in_matter_epoch()/1000000) constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=now.total_seconds() - 10, duration=20, loadControl=0)] + startTime=now - 10, duration=20, loadControl=0)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("5") # Matter UTC is time since 00:00:00 1/1/2000 - now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=now.total_seconds() + 20, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, loadControl=0)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 20, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, loadControl=0)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("6") # Matter UTC is time since 00:00:00 1/1/2000 - now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=now.total_seconds() + 30, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 40, duration=20, loadControl=0)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, loadControl=0)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("7") - now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=now.total_seconds() + 10, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 50, duration=20, loadControl=0)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, loadControl=0)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("8") - now = datetime.datetime.now(tz=datetime.timezone.utc) - datetime.datetime(2000, 1, 1, 0, 0, 0, 0, datetime.timezone.utc) + now = int(utc_time_in_matter_epoch()/1000000) - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 10, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=now.total_seconds() + 50, duration=20, loadControl=0), - Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now.total_seconds() + 30, duration=20, loadControl=0)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, loadControl=0)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("9") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=101)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=101)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("10") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( - startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=-101)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=-101)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("11") From e062c5542f0500302817135a7d560fc8153fa90f Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Thu, 11 Jul 2024 12:25:15 +0000 Subject: [PATCH 24/35] Restyled by autopep8 --- src/python_testing/TC_DEM_2_8.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index e220f674b5b5bd..e71b028dee5688 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -193,11 +193,13 @@ async def test_TC_DEM_2_8(self): await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("9") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=101)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=101)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("10") - constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=-101)] + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=-101)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("11") From d85388ba535f75114e2887238368080de9cf9522 Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Wed, 17 Jul 2024 17:56:35 +0100 Subject: [PATCH 25/35] Added # === BEGIN CI TEST ARGUMENTS banners to TC_DEM python scripts --- src/python_testing/TC_DEM_2_2.py | 13 +++++++++++++ src/python_testing/TC_DEM_2_3.py | 11 +++++++++++ src/python_testing/TC_DEM_2_4.py | 11 +++++++++++ src/python_testing/TC_DEM_2_5.py | 13 +++++++++++++ src/python_testing/TC_DEM_2_6.py | 13 +++++++++++++ src/python_testing/TC_DEM_2_7.py | 13 +++++++++++++ src/python_testing/TC_DEM_2_8.py | 13 +++++++++++++ src/python_testing/TC_DEM_2_9.py | 13 +++++++++++++ 8 files changed, 100 insertions(+) diff --git a/src/python_testing/TC_DEM_2_2.py b/src/python_testing/TC_DEM_2_2.py index e14cdff812f44d..050c9f900cafd2 100644 --- a/src/python_testing/TC_DEM_2_2.py +++ b/src/python_testing/TC_DEM_2_2.py @@ -14,6 +14,19 @@ # 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 +# 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_2_2.""" diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py index 59caf8eb7ab34c..7bfaae4d7d747b 100644 --- a/src/python_testing/TC_DEM_2_3.py +++ b/src/python_testing/TC_DEM_2_3.py @@ -14,6 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# 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 +# 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 === import logging diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py index c43d82dd41c06d..6b818136f2fc20 100644 --- a/src/python_testing/TC_DEM_2_4.py +++ b/src/python_testing/TC_DEM_2_4.py @@ -14,6 +14,17 @@ # See the License for the specific language governing permissions and # limitations under the License. +# 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 +# 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 === import logging import time diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py index 519f6b43fefa21..a4c8af694dc698 100644 --- a/src/python_testing/TC_DEM_2_5.py +++ b/src/python_testing/TC_DEM_2_5.py @@ -14,6 +14,19 @@ # 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 +# 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_2_5.""" diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index 1b4506f69bface..5c581d7f856f75 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -14,6 +14,19 @@ # 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 +# 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_2_6.""" diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 487eecc86fbc4d..5f54682853e2d1 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -14,6 +14,19 @@ # 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 +# 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_2_7.""" diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index e71b028dee5688..b09df1e525eefe 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -14,6 +14,19 @@ # 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 +# 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_2_8.""" diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py index 42448742216484..00f9d23df12268 100644 --- a/src/python_testing/TC_DEM_2_9.py +++ b/src/python_testing/TC_DEM_2_9.py @@ -14,6 +14,19 @@ # 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 +# 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_2_9.""" From fe9443c474079e5861570d25a3c3364e0c3284eb Mon Sep 17 00:00:00 2001 From: pcoleman <pcoleman@geotogether.com> Date: Thu, 18 Jul 2024 17:05:48 +0100 Subject: [PATCH 26/35] Specify --featureSet option on runner command line --- src/python_testing/TC_DEM_2_2.py | 2 +- src/python_testing/TC_DEM_2_3.py | 2 +- src/python_testing/TC_DEM_2_4.py | 2 +- src/python_testing/TC_DEM_2_5.py | 2 +- src/python_testing/TC_DEM_2_6.py | 2 +- src/python_testing/TC_DEM_2_7.py | 2 +- src/python_testing/TC_DEM_2_8.py | 2 +- src/python_testing/TC_DEM_2_9.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/python_testing/TC_DEM_2_2.py b/src/python_testing/TC_DEM_2_2.py index 050c9f900cafd2..dc81cbcc0aa9d2 100644 --- a/src/python_testing/TC_DEM_2_2.py +++ b/src/python_testing/TC_DEM_2_2.py @@ -23,7 +23,7 @@ # 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 +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x01 # 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 === diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py index 7bfaae4d7d747b..9178d7a1e87957 100644 --- a/src/python_testing/TC_DEM_2_3.py +++ b/src/python_testing/TC_DEM_2_3.py @@ -22,7 +22,7 @@ # 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 +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7a # 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 === diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py index 6b818136f2fc20..142b287d962602 100644 --- a/src/python_testing/TC_DEM_2_4.py +++ b/src/python_testing/TC_DEM_2_4.py @@ -22,7 +22,7 @@ # 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 +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7a # 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 === diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py index a4c8af694dc698..7de29c46f1864e 100644 --- a/src/python_testing/TC_DEM_2_5.py +++ b/src/python_testing/TC_DEM_2_5.py @@ -23,7 +23,7 @@ # 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 +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7a # 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 === diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index 5c581d7f856f75..9bfc6240d57791 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -23,7 +23,7 @@ # 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 +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7c # 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 === diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 5f54682853e2d1..77b8bc5e9fecc5 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -23,7 +23,7 @@ # 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 +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7a # 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 === diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index b09df1e525eefe..ab731eb00d84ea 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -23,7 +23,7 @@ # 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 +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7c # 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 === diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py index 00f9d23df12268..8f3a2199c2d568 100644 --- a/src/python_testing/TC_DEM_2_9.py +++ b/src/python_testing/TC_DEM_2_9.py @@ -23,7 +23,7 @@ # 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 +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7e # 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 === From b41cb77ed9d39a649935eeb19889bc43c6e5217b Mon Sep 17 00:00:00 2001 From: pcoleman <pcoleman@geotogether.com> Date: Wed, 24 Jul 2024 08:25:36 +0100 Subject: [PATCH 27/35] Address review comments from Rob Bultman --- src/python_testing/TC_DEMTestBase.py | 5 +++++ src/python_testing/TC_DEM_2_2.py | 11 ++++------- src/python_testing/TC_DEM_2_3.py | 17 ++++++++--------- src/python_testing/TC_DEM_2_4.py | 16 ++++++++-------- src/python_testing/TC_DEM_2_5.py | 2 -- src/python_testing/TC_DEM_2_7.py | 13 ++++++------- src/python_testing/TC_DEM_2_8.py | 13 ++++++------- src/python_testing/TC_DEM_2_9.py | 2 -- 8 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/python_testing/TC_DEMTestBase.py b/src/python_testing/TC_DEMTestBase.py index dc615a82c0a670..a9965f1e362aa9 100644 --- a/src/python_testing/TC_DEMTestBase.py +++ b/src/python_testing/TC_DEMTestBase.py @@ -20,6 +20,7 @@ import chip.clusters as Clusters from chip.interaction_model import InteractionModelError, Status from mobly import asserts +from matter_testing_support import utc_time_in_matter_epoch logger = logging.getLogger(__name__) @@ -185,6 +186,10 @@ def print_forecast(self, forecast): logging.info( f" Cost: [{cost_index}] CostType:{cost.costType} Value: {cost.value} DecimalPoints: {cost.decimalPoints} Currency: {cost.currency}") + def get_current_utc_time_in_seconds(self): + microseconds_in_second = 1000000 + return int(utc_time_in_matter_epoch()/microseconds_in_second) + async def send_test_event_trigger_power_adjustment(self): await self.send_test_event_triggers(eventTrigger=0x0098000000000000) diff --git a/src/python_testing/TC_DEM_2_2.py b/src/python_testing/TC_DEM_2_2.py index dc81cbcc0aa9d2..0c32992d934174 100644 --- a/src/python_testing/TC_DEM_2_2.py +++ b/src/python_testing/TC_DEM_2_2.py @@ -196,7 +196,7 @@ async def test_TC_DEM_2_2(self): await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) self.step("4") - await self.send_power_adjustment_command(power=max_power, + await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxPower, duration=powerAdjustCapabilityStruct.powerAdjustCapability[0].minDuration, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) @@ -218,7 +218,6 @@ async def test_TC_DEM_2_2(self): self.step("5a") powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") - asserts.assert_greater_equal(len(powerAdjustCapabilityStruct.powerAdjustCapability), 1) asserts.assert_equal(powerAdjustCapabilityStruct.cause, Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kNoAdjustment) @@ -254,7 +253,7 @@ async def test_TC_DEM_2_2(self): self.step("11") start = datetime.datetime.now() - await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxPower, + await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].minPower, duration=min_duration, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) @@ -262,13 +261,12 @@ async def test_TC_DEM_2_2(self): self.step("11a") powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") - asserts.assert_greater_equal(len(powerAdjustCapabilityStruct.powerAdjustCapability), 1) asserts.assert_equal(powerAdjustCapabilityStruct.cause, Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kLocalOptimizationAdjustment) self.step("12") await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxPower, - duration=min_duration, + duration=powerAdjustCapabilityStruct.powerAdjustCapability[0].minDuration, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization) # Wait 5 seconds for an event not to be reported @@ -279,7 +277,6 @@ async def test_TC_DEM_2_2(self): self.step("12b") powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") - asserts.assert_greater_equal(len(powerAdjustCapabilityStruct.powerAdjustCapability), 1) asserts.assert_equal(powerAdjustCapabilityStruct.cause, Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kGridOptimizationAdjustment) @@ -294,7 +291,7 @@ async def test_TC_DEM_2_2(self): self.step("14") await self.send_power_adjustment_command(power=max_power, - duration=max_duration, + duration=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxDuration, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py index 9178d7a1e87957..6bdd81c710a914 100644 --- a/src/python_testing/TC_DEM_2_3.py +++ b/src/python_testing/TC_DEM_2_3.py @@ -157,15 +157,14 @@ async def test_TC_DEM_2_3(self): forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") asserts.assert_not_equal(forecast, NullValue) - if forecast is not NullValue: - asserts.assert_less_equal(forecast.earliestStartTime, forecast.startTime, - f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") - asserts.assert_greater_equal(forecast.latestEndTime, forecast.endTime, - f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, - f"Expected forecast forecastUpdateReason {forecast.forecastUpdateReason} to be == Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization") - - self.print_forecast(forecast) + asserts.assert_less_equal(forecast.earliestStartTime, forecast.startTime, + f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") + asserts.assert_greater_equal(forecast.latestEndTime, forecast.endTime, + f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, + f"Expected forecast forecastUpdateReason {forecast.forecastUpdateReason} to be == Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization") + + self.print_forecast(forecast) self.step("3c") await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py index 142b287d962602..94311b6c94f0d2 100644 --- a/src/python_testing/TC_DEM_2_4.py +++ b/src/python_testing/TC_DEM_2_4.py @@ -185,14 +185,13 @@ async def test_TC_DEM_2_4(self): asserts.assert_equal(forecast.slots[1].slotIsPausable, False) asserts.assert_equal(forecast.activeSlotNumber, 0) - if forecast is not NullValue: - asserts.assert_less_equal(forecast.earliestStartTime, forecast.startTime, - f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") - asserts.assert_greater_equal(forecast.latestEndTime, forecast.endTime, - f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") - asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, - f"Expected forecast forecastUpdateReason {forecast.forecastUpdateReason} to be == Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization") - self.print_forecast(forecast) + asserts.assert_less_equal(forecast.earliestStartTime, forecast.startTime, + f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") + asserts.assert_greater_equal(forecast.latestEndTime, forecast.endTime, + f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, + f"Expected forecast forecastUpdateReason {forecast.forecastUpdateReason} to be == Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization") + self.print_forecast(forecast) self.step("3c") await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) @@ -331,6 +330,7 @@ async def test_TC_DEM_2_4(self): logging.info(f"Sleeping for forecast.slots[0].minPauseDuration {forecast.slots[0].minPauseDuration}s") time.sleep(forecast.slots[0].minPauseDuration) event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Resumed) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kNormalCompletion) self.step("16a") await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py index 7de29c46f1864e..1ee99c20f76f70 100644 --- a/src/python_testing/TC_DEM_2_5.py +++ b/src/python_testing/TC_DEM_2_5.py @@ -162,8 +162,6 @@ async def test_TC_DEM_2_5(self): self.step("3b") forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_greater_equal(len(forecast.slots), 2) - asserts.assert_is_not_none(forecast.slots[0].minPowerAdjustment) asserts.assert_is_not_none(forecast.slots[0].maxPowerAdjustment) asserts.assert_is_not_none(forecast.slots[0].minDurationAdjustment) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 77b8bc5e9fecc5..33352fc0cc8527 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -34,8 +34,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from matter_testing_support import (EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main, - utc_time_in_matter_epoch) +from matter_testing_support import (EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main) from mobly import asserts from TC_DEMTestBase import DEMTestBase @@ -177,14 +176,14 @@ async def test_TC_DEM_2_7(self): self.step("4") # Matter UTC is time since 00:00:00 1/1/2000 - now = int(utc_time_in_matter_epoch()/1000000) + now = self.get_current_utc_time_in_seconds() constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now - 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("5") - now = int(utc_time_in_matter_epoch()/1000000) + now = self.get_current_utc_time_in_seconds() constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), @@ -195,7 +194,7 @@ async def test_TC_DEM_2_7(self): await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("6") - now = int(utc_time_in_matter_epoch()/1000000) + now = self.get_current_utc_time_in_seconds() constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), @@ -206,7 +205,7 @@ async def test_TC_DEM_2_7(self): await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("7") - now = int(utc_time_in_matter_epoch()/1000000) + now = self.get_current_utc_time_in_seconds() constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), @@ -217,7 +216,7 @@ async def test_TC_DEM_2_7(self): await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("8") - now = int(utc_time_in_matter_epoch()/1000000) + now = self.get_current_utc_time_in_seconds() constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index ab731eb00d84ea..60a32c97443a99 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -34,8 +34,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from matter_testing_support import (EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main, - utc_time_in_matter_epoch) +from matter_testing_support import (EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main) from mobly import asserts from TC_DEMTestBase import DEMTestBase @@ -165,7 +164,7 @@ async def test_TC_DEM_2_8(self): self.step("4") # Matter UTC is time since 00:00:00 1/1/2000 - now = int(utc_time_in_matter_epoch()/1000000) + now = self.get_current_utc_time_in_seconds() constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( startTime=now - 10, duration=20, loadControl=0)] @@ -173,7 +172,7 @@ async def test_TC_DEM_2_8(self): self.step("5") # Matter UTC is time since 00:00:00 1/1/2000 - now = int(utc_time_in_matter_epoch()/1000000) + now = self.get_current_utc_time_in_seconds() constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 20, duration=20, loadControl=0), @@ -182,7 +181,7 @@ async def test_TC_DEM_2_8(self): self.step("6") # Matter UTC is time since 00:00:00 1/1/2000 - now = int(utc_time_in_matter_epoch()/1000000) + now = self.get_current_utc_time_in_seconds() constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, loadControl=0), @@ -190,7 +189,7 @@ async def test_TC_DEM_2_8(self): await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("7") - now = int(utc_time_in_matter_epoch()/1000000) + now = self.get_current_utc_time_in_seconds() constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, loadControl=0), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), @@ -198,7 +197,7 @@ async def test_TC_DEM_2_8(self): await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) self.step("8") - now = int(utc_time_in_matter_epoch()/1000000) + now = self.get_current_utc_time_in_seconds() constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, loadControl=0), diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py index 8f3a2199c2d568..d8bb9a587ea388 100644 --- a/src/python_testing/TC_DEM_2_9.py +++ b/src/python_testing/TC_DEM_2_9.py @@ -97,7 +97,6 @@ async def test_TC_DEM_2_9(self): feature_map = await self.read_dem_attribute_expect_success(attribute="FeatureMap") if feature_map & Clusters.DeviceEnergyManagement.Bitmaps.Feature.kStateForecastReporting: forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_greater_equal(len(forecast.slots), 1) asserts.assert_is_not_none(forecast.slots[0].manufacturerESAState) else: logging.info('Device does not support StateForecastReporting. Skipping step 3a') @@ -105,7 +104,6 @@ async def test_TC_DEM_2_9(self): self.step("3b") if feature_map & Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPowerForecastReporting: forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") - asserts.assert_greater_equal(len(forecast.slots), 1) asserts.assert_is_not_none(forecast.slots[0].nominalPower) asserts.assert_is_not_none(forecast.slots[0].minPower) From f2ed34fc2dd86d166bb9711aaa1f84f8b72127bd Mon Sep 17 00:00:00 2001 From: pcoleman <pcoleman@geotogether.com> Date: Wed, 24 Jul 2024 08:46:25 +0100 Subject: [PATCH 28/35] Address review comments from Rob Bultman --- src/python_testing/TC_DEM_2_4.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py index 94311b6c94f0d2..390889fc9f2d28 100644 --- a/src/python_testing/TC_DEM_2_4.py +++ b/src/python_testing/TC_DEM_2_4.py @@ -295,7 +295,7 @@ async def test_TC_DEM_2_4(self): asserts.assert_equal(forecast.slots[1].slotIsPausable, False) asserts.assert_equal(forecast.activeSlotNumber, 0) asserts.assert_equal(forecast.forecastUpdateReason, - Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) self.step("13") await self.send_pause_request_command(forecast.slots[0].minPauseDuration, From ac24f5c92064d733d0532fc21dda7381de91f7ae Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Wed, 24 Jul 2024 07:46:54 +0000 Subject: [PATCH 29/35] Restyled by isort --- src/python_testing/TC_DEMTestBase.py | 2 +- src/python_testing/TC_DEM_2_7.py | 2 +- src/python_testing/TC_DEM_2_8.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python_testing/TC_DEMTestBase.py b/src/python_testing/TC_DEMTestBase.py index a9965f1e362aa9..db53c36f8cd1c9 100644 --- a/src/python_testing/TC_DEMTestBase.py +++ b/src/python_testing/TC_DEMTestBase.py @@ -19,8 +19,8 @@ import chip.clusters as Clusters from chip.interaction_model import InteractionModelError, Status -from mobly import asserts from matter_testing_support import utc_time_in_matter_epoch +from mobly import asserts logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index 33352fc0cc8527..ddcc7540abb53e 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -34,7 +34,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from matter_testing_support import (EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main) +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts from TC_DEMTestBase import DEMTestBase diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index 60a32c97443a99..5fe869cfdc3908 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -34,7 +34,7 @@ import chip.clusters as Clusters from chip.interaction_model import Status -from matter_testing_support import (EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main) +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main from mobly import asserts from TC_DEMTestBase import DEMTestBase From 45072a25d1df3dbe19690a46b20b93c587151237 Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Thu, 25 Jul 2024 23:40:48 +0100 Subject: [PATCH 30/35] Update src/python_testing/TC_DEM_2_5.py Co-authored-by: Carolina Lopes <116589288+ccruzagralopes@users.noreply.github.com> --- src/python_testing/TC_DEM_2_5.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py index 1ee99c20f76f70..85d3cd779b22f4 100644 --- a/src/python_testing/TC_DEM_2_5.py +++ b/src/python_testing/TC_DEM_2_5.py @@ -52,7 +52,7 @@ def pics_TC_DEM_2_5(self): """Return the PICS definitions associated with this test.""" pics = [ # Depends on Feature 05 (ForecastAdjustment) & Feature 01 (PowerForecastReporting) - "DEM.S.F05 & DEM.S.F01" + "DEM.S.F05", "DEM.S.F01" ] return pics From bb59a7b2ca4478b36de8a332074b2fcef7cc4a7d Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Thu, 25 Jul 2024 23:42:22 +0100 Subject: [PATCH 31/35] Update TC_DEM_2_6.py - changed PICS conformance to comma separated list --- src/python_testing/TC_DEM_2_6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py index 9bfc6240d57791..7390436effd937 100644 --- a/src/python_testing/TC_DEM_2_6.py +++ b/src/python_testing/TC_DEM_2_6.py @@ -52,7 +52,7 @@ def pics_TC_DEM_2_6(self): """Return the PICS definitions associated with this test.""" pics = [ # Depends on Feature 05 (ForecastAdjustment) & Feature 02 (StateForecastReporting) - "DEM.S.F05 & DEM.S.F02" + "DEM.S.F05", "DEM.S.F02" ] return pics From def5fb29a7d948ec13d3ff008eb0fba822c73ae0 Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Thu, 25 Jul 2024 23:42:53 +0100 Subject: [PATCH 32/35] Update TC_DEM_2_7.py - changed PICS conformance to comma separated list --- src/python_testing/TC_DEM_2_7.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py index ddcc7540abb53e..fa7dba14a53315 100644 --- a/src/python_testing/TC_DEM_2_7.py +++ b/src/python_testing/TC_DEM_2_7.py @@ -52,7 +52,7 @@ def pics_TC_DEM_2_7(self): """Return the PICS definitions associated with this test.""" pics = [ # Depends on Feature 06 (ConstraintBasedAdjustment) & Feature 01 (PowerForecastReporting) - "DEM.S.F06 & DEM.S.F01" + "DEM.S.F06", "DEM.S.F01" ] return pics From 58ecac3cb22931d1cc949c600cc2f8c18e678d4b Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Thu, 25 Jul 2024 23:43:50 +0100 Subject: [PATCH 33/35] Update TC_DEM_2_9.py - changed PICS conformance to comma separated list --- src/python_testing/TC_DEM_2_9.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py index d8bb9a587ea388..8e60b69b481d93 100644 --- a/src/python_testing/TC_DEM_2_9.py +++ b/src/python_testing/TC_DEM_2_9.py @@ -51,7 +51,7 @@ def pics_TC_DEM_2_9(self): """Return the PICS definitions associated with this test.""" pics = [ # Depends on Feature 01 (PowerForecastReporting) | Feature 2 (StateForecastReporting) - "DEM.S.F01 | DEM.S.F02", + "DEM.S.F01", "DEM.S.F02", ] return pics From b1333573c36f5334cae1b01b13a5785245f1a17e Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Thu, 25 Jul 2024 23:44:41 +0100 Subject: [PATCH 34/35] Update TC_DEM_2_8.py - changed PICS conformance to comma separated list --- src/python_testing/TC_DEM_2_8.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py index 5fe869cfdc3908..773648c7e3ba8e 100644 --- a/src/python_testing/TC_DEM_2_8.py +++ b/src/python_testing/TC_DEM_2_8.py @@ -52,7 +52,7 @@ def pics_TC_DEM_2_8(self): """Return the PICS definitions associated with this test.""" pics = [ # Depends on Feature 06 (ConstraintBasedAdjustment) & Feature 02 (StateForecastReporting) - "DEM.S.F06 & DEM.S.F02" + "DEM.S.F06", "DEM.S.F02" ] return pics From 7332dac602d6f2da6cb884fbb774f09539abe459 Mon Sep 17 00:00:00 2001 From: James Harrow <james.harrow@gmail.com> Date: Fri, 26 Jul 2024 05:54:32 +0100 Subject: [PATCH 35/35] Enabled DEM Test scripts as part of CI --- .github/workflows/tests.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 554ee752ff2a08..50934c2899f603 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -512,6 +512,14 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DRLK_2_3.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DeviceBasicComposition.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DeviceConformance.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DEM_2_2.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DEM_2_3.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DEM_2_4.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DEM_2_5.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DEM_2_6.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DEM_2_7.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DEM_2_8.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_DEM_2_9.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_EEM_2_1.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_EEM_2_2.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_EEM_2_3.py'