Skip to content

Commit c29efb9

Browse files
PeterC1965jamesharrowrestyled-commits
authored andcommitted
Add water heater management test scripts (project-chip#34340)
* Add water heater management test scripts * Define runner commands for WHM tests * Specify --featureSet option on runner command line * Add the --featureSet option to the RUNNER command line * Apply suggestions from code review - corrected test step numbers to align to test plan PR. * Apply suggestions from code review - Changing TestSteps into 3 entries * Renamed EWATERHTRBase.py to TC_EWATERHTRBase.py. Changed TestStep to 3 args entries (to split out verification step for readability). * Restyle fix. * Update src/python_testing/TC_EWATERHTR_2_1.py Co-authored-by: jamesharrow <93921463+jamesharrow@users.noreply.github.com> * Start addressing review comments from JamesH * Remove water heater management app * Address review comments from JamesH * Address review comments from JamesH * Address review comments from JamesH * Address review comments from JamesH * Update src/python_testing/TC_EWATERHTR_2_3.py Co-authored-by: jamesharrow <93921463+jamesharrow@users.noreply.github.com> * Update src/python_testing/TC_EWATERHTR_2_3.py Co-authored-by: jamesharrow <93921463+jamesharrow@users.noreply.github.com> * Update src/python_testing/TC_EWATERHTR_2_3.py Co-authored-by: jamesharrow <93921463+jamesharrow@users.noreply.github.com> * Update src/python_testing/TC_EWATERHTR_2_3.py Co-authored-by: jamesharrow <93921463+jamesharrow@users.noreply.github.com> * Update src/python_testing/TC_EWATERHTR_2_3.py Co-authored-by: jamesharrow <93921463+jamesharrow@users.noreply.github.com> * Address review comments from JamesH * Restyled by autopep8 * Restyled by isort * Update src/python_testing/TC_EWATERHTR_2_1.py * Update src/python_testing/TC_EWATERHTR_2_1.py Removed assert TankVolume >= 0 * Restored TC_EEVSE_2_4.py from master * Fixed issue raised on TC_EWATERHTR_2_1.py about checking that BoostState is in valid range. --------- Co-authored-by: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Co-authored-by: James Harrow <james.harrow@gmail.com> Co-authored-by: Restyled.io <commits@restyled.io>
1 parent c951d51 commit c29efb9

File tree

4 files changed

+878
-0
lines changed

4 files changed

+878
-0
lines changed
+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#
2+
# Copyright (c) 2024 Project CHIP Authors
3+
# All rights reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
18+
import logging
19+
import typing
20+
21+
import chip.clusters as Clusters
22+
from chip.interaction_model import InteractionModelError, Status
23+
from mobly import asserts
24+
25+
logger = logging.getLogger(__name__)
26+
27+
28+
class EWATERHTRBase:
29+
30+
async def read_whm_attribute_expect_success(self, endpoint: int = None, attribute: str = ""):
31+
cluster = Clusters.Objects.WaterHeaterManagement
32+
full_attr = getattr(cluster.Attributes, attribute)
33+
return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=full_attr)
34+
35+
async def check_whm_attribute(self, attribute, expected_value, endpoint: int = None):
36+
value = await self.read_whm_attribute_expect_success(endpoint=endpoint, attribute=attribute)
37+
asserts.assert_equal(value, expected_value,
38+
f"Unexpected '{attribute}' value - expected {expected_value}, was {value}")
39+
40+
async def send_boost_command(self, duration: int, one_shot: typing.Optional[bool] = None, emergency_boost: typing.Optional[bool] = None,
41+
temporary_setpoint: typing.Optional[int] = None, target_percentage: typing.Optional[int] = None, target_reheat: typing.Optional[int] = None,
42+
endpoint: int = None, timedRequestTimeoutMs: int = 3000,
43+
expected_status: Status = Status.Success):
44+
try:
45+
await self.send_single_cmd(cmd=Clusters.WaterHeaterManagement.Commands.Boost(
46+
duration=duration,
47+
oneShot=one_shot,
48+
emergencyBoost=emergency_boost,
49+
temporarySetpoint=temporary_setpoint,
50+
targetPercentage=target_percentage,
51+
targetReheat=target_reheat),
52+
endpoint=endpoint,
53+
timedRequestTimeoutMs=timedRequestTimeoutMs)
54+
55+
asserts.assert_equal(expected_status, Status.Success)
56+
57+
except InteractionModelError as e:
58+
asserts.assert_equal(e.status, expected_status, "Unexpected error returned")
59+
60+
async def send_cancel_boost_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000,
61+
expected_status: Status = Status.Success):
62+
try:
63+
await self.send_single_cmd(cmd=Clusters.WaterHeaterManagement.Commands.CancelBoost(),
64+
endpoint=endpoint,
65+
timedRequestTimeoutMs=timedRequestTimeoutMs)
66+
67+
asserts.assert_equal(expected_status, Status.Success)
68+
69+
except InteractionModelError as e:
70+
asserts.assert_equal(e.status, expected_status, "Unexpected error returned")
71+
72+
async def send_test_event_trigger_basic_installation_test_event(self):
73+
await self.send_test_event_triggers(eventTrigger=0x0094000000000000)
74+
75+
async def send_test_event_trigger_basic_installation_test_event_clear(self):
76+
await self.send_test_event_triggers(eventTrigger=0x0094000000000001)
77+
78+
async def send_test_event_trigger_water_temperature20C_test_event(self):
79+
await self.send_test_event_triggers(eventTrigger=0x0094000000000002)
80+
81+
async def send_test_event_trigger_water_temperature61C_test_event(self):
82+
await self.send_test_event_triggers(eventTrigger=0x0094000000000003)
83+
84+
async def send_test_event_trigger_water_temperature66C_test_event(self):
85+
await self.send_test_event_triggers(eventTrigger=0x0094000000000004)
86+
87+
async def send_test_event_trigger_manual_mode_test_event(self):
88+
await self.send_test_event_triggers(eventTrigger=0x0094000000000005)
89+
90+
async def send_test_event_trigger_off_mode_test_event(self):
91+
await self.send_test_event_triggers(eventTrigger=0x0094000000000006)
92+
93+
async def send_test_event_trigger_draw_off_hot_water_test_event(self):
94+
await self.send_test_event_triggers(eventTrigger=0x0094000000000007)
+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#
2+
# Copyright (c) 2024 Project CHIP Authors
3+
# All rights reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
18+
# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments
19+
# for details about the block below.
20+
#
21+
# === BEGIN CI TEST ARGUMENTS ===# test-runner-runs: run1
22+
# test-runner-run/run1/app: ${ALL_CLUSTERS_APP}
23+
# test-runner-run/run1/factoryreset: True
24+
# test-runner-run/run1/quiet: True
25+
# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x03
26+
# 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 --int-arg PIXIT.EWATERHTR.EM:1 PIXIT.EWATERHTR.TP:2
27+
# === END CI TEST ARGUMENTS ===
28+
29+
import logging
30+
31+
import chip.clusters as Clusters
32+
from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
33+
from mobly import asserts
34+
from TC_EWATERHTRBase import EWATERHTRBase
35+
36+
logger = logging.getLogger(__name__)
37+
38+
39+
class TC_EWATERHTR_2_1(MatterBaseTest, EWATERHTRBase):
40+
41+
def desc_TC_EWATERHTR_2_1(self) -> str:
42+
"""Returns a description of this test"""
43+
return "[TC-EWATERHTR-2.1] Attributes with attributes with DUT as Server\n" \
44+
"This test case verifies the non-global attributes of the Water Heater Management cluster server."
45+
46+
def pics_TC_EWATERHTR_2_1(self):
47+
""" This function returns a list of PICS for this test case that must be True for the test to be run"""
48+
return ["EWATERHTR.S"]
49+
50+
def steps_TC_EWATERHTR_2_1(self) -> list[TestStep]:
51+
steps = [
52+
TestStep("1", "Commissioning, already done",
53+
is_commissioning=True),
54+
TestStep("2", "TH reads HeaterTypes attribute.",
55+
"DUT as Server replies with a WaterHeaterTypeBitmap (enum8) greater than 0x00 (at least one type supported), and less than 0x20 (no undefined types supported)."),
56+
TestStep("3", "TH reads HeatDemand attribute.",
57+
"DUT as Server replies with a WaterHeaterDemandBitmap (enum8)."),
58+
TestStep("4", "TH reads TankVolume attribute.",
59+
"DUT as Server replies with a uint16 value."),
60+
TestStep("5", "TH reads EstimatedHeatRequired attribute.",
61+
"DUT as Server replies with an energy-mWh value."),
62+
TestStep("6", "TH reads TankPercentage attribute.",
63+
"DUT as Server replies with a percent value."),
64+
TestStep("7", "TH reads BoostState attribute.",
65+
"DUT as Server replies with a BoostStateEnum (enum8) value."),
66+
]
67+
68+
return steps
69+
70+
@async_test_body
71+
async def test_TC_EWATERHTR_2_1(self):
72+
73+
em_supported = self.matter_test_config.global_test_params['PIXIT.EWATERHTR.EM']
74+
tp_supported = self.matter_test_config.global_test_params['PIXIT.EWATERHTR.TP']
75+
76+
self.step("1")
77+
# Commission DUT - already done
78+
79+
self.step("2")
80+
heaterTypes = await self.read_whm_attribute_expect_success(attribute="HeaterTypes")
81+
asserts.assert_greater(heaterTypes, 0,
82+
f"Unexpected HeaterTypes value - expected {heaterTypes} > 0")
83+
asserts.assert_less_equal(heaterTypes, Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterTypeBitmap.kOther,
84+
f"Unexpected HeaterTypes value - expected {heaterTypes} <= WaterHeaterTypeBitmap.kOther")
85+
86+
self.step("3")
87+
heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand")
88+
asserts.assert_greater(heatDemand, 0,
89+
f"Unexpected HeatDemand value - expected {heatDemand} > 0")
90+
asserts.assert_less_equal(heatDemand, Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kOther,
91+
f"Unexpected HeatDemand value - expected {heatDemand} <= WaterHeaterDemandBitmap.kOther")
92+
93+
self.step("4")
94+
if em_supported:
95+
value = await self.read_whm_attribute_expect_success(attribute="TankVolume")
96+
else:
97+
logging.info("Skipping step 4 as PIXIT.EWATERHTR.EM not supported")
98+
99+
self.step("5")
100+
if em_supported:
101+
value = await self.read_whm_attribute_expect_success(attribute="EstimatedHeatRequired")
102+
asserts.assert_greater_equal(value, 0, f"Unexpected EstimatedHeatRequired value - expected {value} >= 0")
103+
else:
104+
logging.info("Skipping step 5 as PIXIT.EWATERHTR.EM not supported")
105+
106+
self.step("6")
107+
if tp_supported:
108+
value = await self.read_whm_attribute_expect_success(attribute="TankPercentage")
109+
asserts.assert_greater_equal(value, 0, f"Unexpected TankPercentage value - expected {value} >= 0")
110+
asserts.assert_less_equal(value, 100, f"Unexpected TankPercentage value - expected {value} <= 100")
111+
else:
112+
logging.info("Skipping step 6 as PIXIT.EWATERHTR.TP not supported")
113+
114+
self.step("7")
115+
boost_state = await self.read_whm_attribute_expect_success(attribute="BoostState")
116+
asserts.assert_less_equal(boost_state, Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive,
117+
f"Unexpected BoostState value - expected {boost_state} should be BoostStateEnum (enum8) value in range 0x00 to 0x01")
118+
119+
120+
if __name__ == "__main__":
121+
default_matter_test_main()

0 commit comments

Comments
 (0)