From a64e7fda0a4e414e04f2d2939f2ca43eaf6861e0 Mon Sep 17 00:00:00 2001 From: William Date: Mon, 22 Jan 2024 16:52:46 +0000 Subject: [PATCH] OpState + RVC OpState - add tests for new pause and resume compatible states (#31429) * Updated the OpState test 2.3 to test for pause and resume command complience when in the Stopped and Error states. * Removed the RVC OpState test 2.2. * Updated RVC OpState Test 2.3 according to the test plan changes. * Added TC RVC OpState 2.4 * Restyled by autopep8 * Restyled by isort * Fixed typos from code review Co-authored-by: Petru Lauric <81822411+plauric@users.noreply.github.com> * Added required PICS check at the start. * Cleaned up the TC_RVCOPSTATE_2_3 test script and added missing PICS guards. * Added missing PICS guards for TC_RVCOPSTATE_2_4 * Restyled by autopep8 * Removed unused variable in python test. * Fixed typos from code review Co-authored-by: Petru Lauric <81822411+plauric@users.noreply.github.com> * Updated TC_RVCOPSATTE_2_3 with the extara opreational state reads. * Added functions for test harness support Co-authored-by: C Freeman * Restyled by autopep8 --------- Co-authored-by: Restyled.io Co-authored-by: Petru Lauric <81822411+plauric@users.noreply.github.com> Co-authored-by: C Freeman --- .../certification/Test_TC_RVCOPSTATE_2_2.yaml | 334 ------------------ src/python_testing/TC_OPSTATE_2_3.py | 20 +- src/python_testing/TC_RVCOPSTATE_2_3.py | 229 +++++++++--- src/python_testing/TC_RVCOPSTATE_2_4.py | 184 ++++++++++ 4 files changed, 378 insertions(+), 389 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_RVCOPSTATE_2_2.yaml create mode 100644 src/python_testing/TC_RVCOPSTATE_2_4.py diff --git a/src/app/tests/suites/certification/Test_TC_RVCOPSTATE_2_2.yaml b/src/app/tests/suites/certification/Test_TC_RVCOPSTATE_2_2.yaml deleted file mode 100644 index d3e2f0226362b0..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_RVCOPSTATE_2_2.yaml +++ /dev/null @@ -1,334 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# 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. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 226.2.2. [TC-RVCOPSTATE-2.2] Start and Stop commands [DUT as Server] - -PICS: - - RVCOPSTATE.S - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Note" - verification: | - Note: The test case includes preconditions with the PICS codes for start and stop. If the PICS are not supported, the test should be skipped. - - This is a simulated example log for instructional purposes only. In real scenarios, the actual log may vary depending on the feature implementation in Reference App. - disabled: true - - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)" - verification: | - RVCOPSTATE.S.C02.Rsp(Start) and RVCOPSTATE.S.C01.Rsp(Stop) - disabled: true - - - label: - "Step 2: Manually put the DUT into a state wherein it can receive a - Start Command" - verification: | - Manually put the DUT into a state wherein it can receive a Start Command - disabled: true - - - label: "Step 3: TH reads from the DUT the OperationalStateList attribute" - PICS: RVCOPSTATE.S.A0003 - verification: | - ./chip-tool rvcoperationalstate read operational-state-list 1 1 - - Via the TH (chip-tool), verify: - - all entries include an ID (enum8) and a label (string) - - all provided IDs are in the allowed range - - the list includes IDs for Error (0x03), Running (0x01), and Stopped (0x00) - - [1689674049.504261][17222:17224] CHIP:DMG: } - [1689674049.504390][17222:17224] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Attribute 0x0000_0003 DataVersion: 2102885775 - [1689674049.504440][17222:17224] CHIP:TOO: OperationalStateList: 4 entries - [1689674049.504462][17222:17224] CHIP:TOO: [1]: { - [1689674049.504469][17222:17224] CHIP:TOO: OperationalStateID: 0 - [1689674049.504476][17222:17224] CHIP:TOO: } - [1689674049.504484][17222:17224] CHIP:TOO: [2]: { - [1689674049.504490][17222:17224] CHIP:TOO: OperationalStateID: 1 - [1689674049.504495][17222:17224] CHIP:TOO: } - [1689674049.504503][17222:17224] CHIP:TOO: [3]: { - [1689674049.504508][17222:17224] CHIP:TOO: OperationalStateID: 2 - [1689674049.504514][17222:17224] CHIP:TOO: } - [1689674049.504521][17222:17224] CHIP:TOO: [4]: { - [1689674049.504527][17222:17224] CHIP:TOO: OperationalStateID: 3 - [1689674049.504533][17222:17224] CHIP:TOO: } - [1689674049.504605][17222:17224] CHIP:EM: <<< [E:22830i S:37151 M:4250114 (Ack:140781365)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674049.504620][17222:17224] CHIP:IN: (S) Sending msg 4250114 on secure session with LSID: 37151 - disabled: true - - - label: "Step 4: TH sends Start command to the DUT" - PICS: RVCOPSTATE.S.C02.Rsp && RVCOPSTATE.S.C04.Tx - verification: | - ./chip-tool rvcoperationalstate start 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674139.018639][17233:17235] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674139.018658][17233:17235] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Command 0x0000_0004 - [1689674139.018704][17233:17235] CHIP:TOO: OperationalCommandResponse: { - [1689674139.018712][17233:17235] CHIP:TOO: commandResponseState: { - [1689674139.018719][17233:17235] CHIP:TOO: ErrorStateID: 0 - [1689674139.018726][17233:17235] CHIP:TOO: } - [1689674139.018732][17233:17235] CHIP:TOO: } - [1689674139.018755][17233:17235] CHIP:DMG: ICR moving to [AwaitingDe] - [1689674139.018818][17233:17235] CHIP:EM: <<< [E:26021i S:33879 M:235550100 (Ack:58905970)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674139.018837][17233:17235] CHIP:IN: (S) Sending msg 235550100 on secure session with LSID: 33879 - [1689674139.018885][17233:17235] CHIP:EM: Flushed pending ack for MessageCounter:58905970 on exchange 26021i - disabled: true - - - label: "Step 5: TH reads from the DUT the OperationalState attribute" - PICS: RVCOPSTATE.S.A0004 - verification: | - ./chip-tool rvcoperationalstate read operational-state 1 1 - - Via the TH (chip-tool), verify: - - the response has an OperationalStateID field that is set to 0x01 (Running) - - [1689674196.878722][17249:17251] CHIP:DMG: InteractionModelRevision = 1 - [1689674196.878727][17249:17251] CHIP:DMG: } - [1689674196.878800][17249:17251] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Attribute 0x0000_0004 DataVersion: 2102885775 - [1689674196.878834][17249:17251] CHIP:TOO: OperationalState: { - [1689674196.878841][17249:17251] CHIP:TOO: OperationalStateID: 1 - [1689674196.878847][17249:17251] CHIP:TOO: } - [1689674196.878914][17249:17251] CHIP:EM: <<< [E:56939i S:28614 M:63040141 (Ack:57012545)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674196.878928][17249:17251] CHIP:IN: (S) Sending msg 63040141 on secure session with LSID: 28614 - disabled: true - - - label: "Step 6: TH reads from the DUT the OperationalError attribute" - PICS: RVCOPSTATE.S.A0005 - verification: | - ./chip-tool rvcoperationalstate read operational-error 1 1 - - Via the TH (chip-tool), verify: - - the response contains the ErrorStateId set to NoError(0x00) - - [1689674342.832448][17274:17276] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Attribute 0x0000_0005 DataVersion: 2102885775 - [1689674342.832482][17274:17276] CHIP:TOO: OperationalError: { - [1689674342.832500][17274:17276] CHIP:TOO: ErrorStateID: 0 - [1689674342.832509][17274:17276] CHIP:TOO: } - [1689674342.832570][17274:17276] CHIP:EM: <<< [E:37158i S:10451 M:72875113 (Ack:195983315)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674342.832585][17274:17276] CHIP:IN: (S) Sending msg 72875113 on secure session with LSID: 10451 - [1689674342.832614][17274:17276] CHIP:EM: Flushed pending ack for MessageCounter:195983315 on exchange 37158i - disabled: true - - - label: "Step 7: TH reads from the DUT the CountdownTime attribute" - PICS: RVCOPSTATE.S.A0002 - verification: | - ./chip-tool rvcoperationalstate read countdown-time 1 1 - - Via the TH (chip-tool), verify: - - that CountdownTime attribute contains either null our a uint32 value - - if non-null, verify that the value is in the range 1 to 259200 - - store the value in 'initialcountdown-time' - - [1689674384.271623][17278:17280] CHIP:DMG: InteractionModelRevision = 1 - [1689674384.271625][17278:17280] CHIP:DMG: } - [1689674384.271649][17278:17280] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Attribute 0x0000_0002 DataVersion: 2102885775 - [1689674384.271662][17278:17280] CHIP:TOO: CountdownTime: null - [1689674384.271683][17278:17280] CHIP:EM: <<< [E:24665i S:47371 M:757241 (Ack:152992659)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674384.271687][17278:17280] CHIP:IN: (S) Sending msg 757241 on secure session with LSID: 47371 - [1689674384.271696][17278:17280] CHIP:EM: Flushed pending ack for MessageCounter:152992659 on exchange 24665i - disabled: true - - - label: "Step 8: TH reads from the DUT the PhaseList attribute" - PICS: RVCOPSTATE.S.A0000 - verification: | - ./chip-tool rvcoperationalstate read phase-list 1 1 - - Via the TH (chip-tool), verify: - - that PhaseList attribute value contains either null or a list of strings. - - If not null, receord the number of entries in the list as 'phase-list-size'; execute step 7. - If null, go to step 8. - - [1689674447.761859][17290:17292] CHIP:DMG: InteractionModelRevision = 1 - [1689674447.761865][17290:17292] CHIP:DMG: } - [1689674447.761938][17290:17292] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Attribute 0x0000_0000 DataVersion: 2102885775 - [1689674447.761972][17290:17292] CHIP:TOO: PhaseList: null - [1689674447.762041][17290:17292] CHIP:EM: <<< [E:58737i S:13847 M:251354926 (Ack:137738036)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674447.762055][17290:17292] CHIP:IN: (S) Sending msg 251354926 on secure session with LSID: 13847 - [1689674447.762109][17290:17292] CHIP:EM: Flushed pending ack for MessageCounter:137738036 on exchange 58737i - disabled: true - - - label: "Step 9: TH reads from the DUT the CurrentPhase attribute" - PICS: RVCOPSTATE.S.A0001 - verification: | - ./chip-tool rvcoperationalstate read current-phase 1 1 - - Via the TH (chip-tool), verify: - - that the CurrentPhase attribute value contains contains a uint8 value - - that the value is between 0 and 'phase-list-size - 1'. - - [1689674497.950563][17299:17301] CHIP:DMG: } - [1689674497.950635][17299:17301] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Attribute 0x0000_0001 DataVersion: 2102885775 - [1689674497.950664][17299:17301] CHIP:TOO: CurrentPhase: null - [1689674497.950737][17299:17301] CHIP:EM: <<< [E:64019i S:52010 M:245677798 (Ack:138696372)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674497.950752][17299:17301] CHIP:IN: (S) Sending msg 245677798 on secure session with LSID: 52010 - [1689674497.950798][17299:17301] CHIP:EM: Flushed pending ack for MessageCounter:138696372 on exchange 64019i - [1689674497.950899][17299:17299] CHIP:CTL: Shutting down the commissioner - disabled: true - - - label: - "Step 10: TH waits for a vendor defined wait time, this being a period - of time less than the expected duration of the operation that has been - started" - verification: | - TH waits for a vendor defined wait time, this being a period of time less than the expected duration of the operation that has been started - disabled: true - - - label: "Step 11: TH reads from the DUT the CountdownTime attribute" - PICS: RVCOPSTATE.S.A0002 - verification: | - ./chip-tool rvcoperationalstate read countdown-time 1 1 - - - Via the TH (chip-tool), verify: - - that CountdownTime attribute contains either null our a uint32 value - - if non-null, verify that the value is in the range 1 to 259200 - - that the value is approximately 'initialcountdown-time minus the vendor defined wait time' - - - [1689674623.673661][17320:17322] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Attribute 0x0000_0002 DataVersion: 2102885775 - [1689674623.673697][17320:17322] CHIP:TOO: CountdownTime: null - [1689674623.673755][17320:17322] CHIP:EM: <<< [E:42152i S:37580 M:19654175 (Ack:176515710)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674623.673768][17320:17322] CHIP:IN: (S) Sending msg 19654175 on secure session with LSID: 37580 - [1689674623.673795][17320:17322] CHIP:EM: Flushed pending ack for MessageCounter:176515710 on exchange 42152i - disabled: true - - - label: "Step 12: TH sends Start command to the DUT" - PICS: RVCOPSTATE.S.C02.Rsp && RVCOPSTATE.S.C04.Tx - verification: | - ./chip-tool rvcoperationalstate start 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674637.555734][17326:17328] CHIP:DMG: - [1689674637.555742][17326:17328] CHIP:DMG: InteractionModelRevision = 1 - [1689674637.555751][17326:17328] CHIP:DMG: }, - [1689674637.555784][17326:17328] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674637.555805][17326:17328] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Command 0x0000_0004 - [1689674637.555853][17326:17328] CHIP:TOO: OperationalCommandResponse: { - [1689674637.555862][17326:17328] CHIP:TOO: commandResponseState: { - [1689674637.555872][17326:17328] CHIP:TOO: ErrorStateID: 0 - [1689674637.555883][17326:17328] CHIP:TOO: } - [1689674637.555891][17326:17328] CHIP:TOO: } - [1689674637.555913][17326:17328] CHIP:DMG: ICR moving to [AwaitingDe] - [1689674637.555956][17326:17328] CHIP:EM: <<< [E:28742i S:49023 M:139320570 (Ack:91983883)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674637.555971][17326:17328] CHIP:IN: (S) Sending msg 139320570 on secure session with LSID: 49023 - [1689674637.556001][17326:17328] CHIP:EM: Flushed pending ack for MessageCounter:91983883 on exchange 28742i - disabled: true - - - label: "Step 13: TH sends Stop command to the DUT" - PICS: RVCOPSTATE.S.C01.Rsp && RVCOPSTATE.S.C04.Tx - verification: | - ./chip-tool rvcoperationalstate stop 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674653.322963][17330:17332] CHIP:DMG: }, - [1689674653.322994][17330:17332] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674653.323014][17330:17332] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Command 0x0000_0004 - [1689674653.323058][17330:17332] CHIP:TOO: OperationalCommandResponse: { - [1689674653.323066][17330:17332] CHIP:TOO: commandResponseState: { - [1689674653.323076][17330:17332] CHIP:TOO: ErrorStateID: 0 - [1689674653.323085][17330:17332] CHIP:TOO: } - [1689674653.323094][17330:17332] CHIP:TOO: } - [1689674653.323113][17330:17332] CHIP:DMG: ICR moving to [AwaitingDe] - [1689674653.323154][17330:17332] CHIP:EM: <<< [E:62878i S:64455 M:173921517 (Ack:216732582)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674653.323168][17330:17332] CHIP:IN: (S) Sending msg 173921517 on secure session with LSID: 64455 - [1689674653.323195][17330:17332] CHIP:EM: Flushed pending ack for MessageCounter:216732582 on exchange 62878i - [1689674653.323284][17330:17330] CHIP:CTL: Shutting down the commissioner - disabled: true - - - label: "Step 14: TH reads from the DUT the OperationalState attribute" - PICS: RVCOPSTATE.S.A0004 - verification: | - ./chip-tool rvcoperationalstate read operational-state 1 1 - - Via the TH (chip-tool), verify: - - the response has an OperationalStateID field that is set to 0x00 (Stopped) - - [1689674675.459656][17333:17335] CHIP:DMG: } - [1689674675.459738][17333:17335] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Attribute 0x0000_0004 DataVersion: 2102885775 - [1689674675.459772][17333:17335] CHIP:TOO: OperationalState: { - [1689674675.459790][17333:17335] CHIP:TOO: OperationalStateID: 0 - [1689674675.459799][17333:17335] CHIP:TOO: } - [1689674675.459869][17333:17335] CHIP:EM: <<< [E:17771i S:16165 M:1572532 (Ack:102448631)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674675.459886][17333:17335] CHIP:IN: (S) Sending msg 1572532 on secure session with LSID: 16165 - [1689674675.459930][17333:17335] CHIP:EM: Flushed pending ack for MessageCounter:102448631 on exchange 17771i - disabled: true - - - label: "Step 15: TH sends Stop command to the DUT" - PICS: RVCOPSTATE.S.C01.Rsp && RVCOPSTATE.S.C04.Tx - verification: | - ./chip-tool rvcoperationalstate stop 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674689.588712][17337:17339] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674689.588722][17337:17339] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Command 0x0000_0004 - [1689674689.588745][17337:17339] CHIP:TOO: OperationalCommandResponse: { - [1689674689.588749][17337:17339] CHIP:TOO: commandResponseState: { - [1689674689.588757][17337:17339] CHIP:TOO: ErrorStateID: 0 - [1689674689.588762][17337:17339] CHIP:TOO: } - [1689674689.588765][17337:17339] CHIP:TOO: } - [1689674689.588775][17337:17339] CHIP:DMG: ICR moving to [AwaitingDe] - [1689674689.588802][17337:17339] CHIP:EM: <<< [E:63921i S:35027 M:16881995 (Ack:220265764)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674689.588810][17337:17339] CHIP:IN: (S) Sending msg 16881995 on secure session with LSID: 35027 - disabled: true - - - label: - "Step 16: Manually put the DUT into a state wherein it cannot receive - a Start Command" - verification: | - Manually put the DUT into a state wherein it cannot receive a Start Command - disabled: true - - - label: "Step 17: TH sends Start command to the DUT" - PICS: RVCOPSTATE.S.C02.Rsp && RVCOPSTATE.S.C04.Tx - verification: | - ./chip-tool rvcoperationalstate start 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x01 (UnableToStartOrResume) - - [1689674700.385183][17340:17342] CHIP:DMG: }, - [1689674700.385214][17340:17342] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674700.385233][17340:17342] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0061 Command 0x0000_0004 - [1689674700.385266][17340:17342] CHIP:TOO: OperationalCommandResponse: { - [1689674700.385274][17340:17342] CHIP:TOO: commandResponseState: { - [1689674700.385281][17340:17342] CHIP:TOO: ErrorStateID: 1 - [1689674700.385289][17340:17342] CHIP:TOO: } - [1689674700.385295][17340:17342] CHIP:TOO: } - [1689674700.385311][17340:17342] CHIP:DMG: ICR moving to [AwaitingDe] - [1689674700.385361][17340:17342] CHIP:EM: <<< [E:55029i S:46795 M:80501191 (Ack:176711722)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674700.385375][17340:17342] CHIP:IN: (S) Sending msg 80501191 on secure session with LSID: 46795 - [1689674700.385419][17340:17342] CHIP:EM: Flushed pending ack for MessageCounter:176711722 on exchange 55029i - disabled: true diff --git a/src/python_testing/TC_OPSTATE_2_3.py b/src/python_testing/TC_OPSTATE_2_3.py index e7906c0ed225f0..57189c60382f08 100644 --- a/src/python_testing/TC_OPSTATE_2_3.py +++ b/src/python_testing/TC_OPSTATE_2_3.py @@ -62,6 +62,8 @@ async def test_TC_OPSTATE_2_3(self): asserts.assert_true(self.check_pics("OPSTATE.S.A0004"), "OPSTATE.S.A0004 must be supported") asserts.assert_true(self.check_pics("OPSTATE.S.C00.Rsp"), "OPSTATE.S.C00.Rsp must be supported") asserts.assert_true(self.check_pics("OPSTATE.S.C03.Rsp"), "OPSTATE.S.C03.Rsp must be supported") + # This command SHALL be supported by an implementation if any of the other commands are supported (6.5) + asserts.assert_true(self.check_pics("OPSTATE.S.C04.Rsp"), "OPSTATE.S.C04.Rsp must be supported") attributes = Clusters.OperationalState.Attributes @@ -138,7 +140,7 @@ async def test_TC_OPSTATE_2_3(self): asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, "errorStateID(%s) should be NoError(0x00)" % ret.commandResponseState.errorStateID) - self.print_step(13, "Manually put the device in a state where it cannot receive a Pause command") + self.print_step(13, "Manually put the device in the Stopped(0x00) operational state") input("Press Enter when done.\n") self.print_step(14, "Send Pause command") @@ -147,10 +149,22 @@ async def test_TC_OPSTATE_2_3(self): Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, "errorStateID(%s) should be CommandInvalidInState(0x03)" % ret.commandResponseState.errorStateID) - self.print_step(15, "Manually put the device in a state where it cannot receive a Resume command") + self.print_step(15, "Send Resume command") + ret = await self.send_resume_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, + Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, + "errorStateID(%s) should be CommandInvalidInState(0x03)" % ret.commandResponseState.errorStateID) + + self.print_step(16, "Manually put the device in the Error(0x03) operational state") input("Press Enter when done.\n") - self.print_step(16, "Send Resume command") + self.print_step(17, "Send Pause command") + ret = await self.send_pause_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, + Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, + "errorStateID(%s) should be CommandInvalidInState(0x03)" % ret.commandResponseState.errorStateID) + + self.print_step(18, "Send Resume command") ret = await self.send_resume_cmd() asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, diff --git a/src/python_testing/TC_RVCOPSTATE_2_3.py b/src/python_testing/TC_RVCOPSTATE_2_3.py index a0a6af47726d74..8303905482b3f9 100644 --- a/src/python_testing/TC_RVCOPSTATE_2_3.py +++ b/src/python_testing/TC_RVCOPSTATE_2_3.py @@ -28,8 +28,63 @@ # --int-arg PIXIT_ENDPOINT: +# Takes an OpState or RvcOpState state enum and returns a string representation +def state_enum_to_text(state_enum): + if state_enum == Clusters.OperationalState.Enums.OperationalStateEnum.kStopped: + return "Stopped(0x00)" + elif state_enum == Clusters.OperationalState.Enums.OperationalStateEnum.kRunning: + return "Running(0x01)" + elif state_enum == Clusters.OperationalState.Enums.OperationalStateEnum.kPaused: + return "Paused(0x02)" + elif state_enum == Clusters.OperationalState.Enums.OperationalStateEnum.kError: + return "Error(0x03)" + elif state_enum == Clusters.RvcOperationalState.Enums.OperationalStateEnum.kSeekingCharger: + return "SeekingCharger(0x40)" + elif state_enum == Clusters.RvcOperationalState.Enums.OperationalStateEnum.kCharging: + return "Charging(0x41)" + elif state_enum == Clusters.RvcOperationalState.Enums.OperationalStateEnum.kDocked: + return "Docked(0x42)" + else: + return "UnknownEnumValue" + + +# Takes an OpState or RvcOpState error enum and returns a string representation +def error_enum_to_text(error_enum): + if error_enum == Clusters.OperationalState.Enums.ErrorStateEnum.kNoError: + return "NoError(0x00)" + elif error_enum == Clusters.OperationalState.Enums.ErrorStateEnum.kUnableToStartOrResume: + return "UnableToStartOrResume(0x01)" + elif error_enum == Clusters.OperationalState.Enums.ErrorStateEnum.kUnableToCompleteOperation: + return "UnableToCompleteOperation(0x02)" + elif error_enum == Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState: + return "CommandInvalidInState(0x03)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kFailedToFindChargingDock: + return "FailedToFindChargingDock(0x40)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kStuck: + return "Stuck(0x41)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kDustBinMissing: + return "DustBinMissing(0x42)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kDustBinFull: + return "DustBinFull(0x43)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kWaterTankEmpty: + return "WaterTankEmpty(0x44)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kWaterTankMissing: + return "WaterTankMissing(0x45)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kWaterTankLidOpen: + return "WaterTankLidOpen(0x46)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kMopCleaningPadMissing: + return "MopCleaningPadMissing(0x47)" + + def pics_TC_RVCOPSTATE_2_3(self) -> list[str]: + return ["RVCOPSTATE.S"] + + class TC_RVCOPSTATE_2_3(MatterBaseTest): + def __init__(self, *args): + super().__init__(args) + self.endpoint = 0 + async def read_mod_attribute_expect_success(self, endpoint, attribute): cluster = Clusters.Objects.RvcOperationalState return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) @@ -46,8 +101,35 @@ async def send_resume_cmd(self) -> Clusters.Objects.RvcOperationalState.Commands "Unexpected return type for Resume") return ret - def TC_RVCOPSTATE_2_3(self) -> list[str]: - return ["RVCOPSTATE.S"] + # Prints the step number, reads the operational state attribute and checks if it matches with expected_state + async def read_operational_state_with_check(self, step_number, expected_state): + self.print_step(step_number, "Read OperationalState") + operational_state = await self.read_mod_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.RvcOperationalState.Attributes.OperationalState) + logging.info("OperationalState: %s" % operational_state) + asserts.assert_equal(operational_state, expected_state, + "OperationalState(%s) should be %s" % operational_state, state_enum_to_text(expected_state)) + + # Sends the Pause command and checks that the returned error matches the expected_error + async def send_pause_cmd_with_check(self, step_number, expected_error): + self.print_step(step_number, "Send Pause command") + ret = self.send_pause_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, expected_error, + "errorStateID(%s) should be %s" % ret.commandResponseState.errorStateID, + error_enum_to_text(expected_error)) + + # Sends the Resume command and checks that the returned error matches the expected_error + async def send_resume_cmd_with_check(self, step_number, expected_error): + self.print_step(step_number, "Send Pause command") + ret = self.send_resume_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, expected_error, + "errorStateID(%s) should be %s" % ret.commandResponseState.errorStateID, + error_enum_to_text(expected_error)) + + # Prints the instruction and waits for a user input to continue + def print_instruction(self, step_number, instruction): + self.print_step(step_number, instruction) + input("Press Enter when done.\n") @async_test_body async def test_TC_RVCOPSTATE_2_3(self): @@ -62,13 +144,17 @@ async def test_TC_RVCOPSTATE_2_3(self): asserts.assert_true(self.check_pics("RVCOPSTATE.S.A0004"), "RVCOPSTATE.S.A0004 must be supported") asserts.assert_true(self.check_pics("RVCOPSTATE.S.C00.Rsp"), "RVCOPSTATE.S.C00.Rsp must be supported") asserts.assert_true(self.check_pics("RVCOPSTATE.S.C03.Rsp"), "RVCOPSTATE.S.C03.Rsp must be supported") + # This command SHALL be supported by an implementation if any of the other commands are supported (6.5) + asserts.assert_true(self.check_pics("RVCOPSTATE.S.C04.Rsp"), "RVCOPSTATE.S.C04.Rsp must be supported") attributes = Clusters.RvcOperationalState.Attributes + op_states = Clusters.OperationalState.Enums.OperationalStateEnum + rvc_op_states = Clusters.RvcOperationalState.Enums.OperationalStateEnum + op_errors = Clusters.OperationalState.Enums.ErrorStateEnum self.print_step(1, "Commissioning, already done") - self.print_step(2, "Manually put the device in a state where it can receive a Pause command") - input("Press Enter when done.\n") + self.print_instruction(2, "Manually put the device in a state where it can receive a Pause command") self.print_step(3, "Read OperationalStateList attribute") op_state_list = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, @@ -83,78 +169,117 @@ async def test_TC_RVCOPSTATE_2_3(self): asserts.assert_true(all(id in state_ids for id in defined_states), "OperationalStateList is missing a required entry") - self.print_step(4, "Send Pause command") - ret = await self.send_pause_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, - "errorStateID(%s) should be NoError(0x00)" % ret.commandResponseState.errorStateID) + self.print_step(4, "Read OperationalState") + old_opstate_dut = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, + attribute=attributes.OperationalState) + logging.info("OperationalState: %s" % old_opstate_dut) - self.print_step(5, "Read OperationalState attribute") - operational_state = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, - attribute=attributes.OperationalState) - logging.info("OperationalState: %s" % (operational_state)) - asserts.assert_equal(operational_state, Clusters.OperationalState.Enums.OperationalStateEnum.kPaused, - "OperationalState(%s) should be Paused(0x02)" % operational_state) + await self.send_pause_cmd_with_check(5, op_errors.kNoError) + + await self.read_operational_state_with_check(6, op_states.kPaused) if self.check_pics("RVCOPSTATE.S.A0002"): - self.print_step(6, "Read CountdownTime attribute") + self.print_step(7, "Read CountdownTime attribute") initial_countdown_time = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CountdownTime) - logging.info("CountdownTime: %s" % (initial_countdown_time)) + logging.info("CountdownTime: %s" % initial_countdown_time) if initial_countdown_time is not NullValue: in_range = (1 <= initial_countdown_time <= 259200) asserts.assert_true(initial_countdown_time is NullValue or in_range, - "invalid CountdownTime(%s). Must be in between 1 and 259200, or null" % initial_countdown_time) + "invalid CountdownTime(%s). Must be in between 1 and 259200, or null " % initial_countdown_time) - self.print_step(7, "Waiting for 5 seconds") + self.print_step(8, "Waiting for 5 seconds") time.sleep(5) - self.print_step(8, "Read CountdownTime attribute") + self.print_step(9, "Read CountdownTime attribute") countdown_time = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CountdownTime) - logging.info("CountdownTime: %s" % (countdown_time)) + logging.info("CountdownTime: %s" % countdown_time) asserts.assert_true(countdown_time != 0 or countdown_time == NullValue, "invalid CountdownTime(%s). Must be a non zero integer, or null" % countdown_time) - asserts.assert_equal(countdown_time, initial_countdown_time, - "CountdownTime(%s) does not equal to the intial CountdownTime (%s)" % (countdown_time, initial_countdown_time)) + asserts.assert_equal(countdown_time, initial_countdown_time, "CountdownTime(%s) not equal to the initial CountdownTime(%s)" + % (countdown_time, initial_countdown_time)) - self.print_step(9, "Send Pause command") - ret = await self.send_pause_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, - "errorStateID(%s) should be NoError(0x00)" % ret.commandResponseState.errorStateID) + await self.send_pause_cmd_with_check(10, op_errors.kNoError) - self.print_step(10, "Send Resume command") - ret = await self.send_resume_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, - "errorStateID(%s) should be NoError(0x00)" % ret.commandResponseState.errorStateID) + await self.send_resume_cmd_with_check(11, op_errors.kNoError) - self.print_step(11, "Read OperationalState attribute") + self.print_step(12, "Read OperationalState attribute") operational_state = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.OperationalState) - logging.info("OperationalState: %s" % (operational_state)) - asserts.assert_equal(operational_state, Clusters.OperationalState.Enums.OperationalStateEnum.kRunning, - "OperationalState(%s) should be Running(0x01)" % operational_state) + logging.info("OperationalState: %s" % operational_state) + asserts.assert_equal(operational_state, old_opstate_dut, + "OperationalState(%s) should be the state before pause (%s)" % operational_state, old_opstate_dut) - self.print_step(12, "Send Resume command") - ret = await self.send_resume_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, - "errorStateID(%s) should be NoError(0x00)" % ret.commandResponseState.errorStateID) + await self.send_resume_cmd_with_check(13, op_errors.kNoError) - self.print_step(13, "Manually put the device in a state where it cannot receive a Pause command") - input("Press Enter when done.\n") + if self.check_pics("OPSTATE.S.M.RESUME_AFTER_ERR"): + self.print_instruction(16, "Manually put the device in the Running state") - self.print_step(14, "Send Pause command") - ret = await self.send_pause_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, - Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, - "errorStateID(%s) should be CommandInvalidInState(0x03)" % ret.commandResponseState.errorStateID) + await self.read_operational_state_with_check(17, op_states.kRunning) - self.print_step(15, "Manually put the device in a state where it cannot receive a Resume command") - input("Press Enter when done.\n") + self.print_instruction( + 18, "Manually cause the device to pause running due to an error, and be able to resume after clearing the error") + + await self.read_operational_state_with_check(19, op_states.kError) + + self.print_instruction(20, "Manually clear the error") + + await self.read_operational_state_with_check(21, op_states.kPaused) + + await self.send_resume_cmd_with_check(22, op_errors.kNoError) + + await self.read_operational_state_with_check(23, op_states.kRunning) + + if self.check_pics("RVCOPSTATE.S.M.ST_STOPPED"): + self.print_instruction(24, "Manually put the device in the Stopped(0x00) operational state") + + await self.read_operational_state_with_check(25, op_states.kStopped) + + await self.send_pause_cmd_with_check(26, op_errors.kCommandInvalidInState) + + await self.send_resume_cmd_with_check(27, op_errors.kCommandInvalidInState) + + if self.check_pics("RVCOPSTATE.S.M.ST_ERROR"): + self.print_instruction(28, "Manually put the device in the Error(0x03) operational state") + + await self.read_operational_state_with_check(29, op_states.kError) + + await self.send_pause_cmd_with_check(30, op_errors.kCommandInvalidInState) + + await self.send_resume_cmd_with_check(31, op_errors.kCommandInvalidInState) + + if self.check_pics("RVCOPSTATE.S.M.ST_CHARGING"): + self.print_instruction(32, "Manually put the device in the Charging(0x41) operational state") + + await self.read_operational_state_with_check(33, rvc_op_states.kCharging) + + await self.send_pause_cmd_with_check(34, op_errors.kCommandInvalidInState) + + self.print_instruction( + 35, "Manually put the device in the Charging(0x41) operational state and RVC Run Mode cluster's CurrentMode attribute set to a mode with the Idle mode tag") + + await self.read_operational_state_with_check(36, rvc_op_states.kCharging) + + await self.send_resume_cmd_with_check(37, op_errors.kCommandInvalidInState) + + if self.check_pics("RVCOPSTATE.S.M.ST_DOCKED"): + self.print_instruction(38, "Manually put the device in the Docked(0x42) operational state") + + await self.read_operational_state_with_check(39, rvc_op_states.kDocked) + + await self.send_pause_cmd_with_check(40, op_errors.kCommandInvalidInState) + + self.print_instruction( + 41, "Manually put the device in the Docked(0x42) operational state and RVC Run Mode cluster's CurrentMode attribute set to a mode with the Idle mode tag") + + await self.send_resume_cmd_with_check(42, op_errors.kCommandInvalidInState) + + if self.check_pics("RVCOPSTATE.S.M.ST_SEEKING_CHARGER"): + self.print_instruction(43, "Manually put the device in the SeekingCharger(0x40) operational state") + + await self.read_operational_state_with_check(44, rvc_op_states.kSeekingCharger) - self.print_step(16, "Send Resume command") - ret = await self.send_resume_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, - Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, - "errorStateID(%s) should be CommandInvalidInState(0x03)" % ret.commandResponseState.errorStateID) + await self.send_resume_cmd_with_check(45, op_errors.kCommandInvalidInState) if __name__ == "__main__": diff --git a/src/python_testing/TC_RVCOPSTATE_2_4.py b/src/python_testing/TC_RVCOPSTATE_2_4.py new file mode 100644 index 00000000000000..41de4cbbdaa4ef --- /dev/null +++ b/src/python_testing/TC_RVCOPSTATE_2_4.py @@ -0,0 +1,184 @@ +# +# 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 matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + +# This test requires several additional command line arguments +# run with +# --int-arg PIXIT_ENDPOINT: + + +# Takes an OpState or RvcOpState state enum and returns a string representation +def state_enum_to_text(state_enum): + if state_enum == Clusters.OperationalState.Enums.OperationalStateEnum.kStopped: + return "Stopped(0x00)" + elif state_enum == Clusters.OperationalState.Enums.OperationalStateEnum.kRunning: + return "Running(0x01)" + elif state_enum == Clusters.OperationalState.Enums.OperationalStateEnum.kPaused: + return "Paused(0x02)" + elif state_enum == Clusters.OperationalState.Enums.OperationalStateEnum.kError: + return "Error(0x03)" + elif state_enum == Clusters.RvcOperationalState.Enums.OperationalStateEnum.kSeekingCharger: + return "SeekingCharger(0x40)" + elif state_enum == Clusters.RvcOperationalState.Enums.OperationalStateEnum.kCharging: + return "Charging(0x41)" + elif state_enum == Clusters.RvcOperationalState.Enums.OperationalStateEnum.kDocked: + return "Docked(0x42)" + else: + return "UnknownEnumValue" + + +# Takes an OpState or RvcOpState error enum and returns a string representation +def error_enum_to_text(error_enum): + if error_enum == Clusters.OperationalState.Enums.ErrorStateEnum.kNoError: + return "NoError(0x00)" + elif error_enum == Clusters.OperationalState.Enums.ErrorStateEnum.kUnableToStartOrResume: + return "UnableToStartOrResume(0x01)" + elif error_enum == Clusters.OperationalState.Enums.ErrorStateEnum.kUnableToCompleteOperation: + return "UnableToCompleteOperation(0x02)" + elif error_enum == Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState: + return "CommandInvalidInState(0x03)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kFailedToFindChargingDock: + return "FailedToFindChargingDock(0x40)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kStuck: + return "Stuck(0x41)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kDustBinMissing: + return "DustBinMissing(0x42)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kDustBinFull: + return "DustBinFull(0x43)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kWaterTankEmpty: + return "WaterTankEmpty(0x44)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kWaterTankMissing: + return "WaterTankMissing(0x45)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kWaterTankLidOpen: + return "WaterTankLidOpen(0x46)" + elif error_enum == Clusters.RvcOperationalState.Enums.ErrorStateEnum.kMopCleaningPadMissing: + return "MopCleaningPadMissing(0x47)" + + def pics_TC_RVCOPSTATE_2_4(self) -> list[str]: + return ["RVCOPSTATE.S"] + + +class TC_RVCOPSTATE_2_4(MatterBaseTest): + def __init__(self, *args): + super().__init__(args) + self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] + + async def read_mod_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.RvcOperationalState + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def send_go_home_cmd(self) -> Clusters.Objects.RvcOperationalState.Commands.GoHome: + ret = await self.send_single_cmd(cmd=Clusters.Objects.RvcOperationalState.Commands.GoHome(), endpoint=self.endpoint) + asserts.assert_true(type_matches(ret, Clusters.Objects.RvcOperationalState.Commands.OperationalCommandResponse), + "Unexpected return type for GoHome") + return ret + + # Sends the GoHome command and checks that the returned error matches the expected_error + async def send_go_home_cmd_with_check(self, step_number, expected_error): + self.print_step(step_number, "Send GoHome command") + ret = self.send_go_home_cmd() + asserts.assert_equal(ret.commandResponseState.errorStateID, expected_error, + "errorStateID(%s) should be %s" % ret.commandResponseState.errorStateID, + error_enum_to_text(expected_error)) + + # Prints the step number, reads the operational state attribute and checks if it matches with expected_state + async def read_operational_state_with_check(self, step_number, expected_state): + self.print_step(step_number, "Read OperationalState") + operational_state = await self.read_mod_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.RvcOperationalState.Attributes.OperationalState) + logging.info("OperationalState: %s" % operational_state) + asserts.assert_equal(operational_state, expected_state, + "OperationalState(%s) should be %s" % operational_state, state_enum_to_text(expected_state)) + + # Prints the instruction and waits for a user input to continue + def print_instruction(self, step_number, instruction): + self.print_step(step_number, instruction) + input("Press Enter when done.\n") + + @async_test_body + async def test_TC_RVCOPSTATE_2_4(self): + + asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, + "PIXIT_ENDPOINT must be included on the command line in " + "the --int-arg flag as PIXIT_ENDPOINT:") + + asserts.assert_true(self.check_pics("RVCOPSTATE.S.A0004"), "RVCOPSTATE.S.A0004 must be supported") + asserts.assert_true(self.check_pics("RVCOPSTATE.S.C04.Rsp"), "RVCOPSTATE.S.C04.Rsp must be supported") + asserts.assert_true(self.check_pics("RVCOPSTATE.S.C128.Rsp"), "RVCOPSTATE.S.C128.Rsp must be supported") + + op_states = Clusters.OperationalState.Enums.OperationalStateEnum + rvc_op_states = Clusters.RvcOperationalState.Enums.OperationalStateEnum + op_errors = Clusters.OperationalState.Enums.ErrorStateEnum + + self.print_step(1, "Commissioning, already done") + + if self.check_pics("RVCOPSTATE.S.M.ST_STOPPED"): + self.print_instruction(2, "Manually put the device in the STOPPED operational state") + + await self.read_operational_state_with_check(3, op_states.kStopped) + + await self.send_go_home_cmd_with_check(4, op_errors.kNoError) + + await self.read_operational_state_with_check(5, rvc_op_states.kSeekingCharger) + + if self.check_pics("RVCOPSTATE.S.M.ST_RUNNING"): + self.print_instruction(6, "Manually put the device in the RUNNING operational state") + + await self.read_operational_state_with_check(7, op_states.kRunning) + + await self.send_go_home_cmd_with_check(8, op_errors.kNoError) + + await self.read_operational_state_with_check(9, rvc_op_states.kSeekingCharger) + + if self.check_pics("RVCOPSTATE.S.M.ST_PAUSED"): + self.print_instruction(10, "Manually put the device in the PAUSED operational state") + + await self.read_operational_state_with_check(11, op_states.kPaused) + + await self.send_go_home_cmd_with_check(12, op_errors.kNoError) + + await self.read_operational_state_with_check(13, rvc_op_states.kSeekingCharger) + + if self.check_pics("RVCOPSTATE.S.M.ST_ERROR"): + self.print_instruction(14, "Manually put the device in the ERROR operational state") + + await self.read_operational_state_with_check(15, op_states.kError) + + await self.send_go_home_cmd_with_check(16, op_errors.kCommandInvalidInState) + + if self.check_pics("RVCOPSTATE.S.M.ST_CHARGING"): + self.print_instruction(17, "Manually put the device in the CHARGING operational state") + + await self.read_operational_state_with_check(18, rvc_op_states.kCharging) + + await self.send_go_home_cmd_with_check(19, op_errors.kCommandInvalidInState) + + if self.check_pics("RVCOPSTATE.S.M.ST_DOCKED"): + self.print_instruction(20, "Manually put the device in the DOCKED operational state") + + await self.read_operational_state_with_check(21, rvc_op_states.kDocked) + + await self.send_go_home_cmd_with_check(22, op_errors.kCommandInvalidInState) + + +if __name__ == "__main__": + default_matter_test_main()