diff --git a/examples/rvc-app/rvc-common/pics/rvc-app-pics-values b/examples/rvc-app/rvc-common/pics/rvc-app-pics-values index c38f0c1b7e00a0..4ad084ec618dd4 100644 --- a/examples/rvc-app/rvc-common/pics/rvc-app-pics-values +++ b/examples/rvc-app/rvc-common/pics/rvc-app-pics-values @@ -20,7 +20,7 @@ RVCOPSTATE.S.E01=1 RVCOPSTATE.S.C00.Rsp=1 RVCOPSTATE.S.C03.Rsp=1 RVCOPSTATE.S.C04.Tx=1 -RVCOPSTATE.S.C128.Rsp=1 +RVCOPSTATE.S.C80.Rsp=1 RVCOPSTATE.S.M.ST_STOPPED=1 RVCOPSTATE.S.M.ST_RUNNING=1 RVCOPSTATE.S.M.ST_PAUSED=1 @@ -77,4 +77,4 @@ SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL=1 SEAR.S.M.INVALID_STATE_FOR_SKIP=1 SEAR.S.M.NO_SELAREA_FOR_SKIP=1 SEAR.S.M.VALID_STATE_FOR_SKIP=1 -SEAR.S.M.HAS_MANUAL_OPERATING_STATE_CONTROL=1 \ No newline at end of file +SEAR.S.M.HAS_MANUAL_OPERATING_STATE_CONTROL=1 diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index 1fc182bd9ba867..c575bd348fc518 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -9740,7 +9740,7 @@ PICS: id: RVCOPSTATE.S.C03.Rsp - label: "Does the device implement receiving the GoHome command?" - id: RVCOPSTATE.S.C128.Rsp + id: RVCOPSTATE.S.C80.Rsp #Commands generated - label: diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index f64941bb688890..9109f30bec4d73 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -2532,7 +2532,7 @@ RVCOPSTATE.S.C01.Rsp=0 RVCOPSTATE.S.C02.Rsp=0 RVCOPSTATE.S.C03.Rsp=1 RVCOPSTATE.S.C04.Tx=1 -RVCOPSTATE.S.C128.Rsp=1 +RVCOPSTATE.S.C80.Rsp=1 RVCOPSTATE.S.M.ST_STOPPED=1 RVCOPSTATE.S.M.ST_RUNNING=1 RVCOPSTATE.S.M.ST_PAUSED=1 @@ -2618,6 +2618,7 @@ PIXIT.RVCRUNM.MODE_CHANGE_OK=0 # RVCOPSTATE.S.C02.Rsp=0 # RVCOPSTATE.S.C03.Rsp=1 # RVCOPSTATE.S.C04.Tx=1 +# RVCOPSTATE.S.C80.Rsp=1 # RVCOPSTATE.S.C128.Rsp=1 # RVCOPSTATE.C.C00.Tx=1 # RVCOPSTATE.C.C01.Tx=1 diff --git a/src/python_testing/TC_RVCCLEANM_2_2.py b/src/python_testing/TC_RVCCLEANM_2_2.py index 8aaae7ff78738f..e3a92033b3bdf4 100644 --- a/src/python_testing/TC_RVCCLEANM_2_2.py +++ b/src/python_testing/TC_RVCCLEANM_2_2.py @@ -27,13 +27,22 @@ # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto # === END CI TEST ARGUMENTS === +import enum from time import sleep import chip.clusters as Clusters -from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches from mobly import asserts +class RvcStatusEnum(enum.IntEnum): + # TODO remove this class once InvalidInMode response code is implemented in python SDK + Success = 0x0 + UnsupportedMode = 0x1 + GenericFailure = 0x2 + InvalidInMode = 0x3 + + class TC_RVCCLEANM_2_2(MatterBaseTest): def __init__(self, *args): @@ -64,6 +73,11 @@ async def read_clean_supported_modes(self) -> Clusters.Objects.RvcCleanMode.Attr Clusters.RvcCleanMode.Attributes.SupportedModes) return ret + async def read_feature_map_attribute(self): + ret = await self.read_mod_attribute_expect_success(Clusters.RvcCleanMode, + Clusters.RvcCleanMode.Attributes.FeatureMap) + return ret + async def send_clean_change_to_mode_cmd(self, newMode) -> Clusters.Objects.RvcCleanMode.Commands.ChangeToModeResponse: ret = await self.send_single_cmd(cmd=Clusters.Objects.RvcCleanMode.Commands.ChangeToMode(newMode=newMode), endpoint=self.endpoint) return ret @@ -90,6 +104,9 @@ def write_to_app_pipe(self, command): @async_test_body async def test_TC_RVCCLEANM_2_2(self): + # TODO Replace 0x8000 with python object of RVCCLEAN FEATURE bit map when implemented + # 0x8000 corresponds to 16 bit DIRECTMODECH Feature map + self.directmodech_bit_mask = 0x8000 self.endpoint = self.matter_test_config.endpoint self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") if self.is_ci: @@ -157,11 +174,22 @@ async def test_TC_RVCCLEANM_2_2(self): self.new_clean_mode_th = mode break - self.print_step(7, "Send ChangeToMode command") + self.print_step("7a", "Read FeatureMap Attribute") + feature_map = await self.read_feature_map_attribute() + directmode_enabled = feature_map & self.directmodech_bit_mask + + self.print_step("7b", "Send ChangeToMode command") response = await self.send_clean_change_to_mode_cmd(self.new_clean_mode_th) - asserts.assert_equal(response.status, 3, - "The response should contain a ChangeToModeResponse command " - "with the Status set to InvalidInMode(0x03).") + asserts.assert_true(type_matches(response, Clusters.RvcCleanMode.Commands.ChangeToModeResponse), + "The response should ChangeToModeResponse command") + if directmode_enabled: + asserts.assert_equal(response.status, RvcStatusEnum.Success, + "The response should contain a ChangeToModeResponse command " + "with the Status set to Success(0x0).") + else: + asserts.assert_equal(response.status, RvcStatusEnum.InvalidInMode, + "The response should contain a ChangeToModeResponse command " + "with the Status set to InvalidInMode(0x03).") if __name__ == "__main__": diff --git a/src/python_testing/TC_RVCOPSTATE_2_4.py b/src/python_testing/TC_RVCOPSTATE_2_4.py index b680453b06c287..7f03d33b196833 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_4.py +++ b/src/python_testing/TC_RVCOPSTATE_2_4.py @@ -114,7 +114,7 @@ async def test_TC_RVCOPSTATE_2_4(self): asserts.assert_true(self.check_pics("RVCOPSTATE.S.A0004"), "RVCOPSTATE.S.A0004 must be supported") asserts.assert_true(self.check_pics("RVCOPSTATE.S.C04.Tx"), "RVCOPSTATE.S.C04.Tx must be supported") - asserts.assert_true(self.check_pics("RVCOPSTATE.S.C128.Rsp"), "RVCOPSTATE.S.C128.Rsp must be supported") + asserts.assert_true(self.check_pics("RVCOPSTATE.S.C80.Rsp"), "RVCOPSTATE.S.C80.Rsp must be supported") op_states = Clusters.OperationalState.Enums.OperationalStateEnum rvc_op_states = Clusters.RvcOperationalState.Enums.OperationalStateEnum @@ -170,16 +170,16 @@ async def test_TC_RVCOPSTATE_2_4(self): if self.check_pics("PICS_M_ST_SEEKING_CHARGER"): step_name = "Manually put the device in the SEEKING CHARGER operational state" - self.print_step(8, step_name) + self.print_step(11, step_name) if self.is_ci: await self.send_run_change_to_mode_cmd(rvc_app_run_mode_cleaning) await self.send_run_change_to_mode_cmd(rvc_app_run_mode_idle) else: self.wait_for_user_input(prompt_msg=f"{step_name}, and press Enter when ready.") - await self.read_operational_state_with_check(9, rvc_op_states.kSeekingCharger) + await self.read_operational_state_with_check(12, rvc_op_states.kSeekingCharger) - await self.send_go_home_cmd_with_check(10, op_errors.kNoError) + await self.send_go_home_cmd_with_check(13, op_errors.kNoError) if __name__ == "__main__": diff --git a/src/python_testing/TC_RVCRUNM_2_2.py b/src/python_testing/TC_RVCRUNM_2_2.py index dca866adb9f62e..b0d1233010f932 100644 --- a/src/python_testing/TC_RVCRUNM_2_2.py +++ b/src/python_testing/TC_RVCRUNM_2_2.py @@ -27,6 +27,7 @@ # test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --int-arg PIXIT.RVCRUNM.MODE_A:1 PIXIT.RVCRUNM.MODE_B:2 # === END CI TEST ARGUMENTS === +import enum from time import sleep import chip.clusters as Clusters @@ -38,17 +39,25 @@ # --int-arg PIXIT.RVCRUNM.MODE_A: PIXIT.RVCRUNM.MODE_B: +class RvcStatusEnum(enum.IntEnum): + # TODO remove this class once InvalidInMode response code is implemented in python SDK + Success = 0x0 + UnsupportedMode = 0x1 + GenericFailure = 0x2 + InvalidInMode = 0x3 + + def error_enum_to_text(error_enum): try: return f'{Clusters.RvcRunMode.Enums.ModeTag(error_enum).name} 0x{error_enum:02x}' except AttributeError: - if error_enum == 0: + if error_enum == RvcStatusEnum.Success: return "Success(0x00)" - elif error_enum == 0x1: + elif error_enum == RvcStatusEnum.UnsupportedMode: return "UnsupportedMode(0x01)" - elif error_enum == 0x2: + elif error_enum == RvcStatusEnum.GenericFailure: return "GenericFailure(0x02)" - elif error_enum == 0x3: + elif error_enum == RvcStatusEnum.InvalidInMode: return "InvalidInMode(0x03)" raise AttributeError("Unknown Enum value") @@ -122,6 +131,9 @@ async def test_TC_RVCRUNM_2_2(self): "PIXIT.RVCRUNM.MODE_A: \n" "PIXIT.RVCRUNM.MODE_B:") + # TODO Replace 0x8000 with python object of RVCRUN FEATURE bit when implemented + # 0x8000 corresponds to 16 bit DIRECTMODECH Feature map + self.directmodech_bit_mask = 0x8000 self.endpoint = self.matter_test_config.endpoint self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") self.mode_a = self.matter_test_config.global_test_params['PIXIT.RVCRUNM.MODE_A'] @@ -193,15 +205,23 @@ async def test_TC_RVCRUNM_2_2(self): asserts.assert_true(idle_tag_present, "The device must be in a mode with the Idle (0x4000) mode tag.") self.print_step(5, "Send ChangeToMode MODE_A command") - await self.send_change_to_mode_with_check(self.mode_a, 0) + await self.send_change_to_mode_with_check(self.mode_a, RvcStatusEnum.Success) # This step is not described in the test plan, but it ought to be await self.read_current_mode_with_check(self.mode_a) - self.print_step(6, "Send ChangeToMode MODE_B command") - await self.send_change_to_mode_with_check(self.mode_b, 3) + self.print_step("6a", "Read Attribute FeatureMap") + feature_map = await self.read_mod_attribute_expect_success(cluster=Clusters.RvcRunMode, + attribute=Clusters.RvcRunMode.Attributes.FeatureMap) + directmode_enabled = feature_map & self.directmodech_bit_mask + + self.print_step('6b', "Send ChangeToMode MODE_B command") + if directmode_enabled: + await self.send_change_to_mode_with_check(self.mode_b, RvcStatusEnum.Success) + else: + await self.send_change_to_mode_with_check(self.mode_b, RvcStatusEnum.InvalidInMode) self.print_step(7, "Send ChangeToMode idle command") - await self.send_change_to_mode_with_check(self.idle_mode_dut, 0) + await self.send_change_to_mode_with_check(self.idle_mode_dut, RvcStatusEnum.Success) # This step is not described in the test plan, but it ought to be await self.read_current_mode_with_check(self.idle_mode_dut) @@ -228,12 +248,12 @@ async def test_TC_RVCRUNM_2_2(self): "Expected RVCOPSTATE's OperationalState attribute to be one of Stopped(0x00), Paused(0x02), Charging(0x41) or Docked(0x42)") self.print_step(11, "Send ChangeToMode MODE_B command") - await self.send_change_to_mode_with_check(self.mode_b, 0) + await self.send_change_to_mode_with_check(self.mode_b, RvcStatusEnum.Success) # This step is not described in the test plan, but it ought to be await self.read_current_mode_with_check(self.mode_b) self.print_step(12, "Send ChangeToMode idle command") - await self.send_change_to_mode_with_check(self.idle_mode_dut, 0) + await self.send_change_to_mode_with_check(self.idle_mode_dut, RvcStatusEnum.Success) # This step is not described in the test plan, but it ought to be await self.read_current_mode_with_check(self.idle_mode_dut)