14
14
# See the License for the specific language governing permissions and
15
15
# limitations under the License.
16
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
17
# === BEGIN CI TEST ARGUMENTS ===
22
18
# test-runner-runs: run1
23
19
# test-runner-run/run1/app: ${ALL_CLUSTERS_APP}
24
20
# test-runner-run/run1/factoryreset: True
25
21
# test-runner-run/run1/quiet: True
26
22
# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json
27
- # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values -- trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --endpoint 1
23
+ # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --endpoint 1 --bool-arg simulate_occupancy:true
28
24
# === END CI TEST ARGUMENTS ===
25
+ # There are CI issues to be followed up for the test cases below that implements manually controlling sensor device for
26
+ # the occupancy state ON/OFF change.
27
+ # [TC-OCC-3.1] test procedure step 3, 4
28
+ # [TC-OCC-3.2] test precedure step 3a, 3c
29
29
30
30
import logging
31
31
35
35
36
36
37
37
class TC_OCC_2_3 (MatterBaseTest ):
38
- async def read_occ_attribute_expect_success (self , endpoint , attribute ):
38
+ async def read_occ_attribute_expect_success (self , attribute ):
39
39
cluster = Clusters .Objects .OccupancySensing
40
- return await self .read_single_attribute_check_success (endpoint = endpoint , cluster = cluster , attribute = attribute )
40
+ endpoint_id = self .matter_test_config .endpoint
41
+ return await self .read_single_attribute_check_success (endpoint = endpoint_id , cluster = cluster , attribute = attribute )
41
42
42
43
def desc_TC_OCC_2_3 (self ) -> str :
43
44
return "[TC-OCC-2.3] HoldTime Backward Compatibility Test with server as DUT"
44
45
45
46
def steps_TC_OCC_2_3 (self ) -> list [TestStep ]:
46
47
steps = [
47
48
TestStep (1 , "Commission DUT to TH" , is_commissioning = True ),
48
- TestStep (2 , "DUT supports HoldTime attribute. If DUT doesn’t support it, then stop and exit this test case." ),
49
- TestStep (3 , "Based on the feature flag value table, read OccupancySensorType attribute from DUT" ),
50
- TestStep (4 , "If TH reads 0 - PIR, TH reads PIROccupiedToUnoccupiedDelay attribute and its value should be same as HoldTime" ),
51
- TestStep (5 , "If TH reads 1 - Ultrasonic, TH reads UltrasonicOccupiedToUnoccupiedDelay attribute and its value should be same as HoldTime" ),
52
- TestStep (6 , "If TH reads 2 - PHY, TH reads PhysicalContactOccupiedToUnoccupiedDelay attribute and its value should be same as HoldTime" )
49
+ TestStep (2 , "TH reads the FeatureMap attribute on the endpoint for use in later steps." ),
50
+ TestStep (3 , "TH checks DUT HoldTime attribute support in the AttributeList attribute. If DUT doesn't support HoldTime attribute, skip the rest of this test case." ),
51
+ TestStep (4 , "TH writes DUT HoldTime attribute with HoldTimeMin and afterwards reads the attribute." ),
52
+ TestStep (5 , "TH writes DUT HoldTime attribute with HoldTimeMax and afterwards reads the attribute." ),
53
+ TestStep ("6a" , "If DUT FeatureMap has PIR or (!PIR & !US & !PHY), and PIROccupiedToUnoccupiedDelay is supported, then TH writes HoldTimeMin to DUT's HoldTime attribute, otherwise skip 6a, 6b." ),
54
+ TestStep ("6b" , "TH writes DUT's PIROccupiedToUnoccupiedDelay attribute with HoldTimeMax, then TH reads DUT's PIROccupiedToUnoccupiedDelay and HoldTime attributes." ),
55
+ TestStep ("7a" , "If DUT FeatureMap has US, and UltrasonicOccupiedToUnoccupiedDelay is supported, then TH writes HoldTimeMin to DUT's HoldTime attribute, otherwise skip 7a, 7b." ),
56
+ TestStep ("7b" , "TH writes DUT UltrasonicOccupiedToUnoccupiedDelay attribute with HoldTimeMax, then TH reads DUT UltrasonicOccupiedToUnoccupiedDelay and HoldTime attributes." ),
57
+ TestStep ("8a" , "If DUT FeatureMap has PHY, and PhysicalContactOccupiedToUnoccupiedDelay is supported, then TH writes HoldTimeMin to HoldTime attribute, otherwise skip 8a, 8b." ),
58
+ TestStep ("8b" , "TH writes DUT PhysicalContactOccupiedToUnoccupiedDelay attribute with HoldTimeMax, then TH reads DUT PhysicalContactOccupiedToUnoccupiedDelay and HoldTime attributes." ),
53
59
]
54
60
return steps
55
61
@@ -61,67 +67,110 @@ def pics_TC_OCC_2_3(self) -> list[str]:
61
67
62
68
@async_test_body
63
69
async def test_TC_OCC_2_3 (self ):
64
- endpoint = self .matter_test_config .endpoint
65
70
66
- self .step (1 ) # Already done, immediately go to step 2
71
+ cluster = Clusters .Objects .OccupancySensing
72
+ attributes = cluster .Attributes
73
+
74
+ self .step (1 ) # Commissioning already done
67
75
68
76
self .step (2 )
69
77
70
- attributes = Clusters .OccupancySensing .Attributes
71
- attribute_list = await self .read_occ_attribute_expect_success (endpoint = endpoint , attribute = attributes .AttributeList )
78
+ feature_map = await self .read_occ_attribute_expect_success (attribute = attributes .FeatureMap )
79
+ has_feature_pir = (feature_map & cluster .Bitmaps .Feature .kPassiveInfrared ) != 0
80
+ has_feature_ultrasonic = (feature_map & cluster .Bitmaps .Feature .kUltrasonic ) != 0
81
+ has_feature_contact = (feature_map & cluster .Bitmaps .Feature .kPhysicalContact ) != 0
82
+ has_no_legacy_features = ((not has_feature_pir ) and (not has_feature_ultrasonic ) and (not has_feature_contact ))
72
83
73
- if attributes .HoldTime .attribute_id in attribute_list :
74
- occupancy_hold_time_dut = await self .read_occ_attribute_expect_success (endpoint = endpoint , attribute = attributes .HoldTime )
75
- else :
76
- logging .info ("No HoldTime attribute supports. Terminate this test case" )
84
+ logging .info (
85
+ f"Feature map: 0x{ feature_map :x} . PIR: { has_feature_pir } , US:{ has_feature_ultrasonic } , PHY:{ has_feature_contact } " )
77
86
78
87
self .step (3 )
79
- if attributes .OccupancySensorType .attribute_id in attribute_list :
80
- occupancy_sensor_type_dut = await self .read_occ_attribute_expect_success (endpoint = endpoint , attribute = attributes .OccupancySensorType )
81
-
82
- asserts .assert_less_equal (occupancy_sensor_type_dut , 3 , "OccupancySensorType attribute is out of range" )
83
- asserts .assert_greater_equal (occupancy_sensor_type_dut , 0 , "OccupancySensorType attribute is out of range" )
88
+ attribute_list = await self .read_occ_attribute_expect_success (attribute = attributes .AttributeList )
89
+ if attributes .HoldTime .attribute_id not in attribute_list :
90
+ logging .info ("No HoldTime attribute supports. Terminate this test case" )
91
+ self .skip_all_remaining_steps (4 )
92
+ holdtime_dut = await self .read_occ_attribute_expect_success (attribute = attributes .HoldTime )
93
+
94
+ self .step (4 )
95
+ hold_time_limits_dut = await self .read_occ_attribute_expect_success (attribute = attributes .HoldTimeLimits )
96
+ asserts .assert_greater_equal (hold_time_limits_dut .holdTimeMin , 1 , "HoldTimeMin has to be greater or equal to 1." )
97
+ await self .write_single_attribute (attributes .HoldTime (hold_time_limits_dut .holdTimeMin ))
98
+ holdtime_dut = await self .read_occ_attribute_expect_success (attribute = attributes .HoldTime )
99
+ asserts .assert_equal (holdtime_dut , hold_time_limits_dut .holdTimeMin , "HoldTimeMin to HoldTime writing failure" )
100
+
101
+ self .step (5 )
102
+ await self .write_single_attribute (attributes .HoldTime (hold_time_limits_dut .holdTimeMax ))
103
+ asserts .assert_greater_equal (hold_time_limits_dut .holdTimeMax , 10 , "HoldTimeMax has to be greater or equal to 10." )
104
+ holdtime_dut = await self .read_occ_attribute_expect_success (attribute = attributes .HoldTime )
105
+ asserts .assert_equal (holdtime_dut , hold_time_limits_dut .holdTimeMax , "HoldTimeMax to HoldTime writing failure" )
106
+
107
+ has_pir_timing_attrib = attributes .PIROccupiedToUnoccupiedDelay .attribute_id in attribute_list
108
+ has_no_legacy_features = ((not has_feature_pir ) and (not has_feature_ultrasonic ) and (not has_feature_contact ))
109
+
110
+ if (has_feature_pir or has_no_legacy_features ) and has_pir_timing_attrib :
111
+ self .step ("6a" )
112
+ await self .write_single_attribute (attributes .HoldTime (hold_time_limits_dut .holdTimeMin ))
113
+ holdtime_dut = await self .read_occ_attribute_expect_success (attribute = attributes .HoldTime )
114
+ occupancy_pir_otou_delay_dut = await self .read_occ_attribute_expect_success (attribute = attributes .PIROccupiedToUnoccupiedDelay )
115
+ asserts .assert_equal (occupancy_pir_otou_delay_dut , holdtime_dut ,
116
+ "PIROccupiedToUnoccupiedDelay has a different value from HoldTime." )
117
+
118
+ self .step ("6b" )
119
+ # perform reverse
120
+ await self .write_single_attribute (attributes .PIROccupiedToUnoccupiedDelay (hold_time_limits_dut .holdTimeMax ))
121
+ occupancy_pir_otou_delay_dut = await self .read_occ_attribute_expect_success (
122
+ attribute = attributes .PIROccupiedToUnoccupiedDelay )
123
+ holdtime_dut = await self .read_occ_attribute_expect_success (attribute = attributes .HoldTime )
124
+ asserts .assert_equal (occupancy_pir_otou_delay_dut , holdtime_dut ,
125
+ "PIROccupiedToUnoccupiedDelay has a different value from HoldTime in reverse testing." )
126
+ # self.skip_all_remaining_steps("7a")
84
127
else :
85
- logging .info ("OccupancySensorType attribute doesn't exist. Test step skipped" )
86
-
87
- if occupancy_sensor_type_dut == Clusters .OccupancySensing .Enums .OccupancySensorTypeEnum .kPir :
88
- self .step (4 )
89
- occupancy_pir_otou_delay_dut = await self .read_occ_attribute_expect_success (endpoint = endpoint , attribute = attributes .PIROccupiedToUnoccupiedDelay )
90
-
91
- asserts .assert_equal (occupancy_pir_otou_delay_dut , occupancy_hold_time_dut ,
92
- "HoldTime attribute value is not equal to PIROccupiedToUnoccupiedDelay" )
93
- self .skip_step (5 )
94
- self .skip_step (6 )
95
-
96
- elif occupancy_sensor_type_dut == Clusters .OccupancySensing .Enums .OccupancySensorTypeEnum .kUltrasonic :
97
- self .step (4 )
98
- occupancy_pir_otou_delay_dut = await self .read_occ_attribute_expect_success (endpoint = endpoint , attribute = attributes .PIROccupiedToUnoccupiedDelay )
99
-
100
- asserts .assert_equal (occupancy_pir_otou_delay_dut , occupancy_hold_time_dut ,
101
- "HoldTime attribute value is not equal to PIROccupiedToUnoccupiedDelay" )
102
- self .step (5 )
103
- occupancy_us_otou_delay_dut = await self .read_occ_attribute_expect_success (endpoint = endpoint , attribute = attributes .UltrasonicOccupiedToUnoccupiedDelay )
104
-
105
- asserts .assert_equal (occupancy_us_otou_delay_dut , occupancy_hold_time_dut ,
106
- "HoldTime attribute value is not equal to UltrasonicOccupiedToUnoccupiedDelay" )
107
- self .skip_step (6 )
108
-
109
- elif occupancy_sensor_type_dut == Clusters .OccupancySensing .Enums .OccupancySensorTypeEnum .kPIRAndUltrasonic :
110
- occupancy_pirus_otou_delay_dut = await self .read_occ_attribute_expect_success (endpoint = endpoint , attribute = attributes .PIROccupiedToUnoccupiedDelay )
111
-
112
- asserts .assert_equal (occupancy_pirus_otou_delay_dut , occupancy_hold_time_dut ,
113
- "HoldTime attribute value is not equal to PIROccupiedToUnoccupiedDelay" )
114
-
115
- elif occupancy_sensor_type_dut == Clusters .OccupancySensing .Enums .OccupancySensorTypeEnum .kPhysicalContact :
116
- self .skip_step (4 )
117
- self .skip_step (5 )
118
- self .step (6 )
119
- occupancy_phy_otou_delay_dut = await self .read_occ_attribute_expect_success (endpoint = endpoint , attribute = attributes .PhysicalContactOccupiedToUnoccupiedDelay )
120
-
121
- asserts .assert_equal (occupancy_phy_otou_delay_dut , occupancy_hold_time_dut ,
122
- "HoldTime attribute value is not equal to PhysicalContactOccupiedToUnoccupiedDelay" )
128
+ self .skip_step ("6a" )
129
+ self .skip_step ("6b" )
130
+
131
+ has_ultrasonic_timing_attrib = attributes .UltrasonicOccupiedToUnoccupiedDelay .attribute_id in attribute_list
132
+ if has_feature_ultrasonic and has_ultrasonic_timing_attrib :
133
+ self .step ("7a" )
134
+ await self .write_single_attribute (attributes .HoldTime (hold_time_limits_dut .holdTimeMin ))
135
+ holdtime_dut = await self .read_occ_attribute_expect_success (attribute = attributes .HoldTime )
136
+ occupancy_us_otou_delay_dut = await self .read_occ_attribute_expect_success (attribute = attributes .UltrasonicOccupiedToUnoccupiedDelay )
137
+ asserts .assert_equal (occupancy_us_otou_delay_dut , holdtime_dut ,
138
+ "UltrasonicOccupiedToUnoccupiedDelay has a different value from HoldTime." )
139
+
140
+ self .step ("7b" )
141
+ # perform reverse
142
+ await self .write_single_attribute (
143
+ attributes .UltrasonicOccupiedToUnoccupiedDelay (hold_time_limits_dut .holdTimeMax ))
144
+ occupancy_us_otou_delay_dut = await self .read_occ_attribute_expect_success (
145
+ attribute = attributes .UltrasonicOccupiedToUnoccupiedDelay )
146
+ holdtime_dut = await self .read_occ_attribute_expect_success (attribute = attributes .HoldTime )
147
+ asserts .assert_equal (occupancy_us_otou_delay_dut , holdtime_dut ,
148
+ "UltrasonicOccupiedToUnoccupiedDelay has a different value from HoldTime in reverse testing." )
149
+ else :
150
+ self .skip_step ("7a" )
151
+ self .skip_step ("7b" )
152
+
153
+ has_contact_timing_attrib = attributes .PhysicalContactOccupiedToUnoccupiedDelay .attribute_id in attribute_list
154
+ if has_feature_contact and has_contact_timing_attrib :
155
+ self .step ("8a" )
156
+ await self .write_single_attribute (attributes .HoldTime (hold_time_limits_dut .holdTimeMin ))
157
+ holdtime_dut = await self .read_occ_attribute_expect_success (attribute = attributes .HoldTime )
158
+ occupancy_phy_otou_delay_dut = await self .read_occ_attribute_expect_success (attribute = attributes .PhysicalContactOccupiedToUnoccupiedDelay )
159
+ asserts .assert_equal (occupancy_phy_otou_delay_dut , holdtime_dut ,
160
+ "PhysicalContactOccupiedToUnoccupiedDelay has a different value from HoldTime." )
161
+
162
+ self .step ("8b" )
163
+ # perform reverse
164
+ await self .write_single_attribute (
165
+ attributes .PhysicalContactOccupiedToUnoccupiedDelay (hold_time_limits_dut .holdTimeMin ))
166
+ occupancy_phy_otou_delay_dut = await self .read_occ_attribute_expect_success (
167
+ attribute = attributes .PhysicalContactOccupiedToUnoccupiedDelay )
168
+ holdtime_dut = await self .read_occ_attribute_expect_success (attribute = attributes .HoldTime )
169
+ asserts .assert_equal (occupancy_phy_otou_delay_dut , holdtime_dut ,
170
+ "PhysicalContactOccupiedToUnoccupiedDelay has a different value from HoldTime in reverse testing." )
123
171
else :
124
- logging .info ("OccupancySensorType attribute value is out of range" )
172
+ self .skip_step ("8a" )
173
+ self .skip_step ("8b" )
125
174
126
175
127
176
if __name__ == "__main__" :
0 commit comments