diff --git a/src/app/tests/suites/certification/Test_TC_TSTAT_2_2.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_2_2.yaml deleted file mode 100644 index 11be3889e4d9f7..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TSTAT_2_2.yaml +++ /dev/null @@ -1,2005 +0,0 @@ -# Copyright (c) 2021 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. - -name: 42.2.2. [TC-TSTAT-2.2] Setpoint Test Cases with server as DUT - -PICS: - - TSTAT.S - -config: - nodeId: 0x12344321 - cluster: "Thermostat" - endpoint: 1 - -tests: - - label: "Step 1: Commission DUT to TH" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Saving value for comparision in step 2a read MinCoolSetpointLimit" - PICS: TSTAT.S.A0017 - command: "readAttribute" - attribute: "MinCoolSetpointLimit" - response: - saveAs: MinCoolSetpointLimitValue - - - label: "Saving value for comparision in step 2a read MaxCoolSetpointLimit" - PICS: TSTAT.S.A0018 - command: "readAttribute" - attribute: "MaxCoolSetpointLimit" - response: - saveAs: MaxCoolSetpointLimitValue - - - label: - "Saving value for comparision in step 2c read attribute - MinSetpointDeadBand" - PICS: TSTAT.S.A0019 - command: "readAttribute" - attribute: "MinSetpointDeadBand" - response: - saveAs: MinSetpointDeadBandValue - - - label: "Saving value for comparision in step 3a read MinHeatSetpointLimit" - PICS: TSTAT.S.A0015 - command: "readAttribute" - attribute: "MinHeatSetpointLimit" - response: - saveAs: MinHeatSetpointLimitValue - - - label: - "Saving value for comparision in step 3 reads - UnoccupiedCoolingSetpoint attribute" - command: "readAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.A0013 - response: - saveAs: UnoccupiedCoolingSetpointValue - - - label: "Saving value for comparision in step 3a read MaxHeatSetpointLimit" - PICS: TSTAT.S.A0016 - command: "readAttribute" - attribute: "MaxHeatSetpointLimit" - response: - saveAs: MaxHeatSetpointLimitValue - - - label: - "Saving value for comparision in step3c read attribute - OccupiedHeatingSetpoint" - PICS: TSTAT.S.A0012 - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - response: - saveAs: OccupiedHeatingSetpointValue - - - label: - "Saving value for comparision in step3c read attribute - OccupiedCoolingSetpoint" - PICS: TSTAT.S.A0011 - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - response: - saveAs: OccupiedCoolingSetpointValue - - - label: - "Saving value for comparision in step 6a read attribute - AbsMinHeatSetpointLimit" - command: "readAttribute" - attribute: "AbsMinHeatSetpointLimit" - PICS: TSTAT.S.A0003 - response: - saveAs: AbsMinHeatSetpointLimitValue - - - label: - "Saving value for comparision in step 7a read attribute - AbsMaxHeatSetpointLimit" - command: "readAttribute" - attribute: "AbsMaxHeatSetpointLimit" - PICS: TSTAT.S.A0004 - response: - saveAs: AbsMaxHeatSetpointLimitValue - - - label: - "Saving value for comparision in step 8a read attribute - AbsMinCoolSetpointLimit" - command: "readAttribute" - attribute: "AbsMinCoolSetpointLimit" - PICS: TSTAT.S.A0005 - response: - saveAs: AbsMinCoolSetpointLimitValue - - - label: - "Saving value for comparision in step9a read attribute - AbsMaxCoolSetpointLimit" - command: "readAttribute" - attribute: "AbsMaxCoolSetpointLimit" - PICS: TSTAT.S.A0006 - response: - saveAs: AbsMaxCoolSetpointLimitValue - - #Using saved values when optional attributes are available - - label: - "Step 2a: Test Harness Client reads attribute OccupiedCoolingSetpoint - from the DUT" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - response: - constraints: - type: int16s - minValue: MinCoolSetpointLimitValue - maxValue: MaxCoolSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 2a: Test Harness Client reads OccupiedCoolingSetpoint attribute - from Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.A0017 && !TSTAT.S.A0018 - response: - constraints: - type: int16s - minValue: 1600 - maxValue: 3200 - - - label: - "Step 2a: Test Harness Client then attempts Writes a value back that - is different but valid for OccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - arguments: - value: 2500 - - - label: - "Step 2a: Test Harness Client reads it back again to confirm the - successful write of OccupiedCoolingSetpoint attribute" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - response: - value: 2500 - - - label: - "Step 2b: Test Harness Client then attempts Writes - OccupiedCoolingSetpoint to value below the MinCoolSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.A0017 - arguments: - value: 30 - response: - error: CONSTRAINT_ERROR - - #MinCoolSetPointLimit might be negative if not checked before decrement - - label: - "Step 2b: Test Harness Writes OccupiedCoolingSetpoint to value below - the MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #2 Test Harness Client attempts to write OccupiedCoolingSetpoint below the MinCoolSetpointLimit and confirms that the device does not accept the value. - ./chip-tool thermostat write occupied-cooling-setpoint 1000 1 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) for the value which is below of the MinCoolSetpointLimitValue - - [1676028984.901635][19375:19377] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676028984.901706][19375:19377] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676028984.901895][19375:19377] CHIP:EM: <<< [E:18153i M:141749864 (Ack:137408936)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1676028984.901980][19375:19377] CHIP:IN: (S) Sending msg 141749864 on secure session with LSID: 58847 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 2b: Test Harness Writes OccupiedCoolingSetpoint to value above - the MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.A0017 - arguments: - value: 4000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 2b: Test Harness Writes OccupiedCoolingSetpoint to value above - the MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 - arguments: - value: MaxCoolSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 2c: Test Harness Writes the limit of MaxCoolSetpointLimit to - OccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.A0017 - arguments: - value: 3200 - - - label: - "Step 2c: Test Harness Writes the limit of MaxCoolSetpointLimit to - OccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 - arguments: - value: MaxCoolSetpointLimitValue - - - label: - "Step 2c: Test Harness Writes the limit of MinCoolSetpointLimit to - OccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.F05 && !TSTAT.S.A0017 - arguments: - value: 1600 - - - label: - "Step 2c: Test Harness Writes the limit of MinCoolSetpointLimit to - OccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.F05 && TSTAT.S.A0017 - arguments: - value: MinCoolSetpointLimitValue - - #LowerLimit = Max(MinCoolSetpointLimit,(OccupiedHeatingSetpoint + MinSetpointDeadBand)) not possible in YAML - - label: - "Step 2c: Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = - Max(MinCoolSetpointLimit, (OccupiedHeatingSetpoint + - MinSetpointDeadBand)) to OccupiedCoolingSetpoint attribute when Auto - is enabled" - PICS: TSTAT.S.F05 && TSTAT.S.A0011 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - Test Harness Client then attempts to write OccupiedCoolingSetpoint to both of the limits of LowerLimit(1600) & MaxCoolSetpointLimit(3200) and confirms that the device does accept the value. See also Note 5. - - ./chip-tool thermostat write occupied-cooling-setpoint 1600 1 1 - On TH(chip-tool) verify that DUT sends a success response - [1676029009.026653][19381:19383] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029009.026688][19381:19383] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029009.026776][19381:19383] CHIP:EM: <<< [E:29492i M:142792974 (Ack:241003612)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - #Using saved values when optional attributes are available - - label: - "Step 3a: Test Harness Reads OccupiedHeatingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0016 - response: - constraints: - type: int16s - minValue: MinHeatSetpointLimitValue - maxValue: MaxHeatSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 3a: Test Harness Reads OccupiedHeatingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.A0015 && !TSTAT.S.A0016 - response: - constraints: - type: int16s - minValue: 700 - maxValue: 3000 - - - label: - "Step 3a: Test Harness Writes a value back that is different but - valid for OccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - arguments: - value: 2100 - - - label: - "Step 3a: Test Harness Reads it back again to confirm the successful - write of OccupiedHeatingSetpoint attribute" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - response: - value: 2100 - - - label: - "Step 3b: Test Harness Writes OccupiedHeatingSetpoint to value below - the MinHeatSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.A0015 - arguments: - value: 100 - response: - error: CONSTRAINT_ERROR - - #MinHeatSetpointLimit might be negative if not checked before decrement - - label: - "Step 3b: Test Harness Writes OccupiedHeatingSetpoint to value below - the MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client attempts to write OccupiedHeatingSetpoint below the MinHeatSetpointLimit and confirms that the device does not accept the value - - ./chip-tool thermostat write occupied-heating-setpoint 500 1 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676029113.651245][19392:19394] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029113.651285][19392:19394] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029113.651397][19392:19394] CHIP:EM: <<< [E:43315i M:59735604 (Ack:107613834)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 3b: Test Harness Writes OccupiedHeatingSetpoint to value above - the MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.A0016 - arguments: - value: 4010 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 3b: Test Harness Writes OccupiedHeatingSetpoint to value above - the MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 - arguments: - value: MaxHeatSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 3c: Test Harness Writes the limit of MaxHeatSetpointLimit to - OccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.F05 && !TSTAT.S.A0016 - arguments: - value: 3000 - - - label: - "Step 3c: Test Harness Writes the limit of MaxHeatSetpointLimit to - OccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.F05 && TSTAT.S.A0016 - arguments: - value: MaxHeatSetpointLimitValue - - - label: - "Step 3c: Test Harness Writes the limit of MaxHeatSetpointLimit to - OccupiedHeatingSetpoint attribute If TSTAT.S.F05 is true" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F05 && !TSTAT.S.A0015 - arguments: - value: 3000 - response: - error: CONSTRAINT_ERROR - - #UpperLimit = Min(MaxHeatSetpointLimit,(OccupiedCoolingSetpoint - MinSetpointDeadBand)) not possible in YAML - - label: - "Step 3c: Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = - Min(MaxHeatSetpointLimit, (OccupiedCoolingSetpoint - - MinSetpointDeadBand)) to OccupiedHeatingSetpoint attribute when Auto - is enabled" - PICS: - TSTAT.S.F05 && TSTAT.S.A0011 && TSTAT.S.A0012 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - Test Harness Client then attempts to write OccupiedHeatingSetpoint to both of the limits of MinHeatSetpointLimit(700) & UpperLimit(3000) and confirms that the device does accept the value. - - ./chip-tool thermostat write occupied-heating-setpoint 3000 1 1 - - On TH(chip-tool) verify that DUT sends a success response - 1676029222.303920][19403:19405] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029222.303955][19403:19405] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029222.304055][19403:19405] CHIP:EM: <<< [E:236i M:251820549 (Ack:138263425)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 - - ./chip-tool thermostat write occupied-heating-setpoint 700 1 1 - On TH(chip-tool) verify that DUT sends a success response - - - [1678943387.942204][770598:770600] CHIP:DMG: StatusIB = - [1678943387.942212][770598:770600] CHIP:DMG: { - [1678943387.942220][770598:770600] CHIP:DMG: status = 0x00 (SUCCESS), - [1678943387.942228][770598:770600] CHIP:DMG: }, - [1678943387.942236][770598:770600] CHIP:DMG: - [1678943387.942243][770598:770600] CHIP:DMG: }, - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 3c: Test Harness Writes the limit of MinHeatSetpointLimit to - OccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.A0015 - arguments: - value: 700 - - - label: - "Step 3c: Test Harness Writes the limit of MinHeatSetpointLimit to - OccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 - arguments: - value: MinHeatSetpointLimitValue - - - label: - "Step 4a: Test Harness Reads UnoccupiedCoolingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 - response: - constraints: - type: int16s - minValue: MinCoolSetpointLimitValue - maxValue: MaxCoolSetpointLimitValue - - - label: - "Step 4a: Test Harness Reads UnoccupiedCoolingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0017 && !TSTAT.S.A0018 - response: - constraints: - type: int16s - minValue: 1600 - maxValue: 3200 - - - label: - "Step 4a: Test Harness Writes a value back that is different but - valid for UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 - arguments: - value: 2500 - - - label: - "Step 4a: Test Harness Reads it back again to confirm the successful - write of UnoccupiedCoolingSetpoint attribute" - command: "readAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 - response: - value: 2500 - - - label: - "Step 4b: Test Harness Writes UnoccupiedCoolingSetpoint to value - below the MinCoolSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0017 - arguments: - value: 500 - response: - error: CONSTRAINT_ERROR - - #MinCoolSetpointLimit might be negative if not checked before decrement - - label: - "Step 4b: Test Harness Writes UnoccupiedCoolingSetpoint to value - below the MinCoolSetpointLimit" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0017 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client attempts to write OccupiedHeatingSetpoint below the MinHeatSetpointLimit and confirms that the device does not accept the value - - ./chip-tool thermostat write unoccupied-cooling-setpoint 500 1 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676029263.842915][19409:19411] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029263.842943][19409:19411] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029263.843052][19409:19411] CHIP:EM: <<< [E:47350i M:72320003 (Ack:188090912)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 4b: Test Harness Writes UnoccupiedCoolingSetpoint to value - above the MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0018 - arguments: - value: 4010 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 4b: Test Harness Writes UnoccupiedCoolingSetpoint to value - above the MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0018 - arguments: - value: MaxCoolSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 4c: Test Harness Writes the limit of MaxCoolSetpointLimit to - UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0018 && !TSTAT.S.F05 - arguments: - value: 3200 - - - label: - "Step 4c: Test Harness Writes the limit of MaxCoolSetpointLimit to - UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.F05 - arguments: - value: MaxCoolSetpointLimitValue - - #LowerLimit = Max(MinCoolSetpointLimit,(UnoccupiedCoolingSetpoint + MinSetpointDeadBand)) not possible in YAML - - label: - "Step 4c: Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = - Max(MinCoolSetpointLimit, (UnoccupiedCoolingSetpoint + - MinSetpointDeadBand)) to UnoccupiedCoolingSetpoint attribute" - PICS: - TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0013 && TSTAT.S.F05 && - PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - - below mentioned the example command to verify - - ./chip-tool thermostat write unoccupied-cooling-setpoint 2000 1 1 - On TH(chip-tool) verify that DUT sends a success response. As its an optional attribute, we are not getting expected result - [1676029365.250210][19420:19422] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029365.250263][19420:19422] CHIP:TOO: Response Failure: IM Error 0x00000586: General error: 0x86 (UNSUPPORTED_ATTRIBUTE) - [1676029365.250403][19420:19422] CHIP:EM: <<< [E:16230i M:267641165 (Ack:117850882)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1676029365.250467][19420:19422] CHIP:IN: (S) Sending msg 267641165 on secure session with LSID: 45606 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 4c: Test Harness Writes the limit of MinCoolSetpointLimit to - UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0017 && !TSTAT.S.F05 - arguments: - value: 1600 - - - label: - "Step 4c: Test Harness Writes the limit of MinCoolSetpointLimit to - UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0017 && TSTAT.S.F05 - arguments: - value: 1600 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 4c: Test Harness Writes the limit of MinCoolSetpointLimit to - UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.F05 - arguments: - value: MinCoolSetpointLimitValue - - #Using saved values when optional attributes are available - - label: - "Step 5a: Test Harness Reads UnoccupiedHeatingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0016 - response: - constraints: - type: int16s - minValue: MinHeatSetpointLimitValue - maxValue: MaxHeatSetpointLimitValue - - #Using hardcoded values when optional attributes are not available - - label: - "Step 5a: Test Harness Reads UnoccupiedHeatingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0015 && !TSTAT.S.A0016 - response: - constraints: - type: int16s - minValue: 700 - maxValue: 3000 - - - label: - "Step 5a: Test Harness Writes a value back that is different but - valid for UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 - arguments: - value: 2500 - - - label: - "Step 5a: Test Harness Reads it back again to confirm the successful - write of UnoccupiedHeatingSetpoint attribute" - command: "readAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 - response: - value: 2500 - - - label: - "Step 5b: Test Harness Writes UnoccupiedHeatingSetpoint to value - below the MinHeatSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0015 - arguments: - value: 100 - response: - error: CONSTRAINT_ERROR - - #MinHeatSetpointLimit might be negative if not checked before decrement - - label: - "Step 5b: Test Harness Writes UnoccupiedHeatingSetpoint to value - below the MinHeatSetpointLimit" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0015 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client attempts to write UnoccupiedHeatingSetpoint below the MinHeatSetpointLimit and confirms that the device does not accept the value - - ./chip-tool thermostat write unoccupied-heating-setpoint 500 1 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87). As its an optional attribute, we are not getting expected result - - [1676029557.268065][19431:19433] CHIP:DMG: } - [1676029557.268220][19431:19433] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029557.268290][19431:19433] CHIP:TOO: Response Failure: IM Error 0x00000586: General error: 0x86 (UNSUPPORTED_ATTRIBUTE) - [1676029557.268470][19431:19433] CHIP:EM: <<< [E:8458i M:31631638 (Ack:115187982)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 5b: Test Harness Writes UnoccupiedHeatingSetpoint to value - above the MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0016 - arguments: - value: 4010 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 5b: Test Harness Writes UnoccupiedHeatingSetpoint to value - above the MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0016 - arguments: - value: MaxHeatSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 5c: Test Harness Writes the limit of MaxHeatSetpointLimit to - UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0016 && !TSTAT.S.F05 - arguments: - value: 3000 - - - label: - "Step 5c: Test Harness Writes the limit of MaxHeatSetpointLimit to - UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 - arguments: - value: MaxHeatSetpointLimitValue - - - label: - "Step 5c: Test Harness Writes the limit of MaxHeatSetpointLimit to - UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0016 && TSTAT.S.F05 - arguments: - value: 3000 - response: - error: CONSTRAINT_ERROR - - #UpperLimit = Min(MaxHeatSetpointLimit,(UnoccupiedCoolingSetpoint - MinSetpointDeadBand)) not possible in YAML - - label: - "Step 5c: Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = - Min(MaxHeatSetpointLimit, (UnoccupiedCoolingSetpoint - - MinSetpointDeadBand)) to UnoccupiedHeatingSetpoint attribute when Auto - is enabled." - PICS: - TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0013 && TSTAT.S.F05 && - PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - - below mentioned the example command to verify - - ./chip-tool thermostat write unoccupied-heating-setpoint 2000 1 1 - On TH(chip-tool) verify that DUT sends a success response. As its an optional attribute, we are not getting expected result - - [1676029629.242182][19437:19439] CHIP:DMG: } - [1676029629.242250][19437:19439] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029629.242280][19437:19439] CHIP:TOO: Response Failure: IM Error 0x00000586: General error: 0x86 (UNSUPPORTED_ATTRIBUTE) - [1676029629.242366][19437:19439] CHIP:EM: <<< [E:51650i M:149591010 (Ack:214538556)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1676029629.242402][19437:19439] CHIP:IN: (S) Sending msg 149591010 on secure session with LSID: 6132 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 5c: Test Harness Writes the limit of MinHeatSetpointLimit to - UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0015 - arguments: - value: 700 - - - label: - "Step 5c: Test Harness Writes the limit of MinHeatSetpointLimit to - UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0015 - arguments: - value: MinHeatSetpointLimitValue - - #Using saved values when optional attributes are available - - label: - "Step 6a: Test Harness Reads MinHeatSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0016 && TSTAT.S.A0003 - response: - constraints: - type: int16s - minValue: AbsMinHeatSetpointLimitValue - maxValue: MaxHeatSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 6a: Test Harness Reads MinHeatSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.A0016 && !TSTAT.S.A0003 - response: - constraints: - type: int16s - minValue: 700 - maxValue: 3000 - - - label: - "Step 6a: Test Harness Writes a value back that is different but valid - for MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 - arguments: - value: 800 - - - label: - "Step 6a: Test Harness Reads it back again to confirm the successful - write of MinHeatSetpointLimit attribute" - command: "readAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 - response: - value: 800 - - - label: - "Step 6b: Test Harness Writes a value back that is different but - violates the deadband" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.A0015 && TSTAT.S.F05 - arguments: - value: 2000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 6b: Test Harness Writes MinHeatSetpointLimit to value below the - AbsMinHeatSetpointLimit " - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.A0003 - arguments: - value: 100 - response: - error: CONSTRAINT_ERROR - - #AbsMinHeatSetpointLimit might be negative if not checked before decrement - - label: - "Step 6b: Test Harness Writes MinHeatSetpointLimit to value below the - AbsMinHeatSetpointLimit " - PICS: - TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0003 && PICS_SKIP_SAMPLE_APP - verification: | - #1. Test Harness Client attempts to write MinHeatSetpointLimit below the AbsMinHeatSetpointLimit and confirms that the device does not accept the value. - ./chip-tool thermostat write min-heat-setpoint-limit 300 1 1 - On TH (chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676029705.839179][19450:19452] CHIP:DMG: } - [1676029705.839253][19450:19452] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029705.839287][19450:19452] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029705.839411][19450:19452] CHIP:EM: <<< [E:34538i M:185292291 (Ack:127655640)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1676029705.839456][19450:19452] CHIP:IN: (S) Sending msg 185292291 on secure session with LSID: 61694 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 6b: Test Harness Writes MinHeatSetpointLimit to value above the - AbsMaxHeatSetpointLimit " - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.A0016 - arguments: - value: 4050 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 6b: Test Harness Writes MinHeatSetpointLimit to value above the - AbsMaxHeatSetpointLimit " - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0016 - arguments: - value: MaxHeatSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 6c: Test Harness Writes the limit of MaxHeatSetpointLimit to - MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.F05 && !TSTAT.S.A0016 - arguments: - value: 3000 - - - label: - "Step 6c: Test Harness Writes the limit of MaxHeatSetpointLimit to - MinHeatSetpointimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.F05 && TSTAT.S.A0016 - arguments: - value: MaxHeatSetpointLimitValue - - #UpperLimit = Min(MaxHeatSetpointLimit,(MinCoolSetpointLimit - MinSetpointDeadBand)) not possible in YAML - - label: - "Step 6c: Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = - Min(MaxHeatSetpointLimit, (MinCoolSetpointLimit - - MinSetpointDeadBand)) to MinHeatSetpointLimit attribute when Auto is - enabled" - PICS: - TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.F05 && TSTAT.S.A0005 && - PICS_SKIP_SAMPLE_APP - verification: | - Test Harness Client then attempts to write MinHeatSetpointLimit to both of the limits of AbsMinHeatSetpointLimit & UpperLimit and confirms that the device does accept the value. - below is an exaple command. - - ./chip-tool thermostat write min-heat-setpoint-limit 1200 1 1 - - On TH(chip-tool) verify that DUT sends a success response - - [1676029742.329801][19458:19460] CHIP:DMG: } - [1676029742.329846][19458:19460] CHIP:DMG: - [1676029742.329883][19458:19460] CHIP:DMG: StatusIB = - [1676029742.329922][19458:19460] CHIP:DMG: { - [1676029742.329962][19458:19460] CHIP:DMG: status = 0x00 (SUCCESS), - [1676029742.330001][19458:19460] CHIP:DMG: }, - [1676029742.330040][19458:19460] CHIP:DMG: - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 6c: Test Harness Writes the limit of AbsMinHeatSetpointLimit to - MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.A0003 - arguments: - value: 700 - - - label: - "Step 6c: Test Harness Writes the limit of AbsMinHeatSetpointLimit to - MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0003 - arguments: - value: AbsMinHeatSetpointLimitValue - - #Using saved values when optional attributes are available - - label: - "Step 7a: Test Harness Reads MaxHeatSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: - TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && TSTAT.S.A0004 && - TSTAT.S.A0016 - response: - constraints: - type: int16s - minValue: MinHeatSetpointLimitValue - maxValue: AbsMaxHeatSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 7a: Test Harness Reads MaxHeatSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: - " TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && !TSTAT.S.A0004 && - !TSTAT.S.A0016 " - response: - constraints: - type: int16s - minValue: 700 - maxValue: 3000 - - - label: - "Step 7b: Test Harness Writes the limit of AbsMinHeatSetpointLimit to - MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 - arguments: - value: 700 - - - label: - "Step 7b: Test Harness Writes the limit of AbsMaxHeatSetpointLimit to - MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.A0015 && TSTAT.S.F05 - arguments: - value: 3000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 7b: Test Harness Writes a value back that is different but valid - for MaxHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 - arguments: - value: 2900 - - - label: - "Step 7b: Test Harness Reads it back again to confirm the successful - write of MaxHeatSetpointLimit attribute" - command: "readAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 - response: - value: 2900 - - - label: - "Step 7b: Test Harness Writes MaxHeatSetpointLimit to value below the - AbsMinHeatSetpointLimit " - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.A0015 - arguments: - value: 100 - response: - error: CONSTRAINT_ERROR - - #MinHeatSetpointLimit might be negative if not checked before decrement - - label: - "Step 7b: Test Harness Writes MaxHeatSetpointLimit to value below the - MinHeatSetpointLimit" - PICS: - TSTAT.S.F00 && TSTAT.S.A0016 && TSTAT.S.A0015 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client attempts to write MaxHeatSetpointLimit below the MinHeatSetpointLimit and confirms that the device does not accept the value. - ./chip-tool thermostat write max-heat-setpoint-limit 100 1 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676029976.380552][19475:19477] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029976.380598][19475:19477] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029976.380705][19475:19477] CHIP:EM: <<< [E:10254i M:97110781 (Ack:264765613)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 7b: Test Harness Writes MaxHeatSetpointLimit to value above the - AbsMaxHeatSetpointLimit " - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.A0004 - arguments: - value: 4000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 7b: Test Harness Writes MaxHeatSetpointLimit to value above the - AbsMaxHeatSetpointLimit " - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && TSTAT.S.A0004 - arguments: - value: AbsMaxHeatSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 7c: Test Harness Writes the limit of AbsMaxHeatSetpointLimit to - MaxHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && !TSTAT.S.A0004 - arguments: - value: 3000 - - - label: - "Step 7c: Test Harness Writes the limit of AbsMaxHeatSetpointLimit to - MaxHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && TSTAT.S.A0004 - arguments: - value: AbsMaxHeatSetpointLimitValue - - #UpperLimit = Min(AbsMaxHeatSetpointLimit,(MaxCoolSetpointLimit - MinSetpointDeadBand)) not possible in YAML - - label: - "Step 7c: Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = - Min(AbsMaxHeatSetpointLimit, (MaxCoolSetpointLimit - - MinSetpointDeadBand)) to MaxHeatSetpointLimit attribute" - PICS: - TSTAT.S.F00 && TSTAT.S.A0016 && TSTAT.S.F05 && TSTAT.S.A0018 && - PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation - - Test Harness Client then attempts to write MaxHeatSetpointLimit to both of the limits of MinHeatSetpointLimit & UpperLimit and confirms that the device does accept the value. - - below is an examble command - - ./chip-tool thermostat write max-heat-setpoint-limit 2000( Consider the different value but valid4) 1 1 - On TH(chip-tool) verify that DUT sends a success response - - [1676030018.852009][19481:19483] CHIP:DMG: Cluster = 0x201, - [1676030018.852054][19481:19483] CHIP:DMG: Attribute = 0x0000_0016, - [1676030018.852094][19481:19483] CHIP:DMG: } - [1676030018.852138][19481:19483] CHIP:DMG: - [1676030018.852178][19481:19483] CHIP:DMG: StatusIB = - [1676030018.852218][19481:19483] CHIP:DMG: { - [1676030018.852258][19481:19483] CHIP:DMG: status = 0x00 (SUCCESS), - [1676030018.852297][19481:19483] CHIP:DMG: }, - [1676030018.852337][19481:19483] CHIP:DMG: - [1676030018.852370][19481:19483] CHIP:DMG: }, - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 7c: Test Harness Writes the limit of MinHeatSetpointLimit to - MaxHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.A0015 - arguments: - value: 700 - - - label: - "Step 7c: Test Harness Writes the limit of MinHeatSetpointLimit to - MaxHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && TSTAT.S.A0015 - arguments: - value: MinHeatSetpointLimitValue - - #Using saved values when optional attributes are available - - label: - "Step 8a: Test Harness Reads MinCoolSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 && TSTAT.S.A0005 - response: - constraints: - type: int16s - minValue: AbsMinCoolSetpointLimitValue - maxValue: MaxCoolSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 8a: Test Harness Reads MinCoolSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0018 && !TSTAT.S.A0005 - response: - constraints: - type: int16s - minValue: 1600 - maxValue: 3200 - - - label: - "Step 8a: Test Harness Writes a value back that is different but valid - for MinCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 - arguments: - value: 2000 - - - label: - "Step 8a: Test Harness Reads it back again to confirm the successful - write of MinCoolSetpointLimit attribute" - command: "readAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 - response: - value: 2000 - - - label: - "Step 8b: Test Harness Writes MinCoolSetpointLimit to value below the - AbsMinCoolSetpointLimit " - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0005 - arguments: - value: 500 - response: - error: CONSTRAINT_ERROR - - #AbsMinCoolSetpointLimit might be negative if not checked before decrement - - label: - "Step 8b: Test Harness Writes MinCoolSetpointLimit to value below the - AbsMinCoolSetpointLimit" - PICS: - TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0005 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client then attempts to write MinCoolSetpointLimit below the AbsMinCoolSetpointLimit and confirms that the device does not accept the value. - - ./chip-tool thermostat write min-cool-setpoint-limit 400 1 1 - - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676030095.274876][19495:19497] CHIP:DMG: } - [1676030095.274936][19495:19497] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676030095.274965][19495:19497] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676030095.275097][19495:19497] CHIP:EM: <<< [E:51146i M:60043723 (Ack:28649429)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - label: - "Step 8b: Test Harness Writes MinCoolSetpointLimit to value above the - MaxCoolSetpointLimit " - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0018 - arguments: - value: 4000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 8b: Test Harness Writes MinCoolSetpointLimit to value above the - MaxCoolSetpointLimit " - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 - arguments: - value: MaxCoolSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 8c: Test Harness Writes the limit of MaxCoolSetpointLimit to - MinCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0018 - arguments: - value: 3200 - - - label: - "Step 8c: Test Harness Writes the limit of MaxCoolSetpointLimit to - MinCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 - arguments: - value: MaxCoolSetpointLimitValue - - - label: - "Step 8c: Test Harness Writes the limit of AbsMinCoolSetpointLimit to - MinCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0005 && !TSTAT.S.F05 - arguments: - value: 1600 - - - label: - "Step 8c: Test Harness Writes the limit of AbsMinCoolSetpointLimit to - MinCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0005 && !TSTAT.S.F05 - arguments: - value: AbsMinCoolSetpointLimitValue - - #LowerLimit = Max(AbsMinCoolSetpointLimit,(MinHeatSetpointLimit + MinSetpointDeadBand)) not possible in YAML - - label: - "Step 8c: Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = - Max(AbsMinCoolSetpointLimit, (MinHeatSetpointLimit + - MinSetpointDeadBand)) to MinCoolSetpointLimit attribute" - PICS: - TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0015 && TSTAT.S.F05 && - PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - Test Harness Client then attempts to write MinCoolSetpointLimit to both of the limits of LowerLimit & MaxCoolSetpointLimit and confirms that the device does accept the value. - - ./chip-tool thermostat write min-cool-setpoint-limit 1600 1 1 - - On TH(chip-tool) verify that DUT sends a success response - - [1678947233.814534][773656:773658] CHIP:DMG: - [1678947233.814541][773656:773658] CHIP:DMG: StatusIB = - [1678947233.814548][773656:773658] CHIP:DMG: { - [1678947233.814555][773656:773658] CHIP:DMG: status = 0x00 (SUCCESS), - [1678947233.814562][773656:773658] CHIP:DMG: }, - [1678947233.814570][773656:773658] CHIP:DMG: - [1678947233.814576][773656:773658] CHIP:DMG: }, - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - #Using saved values when optional attributes are available - - label: - "Step 9a: Test Harness Reads MaxCoolSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0017 && TSTAT.S.A0006 - response: - constraints: - type: int16s - minValue: MinCoolSetpointLimitValue - maxValue: AbsMaxCoolSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 9a: Test Harness Reads MaxCoolSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0017 && !TSTAT.S.A0006 - response: - constraints: - type: int16s - minValue: 1600 - maxValue: 3200 - - - label: - "Step 9a: Test Harness Writes a value back that is different but valid - for MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.F05 - arguments: - value: 2000 - - - label: - "Step 9a: Test Harness Reads it back again to confirm the successful - write of MaxCoolSetpointLimit attribute" - command: "readAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.F05 - response: - value: 2000 - - - label: - "Step 9b: Test Harness Writes MaxCoolSetpointLimit to value below the - AbsMinCoolSetpointLimit " - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0017 - arguments: - value: 500 - response: - error: CONSTRAINT_ERROR - - #AbsMinCoolSetpointLimit might be negative if not checked before decrement - - label: - "Step 9b: Test Harness Writes MaxCoolSetpointLimit to value below the - AbsMinCoolSetpointLimit" - PICS: - TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0017 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client attempts to write MaxCoolSetpointLimit below the MinCoolSetpointLimit and confirms that the device does not accept the value. - - ./chip-tool thermostat write max-cool-setpoint-limit 100 1 1 - - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676030395.441963][19525:19527] CHIP:DMG: } - [1676030395.442028][19525:19527] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676030395.442059][19525:19527] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676030395.442147][19525:19527] CHIP:EM: <<< [E:35527i M:176995637 (Ack:93643096)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 9b: Test Harness Writes MaxCoolSetpointLimit to value above the - MaxCoolSetpointLimit " - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0006 - arguments: - value: 4000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 9b: Test Harness Writes MaxCoolSetpointLimit to value above the - MaxCoolSetpointLimit " - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0006 - arguments: - value: AbsMaxCoolSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 9c: Test Harness Writes the limit of AbsMaxCoolSetpointLimit to - MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0006 - arguments: - value: 3200 - - - label: - "Step 9c: Test Harness Writes the limit of AbsMaxCoolSetpointLimit to - MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0006 - arguments: - value: AbsMaxCoolSetpointLimitValue - - - label: - "Step 9c: Test Harness Writes the limit of MinCoolSetpointLimit to - MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0017 && !TSTAT.S.F05 - arguments: - value: 1600 - - - label: - "Step 9c: Test Harness Writes the limit of MinCoolSetpointLimit to - MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0017 && TSTAT.S.F05 - arguments: - value: 1600 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 9c: Test Harness Writes the limit of MinCoolSetpointLimit to - MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0017 && !TSTAT.S.F05 - arguments: - value: MinCoolSetpointLimitValue - - #LowerLimit = Max(MinCoolSetpointLimit,(MaxHeatSetpointLimit + MinSetpointDeadBand)) not possible in YAML - - label: - "Step 9c: Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = - Max(MinCoolSetpointLimit, (MaxHeatSetpointLimit + - MinSetpointDeadBand)) to MaxCoolSetpointLimit attribute" - PICS: - TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0016 && TSTAT.S.F05 && - PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - Test Harness Client then attempts to write MaxCoolSetpointLimit to both of the limits of LowerLimit & AbsMaxCoolSetpointLimit and confirms that the device does accept the value. - below is an example command - - ./chip-tool thermostat write max-cool-setpoint-limit 2000 1 1 - - On TH verify that DUT sends a success response - - [1678947558.840324][773890:773892] CHIP:DMG: - [1678947558.840331][773890:773892] CHIP:DMG: StatusIB = - [1678947558.840339][773890:773892] CHIP:DMG: { - [1678947558.840347][773890:773892] CHIP:DMG: status = 0x00 (SUCCESS), - [1678947558.840354][773890:773892] CHIP:DMG: }, - [1678947558.840362][773890:773892] CHIP:DMG: - [1678947558.840369][773890:773892] CHIP:DMG: }, - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 10a: Test Harness Writes (sets back) default value of - MinHeatSetpointLimit" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0003 - arguments: - value: AbsMinHeatSetpointLimitValue - - - label: - "Step 10a: Test Harness Writes (sets back) default value of - MinHeatSetpointLimit" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.A0003 - arguments: - value: 700 - - - label: - "Step 10a: Test Harness Writes (sets back)default value of - MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && TSTAT.S.A0004 - arguments: - value: AbsMaxHeatSetpointLimitValue - - - label: - "Step 10a: Test Harness Writes (sets back)default value of - MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && !TSTAT.S.A0004 - arguments: - value: 3000 - - - label: - "Step 10a: Test Harness Writes MaxHeatSetpointLimit That meets the - deadband of 2.5C" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && TSTAT.S.F05 - arguments: - value: 2950 - - - label: - "Step 10b: Test Harness Writes (sets back) default value of - MinCoolSetpointLimit" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0005 - arguments: - value: AbsMinCoolSetpointLimitValue - - - label: - "Step 10b: Test Harness Writes (sets back) default value of - MinCoolSetpointLimit" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0005 - arguments: - value: 1600 - - - label: - "Step 10b: Test Harness Writes (sets back) default value of - MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0006 - arguments: - value: AbsMaxCoolSetpointLimitValue - - - label: - "Step 10b: Test Harness Writes (sets back) default value of - MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0006 - arguments: - value: 3200 - - - label: - "Step 11a: Test Harness Reads MinSetpointDeadBand attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 - response: - constraints: - type: int8s - minValue: 0 - maxValue: 25 - - - label: - "Step 11a: Test Harness Writes a value back that is different but - valid for MinSetpointDeadBand attribute" - command: "writeAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - arguments: - value: 5 - - - label: - "Step 11a: Test Harness Reads it back again to confirm the successful - write of MinSetpointDeadBand attribute" - command: "readAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - response: - value: 5 - - - label: "Step 11b: Test Harness Writes the value below MinSetpointDeadBand" - command: "writeAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - arguments: - value: -1 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 11b: Test Harness Writes the value above MinSetpointDeadBand " - command: "writeAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - arguments: - value: 30 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 11c: Test Harness Writes the min limit of MinSetpointDeadBand" - command: "writeAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - arguments: - value: 0 - - - label: - "Step 11c: Test Harness Writes the max limit of MinSetpointDeadBand" - command: "writeAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - arguments: - value: 25 - - - label: - "Step 12: Test Harness Reads ControlSequenceOfOperation from Server - DUT, if TSTAT.S.F01 is true" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F01 && !TSTAT.S.F00 - response: - constraints: - anyOf: [0, 1] - - - label: - "Step 12: Test Harness Reads ControlSequenceOfOperation from Server - DUT, if TSTAT.S.F00 is true" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && !TSTAT.S.F01 - response: - constraints: - anyOf: [2, 3] - - - label: - "Step 12: Test Harness Reads ControlSequenceOfOperation from Server - DUT, if both TSTAT.S.F01 and TSTAT.S.F01 are true" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && TSTAT.S.F01 - response: - constraints: - anyOf: [4, 5] - - - label: - "Step 12: Test Harness writes value 1 for attribute - ControlSequenceOfOperation. If TSTAT.S.F01 is true & TSTAT.S.F00 is - false" - command: "writeAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F01 && !TSTAT.S.F00 - arguments: - value: 1 - - - label: - "Step 12: Test Harness Read it back again to confirm the successful - write" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F01 && !TSTAT.S.F00 - response: - value: 1 - - - label: - "Step 12: Test Harness writes value 3 for attribute - ControlSequenceOfOperation. If TSTAT.S.F00 is true & TSTAT.S.F01 is - false" - command: "writeAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && !TSTAT.S.F01 - arguments: - value: 3 - - - label: - "Step 12: Test Harness Read it back again to confirm the successful - write" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && !TSTAT.S.F01 - response: - value: 3 - - - label: - "Step 12: Test Harness writes value 4 for attribute - ControlSequenceOfOperation. If TSTAT.S.F01 & TSTAT.S.F00 are true" - command: "writeAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && TSTAT.S.F01 - arguments: - value: 4 - - - label: - "Step 12: Test Harness Read it back again to confirm the successful - write" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && TSTAT.S.F01 - response: - value: 4 - - - label: - "Test Harness Writes MaxHeatSetpointLimit attribute to default value - of 2950 to meet deadband constraint" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.F05 - arguments: - value: 2950 - - - label: "Step 13: Sets OccupiedCoolingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - arguments: - value: 2600 - - - label: "Step 13: Sets OccupiedHeatingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - arguments: - value: 2000 - - - label: "Step 13: Sends SetpointRaise Command Heat Only" - PICS: TSTAT.S.F00 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 0 - - name: "Amount" - value: -30 - - - label: - "Step 13: Test Harness Reads back OccupiedHeatingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - response: - value: 1700 - - - label: "Step 14: Sets OccupiedHeatingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - arguments: - value: 2000 - - - label: "Step 14: Test Harness Sends SetpointRaise Command Heat Only" - PICS: TSTAT.S.F00 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 0 - - name: "Amount" - value: 30 - - - label: - "Step 14: Test Harness Reads back OccupiedHeatingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - response: - value: 2300 - - - label: "Step 15: Test Harness Sends SetpointRaise Command Cool Only" - PICS: TSTAT.S.F01 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 1 - - name: "Amount" - value: -30 - - - label: - "Step 15: Test Harness Reads back OccupiedCoolingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - response: - value: 2300 - - - label: "Step 16: Sets OccupiedCoolingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - arguments: - value: 2600 - - - label: "Step 16: Test Harness Sends SetpointRaise Command Cool Only" - PICS: TSTAT.S.F01 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 1 - - name: "Amount" - value: 30 - - - label: - "Step 16: Test Harness Reads back OccupiedCoolingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - response: - value: 2900 - - - label: "Step 17: Sets OccupiedCoolingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - arguments: - value: 2600 - - - label: "Step 17: Sets OccupiedHeatingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - arguments: - value: 2000 - - - label: "Step 17: Test Harness Sends SetpointRaise Command Heat & Cool" - PICS: TSTAT.S.F00 || TSTAT.S.F01 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 2 - - name: "Amount" - value: -30 - - - label: - "Step 17: Test Harness Reads back OccupiedCoolingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - response: - value: 2300 - - - label: - "Step 17: Test Harness Reads back OccupiedHeatingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - response: - value: 1700 - - - label: "Step 18: Sets OccupiedCoolingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - arguments: - value: 2600 - - - label: "Step 18: Sets OccupiedHeatingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - arguments: - value: 2000 - - - label: "Step 18: Test Harness Sends SetpointRaise Command Heat & Cool" - PICS: TSTAT.S.F00 || TSTAT.S.F01 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 2 - - name: "Amount" - value: 30 - - - label: - "Step 18: Test Harness Reads back OccupiedCoolingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - response: - value: 2900 - - - label: - "Step 18: Test Harness Reads back OccupiedHeatingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - response: - value: 2300 diff --git a/src/python_testing/TC_TSTAT_2_2.py b/src/python_testing/TC_TSTAT_2_2.py new file mode 100644 index 00000000000000..f4e1dfbc2b70d3 --- /dev/null +++ b/src/python_testing/TC_TSTAT_2_2.py @@ -0,0 +1,796 @@ +# +# 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. + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: +# run1: +# app: ${ALL_CLUSTERS_APP} +# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# script-args: > +# --storage-path admin_storage.json +# --commissioning-method on-network +# --discriminator 1234 +# --passcode 20202021 +# --endpoint 1 +# --trace-to json:${TRACE_TEST_JSON}.json +# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# factory-reset: true +# quiet: true +# === END CI TEST ARGUMENTS === + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import Status +from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) + +cluster = Clusters.Thermostat + + +class TC_TSTAT_2_2(MatterBaseTest): + + def desc_TC_TSTAT_2_2(self) -> str: + """Returns a description of this test""" + return "42.2.2. [TC-TSTAT-2.2] Setpoint Test Cases with server as DUT" + + def pics_TC_TSTAT_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 [self.check_pics("TSTAT.S")] + + def steps_TC_TSTAT_2_2(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2a", "Test Harness Client reads attribute OccupiedCoolingSetpoint from the DUT"), + TestStep("2b", "Test Harness Client then attempts Writes OccupiedCoolingSetpoint to a value below the MinCoolSetpointLimit"), + TestStep("2c", "Test Harness Writes the limit of MaxCoolSetpointLimit to OccupiedCoolingSetpoint attribute"), + TestStep("3a", "Test Harness Reads OccupiedHeatingSetpoint attribute from Server DUT and verifies that the value is within range"), + TestStep("3b", "Test Harness Writes OccupiedHeatingSetpoint to value below the MinHeatSetpointLimit"), + TestStep("3c", "Test Harness Writes the limit of MaxHeatSetpointLimit to OccupiedHeatingSetpoint attribute"), + TestStep("4a", "Test Harness Reads UnoccupiedCoolingSetpoint attribute from Server DUT and verifies that the value is within range"), + TestStep("4b", "Test Harness Writes UnoccupiedCoolingSetpoint to value below the MinCoolSetpointLimit"), + TestStep("4c", "Test Harness Writes the limit of MaxCoolSetpointLimit to UnoccupiedCoolingSetpoint attribute"), + TestStep("5a", "Test Harness Reads UnoccupiedHeatingSetpoint attribute from Server DUT and verifies that the value is within range"), + TestStep("5b", "Test Harness Writes UnoccupiedHeatingSetpoint to value below the MinHeatSetpointLimit"), + TestStep("5c", "Test Harness Writes the limit of MaxHeatSetpointLimit to UnoccupiedHeatingSetpoint attribute"), + TestStep("6a", "Test Harness Reads MinHeatSetpointLimit attribute from Server DUT and verifies that the value is within range"), + TestStep("6b", "Test Harness Writes a value back that is different but violates the deadband"), + TestStep("6c", "Test Harness Writes the limit of MaxHeatSetpointLimit to MinHeatSetpointLimit attribute"), + TestStep("7a", "Test Harness Reads MaxHeatSetpointLimit attribute from Server DUT and verifies that the value is within range"), + TestStep("7b", "Test Harness Writes the limit of AbsMinHeatSetpointLimit to MinHeatSetpointLimit attribute"), + TestStep("7c", "Test Harness Writes the limit of AbsMaxHeatSetpointLimit to MaxHeatSetpointLimit attribute"), + TestStep("8a", "Test Harness Reads MinCoolSetpointLimit attribute from Server DUT and verifies that the value is within range"), + TestStep("8b", "Test Harness Writes MinCoolSetpointLimit to value below the AbsMinCoolSetpointLimit "), + TestStep("8c", "Test Harness Writes the limit of MaxCoolSetpointLimit to MinCoolSetpointLimit attribute"), + TestStep("9a", "Test Harness Reads MaxCoolSetpointLimit attribute from Server DUT and verifies that the value is within range"), + TestStep("9b", "Test Harness Writes MaxCoolSetpointLimit to value below the AbsMinCoolSetpointLimit "), + TestStep("9c", "Test Harness Writes the limit of AbsMaxCoolSetpointLimit to MaxCoolSetpointLimit attribute"), + TestStep("10a", "Test Harness Writes (sets back) default value of MinHeatSetpointLimit"), + TestStep("10b", "Test Harness Writes (sets back) default value of MinCoolSetpointLimit"), + TestStep("11a", "Test Harness Reads MinSetpointDeadBand attribute from Server DUT and verifies that the value is within range"), + TestStep("11b", "Test Harness Writes the value below MinSetpointDeadBand"), + TestStep("11c", "Test Harness Writes the min limit of MinSetpointDeadBand"), + TestStep("12", "Test Harness Reads ControlSequenceOfOperation from Server DUT, if TSTAT.S.F01 is true"), + TestStep("13", "Sets OccupiedCoolingSetpoint to default value"), + TestStep("14", "Sets OccupiedHeatingSetpoint to default value"), + TestStep("15", "Test Harness Sends SetpointRaise Command Cool Only"), + TestStep("16", "Sets OccupiedCoolingSetpoint to default value"), + TestStep("17", "Sets OccupiedCoolingSetpoint to default value"), + TestStep("18", "Sets OccupiedCoolingSetpoint to default value"), + ] + + return steps + + @ async_test_body + async def test_TC_TSTAT_2_2(self): + endpoint = self.get_endpoint() + + # Default values for various optional attributes + AbsMaxCoolSetpointLimitValue = 3200 + AbsMaxHeatSetpointLimitValue = 3000 + AbsMinCoolSetpointLimitValue = 1600 + AbsMinHeatSetpointLimitValue = 700 + MinSetpointDeadBandValue = 250 + MaxCoolSetpointLimitValue = AbsMaxCoolSetpointLimitValue + MaxHeatSetpointLimitValue = AbsMaxHeatSetpointLimitValue + MinCoolSetpointLimitValue = AbsMinCoolSetpointLimitValue + MinHeatSetpointLimitValue = AbsMinHeatSetpointLimitValue + + # Supports a System Mode of Auto + hasAutoModeFeature = self.check_pics("TSTAT.S.F05") + # Thermostat is capable of managing a cooling device + hasCoolingFeature = self.check_pics("TSTAT.S.F01") + # Thermostat is capable of managing a heating device + hasHeatingFeature = self.check_pics("TSTAT.S.F00") + # Supports Occupied and Unoccupied setpoints + hasOccupancyFeature = self.check_pics("TSTAT.S.F02") + + # Does the device implement the AbsMaxCoolSetpointLimit attribute? + hasAbsMaxCoolSetpointLimitAttribute = self.check_pics("TSTAT.S.A0006") + # Does the device implement the AbsMaxHeatSetpointLimit attribute? + hasAbsMaxHeatSetpointLimitAttribute = self.check_pics("TSTAT.S.A0004") + # Does the device implement the AbsMinCoolSetpointLimit attribute? + hasAbsMinCoolSetpointLimitAttribute = self.check_pics("TSTAT.S.A0005") + # Does the device implement the AbsMinHeatSetpointLimit attribute? + hasAbsMinHeatSetpointLimitAttribute = self.check_pics("TSTAT.S.A0003") + # Does the device implement the MaxCoolSetpointLimit attribute? + hasMaxCoolSetpointLimitAttribute = self.check_pics("TSTAT.S.A0018") + # Does the device implement the MaxHeatSetpointLimit attribute? + hasMaxHeatSetpointLimitAttribute = self.check_pics("TSTAT.S.A0016") + # Does the device implement the MinCoolSetpointLimit attribute? + hasMinCoolSetpointLimitAttribute = self.check_pics("TSTAT.S.A0017") + # Does the device implement the MinHeatSetpointLimit attribute? + hasMinHeatSetpointLimitAttribute = self.check_pics("TSTAT.S.A0015") + # Does the device implement the MinSetpointDeadBand attribute? + hasMinSetpointDeadBandAttribute = self.check_pics("TSTAT.S.A0019") + # Does the device implement the OccupiedCoolingSetpoint attribute? + hasOccupiedCoolingSetpointAttribute = self.check_pics("TSTAT.S.A0011") + # Does the device implement the OccupiedHeatingSetpoint attribute? + hasOccupiedHeatingSetpointAttribute = self.check_pics("TSTAT.S.A0012") + # Does the device implement the UnoccupiedCoolingSetpoint attribute? + hasUnoccupiedCoolingSetpointAttribute = self.check_pics("TSTAT.S.A0013") + # Does the device implement the UnoccupiedHeatingSetpoint attribute? + hasUnoccupiedHeatingSetpointAttribute = self.check_pics("TSTAT.S.A0014") + + self.step("1") + + OccupiedHeatingSetpointValue = None + OccupiedCoolingSetpointValue = None + UnoccupiedHeatingSetpointValue = None + UnoccupiedCoolingSetpointValue = None + + ControlSequenceOfOperation = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + + if self.pics_guard(hasMinCoolSetpointLimitAttribute): + # Saving value for comparision in step 2a read MinCoolSetpointLimit + MinCoolSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinCoolSetpointLimit) + + if self.pics_guard(hasMaxCoolSetpointLimitAttribute): + # Saving value for comparision in step 2a read MaxCoolSetpointLimit + MaxCoolSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxCoolSetpointLimit) + + if self.pics_guard(hasMinSetpointDeadBandAttribute): + # Saving value for comparision in step 2c read attribute MinSetpointDeadBand + MinSetpointDeadBandValue = (await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinSetpointDeadBand)) * 10 + + if self.pics_guard(hasMinHeatSetpointLimitAttribute): + # Saving value for comparision in step 3a read MinHeatSetpointLimit + MinHeatSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinHeatSetpointLimit) + + if self.pics_guard(hasMaxHeatSetpointLimitAttribute): + # Saving value for comparision in step 3a read MaxHeatSetpointLimit + MaxHeatSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxHeatSetpointLimit) + + if self.pics_guard(hasOccupiedHeatingSetpointAttribute): + # Saving value for comparision in step3c read attribute OccupiedHeatingSetpoint + OccupiedHeatingSetpointValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + + if self.pics_guard(hasOccupiedCoolingSetpointAttribute): + # Saving value for comparision in step3c read attribute OccupiedCoolingSetpoint + OccupiedCoolingSetpointValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + + if self.pics_guard(hasUnoccupiedHeatingSetpointAttribute): + # Saving value for comparision in step3c read attribute OccupiedHeatingSetpoint + UnoccupiedHeatingSetpointValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedHeatingSetpoint) + + if self.pics_guard(hasUnoccupiedCoolingSetpointAttribute): + # Saving value for comparision in step3c read attribute OccupiedCoolingSetpoint + UnoccupiedCoolingSetpointValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedCoolingSetpoint) + + if self.pics_guard(hasAbsMinHeatSetpointLimitAttribute): + # Saving value for comparision in step 6a read attribute AbsMinHeatSetpointLimit + AbsMinHeatSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.AbsMinHeatSetpointLimit) + + if self.pics_guard(hasAbsMaxHeatSetpointLimitAttribute): + # Saving value for comparision in step 7a read attribute AbsMaxHeatSetpointLimit + AbsMaxHeatSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.AbsMaxHeatSetpointLimit) + + if self.pics_guard(hasAbsMinCoolSetpointLimitAttribute): + # Saving value for comparision in step 8a read attribute AbsMinCoolSetpointLimit + AbsMinCoolSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.AbsMinCoolSetpointLimit) + + if self.pics_guard(hasAbsMaxCoolSetpointLimitAttribute): + # Saving value for comparision in step9a read attribute AbsMaxCoolSetpointLimit + AbsMaxCoolSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.AbsMaxCoolSetpointLimit) + + self.step("2a") + + if self.pics_guard(hasCoolingFeature): + # Test Harness Client reads attribute OccupiedCoolingSetpoint from the DUT + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_greater_equal(val, MinCoolSetpointLimitValue) + asserts.assert_less_equal(val, MaxCoolSetpointLimitValue) + + # Test Harness Client then attempts Writes a value back that is different but valid for OccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(MinCoolSetpointLimitValue + ((MaxCoolSetpointLimitValue - MinCoolSetpointLimitValue) // 2)), endpoint_id=endpoint) + + # Test Harness Client reads it back again to confirm the successful write of OccupiedCoolingSetpoint attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_equal(val, MinCoolSetpointLimitValue + ((MaxCoolSetpointLimitValue - MinCoolSetpointLimitValue) // 2)) + + self.step("2b") + + if self.pics_guard(hasCoolingFeature): + # Test Harness Client then attempts Writes OccupiedCoolingSetpoint to value below the MinCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(MinCoolSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes OccupiedCoolingSetpoint to value above the MaxCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(MaxCoolSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("2c") + + if self.pics_guard(hasCoolingFeature): + # Test Harness Writes the limit of MaxCoolSetpointLimit to OccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(MaxCoolSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = Max(MinCoolSetpointLimit, (OccupiedHeatingSetpoint + MinSetpointDeadBand)) to OccupiedCoolingSetpoint attribute when Auto is enabled + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(max(MinCoolSetpointLimitValue, (OccupiedHeatingSetpointValue + (MinSetpointDeadBandValue)))), endpoint_id=endpoint) + + else: + # Test Harness Writes the limit of MinCoolSetpointLimit to OccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(MinCoolSetpointLimitValue), endpoint_id=endpoint) + + self.step("3a") + + if self.pics_guard(hasHeatingFeature): + # Test Harness Reads OccupiedHeatingSetpoint attribute from Server DUT and verifies that the value is within range + # Using saved values when optional attributes are available + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_greater_equal(val, MinHeatSetpointLimitValue) + asserts.assert_less_equal(val, MaxHeatSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for OccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(MinHeatSetpointLimitValue + ((MaxHeatSetpointLimitValue - MinHeatSetpointLimitValue) // 2)), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of OccupiedHeatingSetpoint attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_equal(val, MinHeatSetpointLimitValue + ((MaxHeatSetpointLimitValue - MinHeatSetpointLimitValue) // 2)) + + self.step("3b") + + if self.pics_guard(hasHeatingFeature): + # Test Harness Writes OccupiedHeatingSetpoint to value below the MinHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(MinHeatSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes OccupiedHeatingSetpoint to value above the MaxHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(MaxHeatSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("3c") + + if self.pics_guard(hasHeatingFeature): + # Test Harness Writes the limit of MinHeatSetpointLimit to OccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(MinHeatSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes the limit of MaxHeatSetpointLimit to OccupiedHeatingSetpoint attribute + upper_limit = min(MaxHeatSetpointLimitValue, (OccupiedCoolingSetpointValue - MinSetpointDeadBandValue)) + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(upper_limit), endpoint_id=endpoint) + + else: + # Test Harness Writes the limit of MaxHeatSetpointLimit to OccupiedHeatingSetpoint attribute If TSTAT.S.F05 is true + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(MaxHeatSetpointLimitValue), endpoint_id=endpoint) + + self.step("4a") + + if self.pics_guard(hasOccupancyFeature and hasCoolingFeature): + # Test Harness Reads UnoccupiedCoolingSetpoint attribute from Server DUT and verifies that the value is within range + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedCoolingSetpoint) + asserts.assert_greater_equal(val, MinCoolSetpointLimitValue) + asserts.assert_less_equal(val, MaxCoolSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for UnoccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(MinCoolSetpointLimitValue + ((MaxCoolSetpointLimitValue - MinCoolSetpointLimitValue) // 2)), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of UnoccupiedCoolingSetpoint attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedCoolingSetpoint) + asserts.assert_equal(val, MinCoolSetpointLimitValue + ((MaxCoolSetpointLimitValue - MinCoolSetpointLimitValue) // 2)) + + self.step("4b") + + if self.pics_guard(hasOccupancyFeature and hasCoolingFeature): + # Test Harness Writes UnoccupiedCoolingSetpoint to value below the MinCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(MinCoolSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes UnoccupiedCoolingSetpoint to value above the MaxCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(MaxCoolSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("4c") + + if self.pics_guard(hasOccupancyFeature and hasCoolingFeature): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = Max(MinCoolSetpointLimit, (UnoccupiedCoolingSetpoint + MinSetpointDeadBand)) to UnoccupiedCoolingSetpoint attribute + LowerLimit = max(MinCoolSetpointLimitValue, (UnoccupiedCoolingSetpointValue + MinSetpointDeadBandValue)) + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(LowerLimit), endpoint_id=endpoint) + + else: + # Test Harness Writes the limit of MinCoolSetpointLimit to UnoccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(MinCoolSetpointLimitValue), endpoint_id=endpoint) + # Test Harness Writes the limit of MaxCoolSetpointLimit to UnoccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(MaxCoolSetpointLimitValue), endpoint_id=endpoint) + + self.step("5a") + + if self.pics_guard(hasOccupancyFeature and hasHeatingFeature): + # Test Harness Reads UnoccupiedHeatingSetpoint attribute from Server DUT and verifies that the value is within range + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedHeatingSetpoint) + asserts.assert_greater_equal(val, MinHeatSetpointLimitValue) + asserts.assert_less_equal(val, MaxHeatSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for UnoccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(MinHeatSetpointLimitValue + ((MaxHeatSetpointLimitValue - MinHeatSetpointLimitValue) // 2)), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of UnoccupiedHeatingSetpoint attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedHeatingSetpoint) + asserts.assert_equal(val, MinHeatSetpointLimitValue + ((MaxHeatSetpointLimitValue - MinHeatSetpointLimitValue) // 2)) + + self.step("5b") + + if self.pics_guard(hasOccupancyFeature and hasHeatingFeature): + # Test Harness Writes UnoccupiedHeatingSetpoint to value below the MinHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(MinHeatSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes UnoccupiedHeatingSetpoint to value above the MaxHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(MaxHeatSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("5c") + + if self.pics_guard(hasOccupancyFeature and hasHeatingFeature): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes the limit of MaxHeatSetpointLimit to UnoccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(max(MaxHeatSetpointLimitValue, (UnoccupiedCoolingSetpointValue + MinSetpointDeadBandValue))), endpoint_id=endpoint) + + else: + # Test Harness Writes the limit of MaxHeatSetpointLimit to UnoccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(MaxHeatSetpointLimitValue), endpoint_id=endpoint) + + # Test Harness Writes the limit of MinHeatSetpointLimit to UnoccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(MinHeatSetpointLimitValue), endpoint_id=endpoint) + + self.step("6a") + + if self.pics_guard(hasHeatingFeature and hasMinHeatSetpointLimitAttribute): + # Test Harness Reads MinHeatSetpointLimit attribute from Server DUT and verifies that the value is within range + # Using saved values when optional attributes are available + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinHeatSetpointLimit) + asserts.assert_greater_equal(val, AbsMinHeatSetpointLimitValue) + asserts.assert_less_equal(val, MaxHeatSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for MinHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMinHeatSetpointLimitValue + 1), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MinHeatSetpointLimit attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinHeatSetpointLimit) + asserts.assert_equal(val, AbsMinHeatSetpointLimitValue + 1) + + self.step("6b") + + if self.pics_guard(hasHeatingFeature and hasMinHeatSetpointLimitAttribute): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes a value back that is different but violates the deadband + existingCoolMinSetpoint = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinCoolSetpointLimit) + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit((existingCoolMinSetpoint - MinSetpointDeadBandValue) + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MinHeatSetpointLimit to value below the AbsMinHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMinHeatSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MinHeatSetpointLimit to value above the AbsMaxHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMaxHeatSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("6c") + + if self.pics_guard(hasHeatingFeature and hasMinHeatSetpointLimitAttribute): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = Min(MaxHeatSetpointLimit, (MinCoolSetpointLimit - MinSetpointDeadBand)) to MinHeatSetpointLimit attribute when Auto is enabled + # UpperLimit = Min(MaxHeatSetpointLimit,(MinCoolSetpointLimit - MinSetpointDeadBand)) not possible in YAML + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(min(MaxHeatSetpointLimitValue, (MinCoolSetpointLimitValue - MinSetpointDeadBandValue))), endpoint_id=endpoint) + else: + # Test Harness Writes the limit of MaxHeatSetpointLimit to MinHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(MaxHeatSetpointLimitValue), endpoint_id=endpoint) + + # Test Harness Writes the limit of AbsMinHeatSetpointLimit to MinHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMinHeatSetpointLimitValue), endpoint_id=endpoint) + + self.step("7a") + + # Test Harness Reads MaxHeatSetpointLimit attribute from Server DUT and verifies that the value is within range + if self.pics_guard(hasHeatingFeature and hasMaxHeatSetpointLimitAttribute): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxHeatSetpointLimit) + asserts.assert_greater_equal(val, MinHeatSetpointLimitValue) + asserts.assert_less_equal(val, AbsMaxHeatSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for MaxHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(MinHeatSetpointLimitValue + 1), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MaxHeatSetpointLimit attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxHeatSetpointLimit) + asserts.assert_equal(val, MinHeatSetpointLimitValue + 1) + + self.step("7b") + + if self.pics_guard(hasHeatingFeature and hasMinHeatSetpointLimitAttribute): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes the limit of AbsMaxHeatSetpointLimit to MinHeatSetpointLimit attribute + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMaxHeatSetpointLimitValue), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + else: + # Test Harness Writes the limit of AbsMinHeatSetpointLimit to MinHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMinHeatSetpointLimitValue), endpoint_id=endpoint) + + # Test Harness Writes a value back that is different but valid for MaxHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(AbsMaxHeatSetpointLimitValue-1), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MaxHeatSetpointLimit attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxHeatSetpointLimit) + asserts.assert_equal(val, AbsMaxHeatSetpointLimitValue-1) + + if self.pics_guard(hasHeatingFeature and hasMaxHeatSetpointLimitAttribute): + # Test Harness Writes MaxHeatSetpointLimit to value below the AbsMinHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(AbsMinHeatSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MaxHeatSetpointLimit to value below the MinHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(MinHeatSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MaxHeatSetpointLimit to value above the AbsMaxHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(AbsMaxHeatSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("7c") + + if self.pics_guard(hasHeatingFeature and hasMaxHeatSetpointLimitAttribute): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = Min(AbsMaxHeatSetpointLimit, (MaxCoolSetpointLimit - MinSetpointDeadBand)) to MaxHeatSetpointLimit attribute + # UpperLimit = Min(AbsMaxHeatSetpointLimit,(MaxCoolSetpointLimit - MinSetpointDeadBand)) + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(min(AbsMaxHeatSetpointLimitValue, MaxCoolSetpointLimitValue - MinSetpointDeadBandValue)), endpoint_id=endpoint) + else: + # Test Harness Writes the limit of AbsMaxHeatSetpointLimit to MaxHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(AbsMaxHeatSetpointLimitValue), endpoint_id=endpoint) + + # Test Harness Writes the limit of MinHeatSetpointLimit to MaxHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(MinHeatSetpointLimitValue), endpoint_id=endpoint) + + self.step("8a") + + if self.pics_guard(hasCoolingFeature and hasMinCoolSetpointLimitAttribute): + # Test Harness Reads MinCoolSetpointLimit attribute from Server DUT and verifies that the value is within range + # Using saved values when optional attributes are available + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinCoolSetpointLimit) + asserts.assert_greater_equal(val, AbsMinCoolSetpointLimitValue) + asserts.assert_less_equal(val, MaxCoolSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for MinCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(AbsMinCoolSetpointLimitValue + 1), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MinCoolSetpointLimit attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinCoolSetpointLimit) + asserts.assert_equal(val, AbsMinCoolSetpointLimitValue + 1) + + self.step("8b") + + if self.pics_guard(hasCoolingFeature and hasMinCoolSetpointLimitAttribute): + # Test Harness Writes MinCoolSetpointLimit to value below the AbsMinCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(AbsMinCoolSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MinCoolSetpointLimit to value above the MaxCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(MaxCoolSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("8c") + + if self.pics_guard(hasCoolingFeature and hasMinCoolSetpointLimitAttribute): + # Test Harness Writes the limit of MaxCoolSetpointLimit to MinCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(MaxCoolSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = Max(AbsMinCoolSetpointLimit, (MinHeatSetpointLimit + MinSetpointDeadBand)) to MinCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(max(AbsMinCoolSetpointLimitValue, MinHeatSetpointLimitValue + MinSetpointDeadBandValue)), endpoint_id=endpoint) + else: + # Test Harness Writes the limit of AbsMinCoolSetpointLimit to MinCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(AbsMinCoolSetpointLimitValue), endpoint_id=endpoint) + + self.step("9a") + + if self.pics_guard(hasCoolingFeature and hasMaxCoolSetpointLimitAttribute): + # Test Harness Reads MaxCoolSetpointLimit attribute from Server DUT and verifies that the value is within range + # Using saved values when optional attributes are available + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxCoolSetpointLimit) + asserts.assert_greater_equal(val, MinCoolSetpointLimitValue) + asserts.assert_less_equal(val, AbsMaxCoolSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for MaxCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(AbsMaxCoolSetpointLimitValue - 1), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MaxCoolSetpointLimit attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxCoolSetpointLimit) + asserts.assert_equal(val, AbsMaxCoolSetpointLimitValue - 1) + + self.step("9b") + + if self.pics_guard(hasCoolingFeature and hasMaxCoolSetpointLimitAttribute): + # Test Harness Writes MaxCoolSetpointLimit to value below the AbsMinCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(MinCoolSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MaxCoolSetpointLimit to value above the AbsMaxCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(AbsMaxCoolSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("9c") + + if self.pics_guard(hasCoolingFeature and hasMaxCoolSetpointLimitAttribute): + # Test Harness Writes the limit of AbsMaxCoolSetpointLimit to MaxCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(AbsMaxCoolSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes the limit of MinCoolSetpointLimit to MaxCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(MinCoolSetpointLimitValue), endpoint_id=endpoint, expect_success=False) + + # Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = Max(MinCoolSetpointLimit, (MaxHeatSetpointLimit + MinSetpointDeadBand)) to MaxCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(max(MinCoolSetpointLimitValue, min(AbsMaxCoolSetpointLimitValue, (MaxHeatSetpointLimitValue + MinSetpointDeadBandValue)))), endpoint_id=endpoint) + else: + # Test Harness Writes the limit of MinCoolSetpointLimit to MaxCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(MinCoolSetpointLimitValue), endpoint_id=endpoint) + + self.step("10a") + + if self.pics_guard(hasHeatingFeature and hasMinHeatSetpointLimitAttribute): + # Test Harness Writes (sets back) default value of MinHeatSetpointLimit + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(MinHeatSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes MaxHeatSetpointLimit That meets the deadband of 2.5C + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(MaxCoolSetpointLimitValue - MinSetpointDeadBandValue), endpoint_id=endpoint) + else: + # Test Harness Writes (sets back)default value of MaxHeatSetpointLimit + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(MaxHeatSetpointLimitValue), endpoint_id=endpoint) + + self.step("10b") + + if self.pics_guard(hasCoolingFeature and hasMinCoolSetpointLimitAttribute): + if self.pics_guard(hasMinCoolSetpointLimitAttribute): + # Test Harness Writes (sets back) default value of MinCoolSetpointLimit + await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(AbsMinCoolSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasMaxCoolSetpointLimitAttribute): + # Test Harness Writes (sets back) default value of MaxCoolSetpointLimit + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(AbsMaxCoolSetpointLimitValue), endpoint_id=endpoint) + + self.step("11a") + + # Test Harness Reads MinSetpointDeadBand attribute from Server DUT and verifies that the value is within range + if self.pics_guard(hasAutoModeFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinSetpointDeadBand) + asserts.assert_less_equal(val, 25) + + if self.pics_guard(self.check_pics("TSTAT.S.M.MinSetpointDeadBandWritable")): + # Test Harness Writes a value back that is different but valid for MinSetpointDeadBand attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinSetpointDeadBand(5), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MinSetpointDeadBand attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinSetpointDeadBand) + asserts.assert_equal(val, 5) + + self.step("11b") + + if self.pics_guard(hasAutoModeFeature and self.check_pics("TSTAT.S.M.MinSetpointDeadBandWritable")): + # Test Harness Writes the value below MinSetpointDeadBand + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinSetpointDeadBand(-1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes the value above MinSetpointDeadBand + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinSetpointDeadBand(30), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("11c") + + if self.pics_guard(hasAutoModeFeature and self.check_pics("TSTAT.S.M.MinSetpointDeadBandWritable")): + # Test Harness Writes the min limit of MinSetpointDeadBand + await self.write_single_attribute(attribute_value=cluster.Attributes.MinSetpointDeadBand(0), endpoint_id=endpoint) + + # Test Harness Writes the max limit of MinSetpointDeadBand + await self.write_single_attribute(attribute_value=cluster.Attributes.MinSetpointDeadBand(25), endpoint_id=endpoint) + + self.step("12") + + # Test Harness Reads ControlSequenceOfOperation from Server DUT, if TSTAT.S.F01 is true + if self.pics_guard(hasCoolingFeature and not hasHeatingFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + asserts.assert_in(val, [0, 1]) + + # Test Harness Reads ControlSequenceOfOperation from Server DUT, if TSTAT.S.F00 is true + if self.pics_guard(hasHeatingFeature and not hasCoolingFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + asserts.assert_in(val, [2, 3]) + + # Test Harness Reads ControlSequenceOfOperation from Server DUT, if both TSTAT.S.F01 and TSTAT.S.F01 are true + if self.pics_guard(hasHeatingFeature and hasCoolingFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + asserts.assert_in(val, [4, 5]) + + if self.pics_guard(hasCoolingFeature and not hasHeatingFeature): + # Test Harness writes value 1 for attribute ControlSequenceOfOperation. If TSTAT.S.F01 is true & TSTAT.S.F00 is false + await self.write_single_attribute(attribute_value=cluster.Attributes.ControlSequenceOfOperation(1), endpoint_id=endpoint) + + # Test Harness Read it back again to confirm the successful write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + + # It's acceptable for the server to ignore any attempts to write to the ControlSequenceOfOperation attribute + if val != ControlSequenceOfOperation: + asserts.assert_equal(val, 1) + + # Test Harness writes value 3 for attribute ControlSequenceOfOperation. If TSTAT.S.F00 is true & TSTAT.S.F01 is false + if self.pics_guard(hasHeatingFeature and not hasCoolingFeature): + await self.write_single_attribute(attribute_value=cluster.Attributes.ControlSequenceOfOperation(3), endpoint_id=endpoint) + + # Test Harness Read it back again to confirm the successful write + if self.pics_guard(hasHeatingFeature and not hasCoolingFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + + # It's acceptable for the server to ignore any attempts to write to the ControlSequenceOfOperation attribute + if val != ControlSequenceOfOperation: + asserts.assert_equal(val, 3) + + # Test Harness writes value 4 for attribute ControlSequenceOfOperation. If TSTAT.S.F01 & TSTAT.S.F00 are true + if self.pics_guard(hasHeatingFeature and hasCoolingFeature): + await self.write_single_attribute(attribute_value=cluster.Attributes.ControlSequenceOfOperation(4), endpoint_id=endpoint) + + # Test Harness Read it back again to confirm the successful write + if self.pics_guard(hasHeatingFeature and hasCoolingFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + + # It's acceptable for the server to ignore any attempts to write to the ControlSequenceOfOperation attribute + if val != ControlSequenceOfOperation: + asserts.assert_equal(val, 4) + + self.step("13") + + if self.pics_guard(hasCoolingFeature): + # Sets OccupiedCoolingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(OccupiedCoolingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature): + # Sets OccupiedHeatingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(OccupiedHeatingSetpointValue), endpoint_id=endpoint) + + # Sends SetpointRaise Command Heat Only + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kHeat, amount=-30), endpoint=endpoint) + + # Test Harness Reads back OccupiedHeatingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_equal(val, OccupiedHeatingSetpointValue - 30 * 10) + + self.step("14") + + if self.pics_guard(hasHeatingFeature): + # Sets OccupiedHeatingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(OccupiedHeatingSetpointValue), endpoint_id=endpoint) + + # Test Harness Sends SetpointRaise Command Heat Only + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kHeat, amount=30), endpoint=endpoint) + + # Test Harness Reads back OccupiedHeatingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_equal(val, OccupiedHeatingSetpointValue + 30 * 10) + + self.step("15") + + if self.pics_guard(hasCoolingFeature): + # Test Harness Sends SetpointRaise Command Cool Only + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kCool, amount=-30), endpoint=endpoint) + + # Test Harness Reads back OccupiedCoolingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_equal(val, OccupiedCoolingSetpointValue - 30 * 10) + + self.step("16") + + if self.pics_guard(hasCoolingFeature): + # Sets OccupiedCoolingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(OccupiedCoolingSetpointValue), endpoint_id=endpoint) + + # Test Harness Sends SetpointRaise Command Cool Only + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kCool, amount=30), endpoint=endpoint) + + # Test Harness Reads back OccupiedCoolingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_equal(val, OccupiedCoolingSetpointValue + 30 * 10) + + self.step("17") + + if self.pics_guard(hasCoolingFeature): + # Sets OccupiedCoolingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(OccupiedCoolingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature): + # Sets OccupiedHeatingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(OccupiedHeatingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature or hasCoolingFeature): + # Test Harness Sends SetpointRaise Command Heat & Cool + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kBoth, amount=-30), endpoint=endpoint) + + if self.pics_guard(hasCoolingFeature): + # Test Harness Reads back OccupiedCoolingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_equal(val, OccupiedCoolingSetpointValue - 30 * 10) + + if self.pics_guard(hasHeatingFeature): + # Test Harness Reads back OccupiedHeatingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_equal(val, OccupiedHeatingSetpointValue - 30 * 10) + + self.step("18") + + if self.pics_guard(hasCoolingFeature): + # Sets OccupiedCoolingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(OccupiedCoolingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature): + # Sets OccupiedHeatingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(OccupiedHeatingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature or hasCoolingFeature): + # Test Harness Sends SetpointRaise Command Heat & Cool + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kBoth, amount=30), endpoint=endpoint) + + if self.pics_guard(hasCoolingFeature): + # Test Harness Reads back OccupiedCoolingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_equal(val, OccupiedCoolingSetpointValue + 30 * 10) + + if self.pics_guard(hasHeatingFeature): + # Test Harness Reads back OccupiedHeatingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_equal(val, OccupiedHeatingSetpointValue + 30 * 10) + + if self.pics_guard(hasCoolingFeature): + # Restores OccupiedCoolingSetpoint to original value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(OccupiedCoolingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature): + # Restores OccupiedHeatingSetpoint to original value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(OccupiedHeatingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasOccupancyFeature and hasCoolingFeature): + # Restores UnoccupiedCoolingSetpoint to original value + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(UnoccupiedCoolingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasOccupancyFeature and hasHeatingFeature): + # Restores UnoccupiedHeatingSetpoint to original value + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(UnoccupiedHeatingSetpointValue), endpoint_id=endpoint) + + +if __name__ == "__main__": + default_matter_test_main()