From f9dfb283614570be1f3635c6a7ec98b501cb7adf Mon Sep 17 00:00:00 2001 From: pcoleman Date: Mon, 15 Jul 2024 20:50:12 +0100 Subject: [PATCH] Add water heater management test scripts --- src/python_testing/EWATERHTRBase.py | 94 ++++++++ src/python_testing/TC_EWATERHTR_2_1.py | 78 +++++++ src/python_testing/TC_EWATERHTR_2_2.py | 299 +++++++++++++++++++++++++ src/python_testing/TC_EWATERHTR_2_3.py | 229 +++++++++++++++++++ 4 files changed, 700 insertions(+) create mode 100644 src/python_testing/EWATERHTRBase.py create mode 100644 src/python_testing/TC_EWATERHTR_2_1.py create mode 100644 src/python_testing/TC_EWATERHTR_2_2.py create mode 100644 src/python_testing/TC_EWATERHTR_2_3.py diff --git a/src/python_testing/EWATERHTRBase.py b/src/python_testing/EWATERHTRBase.py new file mode 100644 index 00000000000000..1a31ba7337913e --- /dev/null +++ b/src/python_testing/EWATERHTRBase.py @@ -0,0 +1,94 @@ +# +# 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 typing + +import chip.clusters as Clusters +from chip.interaction_model import InteractionModelError, Status +from mobly import asserts + +logger = logging.getLogger(__name__) + + +class EWATERHTRBase: + + async def read_whm_attribute_expect_success(self, endpoint: int = None, attribute: str = ""): + cluster = Clusters.Objects.WaterHeaterManagement + full_attr = getattr(cluster.Attributes, attribute) + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=full_attr) + + async def check_whm_attribute(self, attribute, expected_value, endpoint: int = None): + value = await self.read_whm_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_boost_command(self, duration: int, one_shot: typing.Optional[bool] = None, emergency_boost: typing.Optional[bool] = None, + temporary_setpoint: typing.Optional[int] = None, target_percentage: typing.Optional[int] = None, target_reheat: typing.Optional[int] = None, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.WaterHeaterManagement.Commands.Boost( + duration=duration, + oneShot=one_shot, + emergencyBoost=emergency_boost, + temporarySetpoint=temporary_setpoint, + targetPercentage=target_percentage, + targetReheat=target_reheat), + 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_boost_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.WaterHeaterManagement.Commands.CancelBoost(), + 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_basic_installation_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000000) + + async def send_test_event_trigger_basic_installation_test_event_clear(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000001) + + async def send_test_event_trigger_water_temperature20C_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000002) + + async def send_test_event_trigger_water_temperature61C_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000003) + + async def send_test_event_trigger_water_temperature66C_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000004) + + async def send_test_event_trigger_manual_mode_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000005) + + async def send_test_event_trigger_off_mode_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000006) + + async def send_test_event_trigger_draw_off_hot_water_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000007) diff --git a/src/python_testing/TC_EWATERHTR_2_1.py b/src/python_testing/TC_EWATERHTR_2_1.py new file mode 100644 index 00000000000000..6fbdb18b6e8669 --- /dev/null +++ b/src/python_testing/TC_EWATERHTR_2_1.py @@ -0,0 +1,78 @@ +# +# 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 EWATERHTRBase import EWATERHTRBase +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main + +logger = logging.getLogger(__name__) + + +class TC_EWATERHTR_2_1(MatterBaseTest, EWATERHTRBase): + + def desc_TC_EWATERHTR_2_1(self) -> str: + """Returns a description of this test""" + return "[TC-EWATERHTR-2.1] Attributes with attributes with DUT as Server\n" \ + "This test case verifies the non-global attributes of the Water Heater Management cluster server." + + def pics_TC_EWATERHTR_2_1(self): + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + return ["EWATERHTR.S", "EWATERHTR.S.F00", "EWATERHTR.S.F01"] + + def steps_TC_EWATERHTR_2_1(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2a", "TH reads HeaterTypes attribute. DUT as Server replies with a WaterHeaterTypeBitmap (enum8) value to match the DUT type."), + TestStep("2b", "TH reads HeatDemand attribute. DUT as Server replies with a WaterHeaterDemandBitmap (enum8)."), + TestStep("2c", "TH reads TankVolume attribute. DUT as Server replies with a uint16 value."), + TestStep("2d", "TH reads EstimatedHeatRequired attribute. DUT as Server replies with an energy-mWh value."), + TestStep("2e", "TH reads TankPercentage attribute. DUT as Server replies with a percent value."), + TestStep("2f", "TH reads BoostState attribute. DUT as Server replies with a BoostStateEnum (enum8) value."), + ] + + return steps + + @async_test_body + async def test_TC_EWATERHTR_2_1(self): + + self.step("1") + # Commission DUT - already done + + # Note the values used here are configured in WhmManufacturer::Init() + self.step("2a") + await self.check_whm_attribute("HeaterTypes", 0) + + self.step("2b") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("2c") + await self.check_whm_attribute("TankVolume", 0) + + self.step("2d") + await self.check_whm_attribute("EstimatedHeatRequired", 0) + + self.step("2e") + await self.check_whm_attribute("TankPercentage", 0) + + self.step("2f") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_EWATERHTR_2_2.py b/src/python_testing/TC_EWATERHTR_2_2.py new file mode 100644 index 00000000000000..e27929fe365584 --- /dev/null +++ b/src/python_testing/TC_EWATERHTR_2_2.py @@ -0,0 +1,299 @@ +# +# 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 time + +import chip.clusters as Clusters +from EWATERHTRBase import EWATERHTRBase +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) + + +class TC_EWATERHTR_2_2(MatterBaseTest, EWATERHTRBase): + + def desc_TC_EWATERHTR_2_2(self) -> str: + """Returns a description of this test""" + return "[TC-EWATERHTR-2.2] Basic functionality with attributes with DUT as Server\n" \ + "This test case verifies the primary functionality of the Water Heater Management cluster server." + + def pics_TC_EWATERHTR_2_2(self): + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + return ["EWATERHTR.S"] + + def steps_TC_EWATERHTR_2_2(self) -> list[TestStep]: + 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.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Basic installation Test Event. Verify Command response is Success"), + TestStep("3a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("3b", "TH reads BoostState attribute. Verify value is 0 (Inactive)"), + TestStep( + "3c", "TH reads HeaterTypes attribute. Verify value is greater than 0x00 (at least one type supported) and {storeValueAs} HeaterTypes"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Manual mode Test Event. Verify Command response is Success"), + TestStep("4a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("5", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event. Verify Command response is Success"), + TestStep("5a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 20C Test Event. Verify Command response is Success"), + TestStep("6a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source)"), + TestStep("7", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Off mode Test Event. Verify Command response is Success"), + TestStep("7a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("8", "TH sends Boost with Duration=5s,OneShot=True. Verify Command response is Success"), + TestStep("8a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("8b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("9", "Wait 6 seconds"), + TestStep("9a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("9b", "TH reads BoostState attribute. Verify value is 0 (Inactive)"), + TestStep("10", "TH sends Boost with Duration=600s,OneShot=True. Verify Command response is Success"), + TestStep("10a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("10b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event. Verify Command response is Success"), + TestStep("11a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("11b", "TH reads BoostState attribute. Verify value is 0 (Inactive)"), + TestStep("12", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 20C Test Event. Verify Command response is Success"), + TestStep("12a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("13", "TH sends Boost with Duration=600s. Verify Command response is Success"), + TestStep("13a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("13b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event. Verify Command response is Success"), + TestStep("14a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("14b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("15", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 20C Test Event. Verify Command response is Success"), + TestStep("15a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("15b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("16", "TH sends CancelBoost. Verify Command response is Success"), + TestStep("16a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("16b", "TH reads BoostState attribute. Verify value is 0 (Inactive)"), + TestStep("17", "TH sends Boost with Duration=600s,TemporarySetpoint=65C. Verify Command response is Success"), + TestStep("17a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("17b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event. Verify Command response is Success"), + TestStep("18a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("18b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 66C Test Event. Verify Command response is Success"), + TestStep("19a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("19b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("20", "TH sends Boost with Duration=600s,TemporarySetpoint=70C. Verify Command response is Success"), + TestStep("20a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("20b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("21", "TH sends CancelBoost. Verify Command response is Success"), + TestStep("21a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("21b", "TH reads BoostState attribute. Verify value is 0 (Inactive)"), + TestStep("22", "TH sends CancelBoost. Verify Command response is Success"), + TestStep("23", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Basic installation Test Event Clear. Verify Command response is Success"), + ] + + return steps + + @async_test_body + async def test_TC_EWATERHTR_2_2(self): + + self.step("1") + # Commission DUT - already done + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_basic_installation_test_event() + + self.step("3a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("3b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("3c") + heaterTypes = await self.read_whm_attribute_expect_success(attribute="HeaterTypes") + asserts.assert_equal(heaterTypes, Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterTypeBitmap.kImmersionElement1) + + self.step("4") + await self.send_test_event_trigger_manual_mode_test_event() + + self.step("4a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("5") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("5a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("6") + await self.send_test_event_trigger_water_temperature20C_test_event() + + self.step("6a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("7") + await self.send_test_event_trigger_off_mode_test_event() + + self.step("7a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("8") + await self.send_boost_command(duration=5, one_shot=True) + + self.step("8a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("8b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("9") + time.sleep(6) + + self.step("9a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("9b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("10") + await self.send_boost_command(duration=600, one_shot=True) + + self.step("10a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("10b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("11") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("11a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("11b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("12") + await self.send_test_event_trigger_water_temperature20C_test_event() + + self.step("12a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("13") + await self.send_boost_command(duration=600) + + self.step("13a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("13b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("14") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("14a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("14b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("15") + await self.send_test_event_trigger_water_temperature20C_test_event() + + self.step("15a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("15b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("16") + await self.send_cancel_boost_command() + + self.step("16a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("16b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("17") + await self.send_boost_command(duration=600, temporary_setpoint=6500) + + self.step("17a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("17b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("18") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("18a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("18b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("19") + await self.send_test_event_trigger_water_temperature66C_test_event() + + self.step("19a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("19b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("20") + await self.send_boost_command(duration=600, temporary_setpoint=7000) + + self.step("20a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("20b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("21") + await self.send_cancel_boost_command() + + self.step("21a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("21b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("22") + await self.send_cancel_boost_command() + + self.step("23") + await self.send_test_event_trigger_basic_installation_test_event_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_EWATERHTR_2_3.py b/src/python_testing/TC_EWATERHTR_2_3.py new file mode 100644 index 00000000000000..61bab0118918c8 --- /dev/null +++ b/src/python_testing/TC_EWATERHTR_2_3.py @@ -0,0 +1,229 @@ +# +# 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 EWATERHTRBase import EWATERHTRBase +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) + + +class TC_EWATERHTR_2_3(MatterBaseTest, EWATERHTRBase): + + def desc_TC_EWATERHTR_2_3(self) -> str: + """Returns a description of this test""" + return "[TC-EWATERHTR-2.3] Attributes with attributes with DUT as Server\n" \ + "This test case verifies the functionality of the Water Heater Management cluster server with the TankPercentage feature." + + def pics_TC_EWATERHTR_2_3(self): + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + return ["EWATERHTR.S", "EWATERHTR.S.F01"] + + def steps_TC_EWATERHTR_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 value is 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Basic installation Test Event. Verify Command response is Success"), + TestStep("3a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("3b", "TH reads BoostState attribute. Verify value is 0 (Inactive)"), + TestStep("3c", "TH reads TankPercentage attribute. Verify value is 0%"), + TestStep( + "3d", "TH reads HeaterTypes attribute. Verify value is greater than 0x00 (at least one type supported) and {storeValueAs} HeaterTypes"), + TestStep("4", "TH sends Boost with Duration=600s,TargetPercentage=100%. Verify Command response is Success"), + TestStep("4a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("4b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("5", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event. Verify Command response is Success"), + TestStep("5a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("5b", "TH reads BoostState attribute. Verify value is 0 (Active)"), + TestStep("5c", "TH reads TankPercentage attribute. Verify value is 100%"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Draw off hot water Test Event. Verify Command response is Success"), + TestStep("6a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("6b", "TH reads BoostState attribute. Verify value is 0 (Active)"), + TestStep("6c", "TH reads TankPercentage attribute. Verify value is 75%"), + TestStep("7", "TH sends CancelBoost. Verify Command response is Success"), + TestStep("7a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("7b", "TH reads BoostState attribute. Verify value is 0 (Inactive)"), + TestStep("7c", "TH reads TankPercentage attribute. Verify value is 75%"), + TestStep("8", "TH sends Boost with Duration=600s,TargetPercentage=100%,TargetReheat=65%. Verify Command response is Success"), + TestStep("8a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("8b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("8c", "TH reads TankPercentage attribute. Verify value is 75%"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event. Verify Command response is Success"), + TestStep("9a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("9b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("9c", "TH reads TankPercentage attribute. Verify value is 100%"), + TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Draw off hot water Test Event. Verify Command response is Success"), + TestStep("10a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("10b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("10c", "TH reads TankPercentage attribute. Verify value is 75%"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Draw off hot water Test Event. Verify Command response is Success"), + TestStep("11a", "TH reads HeatDemand attribute. Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("11b", "TH reads BoostState attribute. Verify value is 1 (Active)"), + TestStep("11c", "TH reads TankPercentage attribute. Verify value is 50%"), + TestStep("12", "TH sends CancelBoost. Verify Command response is Success"), + TestStep("12a", "TH reads HeatDemand attribute. Verify value is 0x00 (no demand on any source)"), + TestStep("12b", "TH reads BoostState attribute. Verify value is 0 (Inactive)"), + TestStep("12c", "TH reads TankPercentage attribute. Verify value is 50%"), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Basic installation Test Event Clear. Verify Command response is Success"), + ] + + return steps + + @async_test_body + async def test_TC_EWATERHTR_2_3(self): + + self.step("1") + # Commission DUT - already done + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_basic_installation_test_event() + + self.step("3a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("3b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("3c") + await self.check_whm_attribute("TankPercentage", 0) + + self.step("3d") + heaterTypes = await self.read_whm_attribute_expect_success(attribute="HeaterTypes") + asserts.assert_equal(heaterTypes, Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterTypeBitmap.kImmersionElement1) + + self.step("4") + await self.send_boost_command(duration=600, target_percentage=100) + + self.step("4a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("4b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("5") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("5a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("5b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("5c") + await self.check_whm_attribute("TankPercentage", 100) + + self.step("6") + await self.send_test_event_trigger_draw_off_hot_water_test_event() + + self.step("6a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("6b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("6c") + await self.check_whm_attribute("TankPercentage", 75) + + self.step("7") + await self.send_cancel_boost_command() + + self.step("7a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("7b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("7c") + await self.check_whm_attribute("TankPercentage", 75) + + self.step("8") + await self.send_boost_command(duration=600, target_percentage=100, target_reheat=65) + + self.step("8a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("8b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("8c") + await self.check_whm_attribute("TankPercentage", 75) + + self.step("9") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("9a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("9b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("9c") + await self.check_whm_attribute("TankPercentage", 100) + + self.step("10") + await self.send_test_event_trigger_draw_off_hot_water_test_event() + + self.step("10a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("10b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("10c") + await self.check_whm_attribute("TankPercentage", 75) + + self.step("11") + await self.send_test_event_trigger_draw_off_hot_water_test_event() + + self.step("11a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_not_equal(heatDemand & Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kImmersionElement1, 0) + + self.step("11b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("11c") + await self.check_whm_attribute("TankPercentage", 50) + + self.step("12") + await self.send_cancel_boost_command() + + self.step("12a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("12b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("12c") + await self.check_whm_attribute("TankPercentage", 50) + + self.step("13") + await self.send_test_event_trigger_basic_installation_test_event_clear() + + +if __name__ == "__main__": + default_matter_test_main()