From 820034e157d6c31d4ff9ec0f208532463d0abec6 Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Wed, 14 Feb 2024 18:13:12 +0000 Subject: [PATCH 01/12] QA team requested that all attributes in EPM cluster be turned on in energy-management-app (#32095) * Fixes: #32089 In all-clusters-app, Set the EPM PowerMode attribute to AC. In energy-management-app turned on all features and attributes for testing. Fixed issue in TC_EPM_2_1.py when valid attribute is returned. Improved type checking for HarmonicCurrents and HarmonicPhases * Turned on additional attributes in EPM cluster on energy-management-app. Now runs tests without skipping unsupported attributes. * Turned on additional attributes in EPM cluster on energy-management-app. Now runs tests without skipping unsupported attributes. * Fixes #31925 - QA team expect HarmonicCurrents and HarmonicPhases to have 1 entry in the list for testing * Turned off 3 provisional features which fail the TC_DeviceConformance.py test * Removed EVSE attributes which are provisional in 1.3 (SOC, PNC, V2X) --- .../all-clusters-app.matter | 6 - .../all-clusters-common/all-clusters-app.zap | 105 +------ .../src/electrical-power-measurement-stub.cpp | 2 + .../src/energy-evse-stub.cpp | 4 +- .../energy-management-app.matter | 18 +- .../energy-management-app.zap | 290 ++++++++++++------ .../ElectricalPowerMeasurementDelegate.cpp | 55 ++-- .../src/EnergyEvseMain.cpp | 22 +- src/python_testing/TC_EPM_2_1.py | 39 ++- 9 files changed, 284 insertions(+), 257 deletions(-) diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 64d3a8f6283dba..a499ce042d37cd 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -8301,11 +8301,9 @@ endpoint 1 { callback attribute supplyState; callback attribute faultState; callback attribute chargingEnabledUntil; - callback attribute dischargingEnabledUntil; callback attribute circuitCapacity; callback attribute minimumChargeCurrent; callback attribute maximumChargeCurrent; - callback attribute maximumDischargeCurrent; callback attribute userMaximumChargeCurrent; callback attribute randomizationDelayWindow; callback attribute nextChargeStartTime; @@ -8313,13 +8311,9 @@ endpoint 1 { callback attribute nextChargeRequiredEnergy; callback attribute nextChargeTargetSoC; callback attribute approximateEVEfficiency; - callback attribute stateOfCharge; - callback attribute batteryCapacity; - callback attribute vehicleID; callback attribute sessionID; callback attribute sessionDuration; callback attribute sessionEnergyCharged; - callback attribute sessionEnergyDischarged; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index cb3e8ec2930b5e..f659f44a45c808 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -3097,10 +3097,10 @@ "side": "server", "type": "bitmap32", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3113,10 +3113,10 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0x0002", + "defaultValue": null, "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -8570,6 +8570,7 @@ "define": "LAUNDRY_DRYER_CONTROLS_CLUSTER", "side": "server", "enabled": 1, + "apiMaturity": "provisional", "attributes": [ { "name": "SupportedDrynessLevels", @@ -13815,22 +13816,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "DischargingEnabledUntil", - "code": 4, - "mfgCode": null, - "side": "server", - "type": "epoch_s", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "CircuitCapacity", "code": 5, @@ -13879,22 +13864,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "MaximumDischargeCurrent", - "code": 8, - "mfgCode": null, - "side": "server", - "type": "amperage_ma", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "UserMaximumChargeCurrent", "code": 9, @@ -14007,54 +13976,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "StateOfCharge", - "code": 48, - "mfgCode": null, - "side": "server", - "type": "percent", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "BatteryCapacity", - "code": 49, - "mfgCode": null, - "side": "server", - "type": "energy_mwh", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "VehicleID", - "code": 50, - "mfgCode": null, - "side": "server", - "type": "char_string", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "SessionID", "code": 64, @@ -14103,22 +14024,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "SessionEnergyDischarged", - "code": 67, - "mfgCode": null, - "side": "server", - "type": "energy_mwh", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "GeneratedCommandList", "code": 65528, diff --git a/examples/all-clusters-app/all-clusters-common/src/electrical-power-measurement-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/electrical-power-measurement-stub.cpp index 4bcea0e8ed9895..2a4c422d581e55 100644 --- a/examples/all-clusters-app/all-clusters-common/src/electrical-power-measurement-stub.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/electrical-power-measurement-stub.cpp @@ -47,5 +47,7 @@ void emberAfElectricalPowerMeasurementClusterInitCallback(chip::EndpointId endpo OptionalAttributes::kOptionalAttributeNeutralCurrent)); gEPMInstance->Init(); + + gEPMDelegate->SetPowerMode(PowerModeEnum::kAc); } } diff --git a/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp index f9983d47883852..72fe588995784e 100644 --- a/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp @@ -35,9 +35,7 @@ void emberAfEnergyEvseClusterInitCallback(chip::EndpointId endpointId) { gInstance = std::make_unique( endpointId, *gDelegate, - BitMask(EnergyEvse::Feature::kChargingPreferences, EnergyEvse::Feature::kPlugAndCharge, - EnergyEvse::Feature::kRfid, EnergyEvse::Feature::kSoCReporting, - EnergyEvse::Feature::kV2x), + BitMask(EnergyEvse::Feature::kChargingPreferences, EnergyEvse::Feature::kRfid), BitMask(OptionalAttributes::kSupportsUserMaximumChargingCurrent, OptionalAttributes::kSupportsRandomizationWindow, OptionalAttributes::kSupportsApproximateEvEfficiency), diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.matter b/examples/energy-management-app/energy-management-common/energy-management-app.matter index 1ab71d2cc0769d..c56280b2b72f08 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.matter +++ b/examples/energy-management-app/energy-management-common/energy-management-app.matter @@ -1896,7 +1896,19 @@ endpoint 1 { callback attribute ranges; callback attribute voltage; callback attribute activeCurrent; + callback attribute reactiveCurrent; + callback attribute apparentCurrent; callback attribute activePower; + callback attribute reactivePower; + callback attribute apparentPower; + callback attribute RMSVoltage; + callback attribute RMSCurrent; + callback attribute RMSPower; + callback attribute frequency; + callback attribute harmonicCurrents; + callback attribute harmonicPhases; + callback attribute powerFactor; + callback attribute neutralCurrent; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; @@ -1963,11 +1975,9 @@ endpoint 1 { callback attribute supplyState; callback attribute faultState; callback attribute chargingEnabledUntil; - callback attribute dischargingEnabledUntil; callback attribute circuitCapacity; callback attribute minimumChargeCurrent; callback attribute maximumChargeCurrent; - callback attribute maximumDischargeCurrent; callback attribute userMaximumChargeCurrent; callback attribute randomizationDelayWindow; callback attribute nextChargeStartTime; @@ -1975,13 +1985,9 @@ endpoint 1 { callback attribute nextChargeRequiredEnergy; callback attribute nextChargeTargetSoC; callback attribute approximateEVEfficiency; - callback attribute stateOfCharge; - callback attribute batteryCapacity; - callback attribute vehicleID; callback attribute sessionID; callback attribute sessionDuration; callback attribute sessionEnergyCharged; - callback attribute sessionEnergyDischarged; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.zap b/examples/energy-management-app/energy-management-common/energy-management-app.zap index ba1fa29d585485..d795b4fd482448 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.zap +++ b/examples/energy-management-app/energy-management-common/energy-management-app.zap @@ -2860,7 +2860,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2898,6 +2898,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "ReactiveCurrent", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "amperage_ma", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ApparentCurrent", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "amperage_ma", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "ActivePower", "code": 8, @@ -2914,6 +2946,166 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "ReactivePower", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "power_mw", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ApparentPower", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "power_mw", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RMSVoltage", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "voltage_mv", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RMSCurrent", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "amperage_ma", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RMSPower", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "power_mw", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Frequency", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "int64s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "HarmonicCurrents", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "HarmonicPhases", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PowerFactor", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int64s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NeutralCurrent", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "amperage_ma", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -3701,22 +3893,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "DischargingEnabledUntil", - "code": 4, - "mfgCode": null, - "side": "server", - "type": "epoch_s", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "CircuitCapacity", "code": 5, @@ -3765,22 +3941,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "MaximumDischargeCurrent", - "code": 8, - "mfgCode": null, - "side": "server", - "type": "amperage_ma", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "UserMaximumChargeCurrent", "code": 9, @@ -3893,54 +4053,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "StateOfCharge", - "code": 48, - "mfgCode": null, - "side": "server", - "type": "percent", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "BatteryCapacity", - "code": 49, - "mfgCode": null, - "side": "server", - "type": "energy_mwh", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "VehicleID", - "code": 50, - "mfgCode": null, - "side": "server", - "type": "char_string", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "SessionID", "code": 64, @@ -3989,22 +4101,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "SessionEnergyDischarged", - "code": 67, - "mfgCode": null, - "side": "server", - "type": "energy_mwh", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "GeneratedCommandList", "code": 65528, diff --git a/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp b/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp index fe712d92ae1667..fdda913a868a22 100644 --- a/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp +++ b/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp @@ -246,12 +246,17 @@ CHIP_ERROR ElectricalPowerMeasurementDelegate::EndRangesRead() return CHIP_NO_ERROR; } +static const Structs::HarmonicMeasurementStruct::Type kHarmonicCurrentMeasurements[] = { + { .order = 1, .measurement = MakeNullable(static_cast(100000)) } +}; + /* @brief This function is called by the cluster server at the start of read cycle * This could take a semaphore to stop a background update of the data */ -CHIP_ERROR ElectricalPowerMeasurementDelegate::StartHarmonicCurrentsRead() +CHIP_ERROR +ElectricalPowerMeasurementDelegate::StartHarmonicCurrentsRead() { - /* Since we don't an implementation here we don't need to do anything here */ + /* Since we have a static array we don't need to do anything here */ return CHIP_NO_ERROR; } CHIP_ERROR @@ -269,34 +274,34 @@ ElectricalPowerMeasurementDelegate::GetHarmonicCurrentsByIndex(uint8_t harmonicC * MatterReportingAttributeChangeCallback(mEndpointId, ElectricalPowerMeasurement::Id, HarmonicCurrents::Id); */ - /* if (rangeIndex >= ArraySize(mHarmonicCurrentMeasurements)) - * { - * return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; - * } - * - * range = mHarmonicCurrentMeasurements[rangeIndex]; - * - * return CHIP_NO_ERROR; - */ + /* Added to support testing using a static array for now */ + if (harmonicCurrentsIndex >= ArraySize(kHarmonicCurrentMeasurements)) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } - /* Return an empty list for now */ - return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + harmonicCurrent = kHarmonicCurrentMeasurements[harmonicCurrentsIndex]; + return CHIP_NO_ERROR; } /* @brief This function is called by the cluster server at the end of read cycle * This could release a semaphore to allow a background update of the data */ CHIP_ERROR ElectricalPowerMeasurementDelegate::EndHarmonicCurrentsRead() { - /* Since we don't an implementation here we don't need to do anything here */ + /* Since we have a static array we don't need to do anything here */ return CHIP_NO_ERROR; } +static const Structs::HarmonicMeasurementStruct::Type kHarmonicPhaseMeasurements[] = { + { .order = 1, .measurement = MakeNullable(static_cast(100000)) } +}; + /* @brief This function is called by the cluster server at the start of read cycle * This could take a semaphore to stop a background update of the data */ CHIP_ERROR ElectricalPowerMeasurementDelegate::StartHarmonicPhasesRead() { - /* Since we don't an implementation here we don't need to do anything here */ + /* Since we have a static array we don't need to do anything here */ return CHIP_NO_ERROR; } @@ -314,25 +319,21 @@ CHIP_ERROR ElectricalPowerMeasurementDelegate::GetHarmonicPhasesByIndex(uint8_t * MatterReportingAttributeChangeCallback(mEndpointId, ElectricalPowerMeasurement::Id, HarmonicPhases::Id); */ - /* if (rangeIndex >= ArraySize(mHarmonicPhaseMeasurements)) - * { - * return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; - * } - * - * range = mHarmonicPhaseMeasurements[rangeIndex]; - * - * return CHIP_NO_ERROR; - */ + /* Added to support testing using a static array for now */ + if (harmonicPhaseIndex >= ArraySize(kHarmonicPhaseMeasurements)) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } - /* Return an empty list for now */ - return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + harmonicPhase = kHarmonicPhaseMeasurements[harmonicPhaseIndex]; + return CHIP_NO_ERROR; } /* @brief This function is called by the cluster server at the end of read cycle * This could release a semaphore to allow a background update of the data */ CHIP_ERROR ElectricalPowerMeasurementDelegate::EndHarmonicPhasesRead() { - /* Since we don't an implementation here we don't need to do anything here */ + /* Since we have a static array we don't need to do anything here */ return CHIP_NO_ERROR; } diff --git a/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp b/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp index 92593efe6f8370..9beff80e8dc22a 100644 --- a/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp +++ b/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp @@ -152,9 +152,7 @@ CHIP_ERROR EnergyEvseInit() /* Manufacturer may optionally not support all features, commands & attributes */ gEvseInstance = std::make_unique( EndpointId(ENERGY_EVSE_ENDPOINT), *gEvseDelegate, - BitMask(EnergyEvse::Feature::kChargingPreferences, EnergyEvse::Feature::kPlugAndCharge, - EnergyEvse::Feature::kRfid, EnergyEvse::Feature::kSoCReporting, - EnergyEvse::Feature::kV2x), + BitMask(EnergyEvse::Feature::kChargingPreferences, EnergyEvse::Feature::kRfid), BitMask(EnergyEvse::OptionalAttributes::kSupportsUserMaximumChargingCurrent, EnergyEvse::OptionalAttributes::kSupportsRandomizationWindow, EnergyEvse::OptionalAttributes::kSupportsApproximateEvEfficiency), @@ -224,13 +222,27 @@ CHIP_ERROR EnergyMeterInit() } /* Manufacturer may optionally not support all features, commands & attributes */ + /* Turning on all optional features and attributes for test certification purposes */ gEPMInstance = std::make_unique( EndpointId(ENERGY_EVSE_ENDPOINT), *gEPMDelegate, - BitMask(ElectricalPowerMeasurement::Feature::kAlternatingCurrent), + BitMask( + ElectricalPowerMeasurement::Feature::kDirectCurrent, ElectricalPowerMeasurement::Feature::kAlternatingCurrent, + ElectricalPowerMeasurement::Feature::kPolyphasePower, ElectricalPowerMeasurement::Feature::kHarmonics, + ElectricalPowerMeasurement::Feature::kPowerQuality), BitMask( ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRanges, ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeVoltage, - ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeActiveCurrent)); + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeActiveCurrent, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeReactiveCurrent, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeApparentCurrent, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeReactivePower, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeApparentPower, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSVoltage, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSCurrent, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeRMSPower, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeFrequency, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributePowerFactor, + ElectricalPowerMeasurement::OptionalAttributes::kOptionalAttributeNeutralCurrent)); if (!gEPMInstance) { diff --git a/src/python_testing/TC_EPM_2_1.py b/src/python_testing/TC_EPM_2_1.py index fc4347e1ec0a0d..8be16208169de2 100644 --- a/src/python_testing/TC_EPM_2_1.py +++ b/src/python_testing/TC_EPM_2_1.py @@ -23,6 +23,9 @@ logger = logging.getLogger(__name__) +MIN_INT64_ALLOWED = -pow(2, 62) # -(2^62) +MAX_INT64_ALLOWED = pow(2, 62) # (2^62) + class TC_EPM_2_1(MatterBaseTest, EnergyReportingBaseTestHelper): @@ -133,52 +136,52 @@ async def test_TC_EPM_2_1(self): self.step("6") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.Voltage.attribute_id in supported_attributes): - voltage = await self.check_epm_attribute_in_range("Voltage", -2 ^ 62, 2 ^ 62, allow_null=True) + voltage = await self.check_epm_attribute_in_range("Voltage", MIN_INT64_ALLOWED, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd Voltage: {voltage}") self.step("7") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.ActiveCurrent.attribute_id in supported_attributes): - active_current = await self.check_epm_attribute_in_range("ActiveCurrent", -2 ^ 62, 2 ^ 62, allow_null=True) + active_current = await self.check_epm_attribute_in_range("ActiveCurrent", MIN_INT64_ALLOWED, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd ActiveCurrent: {active_current}") self.step("8") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.ReactiveCurrent.attribute_id in supported_attributes): - reactive_current = await self.check_epm_attribute_in_range("ReactiveCurrent", -2 ^ 62, 2 ^ 62, allow_null=True) + reactive_current = await self.check_epm_attribute_in_range("ReactiveCurrent", MIN_INT64_ALLOWED, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd ReactiveCurrent: {reactive_current}") self.step("9") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.ApparentCurrent.attribute_id in supported_attributes): - apparent_current = await self.check_epm_attribute_in_range("ApparentCurrent", 0, 2 ^ 62, allow_null=True) + apparent_current = await self.check_epm_attribute_in_range("ApparentCurrent", 0, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd ApparentCurrent: {apparent_current}") self.step("10") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.ActivePower.attribute_id in supported_attributes): - active_power = await self.check_epm_attribute_in_range("ActivePower", -2 ^ 62, 2 ^ 62, allow_null=True) + active_power = await self.check_epm_attribute_in_range("ActivePower", MIN_INT64_ALLOWED, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd ActivePower: {active_power}") self.step("11") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.ReactivePower.attribute_id in supported_attributes): - reactive_power = await self.check_epm_attribute_in_range("ReactivePower", -2 ^ 62, 2 ^ 62, allow_null=True) + reactive_power = await self.check_epm_attribute_in_range("ReactivePower", MIN_INT64_ALLOWED, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd ReactivePower: {reactive_power}") self.step("12") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.ApparentPower.attribute_id in supported_attributes): - apparent_power = await self.check_epm_attribute_in_range("ApparentPower", -2 ^ 62, 2 ^ 62, allow_null=True) + apparent_power = await self.check_epm_attribute_in_range("ApparentPower", MIN_INT64_ALLOWED, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd ApparentPower: {apparent_power}") self.step("13") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.RMSVoltage.attribute_id in supported_attributes): - rms_voltage = await self.check_epm_attribute_in_range("RMSVoltage", -2 ^ 62, 2 ^ 62, allow_null=True) + rms_voltage = await self.check_epm_attribute_in_range("RMSVoltage", MIN_INT64_ALLOWED, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd RMSVoltage: {rms_voltage}") self.step("14") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.RMSCurrent.attribute_id in supported_attributes): - rms_current = await self.check_epm_attribute_in_range("RMSCurrent", -2 ^ 62, 2 ^ 62, allow_null=True) + rms_current = await self.check_epm_attribute_in_range("RMSCurrent", MIN_INT64_ALLOWED, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd RMSCurrent: {rms_current}") self.step("15") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.RMSPower.attribute_id in supported_attributes): - rms_power = await self.check_epm_attribute_in_range("RMSPower", -2 ^ 62, 2 ^ 62, allow_null=True) + rms_power = await self.check_epm_attribute_in_range("RMSPower", MIN_INT64_ALLOWED, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd RMSPower: {rms_power}") self.step("16") @@ -188,13 +191,23 @@ async def test_TC_EPM_2_1(self): self.step("17") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.HarmonicCurrents.attribute_id in supported_attributes): - harmonic_currents = await self.read_epm_attribute_expect_success("HarmonicCurrents", allow_null=True) + harmonic_currents = await self.read_epm_attribute_expect_success("HarmonicCurrents") logger.info(f"Rx'd HarmonicCurrents: {harmonic_currents}") + asserts.assert_is(type(harmonic_currents), list) + for index, entry in enumerate(harmonic_currents): + logging.info(f" [{index}] order:{entry.order} measurement:{entry.measurement}") + asserts.assert_greater_equal(entry.order, 1) + self.check_value_in_range("Measurement", entry.measurement, MIN_INT64_ALLOWED, MAX_INT64_ALLOWED) self.step("18") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.HarmonicPhases.attribute_id in supported_attributes): - harmonic_phases = await self.read_epm_attribute_expect_success("HarmonicPhases", allow_null=True) + harmonic_phases = await self.read_epm_attribute_expect_success("HarmonicPhases") logger.info(f"Rx'd HarmonicPhases: {harmonic_phases}") + asserts.assert_is(type(harmonic_phases), list) + for index, entry in enumerate(harmonic_phases): + logging.info(f" [{index}] order:{entry.order} measurement:{entry.measurement}") + asserts.assert_greater_equal(entry.order, 1) + self.check_value_in_range("Measurement", entry.measurement, MIN_INT64_ALLOWED, MAX_INT64_ALLOWED) self.step("19") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.PowerFactor.attribute_id in supported_attributes): @@ -203,7 +216,7 @@ async def test_TC_EPM_2_1(self): self.step("20") if self.pics_guard(Clusters.ElectricalPowerMeasurement.Attributes.NeutralCurrent.attribute_id in supported_attributes): - neutral_current = await self.check_epm_attribute_in_range("NeutralCurrent", -2 ^ 62, 2 ^ 62, allow_null=True) + neutral_current = await self.check_epm_attribute_in_range("NeutralCurrent", MIN_INT64_ALLOWED, MAX_INT64_ALLOWED, allow_null=True) logger.info(f"Rx'd NeutralCurrent: {neutral_current}") From 7113c982f24ca98718bfeb62e9236191ad8ceb6d Mon Sep 17 00:00:00 2001 From: Rob Bultman Date: Wed, 14 Feb 2024 14:01:48 -0500 Subject: [PATCH 02/12] [TCTL] Change name from Mode to State (#31978) * Change name * Restyled by prettier-yaml --------- Co-authored-by: Restyled.io --- src/app/tests/suites/certification/Test_TC_TCTL_3_2.yaml | 7 ++++--- src/app/tests/suites/certification/Test_TC_TCTL_3_3.yaml | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_TCTL_3_2.yaml b/src/app/tests/suites/certification/Test_TC_TCTL_3_2.yaml index 2c22fc392f5d52..b2ca70136c3618 100644 --- a/src/app/tests/suites/certification/Test_TC_TCTL_3_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_TCTL_3_2.yaml @@ -135,7 +135,7 @@ tests: Operate device such that a temperature number cannot be accepted cluster: "LogCommands" command: "UserPrompt" - PICS: PICS_USER_PROMPT && TCTL.S.M.SupportsInvalidInMode + PICS: PICS_USER_PROMPT && TCTL.S.M.SupportsInvalidInState arguments: values: - name: "message" @@ -147,7 +147,8 @@ tests: "Step 10: TH sends command SetTemperatureCommand with a temperature number between minTemp and maxTemp inclusive, saved as setTemp" command: "SetTemperature" - PICS: TCTL.S.C00.Rsp && PICS_USER_PROMPT && TCTL.S.M.SupportsInvalidInMode + PICS: + TCTL.S.C00.Rsp && PICS_USER_PROMPT && TCTL.S.M.SupportsInvalidInState arguments: values: - name: "TargetTemperature" @@ -164,7 +165,7 @@ tests: value: 5000 - label: "Step 11: TH reads from the DUT the TemperatureSetpoint attribute" - PICS: TCTL.S.A0000 && TCTL.S.M.SupportsInvalidInMode + PICS: TCTL.S.A0000 && TCTL.S.M.SupportsInvalidInState command: "readAttribute" attribute: "TemperatureSetpoint" response: diff --git a/src/app/tests/suites/certification/Test_TC_TCTL_3_3.yaml b/src/app/tests/suites/certification/Test_TC_TCTL_3_3.yaml index bca4e83790ee2b..1ab48b81dfa8af 100644 --- a/src/app/tests/suites/certification/Test_TC_TCTL_3_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_TCTL_3_3.yaml @@ -101,7 +101,7 @@ tests: Operate device such that a temperature level cannot be accepted cluster: "LogCommands" command: "UserPrompt" - PICS: PICS_USER_PROMPT && TCTL.S.M.SupportsInvalidInMode + PICS: PICS_USER_PROMPT && TCTL.S.M.SupportsInvalidInState arguments: values: - name: "message" @@ -111,7 +111,7 @@ tests: - label: "Step 7: TH sends command SetTemperatureCommand with an invalid value" - PICS: TCTL.S.C00.Rsp && TCTL.S.M.SupportsInvalidInMode + PICS: TCTL.S.C00.Rsp && TCTL.S.M.SupportsInvalidInState command: "SetTemperature" arguments: values: @@ -121,7 +121,7 @@ tests: error: CONSTRAINT_ERROR - label: "Wait for 5s" - PICS: TCTL.S.C00.Rsp && TCTL.S.M.SupportsInvalidInMode + PICS: TCTL.S.C00.Rsp && TCTL.S.M.SupportsInvalidInState cluster: "DelayCommands" command: "WaitForMs" arguments: @@ -131,7 +131,7 @@ tests: - label: "Step 8: TH reads from the DUT the SelectedTemperatureLevel attribute" - PICS: TCTL.S.A0004 && TCTL.S.M.SupportsInvalidInMode + PICS: TCTL.S.A0004 && TCTL.S.M.SupportsInvalidInState command: "readAttribute" attribute: "SelectedTemperatureLevel" response: From c5945680f0800501443da0e55b822a9dfd258275 Mon Sep 17 00:00:00 2001 From: beckerzito Date: Wed, 14 Feb 2024 17:16:44 -0300 Subject: [PATCH 03/12] Add oven opstate yaml (#31557) * Adding OvenOpState test scripts and ciTests.json file * Restyled by whitespace * Restyled by prettier-json * Restyled by prettier-yaml * Restyled by autopep8 * added OvenOpstate2_4 and updated other files * Delete src/app/tests/suites/certification/Test_TC_OVENOPSTATE_1_1.yml * Delete src/app/tests/suites/certification/Test_TC_OVENOPSTATE_2_2.yml * Restyled by whitespace * Restyled by prettier-json * Restyled by prettier-yaml * updated test scripts * updated Test_TC_OVENOPSTATE_2_2.yaml * Restyled by prettier-yaml * updated yamls and ran zap regen * Restyled by isort * Restyled by isort * updated __init__.py * updated citests and mannual tests * updated python scripts * Restyled by autopep8 * updated step3 to automated test in 2_2 * updated citests.json * updated Tests and ciTest file * Revert "updated Tests and ciTest file" This reverts commit 163c8105fc8e96c1be42e01af5f43cd628697dad. * updated according review * zap regen * Revert "zap regen" This reverts commit b057c11a05a2990bf13f2247c0b1b544cf8baed1. * removed zap gen * revert zap gen * Fix opstate pics * Updated commands * Fix white space * fix for PR * Update commands * fixes PR * fix * fix test cases * Restyled by prettier-yaml * fixed place for test case * fixed test json * zap regen * added Ovenopstate2_2 and 2_5 yaml and python files. Also some associated changed files * Removed YAML test * added python tests * Updated zap all cluster app * improvements opstte 1_1 * improvement base code * update example app * improvements on ovenopstate * ci pics update * ci pics updates * fix matter testing support * improvements on test cases * Adding commads for example app * added TC 2.2 to the base test * enabled all tests for oven cavity opstate * added app id to the CI parameters * Blocking start when in fault * added tests for CI * Fix lints * Added test 2.3 * Updated business rules on application * Added app pid parameter to mobile test script * fix pipe * fix lint * Added test 2.4 * fixed parameter from run python script * Fixed Lint * Deleted OVENOPSTATE YAMLs * Fix run python script * Fix lint * Added opstate test cases * Fixed opstate app * removed opstate from YAML * fixes according test plan update * Fixed missing test errors * added countdown behavior to opstate * clean up command line linux * Added TC 2.5 automated * Added OPSTATE and OVENOPSTATE to CI * fixed according review * Restyled by whitespace * Restyled by clang-format * Restyled by autopep8 * Restyled by isort * Updates according review * Restyled by autopep8 * Restyled by isort --------- Co-authored-by: Prakash Ravi Co-authored-by: Restyled.io Co-authored-by: Prakash Ravi <68609205+prakashece@users.noreply.github.com> --- .github/workflows/tests.yaml | 12 + .../all-clusters-app.matter | 11 +- .../all-clusters-common/all-clusters-app.zap | 88 +- .../include/operational-state-delegate-impl.h | 28 +- .../include/oven-operational-state-delegate.h | 32 +- .../src/operational-state-delegate-impl.cpp | 83 ++ .../src/oven-operational-state-delegate.cpp | 97 +- .../linux/AllClustersCommandDelegate.cpp | 56 + .../linux/AllClustersCommandDelegate.h | 5 + scripts/tests/chiptest/__init__.py | 1 - scripts/tests/run_python_test.py | 5 +- src/app/tests/suites/certification/PICS.yaml | 88 ++ .../certification/Test_TC_OPSTATE_1_1.yaml | 162 --- .../certification/Test_TC_OPSTATE_2_2.yaml | 335 ----- .../certification/Test_TC_OPSTATE_2_4.yaml | 94 -- .../certification/Test_TC_OPSTATE_2_5.yaml | 353 ----- .../tests/suites/certification/ci-pics-values | 35 +- src/app/tests/suites/ciTests.json | 1 - src/app/tests/suites/manualTests.json | 2 - .../test/test_scripts/mobile-device-test.py | 6 +- src/python_testing/TC_OPSTATE_1_1.py | 53 + src/python_testing/TC_OPSTATE_2_1.py | 170 +-- src/python_testing/TC_OPSTATE_2_2.py | 50 + src/python_testing/TC_OPSTATE_2_3.py | 156 +-- src/python_testing/TC_OPSTATE_2_4.py | 49 + src/python_testing/TC_OPSTATE_2_5.py | 49 + src/python_testing/TC_OVENOPSTATE_1_1.py | 53 + src/python_testing/TC_OVENOPSTATE_2_1.py | 48 + src/python_testing/TC_OVENOPSTATE_2_2.py | 50 + src/python_testing/TC_OVENOPSTATE_2_3.py | 49 + src/python_testing/TC_OVENOPSTATE_2_4.py | 49 + src/python_testing/TC_OVENOPSTATE_2_5.py | 49 + src/python_testing/TC_OpstateCommon.py | 1217 +++++++++++++++++ 33 files changed, 2255 insertions(+), 1281 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_OPSTATE_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_OPSTATE_2_2.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_OPSTATE_2_4.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_OPSTATE_2_5.yaml create mode 100644 src/python_testing/TC_OPSTATE_1_1.py create mode 100644 src/python_testing/TC_OPSTATE_2_2.py create mode 100644 src/python_testing/TC_OPSTATE_2_4.py create mode 100644 src/python_testing/TC_OPSTATE_2_5.py create mode 100644 src/python_testing/TC_OVENOPSTATE_1_1.py create mode 100644 src/python_testing/TC_OVENOPSTATE_2_1.py create mode 100644 src/python_testing/TC_OVENOPSTATE_2_2.py create mode 100644 src/python_testing/TC_OVENOPSTATE_2_3.py create mode 100644 src/python_testing/TC_OVENOPSTATE_2_4.py create mode 100644 src/python_testing/TC_OVENOPSTATE_2_5.py create mode 100644 src/python_testing/TC_OpstateCommon.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index af9ee570102fac..05d2670edd665e 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -526,6 +526,18 @@ jobs: scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --script "src/python_testing/TestMatterTestingSupport.py" --script-args "--trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --script "src/python_testing/TestSpecParsingSupport.py" --script-args "--trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/TestTimeSyncTrustedTimeSourceRunner.py' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OPSTATE_1_1.py" --script-args "--endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OPSTATE_2_1.py" --script-args "--endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OPSTATE_2_2.py" --script-args "--endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OPSTATE_2_3.py" --script-args "--endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OPSTATE_2_4.py" --script-args "--endpoint 1 --int-arg PIXIT.OPSTATE.ErrorEventGen:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OPSTATE_2_5.py" --script-args "--endpoint 1 --int-arg PIXIT.WAITTIME.REBOOT:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OVENOPSTATE_1_1.py" --script-args "--endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OVENOPSTATE_2_1.py" --script-args "--endpoint 1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OVENOPSTATE_2_2.py" --script-args "--endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OVENOPSTATE_2_3.py" --script-args "--endpoint 1 --int-arg PIXIT.WAITTIME.COUNTDOWN:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OVENOPSTATE_2_4.py" --script-args "--endpoint 1 --int-arg PIXIT.OVENOPSTATE.ErrorEventGen:1 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' + scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-all-clusters-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-all-clusters-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace-to json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_OVENOPSTATE_2_5.py" --script-args "--endpoint 1 --int-arg PIXIT.WAITTIME.REBOOT:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-microwave-oven-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-microwave-oven-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_MWOCTRL_2_2.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-microwave-oven-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-microwave-oven-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_MWOCTRL_2_3.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --app out/linux-x64-microwave-oven-ipv6only-no-ble-no-wifi-tsan-clang-test/chip-microwave-oven-app --factoryreset --app-args "--discriminator 1234 --KVS kvs1 --trace_file json:out/trace_data/app-{SCRIPT_BASE_NAME}.json" --script "src/python_testing/TC_MWOCTRL_2_4.py" --script-args "--storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index a499ce042d37cd..ebb9b3da83929b 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -7831,8 +7831,11 @@ endpoint 1 { } server cluster OvenCavityOperationalState { + emits event OperationalError; + emits event OperationCompletion; callback attribute phaseList; callback attribute currentPhase; + callback attribute countdownTime; callback attribute operationalStateList; callback attribute operationalState; callback attribute operationalError; @@ -7842,6 +7845,12 @@ endpoint 1 { callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; + + handle command Pause; + handle command Stop; + handle command Start; + handle command Resume; + handle command OperationalCommandResponse; } server cluster OvenMode { @@ -8076,7 +8085,7 @@ endpoint 1 { callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; handle command Pause; handle command Stop; diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index f659f44a45c808..1666cef4adc1b8 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -17,6 +17,12 @@ } ], "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "version": "chip-v1" + }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl-with-test-extensions.json", @@ -24,12 +30,6 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data with some extensions" - }, - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "version": "chip-v1" } ], "endpointTypes": [ @@ -8227,6 +8227,48 @@ "side": "server", "enabled": 1, "apiMaturity": "provisional", + "commands": [ + { + "name": "Pause", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Stop", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Start", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Resume", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "OperationalCommandResponse", + "code": 4, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], "attributes": [ { "name": "PhaseList", @@ -8260,6 +8302,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "CountdownTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "elapsed_s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "OperationalStateList", "code": 3, @@ -8404,6 +8462,22 @@ "maxInterval": 65534, "reportableChange": 0 } + ], + "events": [ + { + "name": "OperationalError", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "OperationCompletion", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } ] }, { @@ -11176,7 +11250,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h b/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h index 5c6f70bd28a50c..60b6b09e9b6511 100644 --- a/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h +++ b/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h @@ -33,11 +33,15 @@ namespace OperationalState { class GenericOperationalStateDelegateImpl : public Delegate { public: + uint32_t mRunningTime = 0; + uint32_t mPausedTime = 0; + app::DataModel::Nullable mCountDownTime; + /** * Get the countdown time. This attribute is not used in this application. * @return The current countdown time. */ - app::DataModel::Nullable GetCountdownTime() override { return {}; }; + app::DataModel::Nullable GetCountdownTime() override; /** * Fills in the provided GenericOperationalState with the state at index `index` if there is one, @@ -104,11 +108,33 @@ class OperationalStateDelegate : public GenericOperationalStateDelegateImpl GenericOperationalState(to_underlying(OperationalStateEnum::kError)), }; + const uint32_t kExampleCountDown = 30; + public: OperationalStateDelegate() { GenericOperationalStateDelegateImpl::mOperationalStateList = Span(opStateList); } + + /** + * Handle Command Callback in application: Start + * @param[out] get operational error after callback. + */ + void HandleStartStateCallback(GenericOperationalError & err) override + { + mCountDownTime.SetNonNull(static_cast(kExampleCountDown)); + GenericOperationalStateDelegateImpl::HandleStartStateCallback(err); + } + + /** + * Handle Command Callback in application: Stop + * @param[out] get operational error after callback. + */ + void HandleStopStateCallback(GenericOperationalError & err) override + { + GenericOperationalStateDelegateImpl::HandleStopStateCallback(err); + mCountDownTime.SetNull(); + } }; Instance * GetOperationalStateInstance(); diff --git a/examples/all-clusters-app/all-clusters-common/include/oven-operational-state-delegate.h b/examples/all-clusters-app/all-clusters-common/include/oven-operational-state-delegate.h index f68eec20692d0b..89f9969ffb86a7 100644 --- a/examples/all-clusters-app/all-clusters-common/include/oven-operational-state-delegate.h +++ b/examples/all-clusters-app/all-clusters-common/include/oven-operational-state-delegate.h @@ -33,13 +33,17 @@ namespace OvenCavityOperationalState { class OvenCavityOperationalStateDelegate : public OperationalState::Delegate { private: - inline static const Clusters::OperationalState::GenericOperationalState mOperationalStateList[] = { + inline static const Clusters::OperationalState::GenericOperationalState opStateList[] = { OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)), OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)), OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)), OperationalState::GenericOperationalState(to_underlying(OperationalState::OperationalStateEnum::kError)) }; + Span mOperationalStateList = + Span(opStateList); + Span mOperationalPhaseList; + public: /** * Get the countdown time. This attribute is not supported in our example app. @@ -73,43 +77,29 @@ class OvenCavityOperationalStateDelegate : public OperationalState::Delegate * Handle Command Callback in application: Pause * @param[out] get operational error after callback. */ - void HandlePauseStateCallback(Clusters::OperationalState::GenericOperationalError & err) override - { - // This command in not supported. - err.Set(to_underlying(ErrorStateEnum::kCommandInvalidInState)); - }; + void HandlePauseStateCallback(Clusters::OperationalState::GenericOperationalError & err) override; /** * Handle Command Callback in application: Resume * @param[out] get operational error after callback. */ - void HandleResumeStateCallback(Clusters::OperationalState::GenericOperationalError & err) override - { - // This command in not supported. - err.Set(to_underlying(ErrorStateEnum::kCommandInvalidInState)); - }; + void HandleResumeStateCallback(Clusters::OperationalState::GenericOperationalError & err) override; /** * Handle Command Callback in application: Start * @param[out] get operational error after callback. */ - void HandleStartStateCallback(Clusters::OperationalState::GenericOperationalError & err) override - { - // This command in not supported. - err.Set(to_underlying(ErrorStateEnum::kCommandInvalidInState)); - }; + void HandleStartStateCallback(Clusters::OperationalState::GenericOperationalError & err) override; /** * Handle Command Callback in application: Stop * @param[out] get operational error after callback. */ - void HandleStopStateCallback(Clusters::OperationalState::GenericOperationalError & err) override - { - // This command in not supported. - err.Set(to_underlying(ErrorStateEnum::kCommandInvalidInState)); - }; + void HandleStopStateCallback(Clusters::OperationalState::GenericOperationalError & err) override; }; +Instance * GetOperationalStateInstance(); + void Shutdown(); } // namespace OvenCavityOperationalState diff --git a/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp b/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp index 3370d75bd65f35..2070e1b86754fe 100644 --- a/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp @@ -16,6 +16,7 @@ * limitations under the License. */ #include +#include using namespace chip; using namespace chip::app; @@ -23,6 +24,16 @@ using namespace chip::app::Clusters; using namespace chip::app::Clusters::OperationalState; using namespace chip::app::Clusters::RvcOperationalState; +static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data); + +DataModel::Nullable GenericOperationalStateDelegateImpl::GetCountdownTime() +{ + if (mCountDownTime.IsNull()) + return DataModel::NullNullable; + + return DataModel::MakeNullable((uint32_t) (mCountDownTime.Value() - mRunningTime)); +} + CHIP_ERROR GenericOperationalStateDelegateImpl::GetOperationalStateAtIndex(size_t index, GenericOperationalState & operationalState) { if (index >= mOperationalStateList.size()) @@ -44,6 +55,15 @@ CHIP_ERROR GenericOperationalStateDelegateImpl::GetOperationalPhaseAtIndex(size_ void GenericOperationalStateDelegateImpl::HandlePauseStateCallback(GenericOperationalError & err) { + OperationalState::OperationalStateEnum state = + static_cast(GetInstance()->GetCurrentOperationalState()); + + if (state == OperationalState::OperationalStateEnum::kStopped || state == OperationalState::OperationalStateEnum::kError) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState)); + return; + } + // placeholder implementation auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)); if (error == CHIP_NO_ERROR) @@ -58,6 +78,15 @@ void GenericOperationalStateDelegateImpl::HandlePauseStateCallback(GenericOperat void GenericOperationalStateDelegateImpl::HandleResumeStateCallback(GenericOperationalError & err) { + OperationalState::OperationalStateEnum state = + static_cast(GetInstance()->GetCurrentOperationalState()); + + if (state == OperationalState::OperationalStateEnum::kStopped || state == OperationalState::OperationalStateEnum::kError) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState)); + return; + } + // placeholder implementation auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); if (error == CHIP_NO_ERROR) @@ -72,10 +101,20 @@ void GenericOperationalStateDelegateImpl::HandleResumeStateCallback(GenericOpera void GenericOperationalStateDelegateImpl::HandleStartStateCallback(GenericOperationalError & err) { + OperationalState::GenericOperationalError current_err(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + GetInstance()->GetCurrentOperationalError(current_err); + + if (current_err.errorStateID != to_underlying(OperationalState::ErrorStateEnum::kNoError)) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToStartOrResume)); + return; + } + // placeholder implementation auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); if (error == CHIP_NO_ERROR) { + (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, this); err.Set(to_underlying(ErrorStateEnum::kNoError)); } else @@ -90,6 +129,18 @@ void GenericOperationalStateDelegateImpl::HandleStopStateCallback(GenericOperati auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kStopped)); if (error == CHIP_NO_ERROR) { + (void) DeviceLayer::SystemLayer().CancelTimer(onOperationalStateTimerTick, this); + + OperationalState::GenericOperationalError current_err(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + GetInstance()->GetCurrentOperationalError(current_err); + + Optional> totalTime((DataModel::Nullable(mRunningTime + mPausedTime))); + Optional> pausedTime((DataModel::Nullable(mPausedTime))); + + GetInstance()->OnOperationCompletionDetected(static_cast(current_err.errorStateID), totalTime, pausedTime); + + mRunningTime = 0; + mPausedTime = 0; err.Set(to_underlying(ErrorStateEnum::kNoError)); } else @@ -98,6 +149,38 @@ void GenericOperationalStateDelegateImpl::HandleStopStateCallback(GenericOperati } } +static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data) +{ + GenericOperationalStateDelegateImpl * delegate = reinterpret_cast(data); + + OperationalState::Instance * instance = OperationalState::GetOperationalStateInstance(); + OperationalState::OperationalStateEnum state = + static_cast(instance->GetCurrentOperationalState()); + + auto countdown_time = delegate->GetCountdownTime(); + + if (countdown_time.IsNull() || (!countdown_time.IsNull() && countdown_time.Value() > 0)) + { + if (state == OperationalState::OperationalStateEnum::kRunning) + { + delegate->mRunningTime++; + } + else if (state == OperationalState::OperationalStateEnum::kPaused) + { + delegate->mPausedTime++; + } + } + + if (state == OperationalState::OperationalStateEnum::kRunning || state == OperationalState::OperationalStateEnum::kPaused) + { + (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, delegate); + } + else + { + (void) DeviceLayer::SystemLayer().CancelTimer(onOperationalStateTimerTick, delegate); + } +} + // Init Operational State cluster static OperationalState::Instance * gOperationalStateInstance = nullptr; diff --git a/examples/all-clusters-app/all-clusters-common/src/oven-operational-state-delegate.cpp b/examples/all-clusters-app/all-clusters-common/src/oven-operational-state-delegate.cpp index ecae5c88006ef4..726f326afbb6f8 100644 --- a/examples/all-clusters-app/all-clusters-common/src/oven-operational-state-delegate.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/oven-operational-state-delegate.cpp @@ -22,8 +22,13 @@ using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::OvenCavityOperationalState; -static OperationalState::Instance * gOvenCavityOperationalStateInstance = nullptr; -static OvenCavityOperationalStateDelegate * gOvenCavityOperationalStateDelegate = nullptr; +static OvenCavityOperationalState::Instance * gOvenCavityOperationalStateInstance = nullptr; +static OvenCavityOperationalStateDelegate * gOvenCavityOperationalStateDelegate = nullptr; + +OvenCavityOperationalState::Instance * OvenCavityOperationalState::GetOperationalStateInstance() +{ + return gOvenCavityOperationalStateInstance; +} void OvenCavityOperationalState::Shutdown() { @@ -58,7 +63,7 @@ CHIP_ERROR OvenCavityOperationalStateDelegate::GetOperationalStateAtIndex(size_t index, OperationalState::GenericOperationalState & operationalState) { - if (index >= ArraySize(mOperationalStateList)) + if (index >= mOperationalStateList.size()) { return CHIP_ERROR_NOT_FOUND; } @@ -69,5 +74,89 @@ OvenCavityOperationalStateDelegate::GetOperationalStateAtIndex(size_t index, CHIP_ERROR OvenCavityOperationalStateDelegate::GetOperationalPhaseAtIndex(size_t index, MutableCharSpan & operationalPhase) { - return CHIP_ERROR_NOT_FOUND; + if (index >= mOperationalPhaseList.size()) + { + return CHIP_ERROR_NOT_FOUND; + } + return CopyCharSpanToMutableCharSpan(mOperationalPhaseList[index], operationalPhase); +} + +void OvenCavityOperationalStateDelegate::HandlePauseStateCallback(OperationalState::GenericOperationalError & err) +{ + OperationalState::OperationalStateEnum state = + static_cast(GetInstance()->GetCurrentOperationalState()); + + if (state == OperationalState::OperationalStateEnum::kStopped || state == OperationalState::OperationalStateEnum::kError) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState)); + return; + } + + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +void OvenCavityOperationalStateDelegate::HandleResumeStateCallback(OperationalState::GenericOperationalError & err) +{ + + OperationalState::OperationalStateEnum state = + static_cast(GetInstance()->GetCurrentOperationalState()); + + if (state == OperationalState::OperationalStateEnum::kStopped || state == OperationalState::OperationalStateEnum::kError) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kCommandInvalidInState)); + return; + } + + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +void OvenCavityOperationalStateDelegate::HandleStartStateCallback(OperationalState::GenericOperationalError & err) +{ + OperationalState::GenericOperationalError current_err(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + GetInstance()->GetCurrentOperationalError(current_err); + + if (current_err.errorStateID != to_underlying(OperationalState::ErrorStateEnum::kNoError)) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToStartOrResume)); + return; + } + + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation)); + } +} + +void OvenCavityOperationalStateDelegate::HandleStopStateCallback(OperationalState::GenericOperationalError & err) +{ + auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)); + if (error == CHIP_NO_ERROR) + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + } + else + { + err.Set(to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation)); + } } diff --git a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp index 3145bd605b518c..b2fe3a90b59f3f 100644 --- a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp +++ b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp @@ -30,7 +30,9 @@ #include #include #include +#include #include +#include #include using namespace chip; @@ -179,6 +181,12 @@ void AllClustersAppCommandHandler::HandleCommand(intptr_t context) self->OnAirQualityChange(static_cast(jsonAirQualityEnum.asUInt())); } } + else if (name == "OperationalStateChange") + { + std::string device = self->mJsonValue["Device"].asString(); + std::string operation = self->mJsonValue["Operation"].asString(); + self->OnOperationalStateChange(device, operation, self->mJsonValue["Param"]); + } else { ChipLogError(NotSpecified, "Unhandled command: Should never happens"); @@ -436,6 +444,54 @@ void AllClustersAppCommandHandler::OnModeChangeHandler(std::string device, std:: } } +void AllClustersAppCommandHandler::OnOperationalStateChange(std::string device, std::string operation, Json::Value param) +{ + OperationalState::Instance * operationalStateInstance = nullptr; + if (device == "Generic") + { + operationalStateInstance = OperationalState::GetOperationalStateInstance(); + } + else if (device == "Oven") + { + operationalStateInstance = OvenCavityOperationalState::GetOperationalStateInstance(); + } + else + { + ChipLogDetail(NotSpecified, "Invalid device type : %s", device.c_str()); + return; + } + + if (operation == "Start" || operation == "Resume") + { + operationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)); + } + else if (operation == "Pause") + { + operationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)); + } + else if (operation == "Stop") + { + operationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kStopped)); + } + else if (operation == "OnFault") + { + + uint8_t event_id = to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation); + if (!param.isNull()) + { + event_id = to_underlying(static_cast(param.asUInt())); + } + + OperationalState::GenericOperationalError err(event_id); + operationalStateInstance->OnOperationalErrorDetected(err); + } + else + { + ChipLogDetail(NotSpecified, "Invalid operation : %s", operation.c_str()); + return; + } +} + void AllClustersAppCommandHandler::OnAirQualityChange(uint32_t aNewValue) { AirQuality::Instance * airQualityInstance = AirQuality::GetInstance(); diff --git a/examples/all-clusters-app/linux/AllClustersCommandDelegate.h b/examples/all-clusters-app/linux/AllClustersCommandDelegate.h index 7998cd15581a74..4022b06e9f8565 100644 --- a/examples/all-clusters-app/linux/AllClustersCommandDelegate.h +++ b/examples/all-clusters-app/linux/AllClustersCommandDelegate.h @@ -98,6 +98,11 @@ class AllClustersAppCommandHandler * Should be called when it is necessary to change the air quality attribute. */ void OnAirQualityChange(uint32_t aEnum); + + /** + * Should be called when it is necessary to change the operational state as a manual operation. + */ + void OnOperationalStateChange(std::string device, std::string operation, Json::Value param); }; class AllClustersCommandDelegate : public NamedPipeCommandDelegate diff --git a/scripts/tests/chiptest/__init__.py b/scripts/tests/chiptest/__init__.py index 984cb38080c897..fd4ad6f52867b5 100644 --- a/scripts/tests/chiptest/__init__.py +++ b/scripts/tests/chiptest/__init__.py @@ -209,7 +209,6 @@ def _GetDarwinFrameworkToolUnsupportedTests() -> Set[str]: "Test_TC_GRPKEY_2_1", # darwin-framework-tool does not support writing readonly attributes by name "Test_TC_LCFG_2_1", # darwin-framework-tool does not support writing readonly attributes by name "Test_TC_OPCREDS_3_7", # darwin-framework-tool does not support the GetCommissionerRootCertificate command. - "Test_TC_OPSTATE_2_4", # darwin-framework-tool does not currently support reading or subscribing to Events "Test_TC_SMOKECO_2_2", # darwin-framework-tool does not currently support reading or subscribing to Events "Test_TC_SMOKECO_2_3", # darwin-framework-tool does not currently support reading or subscribing to Events "Test_TC_SMOKECO_2_4", # darwin-framework-tool does not currently support reading or subscribing to Events diff --git a/scripts/tests/run_python_test.py b/scripts/tests/run_python_test.py index fdea7767037aa6..1a9b54a3ad6736 100755 --- a/scripts/tests/run_python_test.py +++ b/scripts/tests/run_python_test.py @@ -125,6 +125,8 @@ def main(app: str, factoryreset: bool, factoryreset_app_only: bool, app_args: st log_cooking_threads = [] app_process = None + app_pid = 0 + if app: if not os.path.exists(app): if app is None: @@ -133,11 +135,12 @@ def main(app: str, factoryreset: bool, factoryreset_app_only: bool, app_args: st logging.info(f"Execute: {app_args}") app_process = subprocess.Popen( app_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0) + app_pid = app_process.pid DumpProgramOutputToQueue( log_cooking_threads, Fore.GREEN + "APP " + Style.RESET_ALL, app_process, log_queue) script_command = [script, "--paa-trust-store-path", os.path.join(DEFAULT_CHIP_ROOT, MATTER_DEVELOPMENT_PAA_ROOT_CERTS), - '--log-format', '%(message)s'] + shlex.split(script_args) + '--log-format', '%(message)s', "--app-pid", str(app_pid)] + shlex.split(script_args) if script_gdb: # diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index d8bc862ba6c62c..407851320ca31c 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -8858,6 +8858,94 @@ PICS: command?" id: OPSTATE.S.C04.Tx + # + #Oven Operational State + # + - label: + "Does the device implement the Operational State cluster as a server?" + id: OVENOPSTATE.S + + - label: + "Does the device implement the Operational State cluster as a client?" + id: OVENOPSTATE.C + + #ManuallyControlled + + - label: "Does the DUT support testing the Stopped(0x00) operational state" + id: OVENOPSTATE.S.M.ST_STOPPED + + - label: "Does the DUT support testing the Running(0x01) operational state" + id: OVENOPSTATE.S.M.ST_RUNNING + + - label: "Does the DUT support testing the Paused(0x02) operational state" + id: OVENOPSTATE.S.M.ST_PAUSED + + - label: "Does the DUT support testing the Error(0x03) operational state?" + id: OVENOPSTATE.S.M.ST_ERROR + + - label: "Does the DUT support testing the NoError(0x00) error state?" + id: OVENOPSTATE.S.M.ERR_NO_ERROR + + - label: + "Does the DUT support testing the UnableToStartOrResume(0x01) error + state?" + id: OVENOPSTATE.S.M.ERR_UNABLE_TO_START_OR_RESUME + + - label: + "Does the DUT support testing the UnableToCompleteOperation(0x02) + error state?" + id: OVENOPSTATE.S.M.ERR_UNABLE_TO_COMPLETE_OPERATION + + - label: + "Does the DUT support testing the CommandInvalidInState(0x03) error + state?" + id: OVENOPSTATE.S.M.ERR_COMMAND_INVALID_IN_STATE + + #Server Attributes + - label: "Does the device implement the PhaseList attribute?" + id: OVENOPSTATE.S.A0000 + + - label: "Does the device implement the CurrentPhase attribute?" + id: OVENOPSTATE.S.A0001 + + - label: "Does the device implement the CountdownTime attribute?" + id: OVENOPSTATE.S.A0002 + + - label: "Does the device implement the OperationalStateList attribute?" + id: OVENOPSTATE.S.A0003 + + - label: "Does the device implement the OperationalState attribute?" + id: OVENOPSTATE.S.A0004 + + - label: "Does the device implement the OperationalError attribute?" + id: OVENOPSTATE.S.A0005 + #Events Generated + + - label: "Does the device generate the OperationalError event?" + id: OVENOPSTATE.S.E00 + + - label: "Does the device generate the OperationCompltion event?" + id: OVENOPSTATE.S.E01 + + #Server Commands Received + - label: "Does the device implement receiving the Pause command?" + id: OVENOPSTATE.S.C00.Rsp + + - label: "Does the device implement receiving the Stop command?" + id: OVENOPSTATE.S.C01.Rsp + + - label: "Does the device implement receiving the Start command?" + id: OVENOPSTATE.S.C02.Rsp + + - label: "Does the device implement receiving the Resume command?" + id: OVENOPSTATE.S.C03.Rsp + + #Commands generated + - label: + "Does the device implement generating the OperationalCommandResponse + command?" + id: OVENOPSTATE.S.C04.Tx + # Smoke CO Alarm Cluster Test Plan - label: "Does the device implement the SMOKECO cluster as a server?" id: SMOKECO.S diff --git a/src/app/tests/suites/certification/Test_TC_OPSTATE_1_1.yaml b/src/app/tests/suites/certification/Test_TC_OPSTATE_1_1.yaml deleted file mode 100644 index 21d6c7e9785e07..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OPSTATE_1_1.yaml +++ /dev/null @@ -1,162 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 201.1.1. [TC-OPSTATE-1.1] Global Attributes with DUT as Server - -PICS: - - OPSTATE.S - -config: - nodeId: 0x12344321 - cluster: "Operational State" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [0, 1, 3, 4, 5, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 3, 4, 5, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads from the DUT the optional attribute(CountdownTime) - in the AttributeList from the DUT" - PICS: OPSTATE.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 5a: TH reads from the DUT the EventList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x00] - - - label: - "Step 5b: TH reads from the DUT the optional - event(OperationCompletion) in EventList." - PICS: PICS_EVENT_LIST_ENABLED && OPSTATE.S.E01 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x01] - - - label: - "Step 6a: TH reads the optional command(Start) in AcceptedCommandList" - PICS: OPSTATE.S.C02.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [1, 2] - - - label: - "Step 6b: TH reads the optional command(Stop) in AcceptedCommandList" - PICS: OPSTATE.S.C01.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 6c: TH reads the optional command(Pause) in AcceptedCommandList" - PICS: OPSTATE.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 3] - - - label: - "Step 6d: TH reads the optional command(Resume) in AcceptedCommandList" - PICS: OPSTATE.S.C03.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 3] - - - label: "Step 7: TH reads from the DUT the AcceptedCommandList attribute" - PICS: - "!OPSTATE.S.C00.Rsp && !OPSTATE.S.C01.Rsp && !OPSTATE.S.C02.Rsp && - !OPSTATE.S.C03.Rsp" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute" - PICS: - (OPSTATE.S.C00.Rsp || OPSTATE.S.C01.Rsp || OPSTATE.S.C02.Rsp || - OPSTATE.S.C03.Rsp) - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [4] diff --git a/src/app/tests/suites/certification/Test_TC_OPSTATE_2_2.yaml b/src/app/tests/suites/certification/Test_TC_OPSTATE_2_2.yaml deleted file mode 100644 index 43dc0dda3dc01e..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OPSTATE_2_2.yaml +++ /dev/null @@ -1,335 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 202.2.2. [TC-OPSTATE-2.2] Start and Stop commands with DUT as Server - -PICS: - - OPSTATE.S - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Note" - verification: | - This is a simulated example log for instructional purposes only. In real scenarios, the actual log may vary depending on the feature implementation in Reference App. - disabled: true - - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)" - verification: | - - disabled: true - - - label: - "Step 2: Manually put the DUT into a state wherein it can receive a - Start Command" - verification: | - Manually put the DUT into a state wherein it can receive a Start Command - disabled: true - - - label: "Step 3: TH reads from the DUT the OperationalStateList attribute" - PICS: OPSTATE.S.A0003 - verification: | - ./chip-tool operationalstate read operational-state-list 1 1 - - Via the TH (chip-tool), verify: - - all entries include an ID (enum8) and a label (string) - - all provided IDs are in the allowed range - - the list includes IDs for Error (0x03), Running (0x01), and Stopped (0x00) - - [1689674049.504261][17222:17224] CHIP:DMG: } - [1689674049.504390][17222:17224] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0003 DataVersion: 2102885775 - [1689674049.504440][17222:17224] CHIP:TOO: OperationalStateList: 4 entries - [1689674049.504462][17222:17224] CHIP:TOO: [1]: { - [1689674049.504469][17222:17224] CHIP:TOO: OperationalStateID: 0 - [1689674049.504476][17222:17224] CHIP:TOO: } - [1689674049.504484][17222:17224] CHIP:TOO: [2]: { - [1689674049.504490][17222:17224] CHIP:TOO: OperationalStateID: 1 - [1689674049.504495][17222:17224] CHIP:TOO: } - [1689674049.504503][17222:17224] CHIP:TOO: [3]: { - [1689674049.504508][17222:17224] CHIP:TOO: OperationalStateID: 2 - [1689674049.504514][17222:17224] CHIP:TOO: } - [1689674049.504521][17222:17224] CHIP:TOO: [4]: { - [1689674049.504527][17222:17224] CHIP:TOO: OperationalStateID: 3 - [1689674049.504533][17222:17224] CHIP:TOO: } - [1689674049.504605][17222:17224] CHIP:EM: <<< [E:22830i S:37151 M:4250114 (Ack:140781365)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674049.504620][17222:17224] CHIP:IN: (S) Sending msg 4250114 on secure session with LSID: 37151 - disabled: true - - - label: "Step 4: TH sends Start command to the DUT" - PICS: OPSTATE.S.C02.Rsp && OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate start 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674139.018639][17233:17235] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674139.018658][17233:17235] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1689674139.018704][17233:17235] CHIP:TOO: OperationalCommandResponse: { - [1689674139.018712][17233:17235] CHIP:TOO: commandResponseState: { - [1689674139.018719][17233:17235] CHIP:TOO: ErrorStateID: 0 - [1689674139.018726][17233:17235] CHIP:TOO: } - [1689674139.018732][17233:17235] CHIP:TOO: } - [1689674139.018755][17233:17235] CHIP:DMG: ICR moving to [AwaitingDe] - [1689674139.018818][17233:17235] CHIP:EM: <<< [E:26021i S:33879 M:235550100 (Ack:58905970)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674139.018837][17233:17235] CHIP:IN: (S) Sending msg 235550100 on secure session with LSID: 33879 - [1689674139.018885][17233:17235] CHIP:EM: Flushed pending ack for MessageCounter:58905970 on exchange 26021i - disabled: true - - - label: "Step 5: TH reads from the DUT the OperationalState attribute" - PICS: OPSTATE.S.A0004 - verification: | - ./chip-tool operationalstate read operational-state 1 1 - - Via the TH (chip-tool), verify: - - the response has an OperationalStateID field that is set to 0x01 (Running) - - [1689674196.878722][17249:17251] CHIP:DMG: InteractionModelRevision = 1 - [1689674196.878727][17249:17251] CHIP:DMG: } - [1689674196.878800][17249:17251] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0004 DataVersion: 2102885775 - [1689674196.878834][17249:17251] CHIP:TOO: OperationalState: { - [1689674196.878841][17249:17251] CHIP:TOO: OperationalStateID: 1 - [1689674196.878847][17249:17251] CHIP:TOO: } - [1689674196.878914][17249:17251] CHIP:EM: <<< [E:56939i S:28614 M:63040141 (Ack:57012545)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674196.878928][17249:17251] CHIP:IN: (S) Sending msg 63040141 on secure session with LSID: 28614 - disabled: true - - - label: "Step 6: TH reads from the DUT the OperationalError attribute" - PICS: OPSTATE.S.A0005 - verification: | - ./chip-tool operationalstate read operational-error 1 1 - - Via the TH (chip-tool), verify: - - the response contains the ErrorStateId set to NoError(0x00) - - [1689674342.832448][17274:17276] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0005 DataVersion: 2102885775 - [1689674342.832482][17274:17276] CHIP:TOO: OperationalError: { - [1689674342.832500][17274:17276] CHIP:TOO: ErrorStateID: 0 - [1689674342.832509][17274:17276] CHIP:TOO: } - [1689674342.832570][17274:17276] CHIP:EM: <<< [E:37158i S:10451 M:72875113 (Ack:195983315)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674342.832585][17274:17276] CHIP:IN: (S) Sending msg 72875113 on secure session with LSID: 10451 - [1689674342.832614][17274:17276] CHIP:EM: Flushed pending ack for MessageCounter:195983315 on exchange 37158i - disabled: true - - - label: "Step 7: TH reads from the DUT the CountdownTime attribute" - PICS: OPSTATE.S.A0002 - verification: | - ./chip-tool operationalstate read countdown-time 1 1 - - Via the TH (chip-tool), verify: - - that CountdownTime attribute contains either null our a uint32 value - - if non-null, verify that the value is in the range 1 to 259200 - - store the value in 'initialcountdown-time' - - [1689674384.271623][17278:17280] CHIP:DMG: InteractionModelRevision = 1 - [1689674384.271625][17278:17280] CHIP:DMG: } - [1689674384.271649][17278:17280] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0002 DataVersion: 2102885775 - [1689674384.271662][17278:17280] CHIP:TOO: CountdownTime: null - [1689674384.271683][17278:17280] CHIP:EM: <<< [E:24665i S:47371 M:757241 (Ack:152992659)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674384.271687][17278:17280] CHIP:IN: (S) Sending msg 757241 on secure session with LSID: 47371 - [1689674384.271696][17278:17280] CHIP:EM: Flushed pending ack for MessageCounter:152992659 on exchange 24665i - disabled: true - - - label: "Step 8: TH reads from the DUT the PhaseList attribute" - PICS: OPSTATE.S.A0000 - verification: | - ./chip-tool operationalstate read phase-list 1 1 - - Via the TH (chip-tool), verify: - - that PhaseList attribute value contains either null or a list of strings. - - If not null, receord the number of entries in the list as 'phase-list-size'; execute step 7. - If null, go to step 8. - - [1689674447.761859][17290:17292] CHIP:DMG: InteractionModelRevision = 1 - [1689674447.761865][17290:17292] CHIP:DMG: } - [1689674447.761938][17290:17292] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0000 DataVersion: 2102885775 - [1689674447.761972][17290:17292] CHIP:TOO: PhaseList: null - [1689674447.762041][17290:17292] CHIP:EM: <<< [E:58737i S:13847 M:251354926 (Ack:137738036)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674447.762055][17290:17292] CHIP:IN: (S) Sending msg 251354926 on secure session with LSID: 13847 - [1689674447.762109][17290:17292] CHIP:EM: Flushed pending ack for MessageCounter:137738036 on exchange 58737i - disabled: true - - - label: "Step 9: TH reads from the DUT the CurrentPhase attribute" - PICS: OPSTATE.S.A0001 - verification: | - ./chip-tool operationalstate read current-phase 1 1 - - Via the TH (chip-tool), verify: - - that the CurrentPhase attribute value contains contains a uint8 value - - that the value is between 0 and 'phase-list-size - 1'. - - [1689674497.950563][17299:17301] CHIP:DMG: } - [1689674497.950635][17299:17301] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0001 DataVersion: 2102885775 - [1689674497.950664][17299:17301] CHIP:TOO: CurrentPhase: null - [1689674497.950737][17299:17301] CHIP:EM: <<< [E:64019i S:52010 M:245677798 (Ack:138696372)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674497.950752][17299:17301] CHIP:IN: (S) Sending msg 245677798 on secure session with LSID: 52010 - [1689674497.950798][17299:17301] CHIP:EM: Flushed pending ack for MessageCounter:138696372 on exchange 64019i - [1689674497.950899][17299:17299] CHIP:CTL: Shutting down the commissioner - disabled: true - - - label: - "Step 10: TH waits for a vendor defined wait time, this being a period - of time less than the expected duration of the operation that has been - started" - verification: | - TH waits for a vendor defined wait time, this being a period of time less than the expected duration of the operation that has been started - disabled: true - - - label: "Step 11: TH reads from the DUT the CountdownTime attribute" - PICS: OPSTATE.S.A0002 - verification: | - ./chip-tool operationalstate read countdown-time 1 1 - - - Via the TH (chip-tool), verify: - - that CountdownTime attribute contains either null our a uint32 value - - if non-null, verify that the value is in the range 1 to 259200 - - that the value is approximately 'initialcountdown-time minus the vendor defined wait time' - - - [1689674623.673661][17320:17322] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0002 DataVersion: 2102885775 - [1689674623.673697][17320:17322] CHIP:TOO: CountdownTime: null - [1689674623.673755][17320:17322] CHIP:EM: <<< [E:42152i S:37580 M:19654175 (Ack:176515710)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674623.673768][17320:17322] CHIP:IN: (S) Sending msg 19654175 on secure session with LSID: 37580 - [1689674623.673795][17320:17322] CHIP:EM: Flushed pending ack for MessageCounter:176515710 on exchange 42152i - disabled: true - - - label: "Step 12: TH sends Start command to the DUT" - PICS: OPSTATE.S.C02.Rsp && OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate start 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674637.555734][17326:17328] CHIP:DMG: - [1689674637.555742][17326:17328] CHIP:DMG: InteractionModelRevision = 1 - [1689674637.555751][17326:17328] CHIP:DMG: }, - [1689674637.555784][17326:17328] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674637.555805][17326:17328] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1689674637.555853][17326:17328] CHIP:TOO: OperationalCommandResponse: { - [1689674637.555862][17326:17328] CHIP:TOO: commandResponseState: { - [1689674637.555872][17326:17328] CHIP:TOO: ErrorStateID: 0 - [1689674637.555883][17326:17328] CHIP:TOO: } - [1689674637.555891][17326:17328] CHIP:TOO: } - [1689674637.555913][17326:17328] CHIP:DMG: ICR moving to [AwaitingDe] - [1689674637.555956][17326:17328] CHIP:EM: <<< [E:28742i S:49023 M:139320570 (Ack:91983883)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674637.555971][17326:17328] CHIP:IN: (S) Sending msg 139320570 on secure session with LSID: 49023 - [1689674637.556001][17326:17328] CHIP:EM: Flushed pending ack for MessageCounter:91983883 on exchange 28742i - disabled: true - - - label: "Step 13: TH sends Stop command to the DUT" - PICS: OPSTATE.S.C01.Rsp && OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate stop 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674653.322963][17330:17332] CHIP:DMG: }, - [1689674653.322994][17330:17332] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674653.323014][17330:17332] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1689674653.323058][17330:17332] CHIP:TOO: OperationalCommandResponse: { - [1689674653.323066][17330:17332] CHIP:TOO: commandResponseState: { - [1689674653.323076][17330:17332] CHIP:TOO: ErrorStateID: 0 - [1689674653.323085][17330:17332] CHIP:TOO: } - [1689674653.323094][17330:17332] CHIP:TOO: } - [1689674653.323113][17330:17332] CHIP:DMG: ICR moving to [AwaitingDe] - [1689674653.323154][17330:17332] CHIP:EM: <<< [E:62878i S:64455 M:173921517 (Ack:216732582)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674653.323168][17330:17332] CHIP:IN: (S) Sending msg 173921517 on secure session with LSID: 64455 - [1689674653.323195][17330:17332] CHIP:EM: Flushed pending ack for MessageCounter:216732582 on exchange 62878i - [1689674653.323284][17330:17330] CHIP:CTL: Shutting down the commissioner - disabled: true - - - label: "Step 14: TH reads from the DUT the OperationalState attribute" - PICS: OPSTATE.S.A0004 - verification: | - ./chip-tool operationalstate read operational-state 1 1 - - Via the TH (chip-tool), verify: - - the response has an OperationalStateID field that is set to 0x00 (Stopped) - - [1689674675.459656][17333:17335] CHIP:DMG: } - [1689674675.459738][17333:17335] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0004 DataVersion: 2102885775 - [1689674675.459772][17333:17335] CHIP:TOO: OperationalState: { - [1689674675.459790][17333:17335] CHIP:TOO: OperationalStateID: 0 - [1689674675.459799][17333:17335] CHIP:TOO: } - [1689674675.459869][17333:17335] CHIP:EM: <<< [E:17771i S:16165 M:1572532 (Ack:102448631)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674675.459886][17333:17335] CHIP:IN: (S) Sending msg 1572532 on secure session with LSID: 16165 - [1689674675.459930][17333:17335] CHIP:EM: Flushed pending ack for MessageCounter:102448631 on exchange 17771i - disabled: true - - - label: "Step 15: TH sends Stop command to the DUT" - PICS: OPSTATE.S.C01.Rsp && OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate stop 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674689.588712][17337:17339] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674689.588722][17337:17339] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1689674689.588745][17337:17339] CHIP:TOO: OperationalCommandResponse: { - [1689674689.588749][17337:17339] CHIP:TOO: commandResponseState: { - [1689674689.588757][17337:17339] CHIP:TOO: ErrorStateID: 0 - [1689674689.588762][17337:17339] CHIP:TOO: } - [1689674689.588765][17337:17339] CHIP:TOO: } - [1689674689.588775][17337:17339] CHIP:DMG: ICR moving to [AwaitingDe] - [1689674689.588802][17337:17339] CHIP:EM: <<< [E:63921i S:35027 M:16881995 (Ack:220265764)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674689.588810][17337:17339] CHIP:IN: (S) Sending msg 16881995 on secure session with LSID: 35027 - disabled: true - - - label: - "Step 16: Manually put the DUT into a state wherein it cannot receive - a Start Command" - PICS: OPSTATE.S.M.ERR_UNABLE_TO_START_OR_RESUME - verification: | - Manually put the DUT into a state wherein it cannot receive a Start Command - disabled: true - - - label: "Step 17: TH sends Start command to the DUT" - PICS: - OPSTATE.S.M.ERR_UNABLE_TO_START_OR_RESUME && OPSTATE.S.C02.Rsp && - OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate start 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x01 (UnableToStartOrResume) - - [1689674700.385183][17340:17342] CHIP:DMG: }, - [1689674700.385214][17340:17342] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674700.385233][17340:17342] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1689674700.385266][17340:17342] CHIP:TOO: OperationalCommandResponse: { - [1689674700.385274][17340:17342] CHIP:TOO: commandResponseState: { - [1689674700.385281][17340:17342] CHIP:TOO: ErrorStateID: 1 - [1689674700.385289][17340:17342] CHIP:TOO: } - [1689674700.385295][17340:17342] CHIP:TOO: } - [1689674700.385311][17340:17342] CHIP:DMG: ICR moving to [AwaitingDe] - [1689674700.385361][17340:17342] CHIP:EM: <<< [E:55029i S:46795 M:80501191 (Ack:176711722)] (S) Msg TX to 1:0000000000000001 [BFDE] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689674700.385375][17340:17342] CHIP:IN: (S) Sending msg 80501191 on secure session with LSID: 46795 - [1689674700.385419][17340:17342] CHIP:EM: Flushed pending ack for MessageCounter:176711722 on exchange 55029i - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_OPSTATE_2_4.yaml b/src/app/tests/suites/certification/Test_TC_OPSTATE_2_4.yaml deleted file mode 100644 index f8d07da34446a9..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OPSTATE_2_4.yaml +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 202.2.4. [TC-OPSTATE-2.4] Mandatory Events with DUT as Server - -PICS: - - OPSTATE.S - -config: - nodeId: 0x12344321 - cluster: "Operational State" - endpoint: 1 - -tests: - - label: "Step 1: Commission DUT to TH" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Set up a subscription to the OperationalError event" - PICS: OPSTATE.S.E00 - command: "subscribeEvent" - event: "OperationalError" - minInterval: 10 - maxInterval: 5000 - - - label: - "Step 3: At the DUT take the vendor defined action to generate an - OperationalError event" - PICS: OPSTATE.S.E00 && PICS_SKIP_SAMPLE_APP - verification: | - After the subscription interval via the TH (chip-tool) verify: - - reception of an OperationalError Event - - ErrorStateID is a defined error - - If the ErrorStateID is manufacturer specific, inclusion of an ErrorStateLabel, not present otherwise - - Optionally an ErrorStateDetails - - NOTE : There's a PIXIT value controlling the ability to execute that ({PIXIT_ERROREVENTGEN}), which as the test case notes, requires vendor specific actions to generated the error at the DUT. This is dependent on the vendor app supporting this. The SDK as it stands won't provide the error, this may be testable by some of the vendors depending on their implementations. - - - [1692859386.707176][6658:6660] CHIP:EM: Rxd Ack; Removing MessageCounter:212756536 from Retrans Table on exchange 36888i - [1692859386.707295][6658:6660] CHIP:DMG: ReportDataMessage = - [1692859386.707360][6658:6660] CHIP:DMG: { - [1692859386.707416][6658:6660] CHIP:DMG: SubscriptionId = 0x97bb846c, - [1692859386.707477][6658:6660] CHIP:DMG: InteractionModelRevision = 10 - [1692859386.707533][6658:6660] CHIP:DMG: } - [1692859386.707621][6658:6660] CHIP:DMG: MoveToState ReadClient[0xffff80011a90]: Moving to [AwaitingSu] - [1692859386.707815][6658:6660] CHIP:EM: <<< [E:36888i S:54523 M:212756537 (Ack:12760634)] (S) Msg TX to 1:0000000000000001 [853D] --- Type 0001:01 (IM:StatusResponse) - [1692859386.707901][6658:6660] CHIP:IN: (S) Sending msg 212756537 on secure session with LSID: 54523 - [1692859386.708167][6658:6660] CHIP:DL: HandlePlatformSpecificBLEEvent 32793 - [1692859386.708237][6658:6660] CHIP:DL: HandlePlatformSpecificBLEEvent 32793 - [1692859386.749217][6658:6660] CHIP:EM: >>> [E:36888i S:54523 M:12760635 (Ack:212756537)] (S) Msg RX from 1:0000000000000001 [853D] --- Type 0001:04 (IM:SubscribeResponse) - [1692859386.749285][6658:6660] CHIP:EM: Found matching exchange: 36888i, Delegate: 0xffff80011aa0 - [1692859386.749350][6658:6660] CHIP:EM: Rxd Ack; Removing MessageCounter:212756537 from Retrans Table on exchange 36888i - [1692859386.749417][6658:6660] CHIP:DMG: SubscribeResponse is received - [1692859386.749489][6658:6660] CHIP:DMG: SubscribeResponseMessage = - [1692859386.749538][6658:6660] CHIP:DMG: { - [1692859386.749584][6658:6660] CHIP:DMG: SubscriptionId = 0x97bb846c, - [1692859386.749637][6658:6660] CHIP:DMG: MaxInterval = 0x6, - [1692859386.749687][6658:6660] CHIP:DMG: InteractionModelRevision = 10 - [1692859386.749734][6658:6660] CHIP:DMG: } - [1692859386.749787][6658:6660] CHIP:DMG: Subscription established with SubscriptionID = 0x97bb846c MinInterval = 5s MaxInterval = 6s Peer = 01:0000000000000001 - [1692859386.749843][6658:6660] CHIP:DMG: MoveToState ReadClient[0xffff80011a90]: Moving to [Subscripti] - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: "Step 4: TH reads from the DUT the OperationalState attribute" - PICS: OPSTATE.S.A0004 && PICS_SKIP_SAMPLE_APP - command: "readAttribute" - attribute: "OperationalState" - response: - value: 0x03 - constraints: - type: enum8 diff --git a/src/app/tests/suites/certification/Test_TC_OPSTATE_2_5.yaml b/src/app/tests/suites/certification/Test_TC_OPSTATE_2_5.yaml deleted file mode 100644 index 6dcc447fbf3dd1..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OPSTATE_2_5.yaml +++ /dev/null @@ -1,353 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 204.2.5. [TC-OPSTATE-2.5] Optional Events with DUT as Server - -PICS: - - OPSTATE.S - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Note" - verification: | - This test case can be continuted only when countdown-time read in step 5 is not null - disabled: true - - - label: "Step 1: Commission DUT to TH" - verification: | - - disabled: true - - - label: "Step 2: Set up a subscription to the OperationCompletion event" - PICS: OPSTATE.S.E01 - verification: | - ./chip-tool interactive start - - operationalstate read-event operation-completion 1 1 - - [1702376916.193452][4893:4896] CHIP:DMG: ReportDataMessage = - [1702376916.193461][4893:4896] CHIP:DMG: { - [1702376916.193469][4893:4896] CHIP:DMG: SubscriptionId = 0x85d7a607, - [1702376916.193497][4893:4896] CHIP:DMG: InteractionModelRevision = 11 - [1702376916.193504][4893:4896] CHIP:DMG: } - disabled: true - - - label: "Step 3: TH reads from the DUT the OperationalState attribute" - PICS: OPSTATE.S.A0004 - verification: | - ./chip-tool operationalstate read operational-state 1 1 - - Via the TH (chip-tool), verify: - - the response includes an ID (enum8) amd a label (string) - - the provided ID is found in the set provided in step 4 - - the provided ID is in the allowed range - - [1689673213.434610][16591:16593] CHIP:DMG: } - [1689673213.434686][16591:16593] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0004 DataVersion: 2102885775 - [1689673213.434721][16591:16593] CHIP:TOO: OperationalState: { - [1689673213.434728][16591:16593] CHIP:TOO: OperationalStateID: 0 - [1689673213.434735][16591:16593] CHIP:TOO: } - disabled: true - - - label: - "Step 4: Manually put the DUT into a state wherein it can receive a - Start Command" - verification: | - - disabled: true - - - label: "Step 5: TH reads from the DUT the CountdownTime attribute" - PICS: OPSTATE.S.A0002 - verification: | - ./chip-tool operationalstate read countdown-time 1 1 - - Via the TH (chip-tool), verify: - - that CountdownTime attribute contains either null our a uint32 value - - if non-null, verify that the value is in the range 1 to 259200 - - store the value in 'initialcountdown-time' - - [1690457637.895405][18808:18810] CHIP:DMG: } - [1690457637.895474][18808:18810] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0002 DataVersion: 4112784416 - [1690457637.895503][18808:18810] CHIP:TOO: CountdownTime: null - disabled: true - - - label: "Step 6: TH sends Start command to the DUT" - PICS: OPSTATE.S.C02.Rsp && OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate start 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674637.555734][17326:17328] CHIP:DMG: - [1689674637.555742][17326:17328] CHIP:DMG: InteractionModelRevision = 1 - [1689674637.555751][17326:17328] CHIP:DMG: }, - [1689674637.555784][17326:17328] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674637.555805][17326:17328] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1689674637.555853][17326:17328] CHIP:TOO: OperationalCommandResponse: { - [1689674637.555862][17326:17328] CHIP:TOO: commandResponseState: { - [1689674637.555872][17326:17328] CHIP:TOO: ErrorStateID: 0 - [1689674637.555883][17326:17328] CHIP:TOO: } - disabled: true - - - label: "Step 7: TH waits for {PIXIT.WAITTIME}" - verification: | - - disabled: true - - - label: "Step 8: TH reads from the DUT the OperationalState attribute" - PICS: OPSTATE.S.A0004 - verification: | - ./chip-tool operationalstate read operational-state 1 1 - - Via the TH (chip-tool), verify: - - the response has an OperationalStateID field that is set to 0x01 (Running) - - [1689674196.878722][17249:17251] CHIP:DMG: InteractionModelRevision = 1 - [1689674196.878727][17249:17251] CHIP:DMG: } - [1689674196.878800][17249:17251] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0004 DataVersion: 2102885775 - [1689674196.878834][17249:17251] CHIP:TOO: OperationalState: { - [1689674196.878841][17249:17251] CHIP:TOO: OperationalStateID: 1 - [1689674196.878847][17249:17251] CHIP:TOO: } - disabled: true - - - label: "Step 9: TH waits for initial-countdown-time" - verification: | - As the initial-countdown-time in null this test cannot be executed further in case of RPI platform. - Note: The below log are for instructional purpose. In real scenarios, the actual log may vary depending on the feature implementation in the Reference App. - disabled: true - - - label: "Step 10: TH sends Stop command to the DUT" - PICS: OPSTATE.S.C01.Rsp && OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate stop 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674653.322963][17330:17332] CHIP:DMG: }, - [1689674653.322994][17330:17332] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674653.323014][17330:17332] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1689674653.323058][17330:17332] CHIP:TOO: OperationalCommandResponse: { - [1689674653.323066][17330:17332] CHIP:TOO: commandResponseState: { - [1689674653.323076][17330:17332] CHIP:TOO: ErrorStateID: 0 - [1689674653.323085][17330:17332] CHIP:TOO: } - [1689674653.323094][17330:17332] CHIP:TOO: } - disabled: true - - - label: - "Step 11: erify TH receives an OperationCompletion event from the DUT - with the following fields populated as follows: 1)CompletionErrorCode - set to NoError(0x00) 2)TotalOperationalTime is approximately - initial-countdown-time or null 3)PausedTime is zero" - PICS: OPSTATE.S.E01 - verification: | - operationalstate read-event operation-completion 1 1 - - [1657193007.841358][5422:5427] CHIP:TOO: Endpoint: 0 Endpoint: 1 Cluster: 0x0000_0060 Event 0x0000_0001 - [1657193007.841387][5422:5427] CHIP:TOO: Event number: 1 - [1657193007.841409][5422:5427] CHIP:TOO: Priority: INFO - [1657193007.841431][5422:5427] CHIP:TOO: Timestamp: 132146 - [1657193007.841531][5422:5427] CHIP:TOO: OperationCompletion: { - [1657193007.841570][5422:5427] CHIP:TOO: CompletionErrorCode: 0x00 - TotalOperationalTime: null - PausedTime: 0 - [1657193007.841594][5422:5427] CHIP:TOO: } - disabled: true - - - label: "Step 12: TH reads from the DUT the OperationalState attribute" - PICS: OPSTATE.S.A0004 - verification: | - ./chip-tool operationalstate read operational-state 1 1 - - Via the TH (chip-tool), verify: - - the response has an OperationalStateID field that is set to 0x00 (Stopped) - - [1689674675.459656][17333:17335] CHIP:DMG: } - [1689674675.459738][17333:17335] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0004 DataVersion: 2102885775 - [1689674675.459772][17333:17335] CHIP:TOO: OperationalState: { - [1689674675.459790][17333:17335] CHIP:TOO: OperationalStateID: 0 - [1689674675.459799][17333:17335] CHIP:TOO: } - disabled: true - - - label: "Step 13: Restart DUT and repeat step 5" - verification: | - - disabled: true - - - label: "Step 14: TH sends Start command to the DUT" - PICS: OPSTATE.S.C02.Rsp && OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate start 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674637.555734][17326:17328] CHIP:DMG: - [1689674637.555742][17326:17328] CHIP:DMG: InteractionModelRevision = 1 - [1689674637.555751][17326:17328] CHIP:DMG: }, - [1689674637.555784][17326:17328] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674637.555805][17326:17328] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1689674637.555853][17326:17328] CHIP:TOO: OperationalCommandResponse: { - [1689674637.555862][17326:17328] CHIP:TOO: commandResponseState: { - [1689674637.555872][17326:17328] CHIP:TOO: ErrorStateID: 0 - [1689674637.555883][17326:17328] CHIP:TOO: } - [1689674637.555891][17326:17328] CHIP:TOO: } - disabled: true - - - label: "Step 15: TH waits for {PIXIT.WAITTIME}" - verification: | - - disabled: true - - - label: "Step 16: TH reads from the DUT the OperationalState attribute" - PICS: OPSTATE.S.A0004 - verification: | - ./chip-tool operationalstate read operational-state 1 1 - - Via the TH (chip-tool), verify: - - the response has an OperationalStateID field that is set to 0x01 (Running) - - [1689674196.878722][17249:17251] CHIP:DMG: InteractionModelRevision = 1 - [1689674196.878727][17249:17251] CHIP:DMG: } - [1689674196.878800][17249:17251] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0004 DataVersion: 2102885775 - [1689674196.878834][17249:17251] CHIP:TOO: OperationalState: { - [1689674196.878841][17249:17251] CHIP:TOO: OperationalStateID: 1 - [1689674196.878847][17249:17251] CHIP:TOO: } - disabled: true - - - label: "Step 17: TH sends Pause command to the DUT" - PICS: OPSTATE.S.C00.Rsp && OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate pause 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1690457565.893634][18795:18797] CHIP:DMG: }, - [1690457565.893663][18795:18797] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1690457565.893681][18795:18797] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1690457565.893714][18795:18797] CHIP:TOO: OperationalCommandResponse: { - [1690457565.893729][18795:18797] CHIP:TOO: commandResponseState: { - [1690457565.893736][18795:18797] CHIP:TOO: ErrorStateID: 0 - [1690457565.893744][18795:18797] CHIP:TOO: } - [1690457565.893750][18795:18797] CHIP:TOO: } - disabled: true - - - label: "Step 18: TH reads from the DUT the OperationalState attribute" - PICS: OPSTATE.S.A0004 - verification: | - ./chip-tool operationalstate read operational-state 1 1 - - Via the TH (chip-tool), verify: - - the response has an OperationalStateID field that is set to 0x02 (Paused) - - [1690457601.103082][18800:18802] CHIP:DMG: InteractionModelRevision = 1 - [1690457601.103090][18800:18802] CHIP:DMG: } - [1690457601.103210][18800:18802] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0004 DataVersion: 4112784416 - [1690457601.103259][18800:18802] CHIP:TOO: OperationalState: 2 - disabled: true - - - label: "Step 19: TH waits for half of initial-countdown-time" - verification: | - - disabled: true - - - label: "Step 20: TH sends Resume command to the DUT" - PICS: OPSTATE.S.C03.Rsp && OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate resume 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x03 (CommandInvalidInState) - - [1690457852.049135][18877:18879] CHIP:DMG: }, - [1690457852.049164][18877:18879] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1690457852.049183][18877:18879] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1690457852.049217][18877:18879] CHIP:TOO: OperationalCommandResponse: { - [1690457852.049224][18877:18879] CHIP:TOO: commandResponseState: { - [1690457852.049238][18877:18879] CHIP:TOO: ErrorStateID: 3 - [1690457852.049246][18877:18879] CHIP:TOO: } - [1690457852.049252][18877:18879] CHIP:TOO: } - disabled: true - - - label: "Step 21: TH reads from the DUT the OperationalState attribute" - PICS: OPSTATE.S.A0004 - verification: | - ./chip-tool operationalstate read operational-state 1 1 - - Via the TH (chip-tool), verify: - - the response has an OperationalStateID field that is set to 0x01 (Running) - - [1689674196.878722][17249:17251] CHIP:DMG: InteractionModelRevision = 1 - [1689674196.878727][17249:17251] CHIP:DMG: } - [1689674196.878800][17249:17251] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Attribute 0x0000_0004 DataVersion: 2102885775 - [1689674196.878834][17249:17251] CHIP:TOO: OperationalState: { - [1689674196.878841][17249:17251] CHIP:TOO: OperationalStateID: 1 - [1689674196.878847][17249:17251] CHIP:TOO: } - disabled: true - - - label: "Step 22: TH waits for initial-countdown-time" - verification: | - TH waits for initial-countdown-time - disabled: true - - - label: "Step 23: TH sends Stop command to the DUT" - PICS: OPSTATE.S.C01.Rsp && OPSTATE.S.C04.Tx - verification: | - ./chip-tool operationalstate stop 1 1 - - Via the TH (chip-tool), verify: - - the response is an instance of OperationalCommandResponse - - The ErrorStateID field is set to 0x00 (NoError) - - [1689674653.322963][17330:17332] CHIP:DMG: }, - [1689674653.322994][17330:17332] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0060 Command=0x0000_0004 - [1689674653.323014][17330:17332] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0060 Command 0x0000_0004 - [1689674653.323058][17330:17332] CHIP:TOO: OperationalCommandResponse: { - [1689674653.323066][17330:17332] CHIP:TOO: commandResponseState: { - [1689674653.323076][17330:17332] CHIP:TOO: ErrorStateID: 0 - [1689674653.323085][17330:17332] CHIP:TOO: } - [1689674653.323094][17330:17332] CHIP:TOO: } - disabled: true - - - label: - "Step 24: Verify TH receives an OperationCompletion event with the - following fields populated as follows: 1. CompletionErrorCode set to - NoError(0x00) 2. TotalOperationalTime is approximately 1.5 times the - initial-countdown-time or null 3. PausedTime is 0.5 times the - initial-countdown-time" - PICS: OPSTATE.S.E01 - verification: | - operationalstate read-event operation-completion 1 1 - - [1657193007.841358][5422:5427] CHIP:TOO: Endpoint: 0 Endpoint: 1 Cluster: 0x0000_0060 Event 0x0000_0001 - [1657193007.841387][5422:5427] CHIP:TOO: Event number: 1 - [1657193007.841409][5422:5427] CHIP:TOO: Priority: INFO - [1657193007.841431][5422:5427] CHIP:TOO: Timestamp: 155146 - [1657193007.841531][5422:5427] CHIP:TOO: OperationCompletion: { - [1657193007.841570][5422:5427] CHIP:TOO: CompletionErrorCode: 0x00 - TotalOperationalTime: null - } - disabled: true diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index edc5c30faea79d..fd11f3ae2ac007 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -1868,6 +1868,39 @@ OPSTATE.S.C04.Tx=1 OPSTATE.S.E00=1 OPSTATE.S.E01=1 + +# Oven Operational State + +OVENOPSTATE.S=1 +OVENOPSTATE.C=1 +#ManuallyControlled + +OVENOPSTATE.S.M.ST_STOPPED=1 +OVENOPSTATE.S.M.ST_RUNNING=1 +OVENOPSTATE.S.M.ST_PAUSED=1 +OVENOPSTATE.S.M.ST_ERROR=1 +OVENOPSTATE.S.M.ERR_NO_ERROR=1 +OVENOPSTATE.S.M.ERR_UNABLE_TO_START_OR_RESUME=1 +OVENOPSTATE.S.M.ERR_UNABLE_TO_COMPLETE_OPERATION=1 +OVENOPSTATE.S.M.ERR_COMMAND_INVALID_IN_STATE=1 + +# Server Attributes +OVENOPSTATE.S.A0000=1 +OVENOPSTATE.S.A0001=1 +OVENOPSTATE.S.A0002=1 +OVENOPSTATE.S.A0003=1 +OVENOPSTATE.S.A0004=1 +OVENOPSTATE.S.A0005=1 +OVENOPSTATE.S.C00.Rsp=1 +OVENOPSTATE.S.C01.Rsp=1 +OVENOPSTATE.S.C02.Rsp=1 +OVENOPSTATE.S.C03.Rsp=1 +OVENOPSTATE.S.C04.Tx=1 + +# Server Events +OVENOPSTATE.S.E00=1 +OVENOPSTATE.S.E01=1 + # Thermostat # Server TSTAT.S=1 @@ -2762,7 +2795,7 @@ DEM.S.A0005=0 DEM.S.A0006=0 DEM.S.A0007=0 -# Features +# Features DEM.S.F00=0 DEM.S.F01=0 DEM.S.F02=0 diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index 9594ea623d1717..cbd655299f8422 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -177,7 +177,6 @@ "Test_TC_OO_2_2", "Test_TC_OO_2_4" ], - "OperationalState": ["Test_TC_OPSTATE_1_1", "Test_TC_OPSTATE_2_4"], "PowerSource": ["Test_TC_PS_1_1", "Test_TC_PS_2_1"], "PressureMeasurement": [ "Test_TC_PRS_1_1", diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json index 0263fc258b8db0..1c66bfccfbb9b0 100644 --- a/src/app/tests/suites/manualTests.json +++ b/src/app/tests/suites/manualTests.json @@ -276,7 +276,6 @@ "LevelControl": [], "LaundryWasherMode": ["Test_TC_LWM_1_2"], "OnOff": ["Test_TC_OO_2_3"], - "OperationalState": ["Test_TC_OPSTATE_2_2", "Test_TC_OPSTATE_2_5"], "RelativeHumidityMeasurement": ["Test_TC_RH_2_2"], "SmokeCOAlarm": [], "RefrigeratorAlarm": ["Test_TC_REFALM_2_2", "Test_TC_REFALM_2_3"], @@ -354,7 +353,6 @@ "LaundryWasherMode", "OnOff", "OvenMode", - "OperationalState", "OvenMode", "RelativeHumidityMeasurement", "SmokeCOAlarm", diff --git a/src/controller/python/test/test_scripts/mobile-device-test.py b/src/controller/python/test/test_scripts/mobile-device-test.py index 87e0a9acb6569b..9ceaa35d24c291 100755 --- a/src/controller/python/test/test_scripts/mobile-device-test.py +++ b/src/controller/python/test/test_scripts/mobile-device-test.py @@ -251,8 +251,12 @@ def do_tests(controller_nodeid, device_nodeid, address, timeout, discriminator, multiple=True, default=[], help="Trace location") +@click.option('--app-pid', + type=int, + default=0, + help="The PID of the app against which the test is going to run") def run(controller_nodeid, device_nodeid, address, timeout, discriminator, setup_pin, enable_test, disable_test, log_level, - log_format, print_test_list, paa_trust_store_path, trace_to): + log_format, print_test_list, paa_trust_store_path, trace_to, app_pid): coloredlogs.install(level=log_level, fmt=log_format, logger=logger) if print_test_list: diff --git a/src/python_testing/TC_OPSTATE_1_1.py b/src/python_testing/TC_OPSTATE_1_1.py new file mode 100644 index 00000000000000..67caefc85862b5 --- /dev/null +++ b/src/python_testing/TC_OPSTATE_1_1.py @@ -0,0 +1,53 @@ +# +# 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. +# + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OPSTATE_1_1(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OPSTATE", + cluster=Clusters.OperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OPSTATE_1_1(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_1_1() + + def pics_TC_OPSTATE_1_1(self) -> list[str]: + return ["OPSTATE.S"] + + @async_test_body + async def test_TC_OPSTATE_1_1(self): + endpoint = self.matter_test_config.endpoint + cluster_revision = 2 + feature_map = 0 + + await self.TEST_TC_OPSTATE_BASE_1_1(endpoint=endpoint, + cluster_revision=cluster_revision, + feature_map=feature_map) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OPSTATE_2_1.py b/src/python_testing/TC_OPSTATE_2_1.py index 98dbe83dc09057..0827202af71c29 100644 --- a/src/python_testing/TC_OPSTATE_2_1.py +++ b/src/python_testing/TC_OPSTATE_2_1.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023 Project CHIP Authors +# Copyright (c) 2024 Project CHIP Authors # All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,173 +15,33 @@ # limitations under the License. # -import logging import chip.clusters as Clusters -from chip.clusters.Types import NullValue -from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main -from mobly import asserts +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo -# This test requires several additional command line arguments -# run with -# --int-arg PIXIT_ENDPOINT: +class TC_OPSTATE_2_1(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) -class TC_OPSTATE_2_1(MatterBaseTest): + test_info = TestInfo( + pics_code="OPSTATE", + cluster=Clusters.OperationalState + ) - async def read_mod_attribute_expect_success(self, endpoint, attribute): - cluster = Clusters.Objects.OperationalState - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + super().setup_base(test_info=test_info) - async def read_and_validate_opstate(self, step, expected_state): - self.print_step(step, "Read OperationalState attribute") - operational_state = await self.read_mod_attribute_expect_success( - endpoint=self.endpoint, attribute=Clusters.OperationalState.Attributes.OperationalState) - logging.info("OperationalState: %s" % (operational_state)) - asserts.assert_equal(operational_state, expected_state, - "OperationalState(%s) should equal %s" % (operational_state, expected_state)) - - async def read_and_validate_operror(self, step, expected_error): - self.print_step(step, "Read OperationalError attribute") - operational_error = await self.read_mod_attribute_expect_success( - endpoint=self.endpoint, attribute=Clusters.OperationalState.Attributes.OperationalError) - logging.info("OperationalError: %s" % (operational_error)) - asserts.assert_equal(operational_error.errorStateID, expected_error, - "errorStateID(%s) should equal %s" % (operational_error.errorStateID, expected_error)) + def steps_TC_OPSTATE_2_1(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_2_1() def pics_TC_OPSTATE_2_1(self) -> list[str]: return ["OPSTATE.S"] @async_test_body async def test_TC_OPSTATE_2_1(self): - - asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, - "PIXIT_ENDPOINT must be included on the command line in " - "the --int-arg flag as PIXIT_ENDPOINT:") - - self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] - - attributes = Clusters.OperationalState.Attributes - - self.print_step(1, "Commissioning, already done") - - if self.check_pics("OPSTATE.S.A0000"): - self.print_step(2, "Read PhaseList attribute") - phase_list = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.PhaseList) - - if phase_list == NullValue: - logging.info("PhaseList is null") - else: - logging.info("PhaseList: %s" % (phase_list)) - - phase_list_len = len(phase_list) - - asserts.assert_less_equal(phase_list_len, 32, - "PhaseList length(%d) must be less than 32!" % phase_list_len) - - if self.check_pics("OPSTATE.S.A0001"): - self.print_step(3, "Read CurrentPhase attribute") - current_phase = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentPhase) - logging.info("CurrentPhase: %s" % (current_phase)) - - if phase_list == NullValue: - asserts.assert_true(current_phase == NullValue, "CurrentPhase(%s) should be null" % current_phase) - else: - asserts.assert_true(0 <= current_phase and current_phase < phase_list_len, - "CurrentPhase(%s) must be between 0 and %s" % (current_phase, (phase_list_len - 1))) - - if self.check_pics("OPSTATE.S.A0002"): - self.print_step(4, "Read CountdownTime attribute") - countdown_time = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, - attribute=attributes.CountdownTime) - - logging.info("CountdownTime: %s" % (countdown_time)) - if countdown_time is not NullValue: - asserts.assert_true(0 <= countdown_time <= 259200, - "CountdownTime(%s) must be between 0 and 259200" % countdown_time) - - if self.check_pics("OPSTATE.S.A0003"): - self.print_step(5, "Read OperationalStateList attribute") - operational_state_list = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, - attribute=attributes.OperationalStateList) - - logging.info("OperationalStateList: %s" % (operational_state_list)) - - defined_states = [state.value for state in Clusters.OperationalState.Enums.OperationalStateEnum - if state is not Clusters.OperationalState.Enums.OperationalStateEnum.kUnknownEnumValue] - - for state in operational_state_list: - in_range = (0x80 <= state.operationalStateID <= 0xBF) - asserts.assert_true(state.operationalStateID in defined_states or in_range, - "Found a OperationalStateList entry with invalid ID value!") - if in_range: - asserts.assert_true(state.operationalStateLabel is not None, - "The OperationalStateLabel should be populated") - if state.operationalStateID == Clusters.OperationalState.Enums.OperationalStateEnum.kError: - error_state_present = True - - asserts.assert_true(error_state_present, "The OperationalStateList does not have an ID entry of Error(0x03)") - - if self.check_pics("OPSTATE.S.A0004"): - self.print_step(6, "Read OperationalState attribute") - operational_state = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, - attribute=attributes.OperationalState) - - logging.info("OperationalState: %s" % (operational_state)) - - in_range = (0x80 <= operational_state <= 0xBF) - asserts.assert_true(operational_state in defined_states or in_range, "OperationalState has an invalid ID value!") - - if self.check_pics("OPSTATE.S.M.ST_STOPPED"): - self.print_step("6a", "Manually put the device in the stopped state") - input("Press Enter when done.\n") - await self.read_and_validate_opstate(step="6b", expected_state=Clusters.OperationalState.Enums.OperationalStateEnum.kStopped) - if self.check_pics("OPSTATE.S.M.ST_RUNNING"): - self.print_step("6c", "Manually put the device in the running state") - input("Press Enter when done.\n") - await self.read_and_validate_opstate(step="6d", expected_state=Clusters.OperationalState.Enums.OperationalStateEnum.kRunning) - if self.check_pics("OPSTATE.S.M.ST_PAUSED"): - self.print_step("6e", "Manually put the device in the paused state") - input("Press Enter when done.\n") - await self.read_and_validate_opstate(step="6f", expected_state=Clusters.OperationalState.Enums.OperationalStateEnum.kPaused) - if self.check_pics("OPSTATE.S.M.ST_ERROR"): - self.print_step("6g", "Manually put the device in the error state") - input("Press Enter when done.\n") - await self.read_and_validate_opstate(step="6h", expected_state=Clusters.OperationalState.Enums.OperationalStateEnum.kError) - - if self.check_pics("OPSTATE.S.A0005"): - self.print_step(7, "Read OperationalError attribute") - operational_error = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, - attribute=attributes.OperationalError) - - logging.info("OperationalError: %s" % (operational_error)) - - # Defined Errors - defined_errors = [error.value for error in Clusters.OperationalState.Enums.ErrorStateEnum - if error is not Clusters.OperationalState.Enums.ErrorStateEnum.kUnknownEnumValue] - - in_range = (0x80 <= operational_error.errorStateID <= 0xBF) - asserts.assert_true(operational_error.errorStateID in defined_errors - or in_range, "OperationalError has an invalid ID value!") - if in_range: - asserts.assert_true(operational_error.errorStateLabel is not None, "ErrorStateLabel should be populated") - - if self.check_pics("OPSTATE.S.M.ERR_NO_ERROR"): - self.print_step("7a", "Manually put the device in the no error state") - input("Press Enter when done.\n") - await self.read_and_validate_operror(step="7b", expected_error=Clusters.OperationalState.Enums.ErrorStateEnum.kNoError) - if self.check_pics("OPSTATE.S.M.ERR_UNABLE_TO_START_OR_RESUME"): - self.print_step("7c", "Manually put the device in the unable to start or resume error state") - input("Press Enter when done.\n") - await self.read_and_validate_operror(step="7d", expected_error=Clusters.OperationalState.Enums.ErrorStateEnum.kUnableToStartOrResume) - if self.check_pics("OPSTATE.S.M.ERR_UNABLE_TO_COMPLETE_OPERATION"): - self.print_step("7e", "Manually put the device in the unable to complete operation error state") - input("Press Enter when done.\n") - await self.read_and_validate_operror(step="7f", expected_error=Clusters.OperationalState.Enums.ErrorStateEnum.kUnableToCompleteOperation) - if self.check_pics("OPSTATE.S.M.ERR_COMMAND_INVALID_IN_STATE"): - self.print_step("7g", "Manually put the device in the command invalid error state") - input("Press Enter when done.\n") - await self.read_and_validate_operror(step="7h", expected_error=Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState) + endpoint = self.matter_test_config.endpoint + await self.TEST_TC_OPSTATE_BASE_2_1(endpoint) if __name__ == "__main__": diff --git a/src/python_testing/TC_OPSTATE_2_2.py b/src/python_testing/TC_OPSTATE_2_2.py new file mode 100644 index 00000000000000..59d36b56cfa66d --- /dev/null +++ b/src/python_testing/TC_OPSTATE_2_2.py @@ -0,0 +1,50 @@ +# +# 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. +# + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OPSTATE_2_2(MatterBaseTest, TC_OPSTATE_BASE): + + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OPSTATE", + cluster=Clusters.OperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OPSTATE_2_2(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_2_2() + + def pics_TC_OPSTATE_2_2(self) -> list[str]: + return ["OPSTATE.S"] + + @async_test_body + async def test_TC_OPSTATE_2_2(self): + endpoint = self.matter_test_config.endpoint + + await self.TEST_TC_OPSTATE_BASE_2_2(endpoint=endpoint) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OPSTATE_2_3.py b/src/python_testing/TC_OPSTATE_2_3.py index 57189c60382f08..e05aef4f607263 100644 --- a/src/python_testing/TC_OPSTATE_2_3.py +++ b/src/python_testing/TC_OPSTATE_2_3.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023 Project CHIP Authors +# Copyright (c) 2024 Project CHIP Authors # All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,160 +15,34 @@ # limitations under the License. # -import logging -import time import chip.clusters as Clusters -from chip.clusters.Types import NullValue -from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, type_matches -from mobly import asserts +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo -# This test requires several additional command line arguments -# run with -# --int-arg PIXIT_ENDPOINT: +class TC_OPSTATE_2_3(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) -class TC_OPSTATE_2_3(MatterBaseTest): + test_info = TestInfo( + pics_code="OPSTATE", + cluster=Clusters.OperationalState + ) - async def read_mod_attribute_expect_success(self, endpoint, attribute): - cluster = Clusters.Objects.OperationalState - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + super().setup_base(test_info=test_info) - async def send_pause_cmd(self) -> Clusters.Objects.OperationalState.Commands.Pause: - ret = await self.send_single_cmd(cmd=Clusters.Objects.OperationalState.Commands.Pause(), endpoint=self.endpoint) - asserts.assert_true(type_matches(ret, Clusters.Objects.OperationalState.Commands.OperationalCommandResponse), - "Unexpected return type for Pause") - return ret - - async def send_resume_cmd(self) -> Clusters.Objects.OperationalState.Commands.Resume: - ret = await self.send_single_cmd(cmd=Clusters.Objects.OperationalState.Commands.Resume(), endpoint=self.endpoint) - asserts.assert_true(type_matches(ret, Clusters.Objects.OperationalState.Commands.OperationalCommandResponse), - "Unexpected return type for Resume") - return ret + def steps_TC_OPSTATE_2_3(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_2_3() def pics_TC_OPSTATE_2_3(self) -> list[str]: return ["OPSTATE.S"] @async_test_body async def test_TC_OPSTATE_2_3(self): + endpoint = self.matter_test_config.endpoint - asserts.assert_true('PIXIT_ENDPOINT' in self.matter_test_config.global_test_params, - "PIXIT_ENDPOINT must be included on the command line in " - "the --int-arg flag as PIXIT_ENDPOINT:") - - self.endpoint = self.matter_test_config.global_test_params['PIXIT_ENDPOINT'] - - asserts.assert_true(self.check_pics("OPSTATE.S.A0003"), "OPSTATE.S.A0003 must be supported") - asserts.assert_true(self.check_pics("OPSTATE.S.A0004"), "OPSTATE.S.A0004 must be supported") - asserts.assert_true(self.check_pics("OPSTATE.S.C00.Rsp"), "OPSTATE.S.C00.Rsp must be supported") - asserts.assert_true(self.check_pics("OPSTATE.S.C03.Rsp"), "OPSTATE.S.C03.Rsp must be supported") - # This command SHALL be supported by an implementation if any of the other commands are supported (6.5) - asserts.assert_true(self.check_pics("OPSTATE.S.C04.Rsp"), "OPSTATE.S.C04.Rsp must be supported") - - attributes = Clusters.OperationalState.Attributes - - self.print_step(1, "Commissioning, already done") - - self.print_step(2, "Manually put the device in a state where it can receive a Pause command") - input("Press Enter when done.\n") - - self.print_step(3, "Read OperationalStateList attribute") - op_state_list = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, - attribute=attributes.OperationalStateList) - - logging.info("OperationalStateList: %s" % (op_state_list)) - - defined_states = [state.value for state in Clusters.OperationalState.Enums.OperationalStateEnum - if state is not Clusters.OperationalState.Enums.OperationalStateEnum.kUnknownEnumValue] - - state_ids = set([s.operationalStateID for s in op_state_list]) - - asserts.assert_true(all(id in state_ids for id in defined_states), "OperationalStateList is missing a required entry") - - self.print_step(4, "Send Pause command") - ret = await self.send_pause_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, - "errorStateID(%s) should be NoError(0x00)" % ret.commandResponseState.errorStateID) - - self.print_step(5, "Read OperationalState attribute") - operational_state = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, - attribute=attributes.OperationalState) - logging.info("OperationalState: %s" % (operational_state)) - asserts.assert_equal(operational_state, Clusters.OperationalState.Enums.OperationalStateEnum.kPaused, - "OperationalState ID should be Paused(0x02)") - - if self.check_pics("OPSTATE.S.A0002"): - self.print_step(6, "Read CountdownTime attribute") - initial_countdown_time = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, - attribute=attributes.CountdownTime) - logging.info("CountdownTime: %s" % (initial_countdown_time)) - if initial_countdown_time is not NullValue: - in_range = (1 <= initial_countdown_time <= 259200) - asserts.assert_true(initial_countdown_time is NullValue or in_range, - "invalid CountdownTime(%s). Must be in between 1 and 259200, or null " % initial_countdown_time) - - self.print_step(7, "Waiting for 5 seconds") - time.sleep(5) - - self.print_step(8, "Read CountdownTime attribute") - countdown_time = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CountdownTime) - logging.info("CountdownTime: %s" % (countdown_time)) - asserts.assert_true(countdown_time != 0 or countdown_time == NullValue, - "invalid CountdownTime(%s). Must be a non zero integer, or null" % countdown_time) - asserts.assert_equal(countdown_time, initial_countdown_time, "CountdownTime(%s) does not equal to the intial CountdownTime(%s)" - % (countdown_time, initial_countdown_time)) - - self.print_step(9, "Send Pause command") - ret = await self.send_pause_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, - "errorStateID(%s) should be NoError(0x00)" % ret.commandResponseState.errorStateID) - - self.print_step(10, "Send Resume command") - ret = await self.send_resume_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, - "errorStateID(%s) should be NoError(0x00)" % ret.commandResponseState.errorStateID) - - self.print_step(11, "Read OperationalState attribute") - operational_state = await self.read_mod_attribute_expect_success(endpoint=self.endpoint, - attribute=attributes.OperationalState) - logging.info("OperationalState: %s" % (operational_state)) - asserts.assert_equal(operational_state, Clusters.OperationalState.Enums.OperationalStateEnum.kRunning, - "OperationalState(%s) should be Running(0x01)" % operational_state) - - self.print_step(12, "Send Resume command") - ret = await self.send_resume_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, Clusters.OperationalState.Enums.ErrorStateEnum.kNoError, - "errorStateID(%s) should be NoError(0x00)" % ret.commandResponseState.errorStateID) - - self.print_step(13, "Manually put the device in the Stopped(0x00) operational state") - input("Press Enter when done.\n") - - self.print_step(14, "Send Pause command") - ret = await self.send_pause_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, - Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, - "errorStateID(%s) should be CommandInvalidInState(0x03)" % ret.commandResponseState.errorStateID) - - self.print_step(15, "Send Resume command") - ret = await self.send_resume_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, - Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, - "errorStateID(%s) should be CommandInvalidInState(0x03)" % ret.commandResponseState.errorStateID) - - self.print_step(16, "Manually put the device in the Error(0x03) operational state") - input("Press Enter when done.\n") - - self.print_step(17, "Send Pause command") - ret = await self.send_pause_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, - Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, - "errorStateID(%s) should be CommandInvalidInState(0x03)" % ret.commandResponseState.errorStateID) - - self.print_step(18, "Send Resume command") - ret = await self.send_resume_cmd() - asserts.assert_equal(ret.commandResponseState.errorStateID, - Clusters.OperationalState.Enums.ErrorStateEnum.kCommandInvalidInState, - "errorStateID(%s) should be CommandInvalidInState(0x03)" % ret.commandResponseState.errorStateID) + await self.TEST_TC_OPSTATE_BASE_2_3(endpoint=endpoint) if __name__ == "__main__": diff --git a/src/python_testing/TC_OPSTATE_2_4.py b/src/python_testing/TC_OPSTATE_2_4.py new file mode 100644 index 00000000000000..7ad8fbccd9cd42 --- /dev/null +++ b/src/python_testing/TC_OPSTATE_2_4.py @@ -0,0 +1,49 @@ +# +# 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. +# + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OPSTATE_2_4(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OPSTATE", + cluster=Clusters.OperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OPSTATE_2_4(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_2_4() + + def pics_TC_OPSTATE_2_4(self) -> list[str]: + return ["OPSTATE.S"] + + @async_test_body + async def test_TC_OPSTATE_2_4(self): + endpoint = self.matter_test_config.endpoint + + await self.TEST_TC_OPSTATE_BASE_2_4(endpoint=endpoint) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OPSTATE_2_5.py b/src/python_testing/TC_OPSTATE_2_5.py new file mode 100644 index 00000000000000..ffaceaeb2863a0 --- /dev/null +++ b/src/python_testing/TC_OPSTATE_2_5.py @@ -0,0 +1,49 @@ +# +# 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. +# + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OPSTATE_2_5(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OPSTATE", + cluster=Clusters.OperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OPSTATE_2_5(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_2_5() + + def pics_TC_OPSTATE_2_5(self) -> list[str]: + return ["OPSTATE.S"] + + @async_test_body + async def test_TC_OPSTATE_2_5(self): + endpoint = self.matter_test_config.endpoint + + await self.TEST_TC_OPSTATE_BASE_2_5(endpoint=endpoint) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OVENOPSTATE_1_1.py b/src/python_testing/TC_OVENOPSTATE_1_1.py new file mode 100644 index 00000000000000..3e6b0a27fbab5d --- /dev/null +++ b/src/python_testing/TC_OVENOPSTATE_1_1.py @@ -0,0 +1,53 @@ +# +# 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. +# + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OVENOPSTATE_1_1(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OVENOPSTATE", + cluster=Clusters.OvenCavityOperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OVENOPSTATE_1_1(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_1_1() + + def pics_TC_OVENOPSTATE_1_1(self) -> list[str]: + return ["OVENOPSTATE.S"] + + @async_test_body + async def test_TC_OVENOPSTATE_1_1(self): + endpoint = self.matter_test_config.endpoint + cluster_revision = 1 + feature_map = 0 + + await self.TEST_TC_OPSTATE_BASE_1_1(endpoint=endpoint, + cluster_revision=cluster_revision, + feature_map=feature_map) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OVENOPSTATE_2_1.py b/src/python_testing/TC_OVENOPSTATE_2_1.py new file mode 100644 index 00000000000000..e6847f22e94f39 --- /dev/null +++ b/src/python_testing/TC_OVENOPSTATE_2_1.py @@ -0,0 +1,48 @@ +# +# 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. +# + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OVENOPSTATE_2_1(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OVENOPSTATE", + cluster=Clusters.OvenCavityOperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OVENOPSTATE_2_1(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_2_1() + + def pics_TC_OVENOPSTATE_2_1(self) -> list[str]: + return ["OVENOPSTATE.S"] + + @async_test_body + async def test_TC_OVENOPSTATE_2_1(self): + endpoint = self.matter_test_config.endpoint + await self.TEST_TC_OPSTATE_BASE_2_1(endpoint) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OVENOPSTATE_2_2.py b/src/python_testing/TC_OVENOPSTATE_2_2.py new file mode 100644 index 00000000000000..7789f5076a7d0a --- /dev/null +++ b/src/python_testing/TC_OVENOPSTATE_2_2.py @@ -0,0 +1,50 @@ +# +# 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. +# + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OVENOPSTATE_2_2(MatterBaseTest, TC_OPSTATE_BASE): + + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OVENOPSTATE", + cluster=Clusters.OvenCavityOperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OVENOPSTATE_2_2(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_2_2() + + def pics_TC_OVENOPSTATE_2_2(self) -> list[str]: + return ["OVENOPSTATE.S"] + + @async_test_body + async def test_TC_OVENOPSTATE_2_2(self): + endpoint = self.matter_test_config.endpoint + + await self.TEST_TC_OPSTATE_BASE_2_2(endpoint=endpoint) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OVENOPSTATE_2_3.py b/src/python_testing/TC_OVENOPSTATE_2_3.py new file mode 100644 index 00000000000000..25434978320b46 --- /dev/null +++ b/src/python_testing/TC_OVENOPSTATE_2_3.py @@ -0,0 +1,49 @@ +# +# 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. +# + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OVENOPSTATE_2_3(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OVENOPSTATE", + cluster=Clusters.OvenCavityOperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OVENOPSTATE_2_3(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_2_3() + + def pics_TC_OVENOPSTATE_2_3(self) -> list[str]: + return ["OVENOPSTATE.S"] + + @async_test_body + async def test_TC_OVENOPSTATE_2_3(self): + endpoint = self.matter_test_config.endpoint + + await self.TEST_TC_OPSTATE_BASE_2_3(endpoint=endpoint) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OVENOPSTATE_2_4.py b/src/python_testing/TC_OVENOPSTATE_2_4.py new file mode 100644 index 00000000000000..4bc2040638b820 --- /dev/null +++ b/src/python_testing/TC_OVENOPSTATE_2_4.py @@ -0,0 +1,49 @@ +# +# 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. +# + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OVENOPSTATE_2_4(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OVENOPSTATE", + cluster=Clusters.OvenCavityOperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OVENOPSTATE_2_4(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_2_4() + + def pics_TC_OVENOPSTATE_2_4(self) -> list[str]: + return ["OVENOPSTATE.S"] + + @async_test_body + async def test_TC_OVENOPSTATE_2_4(self): + endpoint = self.matter_test_config.endpoint + + await self.TEST_TC_OPSTATE_BASE_2_4(endpoint=endpoint) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OVENOPSTATE_2_5.py b/src/python_testing/TC_OVENOPSTATE_2_5.py new file mode 100644 index 00000000000000..7754f0a624ffd3 --- /dev/null +++ b/src/python_testing/TC_OVENOPSTATE_2_5.py @@ -0,0 +1,49 @@ +# +# 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. +# + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OVENOPSTATE_2_5(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OVENOPSTATE", + cluster=Clusters.OvenCavityOperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OVENOPSTATE_2_5(self) -> list[TestStep]: + return self.STEPS_TC_OPSTATE_BASE_2_5() + + def pics_TC_OVENOPSTATE_2_5(self) -> list[str]: + return ["OVENOPSTATE.S"] + + @async_test_body + async def test_TC_OVENOPSTATE_2_5(self): + endpoint = self.matter_test_config.endpoint + + await self.TEST_TC_OPSTATE_BASE_2_5(endpoint=endpoint) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OpstateCommon.py b/src/python_testing/TC_OpstateCommon.py new file mode 100644 index 00000000000000..9e32aac00ec846 --- /dev/null +++ b/src/python_testing/TC_OpstateCommon.py @@ -0,0 +1,1217 @@ +# +# 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. +# + +import json +import logging +import queue +import time +from dataclasses import dataclass +from typing import Any + +import chip.clusters as Clusters +import psutil +from chip.clusters import ClusterObjects as ClusterObjects +from chip.clusters.Attribute import EventReadResult, SubscriptionTransaction +from chip.clusters.Types import NullValue +from chip.interaction_model import InteractionModelError, Status +from matter_testing_support import EventChangeCallback, TestStep +from mobly import asserts + + +def get_pid(name): + pid = None + + for proc in psutil.process_iter(): + if name in proc.name(): + pid = proc.pid + break + + return pid + + +@dataclass +class TestInfo: + pics_code: str + cluster: Clusters + + +class EventSpecificChangeCallback: + def __init__(self, expected_event: ClusterObjects.ClusterEvent): + """This class creates a queue to store received event callbacks, that can be checked by the test script + expected_event: is the expected event + """ + self._q = queue.Queue() + self._expected_cluster_id = expected_event.cluster_id + self._expected_event = expected_event + + async def start(self, dev_ctrl, node_id: int, endpoint: int): + """This starts a subscription for events on the specified node_id and endpoint. The event is specified when the class instance is created.""" + self._subscription = await dev_ctrl.ReadEvent(node_id, + events=[(endpoint, self._expected_event, True)], reportInterval=(1, 5), + fabricFiltered=False, keepSubscriptions=True, autoResubscribe=False) + self._subscription.SetEventUpdateCallback(self.__call__) + + def __call__(self, res: EventReadResult, transaction: SubscriptionTransaction): + """This is the subscription callback when an event is received. + It checks the if the event is the expected one and then posts it into the queue for later processing.""" + if res.Status == Status.Success and res.Header.ClusterId == self._expected_cluster_id and res.Header.EventId == self._expected_event.event_id: + logging.info( + f'Got subscription report for event {self._expected_event.event_id} on cluster {self._expected_cluster_id}: {res.Data}') + self._q.put(res) + + def wait_for_event_report(self, timeout: int = 10): + """This function allows a test script to block waiting for the specific event to arrive with a timeout. + It returns the event data so that the values can be checked.""" + try: + res = self._q.get(block=True, timeout=timeout) + except queue.Empty: + asserts.fail(f"Failed to receive a report for the event {self._expected_event}") + + asserts.assert_equal(res.Header.ClusterId, self._expected_cluster_id, "Expected cluster ID not found in event report") + asserts.assert_equal(res.Header.EventId, self._expected_event.event_id, "Expected event ID not found in event report") + return res.Data + + +class TC_OPSTATE_BASE(): + def setup_base(self, test_info=None, app_pipe="/tmp/chip_all_clusters_fifo_"): + + asserts.assert_true(test_info is not None, + "You shall define the test info!") + + self.test_info = test_info + self.app_pipe = app_pipe + + if self.test_info.cluster == Clusters.OperationalState: + self.device = "Generic" + elif self.test_info.cluster == Clusters.OvenCavityOperationalState: + self.device = "Oven" + else: + asserts.fail(f"This provided cluster ({self.test_info.cluster}) is not supported!") + + def init_test(self): + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + app_pid = get_pid("chip-all-clusters-app") + if app_pid is None: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + # Sends and out-of-band command to test-app + def write_to_app_pipe(self, command): + with open(self.app_pipe, "w") as app_pipe: + app_pipe.write(command + "\n") + + def send_raw_manual_or_pipe_command(self, command): + if self.is_ci: + self.write_to_app_pipe(command) + time.sleep(0.1) + else: + input("Press Enter when done.\n") + + def send_manual_or_pipe_command(self, device: str, name: str, operation: str, param: Any = None): + command = { + "Name": name, + "Device": device, + "Operation": operation, + } + + if param is not None: + command["Param"] = param + + self.send_raw_manual_or_pipe_command(json.dumps(command)) + + async def send_cmd(self, endpoint, cmd, timedRequestTimeoutMs=None): + logging.info(f"##### Command {cmd}") + + try: + return await self.send_single_cmd(cmd=cmd, + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + except InteractionModelError as e: + asserts.fail(f"Unexpected error returned: {e.status}") + + async def send_cmd_expect_response(self, endpoint, cmd, expected_response, timedRequestTimeoutMs=None): + ret = await self.send_cmd(endpoint=endpoint, + cmd=cmd, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(ret.commandResponseState.errorStateID, + expected_response, + f"Command response ({ret.commandResponseState}) mismatched from expectation for {cmd} on {endpoint}") + + async def read_expect_success(self, endpoint, attribute): + logging.info(f"##### Read {attribute}") + attr_value = await self.read_single_attribute_check_success(endpoint=endpoint, + cluster=self.test_info.cluster, + attribute=attribute) + logging.info(f"## {attribute}: {attr_value}") + + return attr_value + + async def read_and_expect_value(self, endpoint, attribute, expected_value): + attr_value = await self.read_expect_success( + endpoint=endpoint, + attribute=attribute) + + asserts.assert_equal(attr_value, expected_value, + f"Value mismatched from expectation for {attribute} on {endpoint}") + + async def read_and_expect_property_value(self, endpoint, attribute, attr_property, expected_value): + attr_value = await self.read_expect_success( + endpoint=endpoint, + attribute=attribute) + field_value = getattr(attr_value, attr_property) + + asserts.assert_equal(field_value, expected_value, + f"Property '{attr_property}' value mismatched from expectation for {attribute} on {endpoint}") + + async def read_and_expect_array_contains(self, endpoint, attribute, expected_contains): + attr_value = await self.read_expect_success( + endpoint=endpoint, + attribute=attribute) + attr_value.sort() + expected_contains.sort() + + logging.info("## Current value: [%s]" % attr_value) + logging.info("## Expected value: [%s]" % expected_contains) + + for item in expected_contains: + if item not in attr_value: + asserts.fail("Entry (%s), not found! The returned value SHALL include all the entries: [%s]!" % ( + item, expected_contains)) + + ############################ + # TEST CASE 1.1 + ############################ + def STEPS_TC_OPSTATE_BASE_1_1(self) -> list[TestStep]: + steps = [TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "TH reads from the DUT the ClusterRevision attribute"), + TestStep(3, "TH reads from the DUT the FeatureMap attribute"), + TestStep(4, "TH reads from the DUT the AttributeList attribute"), + TestStep(5, "TH reads from the DUT the EventList attribute"), + TestStep(6, "TH reads from the DUT the AcceptedCommandList attribute"), + TestStep(7, "TH reads from the DUT the GeneratedCommandList attribute") + ] + return steps + + async def TEST_TC_OPSTATE_BASE_1_1(self, endpoint=1, cluster_revision=1, feature_map=0): + cluster = self.test_info.cluster + attributes = cluster.Attributes + events = cluster.Events + commands = cluster.Commands + + self.init_test() + + # STEP 1: Commission DUT to TH (can be skipped if done in a preceding test) + self.step(1) + + # STEP 2: TH reads from the DUT the ClusterRevision attribute + self.step(2) + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.ClusterRevision, + expected_value=cluster_revision) + + # STEP 3: TH reads from the DUT the FeatureMap attribute + self.step(3) + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.FeatureMap, + expected_value=feature_map) + + # STEP 4: TH reads from the DUT the AttributeList attribute + self.step(4) + expected_value = [ + attributes.PhaseList.attribute_id, + attributes.CurrentPhase.attribute_id, + attributes.OperationalStateList.attribute_id, + attributes.OperationalState.attribute_id, + attributes.OperationalError.attribute_id, + attributes.GeneratedCommandList.attribute_id, + attributes.AcceptedCommandList.attribute_id, + attributes.AttributeList.attribute_id, + attributes.FeatureMap.attribute_id, + attributes.ClusterRevision.attribute_id + ] + + if self.check_pics(f"{self.test_info.pics_code}.S.A0002"): + expected_value.append(attributes.CountdownTime.attribute_id) + + await self.read_and_expect_array_contains(endpoint=endpoint, + attribute=attributes.AttributeList, + expected_contains=expected_value) + + # STEP 5: TH reads from the DUT the EventList attribute + self.step(5) + if self.pics_guard(self.check_pics("PICS_EVENT_LIST_ENABLED")): + expected_value = [ + events.OperationalError.event_id, + ] + + if self.check_pics(f"{self.test_info.pics_code}.S.E01"): + expected_value.append(events.OperationCompletion.event_id) + + await self.read_and_expect_array_contains(endpoint=endpoint, + attribute=attributes.EventList, + expected_contains=expected_value) + + # STEP 6: TH reads from the DUT the AcceptedCommandList attribute + self.step(6) + expected_value = [] + + if (self.check_pics(f"{self.test_info.pics_code}.S.C00.Rsp") or + self.check_pics(f"{self.test_info.pics_code}.S.C03.Rsp")): + expected_value.append(commands.Pause.command_id) + + if (self.check_pics(f"{self.test_info.pics_code}.S.C01.Rsp") or + self.check_pics(f"{self.test_info.pics_code}.S.C02.Rsp")): + expected_value.append(commands.Stop.command_id) + + if self.check_pics(f"{self.test_info.pics_code}.S.C02.Rsp"): + expected_value.append(commands.Start.command_id) + + if (self.check_pics(f"{self.test_info.pics_code}.S.C03.Rsp") or + self.check_pics(f"{self.test_info.pics_code}.S.C00.Rsp")): + expected_value.append(commands.Resume.command_id) + + await self.read_and_expect_array_contains(endpoint=endpoint, + attribute=attributes.AcceptedCommandList, + expected_contains=expected_value) + + # STEP 7: TH reads from the DUT the AcceptedCommandList attribute + self.step(7) + expected_value = [] + + if (self.check_pics(f"{self.test_info.pics_code}.S.C00.Rsp") or + self.check_pics(f"{self.test_info.pics_code}.S.C01.Rsp") or + self.check_pics(f"{self.test_info.pics_code}.S.C02.Rsp") or + self.check_pics(f"{self.test_info.pics_code}.S.C03.Rsp")): + expected_value.append(commands.OperationalCommandResponse.command_id) + + await self.read_and_expect_array_contains(endpoint=endpoint, + attribute=attributes.GeneratedCommandList, + expected_contains=expected_value) + + ############################ + # TEST CASE 2.1 + ############################ + def STEPS_TC_OPSTATE_BASE_2_1(self) -> list[TestStep]: + steps = [TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "TH reads from the DUT the PhaseList attribute"), + TestStep(3, "TH reads from the DUT the CurrentPhase attribute"), + TestStep(4, "TH reads from the DUT the CountdownTime attribute"), + TestStep(5, "TH reads from the DUT the OperationalStateList attribute"), + TestStep(6, "TH reads from the DUT the OperationalState attribute"), + TestStep("6a", "Manually put the device in the Stopped(0x00) operational state"), + TestStep("6b", "TH reads from the DUT the OperationalState attribute"), + TestStep("6c", "Manually put the device in the Running(0x01) operational state"), + TestStep("6d", "TH reads from the DUT the OperationalState attribute"), + TestStep("6e", "Manually put the device in the Paused(0x02) operational state"), + TestStep("6f", "TH reads from the DUT the OperationalState attribute"), + TestStep("6g", "Manually put the device in the Error(0x03) operational state"), + TestStep("6h", "TH reads from the DUT the OperationalState attribute"), + TestStep(7, "TH reads from the DUT the OperationalError attribute"), + TestStep("7a", "Manually put the device in the NoError(0x00) error state"), + TestStep("7b", "TH reads from the DUT the OperationalError attribute"), + TestStep("7c", "Manually put the device in the UnableToStartOrResume(0x01) error state"), + TestStep("7d", "TH reads from the DUT the OperationalError attribute"), + TestStep("7e", "Manually put the device in the UnableToCompleteOperation(0x02) error state"), + TestStep("7f", "TH reads from the DUT the OperationalError attribute"), + TestStep("7g", "Manually put the device in the CommandInvalidInState(0x03) error state"), + TestStep("7h", "TH reads from the DUT the OperationalError attribute") + ] + return steps + + async def TEST_TC_OPSTATE_BASE_2_1(self, endpoint=1): + cluster = self.test_info.cluster + attributes = cluster.Attributes + + self.init_test() + + # STEP 1: Commission DUT to TH (can be skipped if done in a preceding test) + self.step(1) + + # STEP 2: TH reads from the DUT the PhaseList attribute + self.step(2) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0000")): + phase_list = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.PhaseList) + if phase_list is not NullValue: + phase_list_len = len(phase_list) + asserts.assert_less_equal(phase_list_len, 32, + f"PhaseList length({phase_list_len}) must be less than 32!") + + # STEP 3: TH reads from the DUT the CurrentPhase attribute + self.step(3) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0001")): + current_phase = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.CurrentPhase) + if (phase_list == NullValue) or (not phase_list): + asserts.assert_true(current_phase == NullValue, f"CurrentPhase({current_phase}) should be null") + else: + asserts.assert_true(0 <= current_phase and current_phase < phase_list_len, + f"CurrentPhase({current_phase}) must be between 0 and {(phase_list_len - 1)}") + + # STEP 4: TH reads from the DUT the CountdownTime attribute + self.step(4) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0002")): + countdown_time = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.CountdownTime) + if countdown_time is not NullValue: + asserts.assert_true(0 <= countdown_time <= 259200, + f"CountdownTime({countdown_time}) must be between 0 and 259200") + + # STEP 5: TH reads from the DUT the OperationalStateList attribute + self.step(5) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0003")): + operational_state_list = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.OperationalStateList) + defined_states = [state.value for state in cluster.Enums.OperationalStateEnum + if state != cluster.Enums.OperationalStateEnum.kUnknownEnumValue] + + for state in operational_state_list: + in_range = (0x80 <= state.operationalStateID <= 0xBF) + asserts.assert_true(state.operationalStateID in defined_states or in_range, + "Found a OperationalStateList entry with invalid ID value!") + if in_range: + asserts.assert_true(state.operationalStateLabel is not None, + "The OperationalStateLabel should be populated") + + if state.operationalStateID == cluster.Enums.OperationalStateEnum.kError: + error_state_present = True + + asserts.assert_true(error_state_present, "The OperationalStateList does not have an ID entry of Error(0x03)") + + # STEP 6: TH reads from the DUT the OperationalState attribute + self.step(6) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + operational_state = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.OperationalState) + in_range = (0x80 <= operational_state <= 0xBF) + asserts.assert_true(operational_state in defined_states or in_range, + "OperationalState has an invalid ID value!") + + # STEP 6a: Manually put the device in the Stopped(0x00) operational state + self.step("6a") + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ST_STOPPED")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Stop") + # STEP 6b: TH reads from the DUT the OperationalState attribute + self.step("6b") + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kStopped) + else: + self.skip_step("6b") + + # STEP 6c: Manually put the device in the Running(0x01) operational state + self.step("6c") + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ST_RUNNING")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Start") + # STEP 6d: TH reads from the DUT the OperationalState attribute + self.step("6d") + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + else: + self.skip_step("6d") + + # STEP 6e: Manually put the device in the Paused(0x02) operational state + self.step("6e") + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ST_PAUSED")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Pause") + # STEP 6f: TH reads from the DUT the OperationalState attribute + self.step("6f") + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kPaused) + else: + self.skip_step("6f") + + # STEP 6g: Manually put the device in the Error(0x03) operational state + self.step("6g") + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ST_ERROR")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kUnableToStartOrResume) + # STEP 6h: TH reads from the DUT the OperationalState attribute + self.step("6h") + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kError) + else: + self.skip_step("6h") + + # STEP 7: TH reads from the DUT the OperationalError attribute + self.step(7) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0005")): + operational_error = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.OperationalError) + # Defined Errors + defined_errors = [error.value for error in cluster.Enums.ErrorStateEnum + if error != cluster.Enums.ErrorStateEnum.kUnknownEnumValue] + + in_range = (0x80 <= operational_error.errorStateID <= 0xBF) + asserts.assert_true(operational_error.errorStateID in defined_errors + or in_range, "OperationalError has an invalid ID value!") + if in_range: + asserts.assert_true(operational_error.errorStateLabel is not None, "ErrorStateLabel should be populated") + + # STEP 7a: Manually put the device in the NoError(0x00) error state + self.step("7a") + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ERR_NO_ERROR")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kNoError) + # STEP 7b: TH reads from the DUT the OperationalError attribute + self.step("7b") + await self.read_and_expect_property_value(endpoint=endpoint, + attribute=attributes.OperationalError, + attr_property="errorStateID", + expected_value=cluster.Enums.ErrorStateEnum.kNoError) + else: + self.skip_step("7b") + + # STEP 7c: Manually put the device in the UnableToStartOrResume(0x01) error state + self.step("7c") + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ERR_UNABLE_TO_START_OR_RESUME")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kUnableToStartOrResume) + # STEP 7d: TH reads from the DUT the OperationalError attribute + self.step("7d") + await self.read_and_expect_property_value(endpoint=endpoint, + attribute=attributes.OperationalError, + attr_property="errorStateID", + expected_value=cluster.Enums.ErrorStateEnum.kUnableToStartOrResume) + else: + self.skip_step("7d") + + # STEP 7e: Manually put the device in the UnableToCompleteOperation(0x02) error state + self.step("7e") + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ERR_UNABLE_TO_COMPLETE_OPERATION")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kUnableToCompleteOperation) + # STEP 7f: TH reads from the DUT the OperationalError attribute + self.step("7f") + await self.read_and_expect_property_value(endpoint=endpoint, + attribute=attributes.OperationalError, + attr_property="errorStateID", + expected_value=cluster.Enums.ErrorStateEnum.kUnableToCompleteOperation) + else: + self.skip_step("7f") + + # STEP 7g: Manually put the device in the CommandInvalidInState(0x03) error state + self.step("7g") + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ERR_COMMAND_INVALID_IN_STATE")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kCommandInvalidInState) + # STEP 7h: TH reads from the DUT the OperationalError attribute + self.step("7h") + await self.read_and_expect_property_value(endpoint=endpoint, + attribute=attributes.OperationalError, + attr_property="errorStateID", + expected_value=cluster.Enums.ErrorStateEnum.kCommandInvalidInState) + else: + self.skip_step("7h") + + ############################ + # TEST CASE 2.2 + ############################ + def STEPS_TC_OPSTATE_BASE_2_2(self) -> list[TestStep]: + steps = [TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Manually put the DUT into a state wherein it can receive a Start Command"), + TestStep(3, "TH reads from the DUT the OperationalStateList attribute"), + TestStep(4, "TH sends Start command to the DUT"), + TestStep(5, "TH reads from the DUT the OperationalState attribute"), + TestStep(6, "TH reads from the DUT the OperationalError attribute"), + TestStep(7, "TH reads from the DUT the CountdownTime attribute"), + TestStep(8, "TH reads from the DUT the PhaseList attribute"), + TestStep(9, "TH reads from the DUT the CurrentPhase attribute"), + TestStep(10, "TH waits for {PIXIT.WAITTIME.COUNTDOWN}"), + TestStep(11, "TH reads from the DUT the CountdownTime attribute"), + TestStep(12, "TH sends Start command to the DUT"), + TestStep(13, "TH sends Stop command to the DUT"), + TestStep(14, "TH reads from the DUT the OperationalState attribute"), + TestStep(15, "TH sends Stop command to the DUT"), + TestStep(16, "Manually put the DUT into a state wherein it cannot receive a Start Command"), + TestStep(17, "TH sends Start command to the DUT") + ] + return steps + + async def TEST_TC_OPSTATE_BASE_2_2(self, endpoint=1): + cluster = self.test_info.cluster + attributes = cluster.Attributes + commands = cluster.Commands + + self.init_test() + + asserts.assert_true('PIXIT.WAITTIME.COUNTDOWN' in self.matter_test_config.global_test_params, + "PIXIT.WAITTIME.COUNTDOWN must be included on the command line in " + "the --int-arg flag as PIXIT.WAITTIME.COUNTDOWN:") + + wait_time = self.matter_test_config.global_test_params['PIXIT.WAITTIME.COUNTDOWN'] + + if wait_time == 0: + asserts.fail("PIXIT.WAITTIME.COUNTDOWN shall be higher than 0.") + + # STEP 1: Commission DUT to TH (can be skipped if done in a preceding test) + self.step(1) + + # STEP 2: Manually put the DUT into a state wherein it can receive a Start Command + self.step(2) + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kNoError) + + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Stop") + + # STEP 3: TH reads from the DUT the OperationalStateList attribute + self.step(3) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0003")): + operational_state_list = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.OperationalStateList) + + operational_state_list_ids = [op_state.operationalStateID for op_state in operational_state_list] + + defined_states = [state.value for state in cluster.Enums.OperationalStateEnum + if state != cluster.Enums.OperationalStateEnum.kUnknownEnumValue] + + for state in defined_states: + if state not in operational_state_list_ids: + asserts.fail(f"The list shall include structs with the following OperationalStateIds: {defined_states}") + + # STEP 4: TH sends Start command to the DUT + self.step(4) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C02.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Start(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 5: TH reads from the DUT the OperationalState attribute + self.step(5) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + + # STEP 6: TH reads from the DUT the OperationalError attribute + self.step(6) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0005")): + await self.read_and_expect_property_value(endpoint=endpoint, + attribute=attributes.OperationalError, + attr_property="errorStateID", + expected_value=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 7: TH reads from the DUT the CountdownTime attribute + self.step(7) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0002")): + initial_countdown_time = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.CountdownTime) + if initial_countdown_time is not NullValue: + asserts.assert_true(0 <= initial_countdown_time <= 259200, + f"CountdownTime({initial_countdown_time}) must be between 0 and 259200") + + # STEP 8: TH reads from the DUT the PhaseList attribute + self.step(8) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0000")): + phase_list = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.PhaseList) + phase_list_len = 0 + if phase_list is not NullValue: + phase_list_len = len(phase_list) + asserts.assert_less_equal(phase_list_len, 32, + f"PhaseList length({phase_list_len}) must be less than 32!") + + # STEP 9: TH reads from the DUT the CurrentPhase attribute + self.step(9) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0001")): + current_phase = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.CurrentPhase) + if (phase_list == NullValue) or (not phase_list): + asserts.assert_equal(current_phase, NullValue, f"CurrentPhase({current_phase}) should be null") + else: + asserts.assert_less_equal(0, current_phase, + f"CurrentPhase({current_phase}) must be greater or equal than 0") + asserts.assert_less(current_phase < phase_list_len, + f"CurrentPhase({current_phase}) must be less then {(phase_list_len - 1)}") + + # STEP 10: TH waits for {PIXIT.WAITTIME.COUNTDOWN} + self.step(10) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0002")): + time.sleep(wait_time) + + # STEP 11: TH reads from the DUT the CountdownTime attribute + self.step(11) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0002")): + countdown_time = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.CountdownTime) + + if (countdown_time is not NullValue) and (initial_countdown_time is not NullValue): + asserts.assert_less_equal(countdown_time, (initial_countdown_time - wait_time), + f"The countdown time shall have decreased at least {wait_time:.1f} since start command") + + # STEP 12: TH sends Start command to the DUT + self.step(12) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C02.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Start(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 13: TH sends Stop command to the DUT + self.step(13) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C01.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Stop(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 14: TH reads from the DUT the OperationalState attribute + self.step(14) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kStopped) + + # STEP 15: TH sends Stop command to the DUT + self.step(15) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C01.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Stop(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 16: Manually put the DUT into a state wherein it cannot receive a Start Command + self.step(16) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ERR_UNABLE_TO_START_OR_RESUME")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kUnableToCompleteOperation) + + # STEP 17: TH sends Start command to the DUT + self.step(17) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ERR_UNABLE_TO_START_OR_RESUME") and + self.check_pics(f"{self.test_info.pics_code}.S.C02.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Start(), + expected_response=cluster.Enums.ErrorStateEnum.kUnableToStartOrResume) + + ############################ + # TEST CASE 2.3 + ############################ + def STEPS_TC_OPSTATE_BASE_2_3(self) -> list[TestStep]: + steps = [TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Manually put the DUT into a state wherein it can receive a Pause Command"), + TestStep(3, "TH reads from the DUT the OperationalStateList attribute"), + TestStep(4, "TH sends Pause command to the DUT"), + TestStep(5, "TH reads from the DUT the OperationalState attribute"), + TestStep(6, "TH reads from the DUT the CountdownTime attribute"), + TestStep(7, "TH waits for {PIXIT.WAITTIME.COUNTDOWN}"), + TestStep(8, "TH reads from the DUT the CountdownTime attribute"), + TestStep(9, "TH sends Pause command to the DUT"), + TestStep(10, "TH sends Resume command to the DUT"), + TestStep(11, "TH reads from the DUT the OperationalState attribute"), + TestStep(12, "TH sends Resume command to the DUT"), + TestStep(13, "Manually put the device in the Stopped(0x00) operational state"), + TestStep(14, "TH sends Pause command to the DUT"), + TestStep(15, "TH sends Resume command to the DUT"), + TestStep(16, "Manually put the device in the Error(0x03) operational state"), + TestStep(17, "TH sends Pause command to the DUT"), + TestStep(18, "TH sends Resume command to the DUT") + ] + return steps + + async def TEST_TC_OPSTATE_BASE_2_3(self, endpoint=1): + cluster = self.test_info.cluster + attributes = cluster.Attributes + commands = cluster.Commands + + self.init_test() + + asserts.assert_true('PIXIT.WAITTIME.COUNTDOWN' in self.matter_test_config.global_test_params, + "PIXIT.WAITTIME.COUNTDOWN must be included on the command line in " + "the --int-arg flag as PIXIT.WAITTIME.COUNTDOWN:") + + wait_time = self.matter_test_config.global_test_params['PIXIT.WAITTIME.COUNTDOWN'] + + if wait_time == 0: + asserts.fail("PIXIT.WAITTIME.COUNTDOWN shall be higher than 0.") + + # STEP 1: Commission DUT to TH (can be skipped if done in a preceding test) + self.step(1) + + # STEP 2: Manually put the DUT into a state wherein it can receive a Pause Command + self.step(2) + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kNoError) + + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Start") + + # STEP 3: TH reads from the DUT the OperationalStateList attribute + self.step(3) + if self.pics_guard(self.check_pics((f"{self.test_info.pics_code}.S.A0003"))): + operational_state_list = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.OperationalStateList) + + operational_state_list_ids = [op_state.operationalStateID for op_state in operational_state_list] + + defined_states = [state.value for state in cluster.Enums.OperationalStateEnum + if state != cluster.Enums.OperationalStateEnum.kUnknownEnumValue] + + for state in defined_states: + if state not in operational_state_list_ids: + asserts.fail(f"The list shall include structs with the following OperationalStateIds: {defined_states}") + + # STEP 4: TH sends Pause command to the DUT + self.step(4) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C00.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Pause(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 5: TH reads from the DUT the OperationalState attribute + self.step(5) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kPaused) + + # STEP 6: TH reads from the DUT the CountdownTime attribute + self.step(6) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0002")): + initial_countdown_time = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.CountdownTime) + if initial_countdown_time is not NullValue: + asserts.assert_true(0 <= initial_countdown_time <= 259200, + f"CountdownTime({initial_countdown_time}) must be between 0 and 259200") + + # STEP 7: TH waits for {PIXIT.WAITTIME.COUNTDOWN} + self.step(7) + time.sleep(wait_time) + + # STEP 8: TH reads from the DUT the CountdownTime attribute + self.step(8) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0002")): + countdown_time = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.CountdownTime) + + if (countdown_time is not NullValue) and (initial_countdown_time is not NullValue): + asserts.assert_equal(countdown_time, initial_countdown_time, + "The countdown time shall be equal since pause command") + + # STEP 9: TH sends Pause command to the DUT + self.step(9) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C00.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Pause(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 10: TH sends Resume command to the DUT + self.step(10) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C03.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Resume(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 11: TH reads from the DUT the OperationalState attribute + self.step(11) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + + # STEP 12: TH sends Resume command to the DUT + self.step(12) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C03.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Resume(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 13: Manually put the device in the Stopped(0x00) operational state + self.step(13) + if self.pics_guard(self.check_pics((f"{self.test_info.pics_code}.S.M.ST_STOPPED"))): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Stop") + + # STEP 14: TH sends Pause command to the DUT + self.step(14) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C00.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Pause(), + expected_response=cluster.Enums.ErrorStateEnum.kCommandInvalidInState) + + # STEP 15: TH sends Resume command to the DUT + self.step(15) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C03.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Resume(), + expected_response=cluster.Enums.ErrorStateEnum.kCommandInvalidInState) + + # STEP 16: Manually put the device in the Error(0x03) operational state + self.step(16) + if self.pics_guard(self.check_pics((f"{self.test_info.pics_code}.S.M.ST_ERROR"))): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kUnableToStartOrResume) + + # STEP 17: TH sends Pause command to the DUT + self.step(17) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C00.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Pause(), + expected_response=cluster.Enums.ErrorStateEnum.kCommandInvalidInState) + + # STEP 18: TH sends Resume command to the DUT + self.step(18) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C03.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Resume(), + expected_response=cluster.Enums.ErrorStateEnum.kCommandInvalidInState) + + ############################ + # TEST CASE 2.4 + ############################ + def STEPS_TC_OPSTATE_BASE_2_4(self) -> list[TestStep]: + steps = [TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Set up a subscription to the OperationalError event"), + TestStep(3, "At the DUT take the vendor defined action to generate an OperationalError event"), + TestStep(4, "TH reads from the DUT the OperationalState attribute") + ] + return steps + + async def TEST_TC_OPSTATE_BASE_2_4(self, endpoint=1): + cluster = self.test_info.cluster + attributes = cluster.Attributes + events = cluster.Events + + self.init_test() + + pixit_var_name = f'PIXIT.{self.test_info.pics_code}.ErrorEventGen' + print(pixit_var_name in self.matter_test_config.global_test_params) + asserts.assert_true(pixit_var_name in self.matter_test_config.global_test_params, + f"{pixit_var_name} must be included on the command line in the --int-arg flag as {pixit_var_name}:<0 or 1>") + + error_event_gen = self.matter_test_config.global_test_params[pixit_var_name] + + # STEP 1: Commission DUT to TH (can be skipped if done in a preceding test) + self.step(1) + + if self.pics_guard(error_event_gen): + # STEP 2: Set up a subscription to the OperationalError event + self.step(2) + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(cluster) + await events_callback.start(self.default_controller, + self.dut_node_id, + endpoint) + + # STEP 3: At the DUT take the vendor defined action to generate an OperationalError event + self.step(3) + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kUnableToStartOrResume) + event_data = events_callback.wait_for_event_report(events.OperationalError).errorState + + # Defined Errors + defined_errors = [error.value for error in cluster.Enums.ErrorStateEnum + if (error != cluster.Enums.ErrorStateEnum.kUnknownEnumValue or + error != cluster.Enums.ErrorStateEnum.kNoError)] + + in_range = (0x80 <= event_data.errorStateID <= 0xBF) + asserts.assert_true(event_data.errorStateID in defined_errors + or in_range, "Event has an invalid ID value!") + if in_range: + asserts.assert_true(event_data.errorStateLabel is not None, "ErrorStateLabel should be populated") + + # STEP 4: TH reads from the DUT the OperationalState attribute + self.step(4) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kError) + else: + self.skip_step(2) + self.skip_step(3) + self.skip_step(4) + + ############################ + # TEST CASE 2.5 + ############################ + def STEPS_TC_OPSTATE_BASE_2_5(self) -> list[TestStep]: + steps = [TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Set up a subscription to the OperationCompletion event"), + TestStep(3, "Manually put the DUT into a state wherein it can receive a Start Command"), + TestStep(4, "TH sends Start command to the DUT"), + TestStep(5, "TH reads from the DUT the CountdownTime attribute"), + TestStep(6, "TH reads from the DUT the OperationalState attribute"), + TestStep(7, "TH waits for initial-countdown-time"), + TestStep(8, "TH sends Stop command to the DUT"), + TestStep(9, "TH waits for OperationCompletion event"), + TestStep(10, "TH reads from the DUT the OperationalState attribute"), + TestStep(11, "Restart DUT"), + TestStep(12, "TH waits for {PIXIT.WAITTIME.REBOOT}"), + TestStep(13, "TH sends Start command to the DUT"), + TestStep(14, "TH reads from the DUT the OperationalState attribute"), + TestStep(15, "TH sends Pause command to the DUT"), + TestStep(16, "TH reads from the DUT the OperationalState attribute"), + TestStep(17, "TH waits for half of initial-countdown-time"), + TestStep(18, "TH sends Resume command to the DUT"), + TestStep(19, "TH reads from the DUT the OperationalState attribute"), + TestStep(20, "TH waits for initial-countdown-time"), + TestStep(21, "TH sends Stop command to the DUT"), + TestStep(22, "TH waits for OperationCompletion event") + ] + return steps + + async def TEST_TC_OPSTATE_BASE_2_5(self, endpoint=1): + cluster = self.test_info.cluster + attributes = cluster.Attributes + commands = cluster.Commands + events = cluster.Events + + self.init_test() + + asserts.assert_true('PIXIT.WAITTIME.REBOOT' in self.matter_test_config.global_test_params, + "PIXIT.WAITTIME.REBOOT must be included on the command line in " + "the --int-arg flag as PIXIT.WAITTIME.REBOOT:") + + wait_time_reboot = self.matter_test_config.global_test_params['PIXIT.WAITTIME.REBOOT'] + + if wait_time_reboot == 0: + asserts.fail("PIXIT.WAITTIME.REBOOT shall be higher than 0.") + + # STEP 1: Commission DUT to TH (can be skipped if done in a preceding test) + self.step(1) + + # STEP 2: Set up a subscription to the OperationCompletion event + self.step(2) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.E01")): + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventSpecificChangeCallback(events.OperationCompletion) + await events_callback.start(self.default_controller, + self.dut_node_id, + endpoint) + + # STEP 3: Manually put the DUT into a state wherein it can receive a Start Command + self.step(3) + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="OnFault", + param=cluster.Enums.ErrorStateEnum.kNoError) + + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Stop") + + # STEP 4: TH sends Start command to the DUT + self.step(4) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C02.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Start(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 5: TH reads from the DUT the CountdownTime attribute + self.step(5) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0002")): + initial_countdown_time = await self.read_expect_success(endpoint=endpoint, + attribute=attributes.CountdownTime) + + if initial_countdown_time is not NullValue: + # STEP 6: TH reads from the DUT the OperationalState attribute + self.step(6) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + + # STEP 7: TH waits for initial-countdown-time + self.step(7) + time.sleep(initial_countdown_time) + + # STEP 8: TH sends Stop command to the DUT + self.step(8) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C01.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Stop(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 9: TH waits for OperationCompletion event + self.step(9) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.E01")): + event_data = events_callback.wait_for_event_report() + + asserts.assert_equal(event_data.completionErrorCode, cluster.Enums.ErrorStateEnum.kNoError, + f"Completion event error code mismatched from expectation on endpoint {endpoint}.") + + if event_data.totalOperationalTime is not NullValue: + asserts.assert_less_equal(initial_countdown_time, event_data.totalOperationalTime, + f"The total operation time shall be at least {initial_countdown_time:.1f}") + + asserts.assert_equal(0, event_data.pausedTime, + f"Paused time ({event_data.pausedTime}) shall be zero") + + # STEP 10: TH reads from the DUT the OperationalState attribute + self.step(10) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kStopped) + + # STEP 11: Restart DUT + self.step(11) + # In CI environment, the STOP coommand (step 8) already resets the variables. Only ask for + # reboot outside CI environment. + if not self.is_ci: + input("Press Enter when done.\n") + + # STEP 12: TH waits for {PIXIT.WAITTIME.REBOOT} + self.step(12) + time.sleep(wait_time_reboot) + + # STEP 13: TH sends Start command to the DUT + self.step(13) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C02.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Start(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 14: TH reads from the DUT the OperationalState attribute + self.step(14) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + + # STEP 15: TH sends Pause command to the DUT + self.step(15) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C00.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Pause(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 16: TH reads from the DUT the OperationalState attribute + self.step(16) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kPaused) + + # STEP 17: TH waits for half of initial-countdown-time + self.step(17) + time.sleep((initial_countdown_time / 2)) + + # STEP 18: TH sends Resume command to the DUT + self.step(18) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C03.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Resume(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 19: TH reads from the DUT the OperationalState attribute + self.step(19) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.A0004")): + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + + # STEP 20: TH waits for initial-countdown-time + self.step(20) + time.sleep(initial_countdown_time) + + # STEP 21: TH sends Stop command to the DUT + self.step(21) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.C01.Rsp") and + self.check_pics(f"{self.test_info.pics_code}.S.C04.Tx")): + await self.send_cmd_expect_response(endpoint=endpoint, + cmd=commands.Stop(), + expected_response=cluster.Enums.ErrorStateEnum.kNoError) + + # STEP 22: TH waits for OperationCompletion event + self.step(22) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.E01")): + event_data = events_callback.wait_for_event_report() + + asserts.assert_equal(event_data.completionErrorCode, cluster.Enums.ErrorStateEnum.kNoError, + f"Completion event error code mismatched from expectation on endpoint {endpoint}.") + + if event_data.totalOperationalTime is not NullValue: + expected_value = (1.5 * initial_countdown_time) + + asserts.assert_less_equal(expected_value, event_data.totalOperationalTime, + f"The total operation time shall be at least {expected_value:.1f}") + + expected_value = (0.5 * initial_countdown_time) + asserts.assert_less_equal(expected_value, event_data.pausedTime, + f"Paused time ({event_data.pausedTime}) shall be at least {expected_value:.1f}") + else: + self.skip_step(6) + self.skip_step(7) + self.skip_step(8) + self.skip_step(9) + self.skip_step(10) + self.skip_step(11) + self.skip_step(12) + self.skip_step(13) + self.skip_step(14) + self.skip_step(15) + self.skip_step(16) + self.skip_step(17) + self.skip_step(18) + self.skip_step(19) + self.skip_step(20) + self.skip_step(21) + self.skip_step(22) From 113ea32981cb746ef55c7d6141b35821aef8bdfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Josefsen?= <69624991+ReneJosefsen@users.noreply.github.com> Date: Wed, 14 Feb 2024 21:26:10 +0100 Subject: [PATCH 04/12] Update boolcfg-3-1 to match latest test plan (#32075) --- src/python_testing/TC_BOOLCFG_3_1.py | 57 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/src/python_testing/TC_BOOLCFG_3_1.py b/src/python_testing/TC_BOOLCFG_3_1.py index ceeeba33c6ee2d..fb45e60ab38f8d 100644 --- a/src/python_testing/TC_BOOLCFG_3_1.py +++ b/src/python_testing/TC_BOOLCFG_3_1.py @@ -36,7 +36,8 @@ def steps_TC_BOOLCFG_3_1(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), TestStep("2a", "Read FeatureMap attribute"), - TestStep("2b", "Read AttributeList attribute"), + TestStep("2b", "Verify SENS feature is supported"), + TestStep("2c", "Read AttributeList attribute"), TestStep(3, "Read SupportedSensitivityLevels attribute"), TestStep(4, "Read DefaultSensitivityLevel attribute, if supported"), TestStep(5, "Read CurrentSensitivityLevel attribute"), @@ -65,19 +66,26 @@ async def test_TC_BOOLCFG_3_1(self): self.step("2a") feature_map = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.FeatureMap) + is_sens_level_feature_supported = feature_map & Clusters.BooleanStateConfiguration.Bitmaps.Feature.kSensitivityLevel self.step("2b") - attribute_list = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList) + if not is_sens_level_feature_supported: + logging.info("SENS feature not supported, skipping test case") - is_sens_level_feature_supported = feature_map & Clusters.BooleanStateConfiguration.Bitmaps.Feature.kSensitivityLevel + # Skipping all remainig steps + for step in self.get_test_steps(self.current_test_info.name)[self.current_step_index:]: + self.step(step.test_plan_number) + logging.info("Test step skipped") - self.step(3) - if is_sens_level_feature_supported: - numberOfSupportedLevels = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.SupportedSensitivityLevels) + return else: logging.info("Test step skipped") - default_level = 0 + self.step("2c") + attribute_list = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList) + + self.step(3) + numberOfSupportedLevels = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.SupportedSensitivityLevels) self.step(4) if attributes.DefaultSensitivityLevel.attribute_id in attribute_list: @@ -85,20 +93,14 @@ async def test_TC_BOOLCFG_3_1(self): else: logging.info("Test step skipped") - current_level = 0 - self.step(5) - if is_sens_level_feature_supported: - current_level = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentSensitivityLevel) - else: - logging.info("Test step skipped") + current_level = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentSensitivityLevel) self.step(6) - if is_sens_level_feature_supported: - for sens_level in range(numberOfSupportedLevels): - logging.info(f"Write sensitivity level ({sens_level}) to CurrentSensitivityLevel)") - result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.CurrentSensitivityLevel(sens_level))]) - asserts.assert_equal(result[0].Status, Status.Success, "CurrentSensitivityLevel write failed") + for sens_level in range(numberOfSupportedLevels): + logging.info(f"Write sensitivity level ({sens_level}) to CurrentSensitivityLevel)") + result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.CurrentSensitivityLevel(sens_level))]) + asserts.assert_equal(result[0].Status, Status.Success, "CurrentSensitivityLevel write failed") self.step(7) if attributes.DefaultSensitivityLevel.attribute_id in attribute_list: @@ -114,21 +116,18 @@ async def test_TC_BOOLCFG_3_1(self): asserts.assert_equal(result[0].Status, Status.Success, "CurrentSensitivityLevel write failed") self.step(9) - if is_sens_level_feature_supported: - result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.CurrentSensitivityLevel(numberOfSupportedLevels))]) - asserts.assert_equal(result[0].Status, Status.ConstraintError, - "CurrentSensitivityLevel did not return CONSTRAINT_ERROR") + result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.CurrentSensitivityLevel(numberOfSupportedLevels))]) + asserts.assert_equal(result[0].Status, Status.ConstraintError, + "CurrentSensitivityLevel did not return CONSTRAINT_ERROR") self.step(10) - if is_sens_level_feature_supported: - result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.CurrentSensitivityLevel(255))]) - asserts.assert_equal(result[0].Status, Status.ConstraintError, - "CurrentSensitivityLevel did not return CONSTRAINT_ERROR") + result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.CurrentSensitivityLevel(255))]) + asserts.assert_equal(result[0].Status, Status.ConstraintError, + "CurrentSensitivityLevel did not return CONSTRAINT_ERROR") self.step(11) - if is_sens_level_feature_supported: - result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.CurrentSensitivityLevel(current_level))]) - asserts.assert_equal(result[0].Status, Status.Success, "CurrentSensitivityLevel write failed") + result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.CurrentSensitivityLevel(current_level))]) + asserts.assert_equal(result[0].Status, Status.Success, "CurrentSensitivityLevel write failed") if __name__ == "__main__": From 857249d47bcedc3143ac2e53c9f875230c9df85e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Josefsen?= <69624991+ReneJosefsen@users.noreply.github.com> Date: Wed, 14 Feb 2024 21:26:21 +0100 Subject: [PATCH 05/12] [VALCC] Update test scripts to match latest test plan (#32074) * Update test scripts to match latest test plan * Update src/python_testing/TC_VALCC_4_5.py Co-authored-by: C Freeman * Added missing skipped logging * Updated copyright year --------- Co-authored-by: C Freeman --- src/python_testing/TC_VALCC_4_3.py | 97 +++++------------ src/python_testing/TC_VALCC_4_4.py | 164 +++++++++++++++++++++-------- src/python_testing/TC_VALCC_4_5.py | 113 ++++++++++++++++++++ 3 files changed, 257 insertions(+), 117 deletions(-) create mode 100644 src/python_testing/TC_VALCC_4_5.py diff --git a/src/python_testing/TC_VALCC_4_3.py b/src/python_testing/TC_VALCC_4_3.py index 5869328958f64a..d696464827c20f 100644 --- a/src/python_testing/TC_VALCC_4_3.py +++ b/src/python_testing/TC_VALCC_4_3.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023 Project CHIP Authors +# Copyright (c) 2024 Project CHIP Authors # All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,25 +30,19 @@ async def read_valcc_attribute_expect_success(self, endpoint, attribute): return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) def desc_TC_VALCC_4_3(self) -> str: - return "[TC-VALCC-4.3] AutoCloseTime functionality with DUT as Server" + return "[TC-VALCC-4.3] AutoCloseTime functionality with (no synchronized time) DUT as Server" def steps_TC_VALCC_4_3(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), - TestStep(2, "Read FeatureMap attribute"), - TestStep(3, "Verify TimeSync feature is supported"), - TestStep(4, "Send Open command with duration set to 60"), - TestStep(5, "Read UTCTime attribute from TimeSync cluster"), - TestStep(6, "Read AutoCloseTime attribute"), - TestStep(7, "Send Close command"), - TestStep(8, "Read AutoCloseTime attribute"), - TestStep("9a", "Read DefaultOpenDuration attribute"), - TestStep("9b", "Write DefaultOpenDuration attribute"), - TestStep(10, "Send Open command"), - TestStep(11, "Read UTCTime attribute from TimeSync cluster"), - TestStep(12, "Read AutoCloseTime attribute"), - TestStep(13, "Send Close command"), - TestStep(14, "Read AutoCloseTime attribute"), + TestStep("2a", "Read FeatureMap attribute"), + TestStep("2b", "Verify TimeSync feature is supported"), + TestStep("3a", "Read UTCTime attribute from Time Synchronization cluster"), + TestStep("3b", "Verify UTCTime is null"), + TestStep(4, "Send Open command"), + TestStep(5, "Read AutoCloseTime attribute"), + TestStep(6, "Send Close command"), + TestStep(7, "Read AutoCloseTime attribute"), ] return steps @@ -66,12 +60,12 @@ async def test_TC_VALCC_4_3(self): self.step(1) attributes = Clusters.ValveConfigurationAndControl.Attributes - self.step(2) + self.step("2a") feature_map = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.FeatureMap) is_ts_feature_supported = feature_map & Clusters.ValveConfigurationAndControl.Bitmaps.Feature.kTimeSync - self.step(3) + self.step("2b") if not is_ts_feature_supported: logging.info("TimeSync feature not supported skipping test case") @@ -85,82 +79,43 @@ async def test_TC_VALCC_4_3(self): else: logging.info("Test step skipped") - self.step(4) - try: - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(openDuration=60), endpoint=endpoint) - except InteractionModelError as e: - asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") - pass - - self.step(5) + self.step("3a") utcTime = await self.read_single_attribute_check_success(endpoint=0, cluster=Clusters.Objects.TimeSynchronization, attribute=Clusters.TimeSynchronization.Attributes.UTCTime) - asserts.assert_true(utcTime is not NullValue, "OpenDuration is null") - - self.step(6) - auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime) - - asserts.assert_true(auto_close_time_dut is not NullValue, "AutoCloseTime is null") - asserts.assert_greater_equal(auto_close_time_dut, (utcTime + 55000000), - "AutoCloseTime is not in the expected range") - asserts.assert_less_equal(auto_close_time_dut, (utcTime + 60000000), "AutoCloseTime is not in the expected range") - - self.step(7) - try: - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint) - except InteractionModelError as e: - asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") - pass - - self.step(8) - auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime) - - asserts.assert_true(auto_close_time_dut is NullValue, "AutoCloseTime is not null") - self.step("9a") - defaultOpenDuration = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration) + self.step("3b") + if utcTime is not NullValue: + logging.info("UTCTime is not null, skipping test case") - asserts.assert_true(auto_close_time_dut is NullValue, "AutoCloseTime is not null") + # Skipping all remainig steps + for step in self.get_test_steps(self.current_test_info.name)[self.current_step_index:]: + self.step(step.test_plan_number) + logging.info("Test step skipped") - self.step("9b") - if defaultOpenDuration is NullValue: - defaultOpenDuration = 60 + return - result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.DefaultOpenDuration(defaultOpenDuration))]) - asserts.assert_equal(result[0].Status, Status.Success, "DefaultOpenDuration write failed") else: logging.info("Test step skipped") - self.step(10) + self.step(4) try: await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint) except InteractionModelError as e: asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") pass - self.step(11) - utcTime = await self.read_single_attribute_check_success(endpoint=0, cluster=Clusters.Objects.TimeSynchronization, attribute=Clusters.TimeSynchronization.Attributes.UTCTime) - - asserts.assert_true(utcTime is not NullValue, "OpenDuration is null") - - self.step(12) + self.step(5) auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime) + asserts.assert_true(auto_close_time_dut is NullValue, "AutoCloseTime is not null") - asserts.assert_true(auto_close_time_dut is not NullValue, "AutoCloseTime is null") - asserts.assert_greater_equal(auto_close_time_dut, (utcTime + ((defaultOpenDuration - 5) * 1000000)), - "AutoCloseTime is not in the expected range") - asserts.assert_less_equal(auto_close_time_dut, (utcTime + (defaultOpenDuration * 1000000)), - "AutoCloseTime is not in the expected range") - - self.step(13) + self.step(6) try: await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint) except InteractionModelError as e: asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") pass - self.step(14) + self.step(7) auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime) - asserts.assert_true(auto_close_time_dut is NullValue, "AutoCloseTime is not null") diff --git a/src/python_testing/TC_VALCC_4_4.py b/src/python_testing/TC_VALCC_4_4.py index 0d7d1184dbcda3..95aa1743187ee7 100644 --- a/src/python_testing/TC_VALCC_4_4.py +++ b/src/python_testing/TC_VALCC_4_4.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2023 Project CHIP Authors +# Copyright (c) 2024 Project CHIP Authors # All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,12 +15,12 @@ # limitations under the License. # -import time +import logging import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status -from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, utc_time_in_matter_epoch from mobly import asserts @@ -30,19 +30,27 @@ async def read_valcc_attribute_expect_success(self, endpoint, attribute): return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) def desc_TC_VALCC_4_4(self) -> str: - return "[TC-VALCC-4.4] Auto close functionality with DUT as Server" + return "[TC-VALCC-4.4] AutoCloseTime functionality with (synchronized time) DUT as Server" def steps_TC_VALCC_4_4(self) -> list[TestStep]: steps = [ TestStep(1, "Commissioning, already done", is_commissioning=True), - TestStep(2, "Send Open command with duration set to 5"), - TestStep(3, "Read OpenDuration attribute"), - TestStep(4, "Read RemainingDuration attribute"), - TestStep(5, "Read CurrentState attribute"), - TestStep(6, "Wait 6 seconds"), - TestStep(7, "Read OpenDuration attribute"), - TestStep(8, "Read RemainingDuration attribute"), - TestStep(9, "Read CurrentState attribute"), + TestStep("2a", "Read FeatureMap attribute"), + TestStep("2b", "Verify TimeSync feature is supported"), + TestStep("3a", "Read UTCTime attribute from Time Synchronization cluster"), + TestStep("3b", "Set UTCTime, if null"), + TestStep(4, "Send Open command with duration set to 60"), + TestStep(5, "Read UTCTime attribute from TimeSync cluster"), + TestStep(6, "Read AutoCloseTime attribute"), + TestStep(7, "Send Close command"), + TestStep(8, "Read AutoCloseTime attribute"), + TestStep("9a", "Read DefaultOpenDuration attribute"), + TestStep("9b", "Write DefaultOpenDuration attribute"), + TestStep(10, "Send Open command"), + TestStep(11, "Read UTCTime attribute from TimeSync cluster"), + TestStep(12, "Read AutoCloseTime attribute"), + TestStep(13, "Send Close command"), + TestStep(14, "Read AutoCloseTime attribute"), ] return steps @@ -60,53 +68,117 @@ async def test_TC_VALCC_4_4(self): self.step(1) attributes = Clusters.ValveConfigurationAndControl.Attributes - self.step(2) + self.step("2a") + feature_map = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.FeatureMap) + + is_ts_feature_supported = feature_map & Clusters.ValveConfigurationAndControl.Bitmaps.Feature.kTimeSync + + self.step("2b") + if not is_ts_feature_supported: + logging.info("TimeSync feature not supported skipping test case") + + # Skipping all remainig steps + for step in self.get_test_steps(self.current_test_info.name)[self.current_step_index:]: + self.step(step.test_plan_number) + logging.info("Test step skipped") + + return + + else: + logging.info("Test step skipped") + + self.step("3a") + utcTime = await self.read_single_attribute_check_success(endpoint=0, cluster=Clusters.Objects.TimeSynchronization, attribute=Clusters.TimeSynchronization.Attributes.UTCTime) + + self.step("3b") + if utcTime is NullValue: + th_utc = utc_time_in_matter_epoch() + + try: + await self.send_single_cmd(cmd=Clusters.Objects.TimeSynchronization.Commands.SetUTCTime(UTCTime=th_utc, granularity=Clusters.Objects.TimeSynchronization.Enums.GranularityEnum.kMillisecondsGranularity), endpoint=0) + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") + pass + + else: + logging.info("Test step skipped") + + self.step(4) try: - await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(openDuration=5), endpoint=endpoint) + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(openDuration=60), endpoint=endpoint) except InteractionModelError as e: asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") pass - self.step(3) - open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration) - asserts.assert_true(open_duration_dut is not NullValue, "OpenDuration is null") - asserts.assert_equal(open_duration_dut, 5, "OpenDuration is not the expected value") + self.step(5) + utcTime = await self.read_single_attribute_check_success(endpoint=0, cluster=Clusters.Objects.TimeSynchronization, attribute=Clusters.TimeSynchronization.Attributes.UTCTime) - self.step(4) - remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration) - asserts.assert_true(remaining_duration_dut is not NullValue, "RemainingDuration is null") - asserts.assert_greater_equal(remaining_duration_dut, 1, "RemainingDuration is not in the expected range") - asserts.assert_less_equal(remaining_duration_dut, 5, "RemainingDuration is not in the expected range") + self.step(6) + auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime) - self.step(5) - current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) - asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") + asserts.assert_true(auto_close_time_dut is not NullValue, "AutoCloseTime is null") + asserts.assert_greater_equal(auto_close_time_dut, (utcTime + 55000000), + "AutoCloseTime is not in the expected range") + asserts.assert_less_equal(auto_close_time_dut, (utcTime + 60000000), "AutoCloseTime is not in the expected range") - while current_state_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning: - time.sleep(1) + self.step(7) + try: + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint) + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") + pass - current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) - asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") + self.step(8) + auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime) - asserts.assert_equal(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kOpen, - "CurrentState is not the expected value") + asserts.assert_true(auto_close_time_dut is NullValue, "AutoCloseTime is not null") - self.step(6) - time.sleep(6) + self.step("9a") + defaultOpenDuration = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration) - self.step(7) - open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration) - asserts.assert_true(open_duration_dut is NullValue, "OpenDuration is not null") + asserts.assert_true(auto_close_time_dut is NullValue, "AutoCloseTime is not null") - self.step(8) - remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration) - asserts.assert_true(remaining_duration_dut is NullValue, "RemainingDuration is not null") - - self.step(9) - current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) - asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") - asserts.assert_equal(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kClosed, - "CurrentState is not the expected value") + self.step("9b") + if defaultOpenDuration is NullValue: + defaultOpenDuration = 60 + + result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, attributes.DefaultOpenDuration(defaultOpenDuration))]) + asserts.assert_equal(result[0].Status, Status.Success, "DefaultOpenDuration write failed") + else: + logging.info("Test step skipped") + + self.step(10) + try: + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(), endpoint=endpoint) + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") + pass + + self.step(11) + utcTime = await self.read_single_attribute_check_success(endpoint=0, cluster=Clusters.Objects.TimeSynchronization, attribute=Clusters.TimeSynchronization.Attributes.UTCTime) + + asserts.assert_true(utcTime is not NullValue, "OpenDuration is null") + + self.step(12) + auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime) + + asserts.assert_true(auto_close_time_dut is not NullValue, "AutoCloseTime is null") + asserts.assert_greater_equal(auto_close_time_dut, (utcTime + ((defaultOpenDuration - 5) * 1000000)), + "AutoCloseTime is not in the expected range") + asserts.assert_less_equal(auto_close_time_dut, (utcTime + (defaultOpenDuration * 1000000)), + "AutoCloseTime is not in the expected range") + + self.step(13) + try: + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Close(), endpoint=endpoint) + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") + pass + + self.step(14) + auto_close_time_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.AutoCloseTime) + + asserts.assert_true(auto_close_time_dut is NullValue, "AutoCloseTime is not null") if __name__ == "__main__": diff --git a/src/python_testing/TC_VALCC_4_5.py b/src/python_testing/TC_VALCC_4_5.py new file mode 100644 index 00000000000000..7dd21b89eead6e --- /dev/null +++ b/src/python_testing/TC_VALCC_4_5.py @@ -0,0 +1,113 @@ +# +# 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. +# + +import time + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from chip.interaction_model import InteractionModelError, Status +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_VALCC_4_5(MatterBaseTest): + async def read_valcc_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ValveConfigurationAndControl + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + def desc_TC_VALCC_4_5(self) -> str: + return "[TC-VALCC-4.5] Auto close functionality with DUT as Server" + + def steps_TC_VALCC_4_5(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Send Open command with duration set to 5"), + TestStep(3, "Read OpenDuration attribute"), + TestStep(4, "Read RemainingDuration attribute"), + TestStep(5, "Read CurrentState attribute"), + TestStep(6, "Wait 6 seconds"), + TestStep(7, "Read OpenDuration attribute"), + TestStep(8, "Read RemainingDuration attribute"), + TestStep(9, "Read CurrentState attribute"), + ] + return steps + + def pics_TC_VALCC_4_5(self) -> list[str]: + pics = [ + "VALCC.S", + ] + return pics + + @async_test_body + async def test_TC_VALCC_4_5(self): + + endpoint = self.user_params.get("endpoint", 1) + + self.step(1) + attributes = Clusters.ValveConfigurationAndControl.Attributes + + self.step(2) + try: + await self.send_single_cmd(cmd=Clusters.Objects.ValveConfigurationAndControl.Commands.Open(openDuration=5), endpoint=endpoint) + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.Success, "Unexpected error returned") + pass + + self.step(3) + open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration) + asserts.assert_true(open_duration_dut is not NullValue, "OpenDuration is null") + asserts.assert_equal(open_duration_dut, 5, "OpenDuration is not the expected value") + + self.step(4) + remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration) + asserts.assert_true(remaining_duration_dut is not NullValue, "RemainingDuration is null") + asserts.assert_greater_equal(remaining_duration_dut, 1, "RemainingDuration is not in the expected range") + asserts.assert_less_equal(remaining_duration_dut, 5, "RemainingDuration is not in the expected range") + + self.step(5) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") + + while current_state_dut is Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kTransitioning: + time.sleep(1) + + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") + + asserts.assert_equal(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kOpen, + "CurrentState is not the expected value") + + self.step(6) + time.sleep(6) + + self.step(7) + open_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.OpenDuration) + asserts.assert_true(open_duration_dut is NullValue, "OpenDuration is not null") + + self.step(8) + remaining_duration_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.RemainingDuration) + asserts.assert_true(remaining_duration_dut is NullValue, "RemainingDuration is not null") + + self.step(9) + current_state_dut = await self.read_valcc_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentState) + asserts.assert_true(current_state_dut is not NullValue, "CurrentState is null") + asserts.assert_equal(current_state_dut, Clusters.Objects.ValveConfigurationAndControl.Enums.ValveStateEnum.kClosed, + "CurrentState is not the expected value") + + +if __name__ == "__main__": + default_matter_test_main() From d465691e54241111689ef4ee5831a283a1cdc448 Mon Sep 17 00:00:00 2001 From: abeck-whirlpool <129295708+abeck-whirlpool@users.noreply.github.com> Date: Wed, 14 Feb 2024 14:57:31 -0600 Subject: [PATCH 06/12] Removing file (#30933) Co-authored-by: abeck-riis <98488327+abeck-riis@users.noreply.github.com> --- data_model/clusters/Mode_Laundry.xml | 92 ---------------------------- 1 file changed, 92 deletions(-) delete mode 100644 data_model/clusters/Mode_Laundry.xml diff --git a/data_model/clusters/Mode_Laundry.xml b/data_model/clusters/Mode_Laundry.xml deleted file mode 100644 index 63108a01aa876b..00000000000000 --- a/data_model/clusters/Mode_Laundry.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 42a1c72727f1417029b6ad13c4edf00b564d779a Mon Sep 17 00:00:00 2001 From: Abdul Samad Date: Wed, 14 Feb 2024 15:08:58 -0600 Subject: [PATCH 07/12] Fix MRP SessionIdleInterval per spec to 500ms (#32124) * Fix MRP SessionIdleInterval per spec to 500ms Spec has the default SESSION_IDLE_INTERVAL defined as 500ms https://github.com/CHIP-Specifications/connectedhomeip-spec/blob/1.2/src/secure_channel/Message_Reliability_MRP.adoc#8-parameters-and-constants Originally defined as 300ms, this change was introduced as part of spec PR https://github.com/CHIP-Specifications/connectedhomeip-spec/pull/7186 * Update Sleepy -> Session in context of active/idle intervals Reflecting the spec update https://github.com/CHIP-Specifications/connectedhomeip-spec/pull/7186 --- src/app/tests/suites/TestDiscovery.yaml | 4 ++-- src/app/tests/suites/certification/Test_TC_SC_3_3.yaml | 4 ++-- src/app/tests/suites/certification/Test_TC_SC_4_10.yaml | 2 +- src/lib/dnssd/Types.h | 2 +- src/lib/dnssd/tests/TestIncrementalResolve.cpp | 6 +++--- src/messaging/ReliableMessageProtocolConfig.cpp | 4 ++-- src/messaging/ReliableMessageProtocolConfig.h | 4 ++-- src/messaging/tests/MessagingContext.h | 2 +- src/protocols/secure_channel/RendezvousParameters.h | 4 ++-- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/app/tests/suites/TestDiscovery.yaml b/src/app/tests/suites/TestDiscovery.yaml index c4f1afc08be9f8..77c0615a27bc8d 100644 --- a/src/app/tests/suites/TestDiscovery.yaml +++ b/src/app/tests/suites/TestDiscovery.yaml @@ -203,7 +203,7 @@ tests: - name: "productId" value: productId - - label: "Optional TXT key for MRP Sleepy Idle Interval (SII)" + - label: "Optional TXT key for MRP Session Idle Interval (SII)" PICS: MCORE.SC.SII_COMM_DISCOVERY_KEY cluster: "DiscoveryCommands" command: "FindCommissionable" @@ -214,7 +214,7 @@ tests: minValue: 0 maxValue: 3600000 - - label: "Optional TXT key for MRP Sleepy Active Interval (SAI)" + - label: "Optional TXT key for MRP Session Active Interval (SAI)" PICS: MCORE.SC.SAI_COMM_DISCOVERY_KEY cluster: "DiscoveryCommands" command: "FindCommissionable" diff --git a/src/app/tests/suites/certification/Test_TC_SC_3_3.yaml b/src/app/tests/suites/certification/Test_TC_SC_3_3.yaml index f6b17380499be0..048b5241da7a20 100644 --- a/src/app/tests/suites/certification/Test_TC_SC_3_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_SC_3_3.yaml @@ -99,8 +99,8 @@ tests: responderSessionID is of uint16 sigma2ResumeMIC is of Octet String maximum of length 16 bytes responderSEDParams is from any one of the following: - SLEEPY_IDLE_INTERVAL - Verify that it is of uint32 - SLEEPY_ACTIVE_INTERVAL - Verify that it is of uint32 + SESSION_IDLE_INTERVAL - Verify that it is of uint32 + SESSION_ACTIVE_INTERVAL - Verify that it is of uint32 [1683973658.044236][21637:21637] CHIP:EM: Rxd Ack; Removing MessageCounter:113416101 from Retrans Table on exchange 32995r diff --git a/src/app/tests/suites/certification/Test_TC_SC_4_10.yaml b/src/app/tests/suites/certification/Test_TC_SC_4_10.yaml index 298b831b262f41..987bc6279093a8 100644 --- a/src/app/tests/suites/certification/Test_TC_SC_4_10.yaml +++ b/src/app/tests/suites/certification/Test_TC_SC_4_10.yaml @@ -42,7 +42,7 @@ tests: verification: | avahi-browse -rt _matter._tcp On the TH(Chip-tool) Log: Verify the DUT is advertising for: - -SII key is higher than the SLEEPY_IDLE_INTERVAL default value (> 300 milliseconds) + - SII key is higher than the SESSION_IDLE_INTERVAL default value (> 500 milliseconds) - SII key and SAI key is less than 3600000 (1hour in milliseconds) + eth0 IPv6 3A235FF3FA2DAC10-0000000000000055 _matter._tcp local diff --git a/src/lib/dnssd/Types.h b/src/lib/dnssd/Types.h index 06a7352d60d919..a835ebf5647a97 100644 --- a/src/lib/dnssd/Types.h +++ b/src/lib/dnssd/Types.h @@ -112,7 +112,7 @@ struct CommonResolutionData bool IsDeviceTreatedAsSleepy(const ReliableMessageProtocolConfig * defaultMRPConfig) const { - // If either sleepy interval (Idle - SII, Active - SAI) has a value and that value is greater + // If either session interval (Idle - SII, Active - SAI) has a value and that value is greater // than the value passed to this function, then the peer device will be treated as if it is // a Sleepy End Device (SED) return (mrpRetryIntervalIdle.HasValue() && (mrpRetryIntervalIdle.Value() > defaultMRPConfig->mIdleRetransTimeout)) || diff --git a/src/lib/dnssd/tests/TestIncrementalResolve.cpp b/src/lib/dnssd/tests/TestIncrementalResolve.cpp index 2791631a32e8a0..1cc3b714d28ae3 100644 --- a/src/lib/dnssd/tests/TestIncrementalResolve.cpp +++ b/src/lib/dnssd/tests/TestIncrementalResolve.cpp @@ -294,7 +294,7 @@ void TestParseOperational(nlTestSuite * inSuite, void * inContext) { const char * entries[] = { "foo=bar", // unused data - "SII=23" // sleepy idle interval + "SII=23" // session idle interval }; CallOnRecord(inSuite, resolver, TxtResourceRecord(kTestOperationalName.Full(), entries)); @@ -369,7 +369,7 @@ void TestParseCommissionable(nlTestSuite * inSuite, void * inContext) { const char * entries[] = { "some", "foo=bar", "x=y=z", "a=", // unused data - "SII=123" // Sleepy idle interval + "SII=123" // session idle interval }; CallOnRecord(inSuite, resolver, TxtResourceRecord(kTestHostName.Full(), entries)); @@ -381,7 +381,7 @@ void TestParseCommissionable(nlTestSuite * inSuite, void * inContext) { const char * entries[] = { "foo=bar", // unused data - "SAI=321", // sleepy active interval + "SAI=321", // session active interval "D=22345", // Long discriminator "VP=321+654", // VendorProduct "DN=mytest" // Device name diff --git a/src/messaging/ReliableMessageProtocolConfig.cpp b/src/messaging/ReliableMessageProtocolConfig.cpp index 86c95b1ff07346..d1a4deece9c0f8 100644 --- a/src/messaging/ReliableMessageProtocolConfig.cpp +++ b/src/messaging/ReliableMessageProtocolConfig.cpp @@ -60,8 +60,8 @@ void ClearLocalMRPConfigOverride() ReliableMessageProtocolConfig GetDefaultMRPConfig() { - // Default MRP intervals are defined in spec <2.11.3. Parameters and Constants> - static constexpr const System::Clock::Milliseconds32 idleRetransTimeout = 300_ms32; + // Default MRP intervals are defined in spec <4.12.8. Parameters and Constants> + static constexpr const System::Clock::Milliseconds32 idleRetransTimeout = 500_ms32; static constexpr const System::Clock::Milliseconds32 activeRetransTimeout = 300_ms32; static constexpr const System::Clock::Milliseconds16 activeThresholdTime = 4000_ms16; return ReliableMessageProtocolConfig(idleRetransTimeout, activeRetransTimeout, activeThresholdTime); diff --git a/src/messaging/ReliableMessageProtocolConfig.h b/src/messaging/ReliableMessageProtocolConfig.h index a49740ad4d5227..87864d1a67e922 100644 --- a/src/messaging/ReliableMessageProtocolConfig.h +++ b/src/messaging/ReliableMessageProtocolConfig.h @@ -45,7 +45,7 @@ namespace chip { * timeout when it sends a message to the present node and the present node is * perceived by the peer as active. * - * This value is announced to the peer using SAI (Sleepy Active Interval) key + * This value is announced to the peer using SAI (Session Active Interval) key * in the advertised DNS Service Discovery TXT records. Additionally, it is * exchanged in the initial phase of the PASE/CASE session establishment. * @@ -84,7 +84,7 @@ namespace chip { #if CHIP_ENABLE_OPENTHREAD && !CHIP_DEVICE_LAYER_TARGET_LINUX #define CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL (800_ms32) #else -#define CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL (300_ms32) +#define CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL (500_ms32) #endif #endif // CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL && !CHIP_DEVICE_LAYER_TARGET_LINUX diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index a6a6d34fa1c36c..31143a727326be 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -78,7 +78,7 @@ class MessagingContext : public PlatformMemoryUser enum MRPMode { kDefault = 1, // This adopts the default MRP values for idle/active as per the spec. - // i.e IDLE = 4s, ACTIVE = 300ms + // i.e IDLE = 500ms, ACTIVE = 300ms kResponsive = 2, // This adopts values that are better suited for loopback tests that // don't actually go over a network interface, and are tuned much lower diff --git a/src/protocols/secure_channel/RendezvousParameters.h b/src/protocols/secure_channel/RendezvousParameters.h index a82628a483b2e9..e5e366d3b3b704 100644 --- a/src/protocols/secure_channel/RendezvousParameters.h +++ b/src/protocols/secure_channel/RendezvousParameters.h @@ -32,8 +32,8 @@ namespace chip { // The largest supported value for Rendezvous discriminators const uint16_t kMaxRendezvousDiscriminatorValue = 0xFFF; -// The largest supported value for sleepy idle interval and sleepy active interval -inline constexpr uint32_t kMaxSleepyInterval = 3600000; +// The largest supported value for session idle interval and session active interval +inline constexpr uint32_t kMaxSessionIdleInterval = 3600000; class RendezvousParameters { From 14aac831d66e2f875502f3480c4cfac7f24d44c2 Mon Sep 17 00:00:00 2001 From: Kai Liao <140431279+kliao-csa@users.noreply.github.com> Date: Wed, 14 Feb 2024 13:39:54 -0800 Subject: [PATCH 08/12] Initial pass for Issue 30906 "[Feature] Integrate tv-app and tv-casting-app into our CI system" (#32012) * Create examples-tvapp.yaml * Delete .github/workflows/examples-tvapp.yaml * Create examples-tv-app.yaml Using nrfconnect as a template * Update examples-tv-app.yaml --- .github/workflows/examples-tv-app.yaml | 72 ++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 .github/workflows/examples-tv-app.yaml diff --git a/.github/workflows/examples-tv-app.yaml b/.github/workflows/examples-tv-app.yaml new file mode 100644 index 00000000000000..fff6cbb39d1acb --- /dev/null +++ b/.github/workflows/examples-tv-app.yaml @@ -0,0 +1,72 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Build example - TV App and TV Casting App + +on: + push: + pull_request: + merge_group: + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} + cancel-in-progress: true + +env: + CHIP_NO_LOG_TIMESTAMPS: true + +jobs: + tv-app: + name: TV App + + env: + BUILD_TYPE: tv_app + + runs-on: ubuntu-latest + if: github.actor != 'restyled-io[bot]' + + container: + image: ghcr.io/project-chip/chip-build-android:35 + volumes: + - "/tmp/bloat_reports:/tmp/bloat_reports" + + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Checkout submodules & Bootstrap + uses: ./.github/actions/checkout-submodules-and-bootstrap + with: + platform: android + - name: Set up environment for size reports + uses: ./.github/actions/setup-size-reports + if: ${{ !env.ACT }} + with: + gh-context: ${{ toJson(github) }} + - name: Build Android arm64-tv-casting-app + run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py --target android-arm64-tv-casting-app build" + - name: Clean out build output + run: rm -rf ./out examples/tv-casting-app/android/App/app/libs/jniLibs/* examples/tv-casting-app/android/App/app/libs/*.jar + - name: Build Android arm64-tv-server + run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py --target android-arm64-tv-server build" + - name: Clean out build output + run: rm -rf ./out examples/tv-app/android/App/app/libs/jniLibs/* examples/tv-app/android/App/app/libs/*.jar + - name: Uploading Size Reports + uses: ./.github/actions/upload-size-reports + if: ${{ !env.ACT }} + with: + platform-name: TVApp From 83cf341ed734bd5987910929289d28e7e8d7c16c Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:09:15 -0500 Subject: [PATCH 09/12] [Scenes] Yaml steps discrepancies (#32003) * Updated the steps to match the comments in the chip test plan * Updated label for LasConfiguredBy attribute test * Applied comments about verification steps in S_2_5 and S_2_6 --- .../suites/certification/Test_TC_S_1_1.yaml | 15 +- .../suites/certification/Test_TC_S_2_1.yaml | 2 - .../suites/certification/Test_TC_S_2_2.yaml | 5 +- .../suites/certification/Test_TC_S_2_3.yaml | 166 ++- .../suites/certification/Test_TC_S_2_4.yaml | 4 +- .../suites/certification/Test_TC_S_2_5.yaml | 774 +++++++------ .../suites/certification/Test_TC_S_2_6.yaml | 1018 +++++++++++++---- 7 files changed, 1291 insertions(+), 693 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_S_1_1.yaml b/src/app/tests/suites/certification/Test_TC_S_1_1.yaml index 36314424458714..c8a8c359e1cdc8 100644 --- a/src/app/tests/suites/certification/Test_TC_S_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_1_1.yaml @@ -62,7 +62,7 @@ tests: hasMasksSet: [0x1] - label: - "Step 4: TH reads AttributeList mandatory attributes(global attribute + "Step 4a: TH reads AttributeList mandatory attributes(global attribute 65531)" PICS: S.S command: "readAttribute" @@ -70,7 +70,18 @@ tests: response: constraints: type: list - contains: [0, 1, 2, 65528, 65529, 65531, 65532, 65533] + contains: [1, 2, 65528, 65529, 65531, 65532, 65533] + + - label: + "Step 4b: TH reads the LastConfiguredBy optional attribute from the + AttributeList (global attribute 65531)" + PICS: S.S.A0000 + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [0] - label: "Step 5: TH reads from the DUT the EventList attribute" PICS: PICS_EVENT_LIST_ENABLED diff --git a/src/app/tests/suites/certification/Test_TC_S_2_1.yaml b/src/app/tests/suites/certification/Test_TC_S_2_1.yaml index ed8e61f47f6d09..152539147ca37a 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_1.yaml @@ -17,8 +17,6 @@ name: 123.2.1. [TC-S-2.1] Attributes with DUT as Server PICS: - S.S - - S.S.AM - - S.S.AO config: nodeId: 0x12344321 diff --git a/src/app/tests/suites/certification/Test_TC_S_2_2.yaml b/src/app/tests/suites/certification/Test_TC_S_2_2.yaml index d569b12d512a8a..b27d4bfd333cee 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_2.yaml @@ -344,7 +344,6 @@ tests: type: int16u - label: "Step 3d: TH reads attribute FabricSceneInfo from DUT" - PICS: PICS_SDK_CI_ONLY command: "readAttribute" attribute: "FabricSceneInfo" response: @@ -753,7 +752,7 @@ tests: set to G1, the SceneID field set to 0x01, the TransitionTime field set to 70 000 000 (70 000s) and no extension field sets. This should fail and return a status of 0x85 (INVALID_COMMAND)." - PICS: S.S.C00.Rsp && PICS_SDK_CI_ONLY + PICS: S.S.C00.Rsp command: "AddScene" arguments: values: @@ -781,7 +780,7 @@ tests: set to G1, the SceneID field set to 0x01, the TransitionTime field set to 60 000 001 (60 000.001s) and no extension field sets. This should fail and return a status of 0x85 (INVALID_COMMAND)." - PICS: S.S.C00.Rsp && PICS_SDK_CI_ONLY + PICS: S.S.C00.Rsp command: "AddScene" arguments: values: diff --git a/src/app/tests/suites/certification/Test_TC_S_2_3.yaml b/src/app/tests/suites/certification/Test_TC_S_2_3.yaml index 21549a843b29ac..eeeabe22dc4f4c 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_3.yaml @@ -309,48 +309,19 @@ tests: to G1, the SceneID field set to 0x01, the TransitionTime field set to 1000 (1s) and a set of extension fields appropriate to AC1." verification: | - ./chip-tool scenes add-scene GroupID SceneID TransitionTime "SceneName" '[{"clusterId": value, "attributeValueList":[{"attributeId": value, "attributeValue": value}]}' nodeId endpointId + ./chip-tool scenesmanagement add-scene GroupID SceneID TransitionTime "SceneName" '[{"clusterId": value, "attributeValueList":[{"attributeId": value, "attributeValue": value}]}' nodeId endpointId Note: The number of ExtensionFieldSets, the value of clusterId of each ExtensionFieldSet, the number of attributes in attributeValueList and their values varies for each application Verify the "status is success" on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: - [1670970505.887060][5742:5744] CHIP:DMG: InvokeResponseMessage = - [1670970505.887118][5742:5744] CHIP:DMG: { - [1670970505.887172][5742:5744] CHIP:DMG: suppressResponse = false, - [1670970505.887231][5742:5744] CHIP:DMG: InvokeResponseIBs = - [1670970505.887307][5742:5744] CHIP:DMG: [ - [1670970505.887366][5742:5744] CHIP:DMG: InvokeResponseIB = - [1670970505.887444][5742:5744] CHIP:DMG: { - [1670970505.887507][5742:5744] CHIP:DMG: CommandDataIB = - [1670970505.887576][5742:5744] CHIP:DMG: { - [1670970505.887713][5742:5744] CHIP:DMG: CommandPathIB = - [1670970505.887804][5742:5744] CHIP:DMG: { - [1670970505.887940][5742:5744] CHIP:DMG: EndpointId = 0x1, - [1670970505.888093][5742:5744] CHIP:DMG: ClusterId = 0x5, - [1670970505.888242][5742:5744] CHIP:DMG: CommandId = 0x0, - [1670970505.888385][5742:5744] CHIP:DMG: }, - [1670970505.888692][5742:5744] CHIP:DMG: - [1670970505.888769][5742:5744] CHIP:DMG: CommandFields = - [1670970505.888852][5742:5744] CHIP:DMG: { - [1670970505.889030][5742:5744] CHIP:DMG: 0x0 = 0, - [1670970505.889183][5742:5744] CHIP:DMG: 0x1 = 1, - [1670970505.889406][5742:5744] CHIP:DMG: 0x2 = 1, - [1670970505.889515][5742:5744] CHIP:DMG: }, - [1670970505.889603][5742:5744] CHIP:DMG: }, - [1670970505.889684][5742:5744] CHIP:DMG: - [1670970505.889745][5742:5744] CHIP:DMG: }, - [1670970505.889821][5742:5744] CHIP:DMG: - [1670970505.889878][5742:5744] CHIP:DMG: ], - [1670970505.889953][5742:5744] CHIP:DMG: - [1670970505.890009][5742:5744] CHIP:DMG: InteractionModelRevision = 1 - [1670970505.890066][5742:5744] CHIP:DMG: }, - [1670970505.890212][5742:5744] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0005 Command=0x0000_0000 - [1670970505.890328][5742:5744] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - [1670970505.890458][5742:5744] CHIP:TOO: AddSceneResponse: { - [1670970505.890551][5742:5744] CHIP:TOO: status: 0 - [1670970505.890608][5742:5744] CHIP:TOO: groupId: 257 - [1670970505.890717][5742:5744] CHIP:TOO: sceneId: 1 - [1670970505.890774][5742:5744] CHIP:TOO: } + [1705680175.863785][5823:5825] CHIP:DMG: }, + [1705680175.863851][5823:5825] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1705680175.863880][5823:5825] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1705680175.863931][5823:5825] CHIP:TOO: AddSceneResponse: { + [1705680175.863956][5823:5825] CHIP:TOO: status: 0 + [1705680175.863967][5823:5825] CHIP:TOO: groupID: 257 + [1705680175.863977][5823:5825] CHIP:TOO: sceneID: 1 + [1705680175.863986][5823:5825] CHIP:TOO: } cluster: "LogCommands" command: "UserPrompt" PICS: S.S.C00.Rsp && PICS_SKIP_SAMPLE_APP @@ -405,15 +376,50 @@ tests: set to G1 and the SceneID field set to 0x01." PICS: S.S.C01.Rsp && PICS_SKIP_SAMPLE_APP verification: | - ./chip-tool scenes view-scene GroupId SceneId Node-Id EndpointId + ./chip-tool scenesmanagement view-scene GroupId SceneId Node-Id EndpointId Note: The number of ExtensionFieldSets, the value of clusterId of each ExtensionFieldSet, the number of attributes in attributeValueList and their values varies for each application - Verify that the extension fields in the log match the ones expected and that - Status = 0x00 - GroupID = G1 - SceneID = 0x01 - TransitionTime = 0x0001 + Verify that the extension fields in the log match the ones expected in the following log: + [1705680224.968551][5827:5829] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0001 + [1705680224.968559][5827:5829] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0001 + CHIP:TOO: ViewSceneResponse: { + CHIP:TOO: status: 0 + CHIP:TOO: groupID: 1 + CHIP:TOO: sceneID: 1 + CHIP:TOO: transitionTime: 1000 + CHIP:TOO: sceneName: + CHIP:TOO: extensionFieldSets: 3 entries + CHIP:TOO: [1]: { + CHIP:TOO: ClusterID: XX + CHIP:TOO: AttributeValueList: X entries + CHIP:TOO: [1]: { + CHIP:TOO: AttributeID: XX + CHIP:TOO: AttributeValue:XX + CHIP:TOO: } + CHIP:TOO: } + CHIP:TOO: [2]: { + CHIP:TOO: ClusterID: XX + CHIP:TOO: AttributeValueList: X entries + CHIP:TOO: [1]: { + CHIP:TOO: AttributeID: XX + CHIP:TOO: AttributeValue: XX + CHIP:TOO: } + CHIP:TOO: } + CHIP:TOO: [3]: { + CHIP:TOO: ClusterID: XX + CHIP:TOO: AttributeValueList: XX entries + CHIP:TOO: [X]: { + CHIP:TOO: AttributeID: XX + CHIP:TOO: AttributeValue: XX + CHIP:TOO: } + ... + CHIP:TOO: [X]: { + CHIP:TOO: AttributeID: XX + CHIP:TOO: AttributeValue: XX + CHIP:TOO: } + CHIP:TOO: } + CHIP:TOO: } cluster: "LogCommands" command: "UserPrompt" arguments: @@ -449,7 +455,7 @@ tests: - label: "Step 5a: TH configures AC2 on DUT for all implemented application - clusters supporting scenes." + clusters supporting scenesmanagement." cluster: "Level Control" PICS: PICS_SDK_CI_ONLY command: "MoveToLevelWithOnOff" @@ -466,7 +472,7 @@ tests: - label: "Step 5a: TH configures AC2 on DUT for all implemented application - clusters supporting scenes." + clusters supporting scenesmanagement." verification: | Is DUT configured with AC2? cluster: "LogCommands" @@ -563,41 +569,8 @@ tests: field set to G1, the SceneID field set to 0x03, the TransitionTime field set to G1 and a set of extension fields appropriate to AC1." verification: | - ./chip-tool scenes add-scene GroupID SceneID TransitionTime "SceneName" '[{"clusterId": value, "attributeValueList":[{"attributeId": value, "attributeValue": value}]}' groupID endpointId - - Note: The number of ExtensionFieldSets, the value of clusterId of each ExtensionFieldSet, the number of attributes in attributeValueList and their values varies for each application - - Verify the "status is success" on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: - [1670970505.887060][5742:5744] CHIP:DMG: InvokeResponseMessage = - [1670970505.887118][5742:5744] CHIP:DMG: { - [1670970505.887172][5742:5744] CHIP:DMG: suppressResponse = false, - [1670970505.887231][5742:5744] CHIP:DMG: InvokeResponseIBs = - [1670970505.887307][5742:5744] CHIP:DMG: [ - [1670970505.887366][5742:5744] CHIP:DMG: InvokeResponseIB = - [1670970505.887444][5742:5744] CHIP:DMG: { - [1670970505.887507][5742:5744] CHIP:DMG: CommandDataIB = - [1670970505.887576][5742:5744] CHIP:DMG: { - [1670970505.887713][5742:5744] CHIP:DMG: CommandPathIB = - [1670970505.887804][5742:5744] CHIP:DMG: { - [1670970505.887940][5742:5744] CHIP:DMG: EndpointId = 0x1, - [1670970505.888093][5742:5744] CHIP:DMG: ClusterId = 0x5, - [1670970505.888242][5742:5744] CHIP:DMG: CommandId = 0x0, - [1670970505.888385][5742:5744] CHIP:DMG: }, - [1670970505.888692][5742:5744] CHIP:DMG: - [1670970505.888769][5742:5744] CHIP:DMG: CommandFields = - [1670970505.888852][5742:5744] CHIP:DMG: { - [1670970505.889030][5742:5744] CHIP:DMG: 0x0 = 0, - [1670970505.889183][5742:5744] CHIP:DMG: 0x1 = 1, - [1670970505.889406][5742:5744] CHIP:DMG: 0x2 = 1, - [1670970505.889515][5742:5744] CHIP:DMG: }, - [1670970505.889603][5742:5744] CHIP:DMG: }, - [1670970505.889684][5742:5744] CHIP:DMG: - [1670970505.889745][5742:5744] CHIP:DMG: }, - [1670970505.889821][5742:5744] CHIP:DMG: - [1670970505.889878][5742:5744] CHIP:DMG: ], - [1670970505.889953][5742:5744] CHIP:DMG: - [1670970505.890009][5742:5744] CHIP:DMG: InteractionModelRevision = 1 - [1670970505.890066][5742:5744] CHIP:DMG: }, + ./chip-tool scenesmanagement add-scene 0x0101 0x03 1 "scene name" '[{"clusterID": "0x0300", "attributeValueList":[{"attributeID": "0x4002", "attributeValue": "0x01"}]}]' 0xffffffffffff0101 1 + Note: As this is a multicast command, no log is expected. cluster: "LogCommands" command: "UserPrompt" PICS: S.S.C00.Rsp && PICS_SKIP_SAMPLE_APP @@ -651,15 +624,30 @@ tests: set to G1 and the SceneID field set to 0x03." PICS: S.S.C01.Rsp && PICS_SKIP_SAMPLE_APP verification: | - ./chip-tool scenes view-scene GroupId SceneId Node-Id EndpointId + ./chip-tool scenesmanagement view-scene GroupId SceneId Node-Id EndpointId Note: The number of ExtensionFieldSets, the value of clusterId of each ExtensionFieldSet, the number of attributes in attributeValueList and their values varies for each application - Verify that the extension fields in the log match the ones expected and that - Status = 0x00 - GroupID = G1 - SceneID = 0x03 - TransitionTime = 0x03E8 + Verify that the extension fields in the log match the ones expected and that the log output is similar to the following: + [1707285444.028460][13682:13684] CHIP:DMG: }, + [1707285444.028553][13682:13684] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0001 + [1707285444.028579][13682:13684] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0001 + [1707285444.028670][13682:13684] CHIP:TOO: ViewSceneResponse: { + [1707285444.028685][13682:13684] CHIP:TOO: status: 0 + [1707285444.028696][13682:13684] CHIP:TOO: groupID: 257 + [1707285444.028706][13682:13684] CHIP:TOO: sceneID: 3 + [1707285444.028717][13682:13684] CHIP:TOO: transitionTime: 1 + [1707285444.028728][13682:13684] CHIP:TOO: sceneName: scene name + [1707285444.028766][13682:13684] CHIP:TOO: extensionFieldSets: XX entries + [1707285444.028814][13682:13684] CHIP:TOO: [XX]: { + [1707285444.028828][13682:13684] CHIP:TOO: ClusterID: XX + [1707285444.028853][13682:13684] CHIP:TOO: AttributeValueList: XX entries + [1707285444.028882][13682:13684] CHIP:TOO: [XX]: { + [1707285444.028896][13682:13684] CHIP:TOO: AttributeID: XX + [1707285444.028913][13682:13684] CHIP:TOO: AttributeValue: XX + [1707285444.028925][13682:13684] CHIP:TOO: } + [1707285444.028937][13682:13684] CHIP:TOO: } + [1707285444.028950][13682:13684] CHIP:TOO: } cluster: "LogCommands" command: "UserPrompt" arguments: @@ -676,7 +664,7 @@ tests: - label: "Step 6c: TH sends a ViewScene command to group G1 with the GroupID field set to G1 and the SceneID field set to 0x03." - PICS: S.S.C01.Rsp && PICS_SDK_CI_ONLY + PICS: S.S.C01.Rsp command: "ViewScene" groupId: G1 arguments: @@ -711,7 +699,7 @@ tests: - label: "Step 6e: TH sends a ViewScene command to DUT with the GroupID field set to G1 and the SceneID field set to 0x03." - PICS: S.S.C01.Rsp && PICS_SDK_CI_ONLY + PICS: S.S.C01.Rsp command: "ViewScene" arguments: values: diff --git a/src/app/tests/suites/certification/Test_TC_S_2_4.yaml b/src/app/tests/suites/certification/Test_TC_S_2_4.yaml index eac34fdea1fee6..c3ba72dcf05b80 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_4.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_4.yaml @@ -296,7 +296,7 @@ tests: - label: "Step 6a: TH configures AC2 on DUT for all implemented application clusters supporting scenes." - PICS: PICS_SDK_CI_ONLY + PICS: S.S.C05.Rsp && PICS_SDK_CI_ONLY cluster: "Level Control" command: "MoveToLevelWithOnOff" arguments: @@ -317,7 +317,7 @@ tests: Is DUT configured with AC2? cluster: "LogCommands" command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP + PICS: S.S.C05.Rsp && PICS_SKIP_SAMPLE_APP arguments: values: - name: "message" diff --git a/src/app/tests/suites/certification/Test_TC_S_2_5.yaml b/src/app/tests/suites/certification/Test_TC_S_2_5.yaml index 31ed8b17a2bcdb..e1624bf79d7e64 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_5.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_5.yaml @@ -61,14 +61,51 @@ tests: the GroupKeyMap attribute with one entry as follows: List item 1: FabricIndex: 1 GroupId: 0x0001 GroupKeySetId: 0x01a1" verification: | - ./chip-tool groupkeymanagement write group-key-map '[{"groupId": 1, "groupKeySetID": 1, "fabricIndex": 1}]' 1 0 - - [1688019387.509419][1710:1712] CHIP:DMG: } - [1688019387.509461][1710:1712] CHIP:DMG: - [1688019387.509497][1710:1712] CHIP:DMG: StatusIB = - [1688019387.509534][1710:1712] CHIP:DMG: { - [1688019387.509572][1710:1712] CHIP:DMG: status = 0x00 (SUCCESS), - [1688019387.509610][1710:1712] CHIP:DMG: }, + ./chip-tool groupkeymanagement write group-key-map '[{"groupId": "0x0001", "groupKeySetID": "0x01a1", "fabricIndex": 1} ]' 1 0 + + Verify DUT responds with SUCCESS status response on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: + + [1701076939.782934][16287:16289] CHIP:DMG: WriteResponseMessage = + [1701076939.782939][16287:16289] CHIP:DMG: { + [1701076939.782942][16287:16289] CHIP:DMG: AttributeStatusIBs = + [1701076939.782948][16287:16289] CHIP:DMG: [ + [1701076939.782951][16287:16289] CHIP:DMG: AttributeStatusIB = + [1701076939.782956][16287:16289] CHIP:DMG: { + [1701076939.782960][16287:16289] CHIP:DMG: AttributePathIB = + [1701076939.782965][16287:16289] CHIP:DMG: { + [1701076939.782970][16287:16289] CHIP:DMG: Endpoint = 0x0, + [1701076939.782973][16287:16289] CHIP:DMG: Cluster = 0x3f, + [1701076939.782977][16287:16289] CHIP:DMG: Attribute = 0x0000_0000, + [1701076939.782981][16287:16289] CHIP:DMG: } + [1701076939.782986][16287:16289] CHIP:DMG: + [1701076939.782990][16287:16289] CHIP:DMG: StatusIB = + [1701076939.782993][16287:16289] CHIP:DMG: { + [1701076939.782997][16287:16289] CHIP:DMG: status = 0x00 (SUCCESS), + [1701076939.783000][16287:16289] CHIP:DMG: }, + [1701076939.783004][16287:16289] CHIP:DMG: + [1701076939.783007][16287:16289] CHIP:DMG: }, + [1701076939.783014][16287:16289] CHIP:DMG: + [1701076939.783017][16287:16289] CHIP:DMG: AttributeStatusIB = + [1701076939.783021][16287:16289] CHIP:DMG: { + [1701076939.783024][16287:16289] CHIP:DMG: AttributePathIB = + [1701076939.783027][16287:16289] CHIP:DMG: { + [1701076939.783030][16287:16289] CHIP:DMG: Endpoint = 0x0, + [1701076939.783034][16287:16289] CHIP:DMG: Cluster = 0x3f, + [1701076939.783038][16287:16289] CHIP:DMG: Attribute = 0x0000_0000, + [1701076939.783042][16287:16289] CHIP:DMG: ListIndex = Null, + [1701076939.783045][16287:16289] CHIP:DMG: } + [1701076939.783050][16287:16289] CHIP:DMG: + [1701076939.783053][16287:16289] CHIP:DMG: StatusIB = + [1701076939.783056][16287:16289] CHIP:DMG: { + [1701076939.783060][16287:16289] CHIP:DMG: status = 0x00 (SUCCESS), + [1701076939.783063][16287:16289] CHIP:DMG: }, + [1701076939.783067][16287:16289] CHIP:DMG: + [1701076939.783069][16287:16289] CHIP:DMG: }, + [1701076939.783074][16287:16289] CHIP:DMG: + [1701076939.783077][16287:16289] CHIP:DMG: ], + [1701076939.783084][16287:16289] CHIP:DMG: + [1701076939.783087][16287:16289] CHIP:DMG: InteractionModelRevision = 11 + [1701076939.783090][16287:16289] CHIP:DMG: } disabled: true - label: "Step 1: TH sends a RemoveAllGroups command to DUT." @@ -76,12 +113,12 @@ tests: verification: | ./chip-tool groups remove-all-groups 1 1 - [1688019423.251477][1716:1718] CHIP:DMG: }, + Verify DUT responds with SUCCESS status response on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: [1688019423.251524][1716:1718] CHIP:DMG: - [1688019423.251561][1716:1718] CHIP:DMG: StatusIB = - [1688019423.251602][1716:1718] CHIP:DMG: { - [1688019423.251643][1716:1718] CHIP:DMG: status = 0x00 (SUCCESS), - [1688019423.251686][1716:1718] CHIP:DMG: }, + [1688019423.251561][1716:1718] CHIP:DMG: StatusIB = + [1688019423.251602][1716:1718] CHIP:DMG: { + [1688019423.251643][1716:1718] CHIP:DMG: status = 0x00 (SUCCESS), + [1688019423.251686][1716:1718] CHIP:DMG: }, [1688019423.251727][1716:1718] CHIP:DMG: disabled: true @@ -92,11 +129,16 @@ tests: verification: | ./chip-tool groups add-group 0x0001 grp1 1 1 - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0004 Command 0x0000_0000 - CHIP:TOO: AddGroupResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 1 - CHIP:TOO: } + Verify the AddGroupResponse with following fields: + Status is SUCCESS + Group ID is 0x0001 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1701259653.925863][10637:10639] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0004 Command=0x0000_0000 + [1701259653.925872][10637:10639] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0004 Command 0x0000_0000 + [1701259653.925891][10637:10639] CHIP:TOO: AddGroupResponse: { + [1701259653.925896][10637:10639] CHIP:TOO: status: 0 + [1701259653.925899][10637:10639] CHIP:TOO: groupID: 1 + [1701259653.925902][10637:10639] CHIP:TOO: } disabled: true - label: @@ -106,32 +148,137 @@ tests: verification: | ./chip-tool scenesmanagement remove-all-scenes 0x0001 1 1 - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0003 - CHIP:TOO: RemoveAllScenesResponse: { - CHIP:TOO: status: 1 - CHIP:TOO: groupID: 1 - CHIP:TOO: } + Verify the RemoveAllScenesResponse with following fields: + Status is SUCCESS + Group ID is 0x0001 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1706764352.114217][4432:4434] CHIP:DMG: }, + [1706764352.114233][4432:4434] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0003 + [1706764352.114241][4432:4434] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0003 + [1706764352.114257][4432:4434] CHIP:TOO: RemoveAllScenesResponse: { + [1706764352.114264][4432:4434] CHIP:TOO: status: 0 + [1706764352.114267][4432:4434] CHIP:TOO: groupID: 1 + [1706764352.114269][4432:4434] CHIP:TOO: } disabled: true - label: "Step 4a: TH reads from the DUT the SceneTableSize attribute" verification: | ./chip-tool scenesmanagement read scene-table-size 1 1 - [1688019474.695136][1726:1728] CHIP:DMG: } - [1688019474.695335][1726:1728] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Attribute 0x0000_0006 DataVersion: 1550229741 - [1688019474.695397][1726:1728] CHIP:TOO: SceneTableSize: (Default table size: 16) + Verify the "SceneTableSize" attribute value is SceneTableSize(minimum=16) on the TH (Chip-tool) and below is the sample log provided for the raspi platform: + + [1706764370.034843][4435:4437] CHIP:DMG: } + [1706764370.034970][4435:4437] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0001 DataVersion: 3964423870 + [1706764370.035000][4435:4437] CHIP:TOO: SceneTableSize: 16 disabled: true - label: "Step 4b: TH sends a subscription request action for FabricSceneInfo to the DUT." verification: | + Please use Interactive mode to Verify the subscription of an event + Here the command to enter interactive mode:-- ./chip-tool interactive start - >>> any subscribe-by-id 0x0062 0x0002 min-interval max-interval node-id endpoint + + Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully + + scenesmanagement subscribe fabric-scene-info 0 200 1 1 + + Verify the DUT sends a report data for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into RemainingCapacity and is equals to (MaxRemainingCapacity) on the TH (Chip-tool) and below is the sample log provided for the raspi platform: + + [1706764401.002841][4438:4440] CHIP:DMG: ReportDataMessage = + [1706764401.002862][4438:4440] CHIP:DMG: { + [1706764401.002879][4438:4440] CHIP:DMG: SubscriptionId = 0x679cab48, + [1706764401.002891][4438:4440] CHIP:DMG: AttributeReportIBs = + [1706764401.002916][4438:4440] CHIP:DMG: [ + [1706764401.002926][4438:4440] CHIP:DMG: AttributeReportIB = + [1706764401.002950][4438:4440] CHIP:DMG: { + [1706764401.002960][4438:4440] CHIP:DMG: AttributeDataIB = + [1706764401.002972][4438:4440] CHIP:DMG: { + [1706764401.002985][4438:4440] CHIP:DMG: DataVersion = 0xec4c4ebe, + [1706764401.002996][4438:4440] CHIP:DMG: AttributePathIB = + [1706764401.003008][4438:4440] CHIP:DMG: { + [1706764401.003021][4438:4440] CHIP:DMG: Endpoint = 0x1, + [1706764401.003035][4438:4440] CHIP:DMG: Cluster = 0x62, + [1706764401.003048][4438:4440] CHIP:DMG: Attribute = 0x0000_0002, + [1706764401.003059][4438:4440] CHIP:DMG: } + [1706764401.003076][4438:4440] CHIP:DMG: + [1706764401.003088][4438:4440] CHIP:DMG: Data = [ + [1706764401.003105][4438:4440] CHIP:DMG: + [1706764401.003121][4438:4440] CHIP:DMG: { + [1706764401.003136][4438:4440] CHIP:DMG: 0x0 = 0, + [1706764401.003150][4438:4440] CHIP:DMG: 0x1 = 1, + [1706764401.003162][4438:4440] CHIP:DMG: 0x2 = 1, + [1706764401.003175][4438:4440] CHIP:DMG: 0x3 = false, + [1706764401.003190][4438:4440] CHIP:DMG: 0x4 = 7, + [1706764401.003203][4438:4440] CHIP:DMG: 0xfe = 1, + [1706764401.003216][4438:4440] CHIP:DMG: }, + [1706764401.003229][4438:4440] CHIP:DMG: ], + [1706764401.003239][4438:4440] CHIP:DMG: }, + [1706764401.003260][4438:4440] CHIP:DMG: + [1706764401.003270][4438:4440] CHIP:DMG: }, + [1706764401.003292][4438:4440] CHIP:DMG: + [1706764401.003301][4438:4440] CHIP:DMG: ], + [1706764401.003324][4438:4440] CHIP:DMG: + [1706764401.003334][4438:4440] CHIP:DMG: InteractionModelRevision = 11 + [1706764401.003343][4438:4440] CHIP:DMG: } + [1706764401.003557][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3964423870 + [1706764401.003615][4438:4440] CHIP:TOO: FabricSceneInfo: 1 entries + [1706764401.003676][4438:4440] CHIP:TOO: [1]: { + [1706764401.003698][4438:4440] CHIP:TOO: SceneCount: 0 + [1706764401.003708][4438:4440] CHIP:TOO: CurrentScene: 1 + [1706764401.003718][4438:4440] CHIP:TOO: CurrentGroup: 1 + [1706764401.003728][4438:4440] CHIP:TOO: SceneValid: FALSE + [1706764401.003740][4438:4440] CHIP:TOO: RemainingCapacity: 7 + [1706764401.003750][4438:4440] CHIP:TOO: FabricIndex: 1 + [1706764401.003761][4438:4440] CHIP:TOO: } + disabled: true + + - label: + "Step 4c: Keep subscription session active for the remainder of the + test" + verification: | + Keep subscription session active for the remainder of the test + + Confirm that the subscription session is active for the remainder of the test by the reception of Liveness checks: + [1706798074.365883][5179:5181] CHIP:DMG: Refresh LivenessCheckTime for 64224 milliseconds with SubscriptionId = 0x8537dfcd Peer = 01:0000000000000001 + disabled: true + + - label: + "Step 5a: TH sends a AddScene command to DUT with the GroupID field + set to G1, the SceneID field set to 0x01, the TransitionTime field set + to 20000 (20s) and no extension field sets." + PICS: S.S.C00.Rsp + verification: | + scenesmanagement add-scene 0x0001 0x01 20 scene1 [] 1 1 + + Verify the AddSceneResponse with following fields: + Status is SUCCESS + Group ID is 0x0001 + SceneID field set to 0x01 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1706764438.086631][4438:4440] CHIP:DMG: }, + [1706764438.086653][4438:4440] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1706764438.086665][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1706764438.086681][4438:4440] CHIP:TOO: AddSceneResponse: { + [1706764438.086685][4438:4440] CHIP:TOO: status: 0 + [1706764438.086688][4438:4440] CHIP:TOO: groupID: 1 + [1706764438.086690][4438:4440] CHIP:TOO: sceneID: 1 + [1706764438.086692][4438:4440] CHIP:TOO: } + disabled: true + + - label: + "Step 5b: Verify that the DUT sends a report data for FabricSceneInfo + after the MinIntervalFloor time; store the RemainingCapacity field + from this fabric’s entry reported in FabricSceneInfo into + RemainingCapacity; verify RemainingCapacity equals + (MaxRemainingCapacity-1)." + verification: | + Verify that the DUT sends a report data for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into RemainingCapacity and is equals to (MaxRemainingCapacity-1). [1706764465.493922][4438:4440] CHIP:DMG: ReportDataMessage = [1706764465.493926][4438:4440] CHIP:DMG: { - [1706764465.493928][4438:4440] CHIP:DMG: SubscriptionId = 0x8537dfcd, + [1706764465.493928][4438:4440] CHIP:DMG: SubscriptionId = 0xcd5a528f, [1706764465.493931][4438:4440] CHIP:DMG: AttributeReportIBs = [1706764465.493937][4438:4440] CHIP:DMG: [ [1706764465.493939][4438:4440] CHIP:DMG: AttributeReportIB = @@ -175,102 +322,6 @@ tests: [1706764465.494167][4438:4440] CHIP:TOO: RemainingCapacity: 6 [1706764465.494170][4438:4440] CHIP:TOO: FabricIndex: 1 [1706764465.494174][4438:4440] CHIP:TOO: } - ... - [1706797894.367789][5179:5181] CHIP:DMG: Subscription established with SubscriptionID = 0x8537dfcd MinInterval = 0s MaxInterval = 60s Peer = 01:0000000000000001 - ... - [1706798074.365189][5179:5181] CHIP:EM: >>> [E:29283r S:30665 M:266174816] (S) Msg RX from 1:0000000000000001 [0714] --- Type 0001:05 (IM:ReportData) - [1706798074.365317][5179:5181] CHIP:EM: Handling via exchange: 29283r, Delegate: 0xaaaacccf2a88 - [1706798074.365449][5179:5181] CHIP:DMG: ReportDataMessage = - [1706798074.365517][5179:5181] CHIP:DMG: { - [1706798074.365576][5179:5181] CHIP:DMG: SubscriptionId = 0x8537dfcd, - [1706798074.365638][5179:5181] CHIP:DMG: InteractionModelRevision = 11 - [1706798074.365696][5179:5181] CHIP:DMG: } - [1706798074.365883][5179:5181] CHIP:DMG: Refresh LivenessCheckTime for 64224 milliseconds with SubscriptionId = 0x85 - 37dfcd Peer = 01:0000000000000001 - - disabled: true - - - label: - "Step 4c: Keep subscription session active for the remainder of the - test" - verification: | - Confirm that the subscription session is active for the remainder of the test by the reception of Liveness checks: - - [1706798074.365883][5179:5181] CHIP:DMG: Refresh LivenessCheckTime for 64224 milliseconds with SubscriptionId = 0x8537dfcd Peer = 01:0000000000000001 - - disabled: true - - - label: - "Step 5a: TH sends a AddScene command to DUT with the GroupID field - set to G1, the SceneID field set to 0x01, the TransitionTime field set - to 20000 (20s) and no extension field sets." - PICS: S.S.C00.Rsp - verification: | - ./chip-tool scenesmanagement add-scene 0x0001 0x1 20000 scene1 [] 1 1 - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - CHIP:TOO: AddSceneResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 1 - CHIP:TOO: sceneID: 1 - CHIP:TOO: } - disabled: true - - - label: - "Step 5b: Verify that the DUT sends a report data for FabricSceneInfo - after the MinIntervalFloor time; store the RemainingCapacity field - from this fabric’s entry reported in FabricSceneInfo into - RemainingCapacity; verify RemainingCapacity equals - (MaxRemainingCapacity-1)." - verification: | - CHIP:DMG: ReportDataMessage = - CHIP:DMG: { - CHIP:DMG: SubscriptionId = 0x8537dfcd, - CHIP:DMG: AttributeReportIBs = - CHIP:DMG: [ - CHIP:DMG: AttributeReportIB = - CHIP:DMG: { - CHIP:DMG: AttributeDataIB = - CHIP:DMG: { - CHIP:DMG: DataVersion = 0x92ecb45d, - CHIP:DMG: AttributePathIB = - CHIP:DMG: { - CHIP:DMG: Endpoint = 0x1, - CHIP:DMG: Cluster = 0x62, - CHIP:DMG: Attribute = 0x0000_0002, - CHIP:DMG: } - CHIP:DMG: - CHIP:DMG: Data = [ - CHIP:DMG: - CHIP:DMG: { - CHIP:DMG: 0x0 = 1, - CHIP:DMG: 0x1 = 0, - CHIP:DMG: 0x2 = 0, - CHIP:DMG: 0x3 = false, - CHIP:DMG: 0x4 = 6, - CHIP:DMG: 0xfe = 1, - CHIP:DMG: }, - CHIP:DMG: ], - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: ], - CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 11 - CHIP:DMG: } - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 1 - CHIP:TOO: CurrentScene: 0 - CHIP:TOO: CurrentGroup: 0 - CHIP:TOO: SceneValid: FALSE - CHIP:TOO: RemainingCapacity: 6 - CHIP:TOO: FabricIndex: 1 - CHIP:TOO: } - CHIP:DMG: Refresh LivenessCheckTime for 9224 milliseconds with SubscriptionId = 0x8537dfcd Peer = 01:0000000000000001 - disabled: true - label: @@ -280,14 +331,21 @@ tests: 8a." PICS: S.S.C04.Rsp verification: | - ./chip-tool scenesmanagement store-scene 0x0001 0x2 20000 scene2 [] 1 1 - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - CHIP:TOO: AddSceneResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 1 - CHIP:TOO: sceneID: 2 - CHIP:TOO: } + ./chiptool scenesmanagement store-scene 0x0001 0x02 1 1 + + Verify the StoreSceneResponse with following fields: + Status is SUCCESS + Group ID is 0x0001 + SceneID field set to 0x02 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1706764492.588457][4438:4440] CHIP:DMG: }, + [1706764492.588474][4438:4440] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0004 + [1706764492.588479][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0004 + [1706764492.588490][4438:4440] CHIP:TOO: StoreSceneResponse: { + [1706764492.588494][4438:4440] CHIP:TOO: status: 0 + [1706764492.588497][4438:4440] CHIP:TOO: groupID: 1 + [1706764492.588500][4438:4440] CHIP:TOO: sceneID: 2 + [1706764492.588503][4438:4440] CHIP:TOO: } disabled: true - label: @@ -297,53 +355,54 @@ tests: RemainingCapacity; verify RemainingCapacity equals (MaxRemainingCapacity-2)." verification: | - CHIP:DMG: ReportDataMessage = - CHIP:DMG: { - CHIP:DMG: SubscriptionId = 0x8537dfcd, - CHIP:DMG: AttributeReportIBs = - CHIP:DMG: [ - CHIP:DMG: AttributeReportIB = - CHIP:DMG: { - CHIP:DMG: AttributeDataIB = - CHIP:DMG: { - CHIP:DMG: DataVersion = 0x92ecb45d, - CHIP:DMG: AttributePathIB = - CHIP:DMG: { - CHIP:DMG: Endpoint = 0x1, - CHIP:DMG: Cluster = 0x62, - CHIP:DMG: Attribute = 0x0000_0002, - CHIP:DMG: } - CHIP:DMG: - CHIP:DMG: Data = [ - CHIP:DMG: - CHIP:DMG: { - CHIP:DMG: 0x0 = 2, - CHIP:DMG: 0x1 = 2, - CHIP:DMG: 0x2 = 1, - CHIP:DMG: 0x3 = true, - CHIP:DMG: 0x4 = 5, - CHIP:DMG: 0xfe = 1, - CHIP:DMG: }, - CHIP:DMG: ], - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: ], - CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 11 - CHIP:DMG: } - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 2 - CHIP:TOO: CurrentScene: 2 - CHIP:TOO: CurrentGroup: 1 - CHIP:TOO: SceneValid: TRUE - CHIP:TOO: RemainingCapacity: 5 - CHIP:TOO: FabricIndex: 1 - CHIP:TOO: } - CHIP:DMG: Refresh LivenessCheckTime for 9224 milliseconds with SubscriptionId = 0x8537dfcd Peer = 01:0000000000000001 + Verify that the DUT sends a report data for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into RemainingCapacity and is equals to (MaxRemainingCapacity-2). + + [1706764510.478452][4438:4440] CHIP:DMG: ReportDataMessage = + [1706764510.478456][4438:4440] CHIP:DMG: { + [1706764510.478462][4438:4440] CHIP:DMG: SubscriptionId = 0x6b998a6d, + [1706764510.478466][4438:4440] CHIP:DMG: AttributeReportIBs = + [1706764510.478475][4438:4440] CHIP:DMG: [ + [1706764510.478478][4438:4440] CHIP:DMG: AttributeReportIB = + [1706764510.478485][4438:4440] CHIP:DMG: { + [1706764510.478488][4438:4440] CHIP:DMG: AttributeDataIB = + [1706764510.478492][4438:4440] CHIP:DMG: { + [1706764510.478496][4438:4440] CHIP:DMG: DataVersion = 0xec4c4ec3, + [1706764510.478499][4438:4440] CHIP:DMG: AttributePathIB = + [1706764510.478503][4438:4440] CHIP:DMG: { + [1706764510.478507][4438:4440] CHIP:DMG: Endpoint = 0x1, + [1706764510.478511][4438:4440] CHIP:DMG: Cluster = 0x62, + [1706764510.478515][4438:4440] CHIP:DMG: Attribute = 0x0000_0002, + [1706764510.478518][4438:4440] CHIP:DMG: } + [1706764510.478522][4438:4440] CHIP:DMG: + [1706764510.478526][4438:4440] CHIP:DMG: Data = [ + [1706764510.478530][4438:4440] CHIP:DMG: + [1706764510.478535][4438:4440] CHIP:DMG: { + [1706764510.478542][4438:4440] CHIP:DMG: 0x0 = 2, + [1706764510.478547][4438:4440] CHIP:DMG: 0x1 = 2, + [1706764510.478551][4438:4440] CHIP:DMG: 0x2 = 1, + [1706764510.478556][4438:4440] CHIP:DMG: 0x3 = true, + [1706764510.478561][4438:4440] CHIP:DMG: 0x4 = 5, + [1706764510.478566][4438:4440] CHIP:DMG: 0xfe = 1, + [1706764510.478570][4438:4440] CHIP:DMG: }, + [1706764510.478575][4438:4440] CHIP:DMG: ], + [1706764510.478578][4438:4440] CHIP:DMG: }, + [1706764510.478586][4438:4440] CHIP:DMG: + [1706764510.478589][4438:4440] CHIP:DMG: }, + [1706764510.478597][4438:4440] CHIP:DMG: + [1706764510.478601][4438:4440] CHIP:DMG: ], + [1706764510.478609][4438:4440] CHIP:DMG: + [1706764510.478612][4438:4440] CHIP:DMG: InteractionModelRevision = 11 + [1706764510.478616][4438:4440] CHIP:DMG: } + [1706764510.478681][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3964423875 + [1706764510.478697][4438:4440] CHIP:TOO: FabricSceneInfo: 1 entries + [1706764510.478710][4438:4440] CHIP:TOO: [1]: { + [1706764510.478714][4438:4440] CHIP:TOO: SceneCount: 2 + [1706764510.478718][4438:4440] CHIP:TOO: CurrentScene: 2 + [1706764510.478721][4438:4440] CHIP:TOO: CurrentGroup: 1 + [1706764510.478725][4438:4440] CHIP:TOO: SceneValid: TRUE + [1706764510.478729][4438:4440] CHIP:TOO: RemainingCapacity: 5 + [1706764510.478733][4438:4440] CHIP:TOO: FabricIndex: 1 + [1706764510.478737][4438:4440] CHIP:TOO: } disabled: true - label: @@ -353,7 +412,21 @@ tests: field sets. If RemainingCapacity is 0, continue to Step 8a." PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0001 0x3 20000 scene3 [] 1 1 + ./chip-tool scenesmanagement add-scene 0x0001 0x03 20 scene1 [] 1 1 + + Verify the AddSceneResponse with following fields: + Status is SUCCESS + Group ID is 0x0001 + SceneID field set to 0x03 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1706764534.554889][4438:4440] CHIP:DMG: }, + [1706764534.554927][4438:4440] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1706764534.554933][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1706764534.554947][4438:4440] CHIP:TOO: AddSceneResponse: { + [1706764534.554952][4438:4440] CHIP:TOO: status: 0 + [1706764534.554955][4438:4440] CHIP:TOO: groupID: 1 + [1706764534.554958][4438:4440] CHIP:TOO: sceneID: 3 + [1706764534.554961][4438:4440] CHIP:TOO: } disabled: true - label: @@ -363,53 +436,54 @@ tests: RemainingCapacity; verify RemainingCapacity equals (MaxRemainingCapacity-3)." verification: | - CHIP:DMG: ReportDataMessage = - CHIP:DMG: { - CHIP:DMG: SubscriptionId = 0x8537dfcd, - CHIP:DMG: AttributeReportIBs = - CHIP:DMG: [ - CHIP:DMG: AttributeReportIB = - CHIP:DMG: { - CHIP:DMG: AttributeDataIB = - CHIP:DMG: { - CHIP:DMG: DataVersion = 0x92ecb45d, - CHIP:DMG: AttributePathIB = - CHIP:DMG: { - CHIP:DMG: Endpoint = 0x1, - CHIP:DMG: Cluster = 0x62, - CHIP:DMG: Attribute = 0x0000_0002, - CHIP:DMG: } - CHIP:DMG: - CHIP:DMG: Data = [ - CHIP:DMG: - CHIP:DMG: { - CHIP:DMG: 0x0 = 3, - CHIP:DMG: 0x1 = 2, - CHIP:DMG: 0x2 = 1, - CHIP:DMG: 0x3 = true, - CHIP:DMG: 0x4 = 4, - CHIP:DMG: 0xfe = 1, - CHIP:DMG: }, - CHIP:DMG: ], - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: ], - CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 11 - CHIP:DMG: } - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 3 - CHIP:TOO: CurrentScene: 2 - CHIP:TOO: CurrentGroup: 1 - CHIP:TOO: SceneValid: TRUE - CHIP:TOO: RemainingCapacity: 4 - CHIP:TOO: FabricIndex: 1 - CHIP:TOO: } - CHIP:DMG: Refresh LivenessCheckTime for 9224 milliseconds with SubscriptionId = 0x8537dfcd Peer = 01:0000000000000001 + Verify that the DUT sends a report data for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into RemainingCapacity and is equals to (MaxRemainingCapacity-3). + + [1706764553.457875][4438:4440] CHIP:DMG: ReportDataMessage = + [1706764553.457878][4438:4440] CHIP:DMG: { + [1706764553.457880][4438:4440] CHIP:DMG: SubscriptionId = 0xa7ba9271, + [1706764553.457883][4438:4440] CHIP:DMG: AttributeReportIBs = + [1706764553.457888][4438:4440] CHIP:DMG: [ + [1706764553.457892][4438:4440] CHIP:DMG: AttributeReportIB = + [1706764553.457901][4438:4440] CHIP:DMG: { + [1706764553.457905][4438:4440] CHIP:DMG: AttributeDataIB = + [1706764553.457910][4438:4440] CHIP:DMG: { + [1706764553.457913][4438:4440] CHIP:DMG: DataVersion = 0xec4c4ec5, + [1706764553.457915][4438:4440] CHIP:DMG: AttributePathIB = + [1706764553.457918][4438:4440] CHIP:DMG: { + [1706764553.457920][4438:4440] CHIP:DMG: Endpoint = 0x1, + [1706764553.457923][4438:4440] CHIP:DMG: Cluster = 0x62, + [1706764553.457926][4438:4440] CHIP:DMG: Attribute = 0x0000_0002, + [1706764553.457929][4438:4440] CHIP:DMG: } + [1706764553.457932][4438:4440] CHIP:DMG: + [1706764553.457935][4438:4440] CHIP:DMG: Data = [ + [1706764553.457938][4438:4440] CHIP:DMG: + [1706764553.457941][4438:4440] CHIP:DMG: { + [1706764553.457944][4438:4440] CHIP:DMG: 0x0 = 3, + [1706764553.457947][4438:4440] CHIP:DMG: 0x1 = 2, + [1706764553.457950][4438:4440] CHIP:DMG: 0x2 = 1, + [1706764553.457953][4438:4440] CHIP:DMG: 0x3 = true, + [1706764553.457957][4438:4440] CHIP:DMG: 0x4 = 4, + [1706764553.457963][4438:4440] CHIP:DMG: 0xfe = 1, + [1706764553.457968][4438:4440] CHIP:DMG: }, + [1706764553.457973][4438:4440] CHIP:DMG: ], + [1706764553.457977][4438:4440] CHIP:DMG: }, + [1706764553.457985][4438:4440] CHIP:DMG: + [1706764553.457990][4438:4440] CHIP:DMG: }, + [1706764553.457998][4438:4440] CHIP:DMG: + [1706764553.458002][4438:4440] CHIP:DMG: ], + [1706764553.458011][4438:4440] CHIP:DMG: + [1706764553.458016][4438:4440] CHIP:DMG: InteractionModelRevision = 11 + [1706764553.458019][4438:4440] CHIP:DMG: } + [1706764553.458074][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3964423877 + [1706764553.458086][4438:4440] CHIP:TOO: FabricSceneInfo: 1 entries + [1706764553.458095][4438:4440] CHIP:TOO: [1]: { + [1706764553.458098][4438:4440] CHIP:TOO: SceneCount: 3 + [1706764553.458100][4438:4440] CHIP:TOO: CurrentScene: 2 + [1706764553.458102][4438:4440] CHIP:TOO: CurrentGroup: 1 + [1706764553.458104][4438:4440] CHIP:TOO: SceneValid: TRUE + [1706764553.458107][4438:4440] CHIP:TOO: RemainingCapacity: 4 + [1706764553.458109][4438:4440] CHIP:TOO: FabricIndex: 1 + [1706764553.458111][4438:4440] CHIP:TOO: } disabled: true - label: @@ -417,14 +491,20 @@ tests: set to G1 and the SceneID field set to 0x01." PICS: S.S.C02.Rsp verification: | - ./chip-tool scenesmanagement remove-scene 0x0001 0x1 1 1 - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0002 - CHIP:TOO: RemoveSceneResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 1 - CHIP:TOO: sceneID: 1 - CHIP:TOO: } + ./chip-tool scenesmanagement remove-scene 0x0001 0x01 1 1 + + Verify the RemoveScenesResponse with following fields: + Status is SUCCESS + Group ID is 0x0001 + SceneID field set to 0x01 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1706764583.008025][4438:4440] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0002 + [1706764583.008031][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0002 + [1706764583.008044][4438:4440] CHIP:TOO: RemoveSceneResponse: { + [1706764583.008049][4438:4440] CHIP:TOO: status: 0 + [1706764583.008054][4438:4440] CHIP:TOO: groupID: 1 + [1706764583.008059][4438:4440] CHIP:TOO: sceneID: 1 + [1706764583.008064][4438:4440] CHIP:TOO: } disabled: true - label: @@ -434,53 +514,54 @@ tests: RemainingCapacity; verify RemainingCapacity equals (MaxRemainingCapacity-2)." verification: | - CHIP:DMG: ReportDataMessage = - CHIP:DMG: { - CHIP:DMG: SubscriptionId = 0x8537dfcd, - CHIP:DMG: AttributeReportIBs = - CHIP:DMG: [ - CHIP:DMG: AttributeReportIB = - CHIP:DMG: { - CHIP:DMG: AttributeDataIB = - CHIP:DMG: { - CHIP:DMG: DataVersion = 0x92ecb45d, - CHIP:DMG: AttributePathIB = - CHIP:DMG: { - CHIP:DMG: Endpoint = 0x1, - CHIP:DMG: Cluster = 0x62, - CHIP:DMG: Attribute = 0x0000_0002, - CHIP:DMG: } - CHIP:DMG: - CHIP:DMG: Data = [ - CHIP:DMG: - CHIP:DMG: { - CHIP:DMG: 0x0 = 2, - CHIP:DMG: 0x1 = 2, - CHIP:DMG: 0x2 = 1, - CHIP:DMG: 0x3 = true, - CHIP:DMG: 0x4 = 5, - CHIP:DMG: 0xfe = 1, - CHIP:DMG: }, - CHIP:DMG: ], - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: ], - CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 11 - CHIP:DMG: } - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 2 - CHIP:TOO: CurrentScene: 2 - CHIP:TOO: CurrentGroup: 1 - CHIP:TOO: SceneValid: TRUE - CHIP:TOO: RemainingCapacity: 5 - CHIP:TOO: FabricIndex: 1 - CHIP:TOO: } - CHIP:DMG: Refresh LivenessCheckTime for 9224 milliseconds with SubscriptionId = 0x8537dfcd Peer = 01:0000000000000001 + Verify that the DUT sends a report data for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into RemainingCapacity and is equals to (MaxRemainingCapacity-2). + + [1706764600.346946][4438:4440] CHIP:DMG: ReportDataMessage = + [1706764600.346951][4438:4440] CHIP:DMG: { + [1706764600.346955][4438:4440] CHIP:DMG: SubscriptionId = 0xb5fdbb95, + [1706764600.346959][4438:4440] CHIP:DMG: AttributeReportIBs = + [1706764600.346968][4438:4440] CHIP:DMG: [ + [1706764600.346973][4438:4440] CHIP:DMG: AttributeReportIB = + [1706764600.346982][4438:4440] CHIP:DMG: { + [1706764600.346986][4438:4440] CHIP:DMG: AttributeDataIB = + [1706764600.346992][4438:4440] CHIP:DMG: { + [1706764600.346999][4438:4440] CHIP:DMG: DataVersion = 0xec4c4ec7, + [1706764600.347003][4438:4440] CHIP:DMG: AttributePathIB = + [1706764600.347010][4438:4440] CHIP:DMG: { + [1706764600.347016][4438:4440] CHIP:DMG: Endpoint = 0x1, + [1706764600.347021][4438:4440] CHIP:DMG: Cluster = 0x62, + [1706764600.347027][4438:4440] CHIP:DMG: Attribute = 0x0000_0002, + [1706764600.347031][4438:4440] CHIP:DMG: } + [1706764600.347038][4438:4440] CHIP:DMG: + [1706764600.347043][4438:4440] CHIP:DMG: Data = [ + [1706764600.347048][4438:4440] CHIP:DMG: + [1706764600.347054][4438:4440] CHIP:DMG: { + [1706764600.347060][4438:4440] CHIP:DMG: 0x0 = 2, + [1706764600.347065][4438:4440] CHIP:DMG: 0x1 = 2, + [1706764600.347071][4438:4440] CHIP:DMG: 0x2 = 1, + [1706764600.347077][4438:4440] CHIP:DMG: 0x3 = true, + [1706764600.347083][4438:4440] CHIP:DMG: 0x4 = 5, + [1706764600.347089][4438:4440] CHIP:DMG: 0xfe = 1, + [1706764600.347094][4438:4440] CHIP:DMG: }, + [1706764600.347098][4438:4440] CHIP:DMG: ], + [1706764600.347103][4438:4440] CHIP:DMG: }, + [1706764600.347111][4438:4440] CHIP:DMG: + [1706764600.347115][4438:4440] CHIP:DMG: }, + [1706764600.347124][4438:4440] CHIP:DMG: + [1706764600.347128][4438:4440] CHIP:DMG: ], + [1706764600.347135][4438:4440] CHIP:DMG: + [1706764600.347138][4438:4440] CHIP:DMG: InteractionModelRevision = 11 + [1706764600.347140][4438:4440] CHIP:DMG: } + [1706764600.347196][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3964423879 + [1706764600.347211][4438:4440] CHIP:TOO: FabricSceneInfo: 1 entries + [1706764600.347224][4438:4440] CHIP:TOO: [1]: { + [1706764600.347230][4438:4440] CHIP:TOO: SceneCount: 2 + [1706764600.347234][4438:4440] CHIP:TOO: CurrentScene: 2 + [1706764600.347257][4438:4440] CHIP:TOO: CurrentGroup: 1 + [1706764600.347261][4438:4440] CHIP:TOO: SceneValid: TRUE + [1706764600.347267][4438:4440] CHIP:TOO: RemainingCapacity: 5 + [1706764600.347272][4438:4440] CHIP:TOO: FabricIndex: 1 + [1706764600.347276][4438:4440] CHIP:TOO: } disabled: true - label: @@ -488,13 +569,19 @@ tests: field set to G1." PICS: S.S.C03.Rsp verification: | - ./chip-tool scenesmanagement remove-all-scenes 0x0001 1 1 - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0003 - CHIP:TOO: RemoveAllScenesResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 1 - CHIP:TOO: } + scenesmanagement remove-all-scenes 0x0001 1 1 + + Verify the RemoveAllScenesResponse with following fields: + Status is SUCCESS + Group ID is 0x0001 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1706764629.391457][4438:4440] CHIP:DMG: }, + [1706764629.391475][4438:4440] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0003 + [1706764629.391479][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0003 + [1706764629.391488][4438:4440] CHIP:TOO: RemoveAllScenesResponse: { + [1706764629.391492][4438:4440] CHIP:TOO: status: 0 + [1706764629.391495][4438:4440] CHIP:TOO: groupID: 1 + [1706764629.391498][4438:4440] CHIP:TOO: } disabled: true - label: @@ -504,53 +591,54 @@ tests: RemainingCapacity; verify RemainingCapacity equals (MaxRemainingCapacity)." verification: | - CHIP:DMG: ReportDataMessage = - CHIP:DMG: { - CHIP:DMG: SubscriptionId = 0x8537dfcd, - CHIP:DMG: AttributeReportIBs = - CHIP:DMG: [ - CHIP:DMG: AttributeReportIB = - CHIP:DMG: { - CHIP:DMG: AttributeDataIB = - CHIP:DMG: { - CHIP:DMG: DataVersion = 0x92ecb45d, - CHIP:DMG: AttributePathIB = - CHIP:DMG: { - CHIP:DMG: Endpoint = 0x1, - CHIP:DMG: Cluster = 0x62, - CHIP:DMG: Attribute = 0x0000_0002, - CHIP:DMG: } - CHIP:DMG: - CHIP:DMG: Data = [ - CHIP:DMG: - CHIP:DMG: { - CHIP:DMG: 0x0 = 0, - CHIP:DMG: 0x1 = 2, - CHIP:DMG: 0x2 = 1, - CHIP:DMG: 0x3 = false, - CHIP:DMG: 0x4 = 7, - CHIP:DMG: 0xfe = 1, - CHIP:DMG: }, - CHIP:DMG: ], - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: ], - CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 11 - CHIP:DMG: } - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 0 - CHIP:TOO: CurrentScene: 2 - CHIP:TOO: CurrentGroup: 1 - CHIP:TOO: SceneValid: FALSE - CHIP:TOO: RemainingCapacity: 7 - CHIP:TOO: FabricIndex: 1 - CHIP:TOO: } - CHIP:DMG: Refresh LivenessCheckTime for 9224 milliseconds with SubscriptionId = 0x8537dfcd Peer = 01:0000000000000001 + Verify that the DUT sends a report data for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into RemainingCapacity and is equals to (MaxRemainingCapacity). + + [1706764645.968086][4438:4440] CHIP:DMG: ReportDataMessage = + [1706764645.968089][4438:4440] CHIP:DMG: { + [1706764645.968092][4438:4440] CHIP:DMG: SubscriptionId = 0x8dd9174a, + [1706764645.968094][4438:4440] CHIP:DMG: AttributeReportIBs = + [1706764645.968101][4438:4440] CHIP:DMG: [ + [1706764645.968103][4438:4440] CHIP:DMG: AttributeReportIB = + [1706764645.968109][4438:4440] CHIP:DMG: { + [1706764645.968112][4438:4440] CHIP:DMG: AttributeDataIB = + [1706764645.968115][4438:4440] CHIP:DMG: { + [1706764645.968119][4438:4440] CHIP:DMG: DataVersion = 0xec4c4ec9, + [1706764645.968122][4438:4440] CHIP:DMG: AttributePathIB = + [1706764645.968127][4438:4440] CHIP:DMG: { + [1706764645.968130][4438:4440] CHIP:DMG: Endpoint = 0x1, + [1706764645.968134][4438:4440] CHIP:DMG: Cluster = 0x62, + [1706764645.968137][4438:4440] CHIP:DMG: Attribute = 0x0000_0002, + [1706764645.968140][4438:4440] CHIP:DMG: } + [1706764645.968145][4438:4440] CHIP:DMG: + [1706764645.968148][4438:4440] CHIP:DMG: Data = [ + [1706764645.968151][4438:4440] CHIP:DMG: + [1706764645.968154][4438:4440] CHIP:DMG: { + [1706764645.968158][4438:4440] CHIP:DMG: 0x0 = 0, + [1706764645.968162][4438:4440] CHIP:DMG: 0x1 = 2, + [1706764645.968166][4438:4440] CHIP:DMG: 0x2 = 1, + [1706764645.968169][4438:4440] CHIP:DMG: 0x3 = false, + [1706764645.968173][4438:4440] CHIP:DMG: 0x4 = 7, + [1706764645.968177][4438:4440] CHIP:DMG: 0xfe = 1, + [1706764645.968180][4438:4440] CHIP:DMG: }, + [1706764645.968184][4438:4440] CHIP:DMG: ], + [1706764645.968186][4438:4440] CHIP:DMG: }, + [1706764645.968192][4438:4440] CHIP:DMG: + [1706764645.968195][4438:4440] CHIP:DMG: }, + [1706764645.968201][4438:4440] CHIP:DMG: + [1706764645.968203][4438:4440] CHIP:DMG: ], + [1706764645.968210][4438:4440] CHIP:DMG: + [1706764645.968212][4438:4440] CHIP:DMG: InteractionModelRevision = 11 + [1706764645.968215][4438:4440] CHIP:DMG: } + [1706764645.968262][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3964423881 + [1706764645.968272][4438:4440] CHIP:TOO: FabricSceneInfo: 1 entries + [1706764645.968283][4438:4440] CHIP:TOO: [1]: { + [1706764645.968286][4438:4440] CHIP:TOO: SceneCount: 0 + [1706764645.968289][4438:4440] CHIP:TOO: CurrentScene: 2 + [1706764645.968291][4438:4440] CHIP:TOO: CurrentGroup: 1 + [1706764645.968294][4438:4440] CHIP:TOO: SceneValid: FALSE + [1706764645.968297][4438:4440] CHIP:TOO: RemainingCapacity: 7 + [1706764645.968300][4438:4440] CHIP:TOO: FabricIndex: 1 + [1706764645.968303][4438:4440] CHIP:TOO: } disabled: true - label: @@ -558,12 +646,14 @@ tests: KeySetRemove command to the GroupKeyManagement cluster with the GroupKeySetID field set to 0x01a1" verification: | - ./chip-tool groupkeymanagement key-set-remove 1 1 0 + ./chip-tool groupkeymanagement key-set-remove 0x01a1 1 0 + + Verify DUT responds with SUCCESS status response on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: - [1688019719.867880][1746:1748] CHIP:DMG: }, + [1688019719.867880][1746:1748] CHIP:DMG: }, [1688019719.867923][1746:1748] CHIP:DMG: - [1688019719.867956][1746:1748] CHIP:DMG: StatusIB = - [1688019719.867995][1746:1748] CHIP:DMG: { - [1688019719.868033][1746:1748] CHIP:DMG: status = 0x00 (SUCCESS), - [1688019719.868071][1746:1748] CHIP:DMG: }, + [1688019719.867956][1746:1748] CHIP:DMG: StatusIB = + [1688019719.867995][1746:1748] CHIP:DMG: { + [1688019719.868033][1746:1748] CHIP:DMG: status = 0x00 (SUCCESS), + [1688019719.868071][1746:1748] CHIP:DMG: }, disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_S_2_6.yaml b/src/app/tests/suites/certification/Test_TC_S_2_6.yaml index 2d5e5cf0df2b99..4c81d96190abfc 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_6.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_6.yaml @@ -27,11 +27,64 @@ config: endpoint: 0 tests: - - label: "Precondition" + - label: "Precondition: Commission DUT to TH1" verification: | - - TH1, TH2, and TH3 should be on separate, distinct fabrics. - - A given fabric SHALL NOT consume more than half (rounded down towards 0) of the Scene Table entries (as indicated in the SceneTableSize attribute). - - MaxRemainingCapacity is SceneTableSize/2. + Once DUT reach the commissionable state send the following command on TH1: + ./chip-tool pairing onnetwork 1 20202021 + Verify the commissioning completed with success on TH(chip-tool) from DUT + [1650455358.501816][4366:4371] CHIP:TOO: Device commissioning completed with success + disabled: true + + - label: "Precondition: Commission DUT to TH2 (Open Commissioning Window)" + verification: | + Open a commissioning window On TH1(Chiptool)using below command + + ./chip-tool pairing open-commissioning-window 1 1 400 2000 3841 + + Verify the Successfully opened pairing window On TH1(Chiptool)e device + + [1657186324.710951][10820:10825] CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_003C Command=0x0000_0000 Status=0x0 + [1657186324.710980][10820:10825] CHIP:CTL: Successfully opened pairing window On TH(Chiptool)e device + [1657186324.711048][10820:10825] CHIP:CTL: Manual pairing code: [36253605617] + [1657186324.711108][10820:10825] CHIP:CTL: SetupQRCode: [MT:-24J0IRV01A7TB7E700] + disabled: true + + - label: "Precondition: Commission DUT to TH2 (Pairing)" + verification: | + Now send the below command for commissionin DUT to TH2 with Manual pairing code generated in TH1 using open commission window + + ./chip-tool pairing code 2 36253605617 --commissioner-name beta + + Verify the commissioning completed with success on TH2(chip-tool) from DUT + + [1657186359.584672][3509:3514] CHIP:CTL: Successfully finished commissioning step 'Cleanup' + [1657186359.584743][3509:3514] CHIP:TOO: Device commissioning completed with success + disabled: true + + - label: "Precondition: Commission DUT to TH3 (Open Commissioning Window)" + verification: | + Open a commissioning window On TH1(Chiptool)using below command + + ./chip-tool pairing open-commissioning-window 1 1 400 2000 3842 + + Verify the Successfully opened pairing window On TH1(Chiptool)e device + + [1701254594.851779][10096:10098] CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_003C Command=0x0000_0000 Status=0x0 + [1701254594.851783][10096:10098] CHIP:CTL: Successfully opened pairing window on the device + [1701254594.851789][10096:10098] CHIP:CTL: Manual pairing code: [36545248276] + [1701254594.851795][10096:10098] CHIP:CTL: SetupQRCode: [MT:-24J0Q1212K4.08JP10] + disabled: true + + - label: "Precondition: Commission DUT to TH3 (Pairing)" + verification: | + send the below command for commissionin DUT to TH3 with Manual pairing code generated in TH1 using open commission window + + ./chip-tool pairing code 3 36545248276 --commissioner-name gamma + + Verify the commissioning completed with success on TH3(chip-tool) from DUT + + [1657186359.584672][3509:3514] CHIP:CTL: Successfully finished commissioning step 'Cleanup' + [1657186359.584743][3509:3514] CHIP:TOO: Device commissioning completed with success disabled: true - label: @@ -52,85 +105,119 @@ tests: PICS: S.S.C03.Rsp verification: | ./chip-tool scenesmanagement remove-all-scenes 0x0000 2 1 --commissioner-name beta + + Verify the RemoveAllScenesResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1700826575.191275][15971:15973] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0003 + [1700826575.191321][15971:15973] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0003 + [1700826575.191938][15971:15973] CHIP:TOO: RemoveAllScenesResponse: { + [1700826575.191974][15971:15973] CHIP:TOO: status: 0 + [1700826575.191985][15971:15973] CHIP:TOO: groupID: 0 + [1700826575.191995][15971:15973] CHIP:TOO: } + ./chip-tool scenesmanagement remove-all-scenes 0x0000 3 1 --commissioner-name gamma + + Verify the RemoveAllScenesResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1700826595.190538][15975:15977] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0003 + [1700826595.190578][15975:15977] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0003 + [1700826595.190637][15975:15977] CHIP:TOO: RemoveAllScenesResponse: { + [1700826595.190652][15975:15977] CHIP:TOO: status: 0 + [1700826595.190661][15975:15977] CHIP:TOO: groupID: 0 + [1700826595.190669][15975:15977] CHIP:TOO: } disabled: true - label: "Step 2a: TH1 reads from the DUT the SceneTableSize attribute" verification: | ./chip-tool scenesmanagement read scene-table-size 1 1 - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Attribute 0x0000_0006 DataVersion: 2793536935 - CHIP:TOO: SceneTableSize: 16 + Verify the "SceneTableSize" attribute value is SceneTableSize(minimum=16) which is recorded into SceneTableSize on the TH (Chip-tool) and below is the sample log provided for the raspi platform: + + [1700826614.634340][15990:15992] CHIP:DMG: } + [1700826614.634390][15990:15992] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0006 DataVersion: 1908396086 + [1700826614.634399][15990:15992] CHIP:TOO: SceneTableSize: 16 disabled: true - label: "Step 2b: TH1 sends a subscription request action for FabricSceneInfo to the DUT." verification: | - ./chipt-tool interactive start - any subscribe-by-id 0x0062 0x0002 0 5 1 1 - - CHIP:DMG: ReportDataMessage = - CHIP:DMG: { - CHIP:DMG: SubscriptionId = 0xce6a96bc, - CHIP:DMG: AttributeReportIBs = - CHIP:DMG: [ - CHIP:DMG: AttributeReportIB = - CHIP:DMG: { - CHIP:DMG: AttributeDataIB = - CHIP:DMG: { - CHIP:DMG: DataVersion = 0x92ecb46c, - CHIP:DMG: AttributePathIB = - CHIP:DMG: { - CHIP:DMG: Endpoint = 0x1, - CHIP:DMG: Cluster = 0x62, - CHIP:DMG: Attribute = 0x0000_0002, - CHIP:DMG: } - CHIP:DMG: - CHIP:DMG: Data = [ - CHIP:DMG: - CHIP:DMG: { - CHIP:DMG: 0x0 = 0, - CHIP:DMG: 0x1 = 0, - CHIP:DMG: 0x2 = 0, - CHIP:DMG: 0x3 = false, - CHIP:DMG: 0x4 = 7, - CHIP:DMG: 0xfe = 1, - CHIP:DMG: }, - CHIP:DMG: ], - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: ], - CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 11 - CHIP:DMG: } - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 2464986220 - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 0 - CHIP:TOO: CurrentScene: 0 - CHIP:TOO: CurrentGroup: 0 - CHIP:TOO: SceneValid: FALSE - CHIP:TOO: RemainingCapacity: 7 - CHIP:TOO: FabricIndex: 1 - CHIP:TOO: } - + Please use Interactive mode to Verify the subscription + Here the command to enter interactive mode:-- + ./chip-tool interactive start + + Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully + + scenesmanagement subscribe fabric-scene-info 100 200 1 1 + + Verify the DUT sends a report data to TH1 for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into Remaining1stCapacity and is equals to (MaxRemainingCapacity) on the TH (Chip-tool) and below is the sample log provided for the raspi platform: + + [1701251118.633541][8779:8781] CHIP:DMG: ReportDataMessage = + [1701251118.633544][8779:8781] CHIP:DMG: { + [1701251118.633547][8779:8781] CHIP:DMG: SubscriptionId = 0x349c4fb0, + [1701251118.633550][8779:8781] CHIP:DMG: AttributeReportIBs = + [1701251118.633557][8779:8781] CHIP:DMG: [ + [1701251118.633560][8779:8781] CHIP:DMG: AttributeReportIB = + [1701251118.633567][8779:8781] CHIP:DMG: { + [1701251118.633570][8779:8781] CHIP:DMG: AttributeDataIB = + [1701251118.633574][8779:8781] CHIP:DMG: { + [1701251118.633577][8779:8781] CHIP:DMG: DataVersion = 0xe203cd66, + [1701251118.633581][8779:8781] CHIP:DMG: AttributePathIB = + [1701251118.633584][8779:8781] CHIP:DMG: { + [1701251118.633587][8779:8781] CHIP:DMG: Endpoint = 0x1, + [1701251118.633591][8779:8781] CHIP:DMG: Cluster = 0x62, + [1701251118.633594][8779:8781] CHIP:DMG: Attribute = 0x0000_0002, + [1701251118.633598][8779:8781] CHIP:DMG: } + [1701251118.633602][8779:8781] CHIP:DMG: + [1701251118.633606][8779:8781] CHIP:DMG: Data = [ + [1701251118.633610][8779:8781] CHIP:DMG: + [1701251118.633614][8779:8781] CHIP:DMG: { + [1701251118.633618][8779:8781] CHIP:DMG: 0x0 = 0, + [1701251118.633621][8779:8781] CHIP:DMG: 0x1 = 0, + [1701251118.633625][8779:8781] CHIP:DMG: 0x2 = 0, + [1701251118.633629][8779:8781] CHIP:DMG: 0x3 = false, + [1701251118.633633][8779:8781] CHIP:DMG: 0x4 = 7, + [1701251118.633637][8779:8781] CHIP:DMG: 0xfe = 1, + [1701251118.633640][8779:8781] CHIP:DMG: }, + [1701251118.633644][8779:8781] CHIP:DMG: ], + [1701251118.633646][8779:8781] CHIP:DMG: }, + [1701251118.633652][8779:8781] CHIP:DMG: + [1701251118.633655][8779:8781] CHIP:DMG: }, + [1701251118.633661][8779:8781] CHIP:DMG: + [1701251118.633663][8779:8781] CHIP:DMG: ], + [1701251118.633669][8779:8781] CHIP:DMG: + [1701251118.633672][8779:8781] CHIP:DMG: InteractionModelRevision = 11 + [1701251118.633675][8779:8781] CHIP:DMG: } + [1701251118.633729][8779:8781] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3791900006 + [1701251118.633743][8779:8781] CHIP:TOO: FabricSceneInfo: 1 entries + [1701251118.633758][8779:8781] CHIP:TOO: [1]: { + [1701251118.633765][8779:8781] CHIP:TOO: SceneCount: 0 + [1701251118.633768][8779:8781] CHIP:TOO: CurrentScene: 0 + [1701251118.633770][8779:8781] CHIP:TOO: CurrentGroup: 0 + [1701251118.633773][8779:8781] CHIP:TOO: SceneValid: FALSE + [1701251118.633776][8779:8781] CHIP:TOO: RemainingCapacity: 7 + [1701251118.633779][8779:8781] CHIP:TOO: FabricIndex: 1 + [1701251118.633783][8779:8781] CHIP:TOO: } disabled: true - label: "Step 2c: Keep subscription session active for the remaining of the test" verification: | + Keep subscription session active for the remaining of the test + Confirm that the subscription session is active for the remainder of the test by the reception of Liveness checks: CHIP:EM: >>> [E:44665r S:45698 M:201545516] (S) Msg RX from 1:0000000000000001 [1042] --- Type 0001:05 (IM:ReportData) CHIP:EM: Handling via exchange: 44665r, Delegate: 0xaaaaea044808 CHIP:DMG: ReportDataMessage = CHIP:DMG: { - CHIP:DMG: SubscriptionId = 0xce6a96bc, - CHIP:DMG: InteractionModelRevision = 11 + CHIP:DMG: SubscriptionId = 0xce6a96bc, + CHIP:DMG: InteractionModelRevision = 11 CHIP:DMG: } CHIP:DMG: Refresh LivenessCheckTime for 9224 milliseconds with SubscriptionId = 0xce6a96bc Peer = 01:0000000000000001 disabled: true @@ -138,28 +225,123 @@ tests: - label: "Step 2d: Repeat Step 2b and 2c with TH2 and TH3" verification: | TH2: - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Attribute 0x0000_0007 DataVersion: 2793536968 - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 0 - CHIP:TOO: CurrentScene: 0 - CHIP:TOO: CurrentGroup: 0 - CHIP:TOO: SceneValid: FALSE - CHIP:TOO: RemainingCapacity: 7 - CHIP:TOO: FabricIndex: 2 - CHIP:TOO: } + + Please use Interactive mode to Verify the subscription of an event + Here the command to enter interactive mode:-- + ./chip-tool interactive start + + Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully + + scenesmanagement subscribe fabric-scene-info 100 200 2 1 --commissioner-name beta + + Verify the DUT sends a report data to TH2 for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into Remaining2ndCapacity and is equals to (MaxRemainingCapacity) on the TH2 (Chip-tool) and below is the sample log provided for the raspi platform: + + [1701242801.625064][7636:7638] CHIP:DMG: ReportDataMessage = + [1701242801.625076][7636:7638] CHIP:DMG: { + [1701242801.625089][7636:7638] CHIP:DMG: SubscriptionId = 0x9682625a, + [1701242801.625100][7636:7638] CHIP:DMG: AttributeReportIBs = + [1701242801.625126][7636:7638] CHIP:DMG: [ + [1701242801.625136][7636:7638] CHIP:DMG: AttributeReportIB = + [1701242801.625161][7636:7638] CHIP:DMG: { + [1701242801.625172][7636:7638] CHIP:DMG: AttributeDataIB = + [1701242801.625184][7636:7638] CHIP:DMG: { + [1701242801.625198][7636:7638] CHIP:DMG: DataVersion = 0x4daee67b, + [1701242801.625209][7636:7638] CHIP:DMG: AttributePathIB = + [1701242801.625223][7636:7638] CHIP:DMG: { + [1701242801.625237][7636:7638] CHIP:DMG: Endpoint = 0x1, + [1701242801.625250][7636:7638] CHIP:DMG: Cluster = 0x62, + [1701242801.625263][7636:7638] CHIP:DMG: Attribute = 0x0000_0002, + [1701242801.625275][7636:7638] CHIP:DMG: } + [1701242801.625291][7636:7638] CHIP:DMG: + [1701242801.625303][7636:7638] CHIP:DMG: Data = [ + [1701242801.625316][7636:7638] CHIP:DMG: + [1701242801.625330][7636:7638] CHIP:DMG: { + [1701242801.625346][7636:7638] CHIP:DMG: 0x0 = 0, + [1701242801.625361][7636:7638] CHIP:DMG: 0x1 = 0, + [1701242801.625375][7636:7638] CHIP:DMG: 0x2 = 0, + [1701242801.625390][7636:7638] CHIP:DMG: 0x3 = false, + [1701242801.625405][7636:7638] CHIP:DMG: 0x4 = 7, + [1701242801.625418][7636:7638] CHIP:DMG: 0xfe = 2, + [1701242801.625432][7636:7638] CHIP:DMG: }, + [1701242801.625444][7636:7638] CHIP:DMG: ], + [1701242801.625455][7636:7638] CHIP:DMG: }, + [1701242801.625477][7636:7638] CHIP:DMG: + [1701242801.625487][7636:7638] CHIP:DMG: }, + [1701242801.625509][7636:7638] CHIP:DMG: + [1701242801.625519][7636:7638] CHIP:DMG: ], + [1701242801.625541][7636:7638] CHIP:DMG: + [1701242801.625552][7636:7638] CHIP:DMG: InteractionModelRevision = 11 + [1701242801.625562][7636:7638] CHIP:DMG: } + [1701242801.625758][7636:7638] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 1303307899 + [1701242801.625808][7636:7638] CHIP:TOO: FabricSceneInfo: 1 entries + [1701242801.625852][7636:7638] CHIP:TOO: [1]: { + [1701242801.625874][7636:7638] CHIP:TOO: SceneCount: 0 + [1701242801.625885][7636:7638] CHIP:TOO: CurrentScene: 0 + [1701242801.625896][7636:7638] CHIP:TOO: CurrentGroup: 0 + [1701242801.625907][7636:7638] CHIP:TOO: SceneValid: FALSE + [1701242801.625919][7636:7638] CHIP:TOO: RemainingCapacity: 7 + [1701242801.625930][7636:7638] CHIP:TOO: FabricIndex: 2 + [1701242801.625941][7636:7638] CHIP:TOO: } + TH3: - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Attribute 0x0000_0007 DataVersion: 2793536968 - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 0 - CHIP:TOO: CurrentScene: 0 - CHIP:TOO: CurrentGroup: 0 - CHIP:TOO: SceneValid: FALSE - CHIP:TOO: RemainingCapacity: 7 - CHIP:TOO: FabricIndex: 3 - CHIP:TOO: } + + Please use Interactive mode to Verify the subscription of an event + Here the command to enter interactive mode:-- + ./chip-tool interactive start + + Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully + + scenesmanagement subscribe fabric-scene-info 100 200 3 1 --commissioner-name gamma + + Verify the DUT sends a report data to TH3 for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into Remaining3ndCapacity and is equals to (MaxRemainingCapacity) on the TH3 (Chip-tool) and below is the sample log provided for the raspi platform: + + [1701242829.236595][7642:7644] CHIP:DMG: ReportDataMessage = + [1701242829.236616][7642:7644] CHIP:DMG: { + [1701242829.236629][7642:7644] CHIP:DMG: SubscriptionId = 0x31889fa9, + [1701242829.236640][7642:7644] CHIP:DMG: AttributeReportIBs = + [1701242829.236665][7642:7644] CHIP:DMG: [ + [1701242829.236675][7642:7644] CHIP:DMG: AttributeReportIB = + [1701242829.236702][7642:7644] CHIP:DMG: { + [1701242829.236712][7642:7644] CHIP:DMG: AttributeDataIB = + [1701242829.236724][7642:7644] CHIP:DMG: { + [1701242829.236738][7642:7644] CHIP:DMG: DataVersion = 0x4daee67b, + [1701242829.236750][7642:7644] CHIP:DMG: AttributePathIB = + [1701242829.236766][7642:7644] CHIP:DMG: { + [1701242829.236778][7642:7644] CHIP:DMG: Endpoint = 0x1, + [1701242829.236792][7642:7644] CHIP:DMG: Cluster = 0x62, + [1701242829.236807][7642:7644] CHIP:DMG: Attribute = 0x0000_0001, + [1701242829.236818][7642:7644] CHIP:DMG: } + [1701242829.236834][7642:7644] CHIP:DMG: + [1701242829.236847][7642:7644] CHIP:DMG: Data = [ + [1701242829.236861][7642:7644] CHIP:DMG: + [1701242829.236875][7642:7644] CHIP:DMG: { + [1701242829.236891][7642:7644] CHIP:DMG: 0x0 = 0, + [1701242829.236905][7642:7644] CHIP:DMG: 0x1 = 0, + [1701242829.236921][7642:7644] CHIP:DMG: 0x2 = 0, + [1701242829.236935][7642:7644] CHIP:DMG: 0x3 = false, + [1701242829.236952][7642:7644] CHIP:DMG: 0x4 = 7, + [1701242829.236966][7642:7644] CHIP:DMG: 0xfe = 3, + [1701242829.236979][7642:7644] CHIP:DMG: }, + [1701242829.236992][7642:7644] CHIP:DMG: ], + [1701242829.237003][7642:7644] CHIP:DMG: }, + [1701242829.237026][7642:7644] CHIP:DMG: + [1701242829.237036][7642:7644] CHIP:DMG: }, + [1701242829.237059][7642:7644] CHIP:DMG: + [1701242829.237069][7642:7644] CHIP:DMG: ], + [1701242829.237092][7642:7644] CHIP:DMG: + [1701242829.237102][7642:7644] CHIP:DMG: InteractionModelRevision = 11 + [1701242829.237112][7642:7644] CHIP:DMG: } + [1701242829.237312][7642:7644] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0001 DataVersion: 1303307899 + [1701242829.237369][7642:7644] CHIP:TOO: FabricSceneInfo: 1 entries + [1701242829.237411][7642:7644] CHIP:TOO: [1]: { + [1701242829.237433][7642:7644] CHIP:TOO: SceneCount: 0 + [1701242829.237443][7642:7644] CHIP:TOO: CurrentScene: 0 + [1701242829.237454][7642:7644] CHIP:TOO: CurrentGroup: 0 + [1701242829.237465][7642:7644] CHIP:TOO: SceneValid: FALSE + [1701242829.237477][7642:7644] CHIP:TOO: RemainingCapacity: 7 + [1701242829.237487][7642:7644] CHIP:TOO: FabricIndex: 3 + [1701242829.237498][7642:7644] CHIP:TOO: } disabled: true - label: @@ -168,14 +350,20 @@ tests: set to 20000 (20s) and no extension field sets." PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0000 0x1 20000 scene1 [] 1 1 - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - CHIP:TOO: AddSceneResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 0 - CHIP:TOO: sceneID: 1 - CHIP:TOO: } + ./chip-tool scenesmanagement add-scene 0x0000 0x01 20 scene1 [] 1 1 + + Verify the AddSceneResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 + SceneID field set to 0x01 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1700827169.206479][16026:16028] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1700827169.206492][16026:16028] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1700827169.206523][16026:16028] CHIP:TOO: AddSceneResponse: { + [1700827169.206537][16026:16028] CHIP:TOO: status: 0 + [1700827169.206548][16026:16028] CHIP:TOO: groupID: 0 + [1700827169.206558][16026:16028] CHIP:TOO: sceneID: 1 + [1700827169.206568][16026:16028] CHIP:TOO: } disabled: true - label: @@ -185,53 +373,56 @@ tests: FabricSceneInfo into Remaining1stCapacity; verify Remaining1stCapacity equals (MaxRemainingCapacity-1)." verification: | - Confirm that a report data message is received with the updated data: - CHIP:DMG: ReportDataMessage = - CHIP:DMG: { - CHIP:DMG: SubscriptionId = 0xce6a96bc, - CHIP:DMG: AttributeReportIBs = - CHIP:DMG: [ - CHIP:DMG: AttributeReportIB = - CHIP:DMG: { - CHIP:DMG: AttributeDataIB = - CHIP:DMG: { - CHIP:DMG: DataVersion = 0x92ecb46e, - CHIP:DMG: AttributePathIB = - CHIP:DMG: { - CHIP:DMG: Endpoint = 0x1, - CHIP:DMG: Cluster = 0x62, - CHIP:DMG: Attribute = 0x0000_0002, - CHIP:DMG: } - CHIP:DMG: - CHIP:DMG: Data = [ - CHIP:DMG: - CHIP:DMG: { - CHIP:DMG: 0x0 = 1, - CHIP:DMG: 0x1 = 0, - CHIP:DMG: 0x2 = 0, - CHIP:DMG: 0x3 = false, - CHIP:DMG: 0x4 = 6, - CHIP:DMG: 0xfe = 1, - CHIP:DMG: }, - CHIP:DMG: ], - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: ], - CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 11 - CHIP:DMG: } - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 2464986222 - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 0 - CHIP:TOO: CurrentScene: 0 - CHIP:TOO: CurrentGroup: 0 - CHIP:TOO: SceneValid: FALSE - CHIP:TOO: RemainingCapacity: 6 - CHIP:TOO: FabricIndex: 1 - CHIP:TOO: } + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 1 1 + + Verify the DUT sends a report data to TH1 for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into Remaining1stCapacity and is equals to (MaxRemainingCapacity-1) on the TH (Chip-tool) and below is the sample log provided for the raspi platform: + + [1701246692.659639][8121:8123] CHIP:DMG: ReportDataMessage = + [1701246692.659654][8121:8123] CHIP:DMG: { + [1701246692.659667][8121:8123] CHIP:DMG: SubscriptionId = 0xceee757a, + [1701246692.659678][8121:8123] CHIP:DMG: AttributeReportIBs = + [1701246692.659702][8121:8123] CHIP:DMG: [ + [1701246692.659711][8121:8123] CHIP:DMG: AttributeReportIB = + [1701246692.659737][8121:8123] CHIP:DMG: { + [1701246692.659748][8121:8123] CHIP:DMG: AttributeDataIB = + [1701246692.659758][8121:8123] CHIP:DMG: { + [1701246692.659772][8121:8123] CHIP:DMG: DataVersion = 0xa64c547f, + [1701246692.659783][8121:8123] CHIP:DMG: AttributePathIB = + [1701246692.659797][8121:8123] CHIP:DMG: { + [1701246692.659810][8121:8123] CHIP:DMG: Endpoint = 0x1, + [1701246692.659822][8121:8123] CHIP:DMG: Cluster = 0x62, + [1701246692.659836][8121:8123] CHIP:DMG: Attribute = 0x0000_0002, + [1701246692.659847][8121:8123] CHIP:DMG: } + [1701246692.659864][8121:8123] CHIP:DMG: + [1701246692.659876][8121:8123] CHIP:DMG: Data = [ + [1701246692.659889][8121:8123] CHIP:DMG: + [1701246692.659903][8121:8123] CHIP:DMG: { + [1701246692.659918][8121:8123] CHIP:DMG: 0x0 = 1, + [1701246692.659932][8121:8123] CHIP:DMG: 0x1 = 0, + [1701246692.659946][8121:8123] CHIP:DMG: 0x2 = 0, + [1701246692.659960][8121:8123] CHIP:DMG: 0x3 = false, + [1701246692.659974][8121:8123] CHIP:DMG: 0x4 = 6, + [1701246692.659987][8121:8123] CHIP:DMG: 0xfe = 1, + [1701246692.660001][8121:8123] CHIP:DMG: }, + [1701246692.660024][8121:8123] CHIP:DMG: ], + [1701246692.660035][8121:8123] CHIP:DMG: }, + [1701246692.660055][8121:8123] CHIP:DMG: + [1701246692.660065][8121:8123] CHIP:DMG: }, + [1701246692.660090][8121:8123] CHIP:DMG: + [1701246692.660100][8121:8123] CHIP:DMG: ], + [1701246692.660125][8121:8123] CHIP:DMG: + [1701246692.660135][8121:8123] CHIP:DMG: InteractionModelRevision = 11 + [1701246692.660145][8121:8123] CHIP:DMG: } + [1701246692.660363][8121:8123] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 2790020223 + [1701246692.660403][8121:8123] CHIP:TOO: FabricSceneInfo: 1 entries + [1701246692.660436][8121:8123] CHIP:TOO: [1]: { + [1701246692.660449][8121:8123] CHIP:TOO: SceneCount: 1 + [1701246692.660459][8121:8123] CHIP:TOO: CurrentScene: 0 + [1701246692.660471][8121:8123] CHIP:TOO: CurrentGroup: 0 + [1701246692.660482][8121:8123] CHIP:TOO: SceneValid: FALSE + [1701246692.660494][8121:8123] CHIP:TOO: RemainingCapacity: 6 + [1701246692.660505][8121:8123] CHIP:TOO: FabricIndex: 1 + [1701246692.660516][8121:8123] CHIP:TOO: } disabled: true - label: @@ -281,51 +472,367 @@ tests: field sets." PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0000 0x08 20000 scene101 [] 1 1 - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - CHIP:TOO: AddSceneResponse: { - CHIP:TOO: status: 137 - CHIP:TOO: groupID: 0 - CHIP:TOO: sceneID: 8 - CHIP:TOO: } + ./chip-tool scenesmanagement add-scene 0x0000 0x08 0x0014 scene9 [] 1 1 + + Verify the AddSceneResponse with following fields: + Status is RESOURCE_EXHAUSTED(0x89) on the TH1(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1701244361.448569][7642:7644] CHIP:DMG: }, + [1701244361.448586][7642:7644] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1701244361.448590][7642:7644] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1701244361.448600][7642:7644] CHIP:TOO: AddSceneResponse: { + [1701244361.448604][7642:7644] CHIP:TOO: status: 137 + [1701244361.448608][7642:7644] CHIP:TOO: groupID: 0 + [1701244361.448611][7642:7644] CHIP:TOO: sceneID: 8 + [1701244361.448614][7642:7644] CHIP:TOO: } disabled: true - label: "Step 5a: Repeat Step 4a with TH2" PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0000 0x2 20000 scene1 [] 2 1 --commissioner-name beta - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - CHIP:TOO: AddSceneResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 0 - CHIP:TOO: sceneID: 2 - CHIP:TOO: } + ./chip-tool scenesmanagement add-scene 0x0000 0x02 0x0014 scene1 [] 2 1 --commissioner-name beta + + Verify the AddSceneResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 + SceneID field set to 0x02 on the TH2(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1700828173.261569][16115:16117] CHIP:DMG: }, + [1700828173.261586][16115:16117] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1700828173.261600][16115:16117] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1700828173.261629][16115:16117] CHIP:TOO: AddSceneResponse: { + [1700828173.261633][16115:16117] CHIP:TOO: status: 0 + [1700828173.261636][16115:16117] CHIP:TOO: groupID: 0 + [1700828173.261638][16115:16117] CHIP:TOO: sceneID: 2 + [1700828173.261640][16115:16117] CHIP:TOO: } + + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 2 1 --commissioner-name beta + + Verify the DUT sends a report data messages after the MinIntervalFloor time to TH2 for RemainingCapacity field in FabricSceneInfo for that fabric with updated value on the TH2 (Chip-tool) and below is the sample log provided for the raspi platform: + + [1701244532.841112][7824:7826] CHIP:DMG: ReportDataMessage = + [1701244532.841116][7824:7826] CHIP:DMG: { + [1701244532.841120][7824:7826] CHIP:DMG: SubscriptionId = 0xf6c52c20, + [1701244532.841123][7824:7826] CHIP:DMG: AttributeReportIBs = + [1701244532.841131][7824:7826] CHIP:DMG: [ + [1701244532.841134][7824:7826] CHIP:DMG: AttributeReportIB = + [1701244532.841141][7824:7826] CHIP:DMG: { + [1701244532.841144][7824:7826] CHIP:DMG: AttributeDataIB = + [1701244532.841148][7824:7826] CHIP:DMG: { + [1701244532.841152][7824:7826] CHIP:DMG: DataVersion = 0x4daee699, + [1701244532.841155][7824:7826] CHIP:DMG: AttributePathIB = + [1701244532.841159][7824:7826] CHIP:DMG: { + [1701244532.841163][7824:7826] CHIP:DMG: Endpoint = 0x1, + [1701244532.841167][7824:7826] CHIP:DMG: Cluster = 0x62, + [1701244532.841171][7824:7826] CHIP:DMG: Attribute = 0x0000_0002, + [1701244532.841175][7824:7826] CHIP:DMG: } + [1701244532.841179][7824:7826] CHIP:DMG: + [1701244532.841183][7824:7826] CHIP:DMG: Data = [ + [1701244532.841187][7824:7826] CHIP:DMG: + [1701244532.841192][7824:7826] CHIP:DMG: { + [1701244532.841196][7824:7826] CHIP:DMG: 0x0 = 1, + [1701244532.841200][7824:7826] CHIP:DMG: 0x1 = 0, + [1701244532.841204][7824:7826] CHIP:DMG: 0x2 = 0, + [1701244532.841209][7824:7826] CHIP:DMG: 0x3 = false, + [1701244532.841213][7824:7826] CHIP:DMG: 0x4 = 6, + [1701244532.841217][7824:7826] CHIP:DMG: 0xfe = 2, + [1701244532.841221][7824:7826] CHIP:DMG: }, + [1701244532.841225][7824:7826] CHIP:DMG: ], + [1701244532.841228][7824:7826] CHIP:DMG: }, + [1701244532.841237][7824:7826] CHIP:DMG: + [1701244532.841240][7824:7826] CHIP:DMG: }, + [1701244532.841248][7824:7826] CHIP:DMG: + [1701244532.841251][7824:7826] CHIP:DMG: ], + [1701244532.841257][7824:7826] CHIP:DMG: + [1701244532.841261][7824:7826] CHIP:DMG: InteractionModelRevision = 11 + [1701244532.841264][7824:7826] CHIP:DMG: } + [1701244532.841324][7824:7826] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 1303307929 + [1701244532.841340][7824:7826] CHIP:TOO: FabricSceneInfo: 1 entries + [1701244532.841351][7824:7826] CHIP:TOO: [1]: { + [1701244532.841355][7824:7826] CHIP:TOO: SceneCount: 1 + [1701244532.841358][7824:7826] CHIP:TOO: CurrentScene: 0 + [1701244532.841361][7824:7826] CHIP:TOO: CurrentGroup: 0 + [1701244532.841365][7824:7826] CHIP:TOO: SceneValid: FALSE + [1701244532.841368][7824:7826] CHIP:TOO: RemainingCapacity: 6 + [1701244532.841371][7824:7826] CHIP:TOO: FabricIndex: 2 + [1701244532.841375][7824:7826] CHIP:TOO: } + . + . + . + ./chip-tool scenesmanagement add-scene 0x0000 0x08 0x0014 scene7 [] 2 1 --commissioner-name beta + + Verify the AddSceneResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 + SceneID field set to 0x08 on the TH2(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1700829509.052437][16198:16200] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1700829509.052452][16198:16200] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1700829509.052485][16198:16200] CHIP:TOO: AddSceneResponse: { + [1700829509.052500][16198:16200] CHIP:TOO: status: 0 + [1700829509.052511][16198:16200] CHIP:TOO: groupID: 0 + [1700829509.052521][16198:16200] CHIP:TOO: sceneID: 8 + [1700829509.052532][16198:16200] CHIP:TOO: } + + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 2 1 --commissioner-name beta + + Verify the DUT sends a report data messages after the MinIntervalFloor time to TH2 for RemainingCapacity field in FabricSceneInfo for that fabric with updated value(decreasing to 0) on the TH2 (Chip-tool) and below is the sample log provided for the raspi platform: + + [1701245132.869725][7824:7826] CHIP:DMG: ReportDataMessage = + [1701245132.869737][7824:7826] CHIP:DMG: { + [1701245132.869748][7824:7826] CHIP:DMG: SubscriptionId = 0xf6c52c20, + [1701245132.869756][7824:7826] CHIP:DMG: AttributeReportIBs = + [1701245132.869779][7824:7826] CHIP:DMG: [ + [1701245132.869790][7824:7826] CHIP:DMG: AttributeReportIB = + [1701245132.869814][7824:7826] CHIP:DMG: { + [1701245132.869825][7824:7826] CHIP:DMG: AttributeDataIB = + [1701245132.869835][7824:7826] CHIP:DMG: { + [1701245132.869854][7824:7826] CHIP:DMG: DataVersion = 0x4daee6a5, + [1701245132.869866][7824:7826] CHIP:DMG: AttributePathIB = + [1701245132.869879][7824:7826] CHIP:DMG: { + [1701245132.869893][7824:7826] CHIP:DMG: Endpoint = 0x1, + [1701245132.869906][7824:7826] CHIP:DMG: Cluster = 0x62, + [1701245132.869923][7824:7826] CHIP:DMG: Attribute = 0x0000_0002, + [1701245132.869935][7824:7826] CHIP:DMG: } + [1701245132.869951][7824:7826] CHIP:DMG: + [1701245132.869963][7824:7826] CHIP:DMG: Data = [ + [1701245132.869978][7824:7826] CHIP:DMG: + [1701245132.869995][7824:7826] CHIP:DMG: { + [1701245132.870010][7824:7826] CHIP:DMG: 0x0 = 7, + [1701245132.870026][7824:7826] CHIP:DMG: 0x1 = 0, + [1701245132.870038][7824:7826] CHIP:DMG: 0x2 = 0, + [1701245132.870052][7824:7826] CHIP:DMG: 0x3 = false, + [1701245132.870066][7824:7826] CHIP:DMG: 0x4 = 0, + [1701245132.870081][7824:7826] CHIP:DMG: 0xfe = 2, + [1701245132.870094][7824:7826] CHIP:DMG: }, + [1701245132.870106][7824:7826] CHIP:DMG: ], + [1701245132.870117][7824:7826] CHIP:DMG: }, + [1701245132.870140][7824:7826] CHIP:DMG: + [1701245132.870149][7824:7826] CHIP:DMG: }, + [1701245132.870171][7824:7826] CHIP:DMG: + [1701245132.870180][7824:7826] CHIP:DMG: ], + [1701245132.870205][7824:7826] CHIP:DMG: + [1701245132.870215][7824:7826] CHIP:DMG: InteractionModelRevision = 11 + [1701245132.870225][7824:7826] CHIP:DMG: } + [1701245132.870446][7824:7826] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 1303307941 + [1701245132.870486][7824:7826] CHIP:TOO: FabricSceneInfo: 1 entries + [1701245132.870517][7824:7826] CHIP:TOO: [1]: { + [1701245132.870530][7824:7826] CHIP:TOO: SceneCount: 7 + [1701245132.870541][7824:7826] CHIP:TOO: CurrentScene: 0 + [1701245132.870549][7824:7826] CHIP:TOO: CurrentGroup: 0 + [1701245132.870561][7824:7826] CHIP:TOO: SceneValid: FALSE + [1701245132.870573][7824:7826] CHIP:TOO: RemainingCapacity: 0 + [1701245132.870584][7824:7826] CHIP:TOO: FabricIndex: 2 + [1701245132.870594][7824:7826] CHIP:TOO: } + + + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 3 1 --commissioner-name gamma + + Verify that the DUT sends report data messages after the MinIntervalFloor time to TH3 for RemainingCapacity field in FabricSceneInfo for that fabric with updated value (decreasing to SceneTableSize - (2 * MaxRemainingCapacity)) on the TH2 (Chip-tool) and below is the sample log provided for the raspi platform: + + [1705916737.108024][21608:21610] CHIP:DMG: ReportDataMessage = + [1705916737.108028][21608:21610] CHIP:DMG: { + [1705916737.108031][21608:21610] CHIP:DMG: SubscriptionId = 0xbb681f96, + [1705916737.108034][21608:21610] CHIP:DMG: AttributeReportIBs = + [1705916737.108041][21608:21610] CHIP:DMG: [ + [1705916737.108043][21608:21610] CHIP:DMG: AttributeReportIB = + [1705916737.108050][21608:21610] CHIP:DMG: { + [1705916737.108053][21608:21610] CHIP:DMG: AttributeDataIB = + [1705916737.108056][21608:21610] CHIP:DMG: { + [1705916737.108060][21608:21610] CHIP:DMG: DataVersion = 0xb6069420, + [1705916737.108063][21608:21610] CHIP:DMG: AttributePathIB = + [1705916737.108066][21608:21610] CHIP:DMG: { + [1705916737.108070][21608:21610] CHIP:DMG: Endpoint = 0x1, + [1705916737.108073][21608:21610] CHIP:DMG: Cluster = 0x62, + [1705916737.108077][21608:21610] CHIP:DMG: Attribute = 0x0000_0002, + [1705916737.108080][21608:21610] CHIP:DMG: } + [1705916737.108084][21608:21610] CHIP:DMG: + [1705916737.108087][21608:21610] CHIP:DMG: Data = [ + [1705916737.108091][21608:21610] CHIP:DMG: + [1705916737.108094][21608:21610] CHIP:DMG: { + [1705916737.108098][21608:21610] CHIP:DMG: 0x0 = 0, + [1705916737.108102][21608:21610] CHIP:DMG: 0x1 = 0, + [1705916737.108106][21608:21610] CHIP:DMG: 0x2 = 0, + [1705916737.108109][21608:21610] CHIP:DMG: 0x3 = false, + [1705916737.108113][21608:21610] CHIP:DMG: 0x4 = 7, + [1705916737.108117][21608:21610] CHIP:DMG: 0xfe = 3, + [1705916737.108120][21608:21610] CHIP:DMG: }, + [1705916737.108123][21608:21610] CHIP:DMG: ], + [1705916737.108126][21608:21610] CHIP:DMG: }, + [1705916737.108132][21608:21610] CHIP:DMG: + [1705916737.108135][21608:21610] CHIP:DMG: }, + [1705916737.108141][21608:21610] CHIP:DMG: + [1705916737.108144][21608:21610] CHIP:DMG: ], + [1705916737.108150][21608:21610] CHIP:DMG: + [1705916737.108153][21608:21610] CHIP:DMG: InteractionModelRevision = 11 + [1705916737.108155][21608:21610] CHIP:DMG: } + [1705916737.108218][21608:21610] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3053884448 + [1705916737.108239][21608:21610] CHIP:TOO: FabricSceneInfo: 1 entries + [1705916737.108259][21608:21610] CHIP:TOO: [1]: { + [1705916737.108266][21608:21610] CHIP:TOO: SceneCount: 0 + [1705916737.108268][21608:21610] CHIP:TOO: CurrentScene: 0 + [1705916737.108271][21608:21610] CHIP:TOO: CurrentGroup: 0 + [1705916737.108274][21608:21610] CHIP:TOO: SceneValid: FALSE + [1705916737.108277][21608:21610] CHIP:TOO: RemainingCapacity: 2 + [1705916737.108280][21608:21610] CHIP:TOO: FabricIndex: 3 + [1705916737.108283][21608:21610] CHIP:TOO: } disabled: true - label: "Step 5b: Repeat Step 4b with TH2" PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0000 0x11 20000 scene201 [] 2 1 --commissioner-name beta - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - CHIP:TOO: AddSceneResponse: { - CHIP:TOO: status: 137 - CHIP:TOO: groupID: 0 - CHIP:TOO: sceneID: 17 - CHIP:TOO: } + ./chip-tool scenesmanagement add-scene 0x0000 0x09 0x0014 scene8 [] 2 1 --commissioner-name beta + + Verify the AddSceneResponse with following fields: + Status is RESOURCE_EXHAUSTED(0x89) on the TH2(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1701245223.543911][7824:7826] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1701245223.543925][7824:7826] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1701245223.543957][7824:7826] CHIP:TOO: AddSceneResponse: { + [1701245223.543971][7824:7826] CHIP:TOO: status: 137 + [1701245223.543983][7824:7826] CHIP:TOO: groupID: 0 + [1701245223.543994][7824:7826] CHIP:TOO: sceneID: 9 + [1701245223.544004][7824:7826] CHIP:TOO: } disabled: true - label: "Step 6a: Repeat Step 4a with TH3" PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0000 0x3 20000 scene1 [] 2 1 --commissioner-name gamma - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - CHIP:TOO: AddSceneResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 0 - CHIP:TOO: sceneID: 3 - CHIP:TOO: } + ./chip-tool scenesmanagement add-scene 0x0000 0x02 0x0014 scene1 [] 3 1 --commissioner-name gamma + + Verify the AddSceneResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 + SceneID field set to 0x02 on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1705915133.113882][21363:21365] CHIP:DMG: }, + [1705915133.113949][21363:21365] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1705915133.113982][21363:21365] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1705915133.114065][21363:21365] CHIP:TOO: AddSceneResponse: { + [1705915133.114081][21363:21365] CHIP:TOO: status: 0 + [1705915133.114092][21363:21365] CHIP:TOO: groupID: 0 + [1705915133.114103][21363:21365] CHIP:TOO: sceneID: 1 + [1705915133.114113][21363:21365] CHIP:TOO: } + + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 3 1 --commissioner-name gamma + + Verify that the DUT sends report data messages after the MinIntervalFloor time to TH3 for RemainingCapacity field in FabricSceneInfo for that fabric with updated value on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1705915183.311738][21363:21365] CHIP:DMG: ReportDataMessage = + [1705915183.311752][21363:21365] CHIP:DMG: { + [1705915183.311765][21363:21365] CHIP:DMG: SubscriptionId = 0x62039a894, + [1705915183.311775][21363:21365] CHIP:DMG: AttributeReportIBs = + [1705915183.311801][21363:21365] CHIP:DMG: [ + [1705915183.311811][21363:21365] CHIP:DMG: AttributeReportIB = + [1705915183.311835][21363:21365] CHIP:DMG: { + [1705915183.311845][21363:21365] CHIP:DMG: AttributeDataIB = + [1705915183.311858][21363:21365] CHIP:DMG: { + [1705915183.311871][21363:21365] CHIP:DMG: DataVersion = 0x7e84d696, + [1705915183.311882][21363:21365] CHIP:DMG: AttributePathIB = + [1705915183.311896][21363:21365] CHIP:DMG: { + [1705915183.311909][21363:21365] CHIP:DMG: Endpoint = 0x1, + [1705915183.311923][21363:21365] CHIP:DMG: Cluster = 0x62, + [1705915183.311937][21363:21365] CHIP:DMG: Attribute = 0x0000_0002, + [1705915183.311948][21363:21365] CHIP:DMG: } + [1705915183.311964][21363:21365] CHIP:DMG: + [1705915183.311976][21363:21365] CHIP:DMG: Data = [ + [1705915183.311990][21363:21365] CHIP:DMG: + [1705915183.312003][21363:21365] CHIP:DMG: { + [1705915183.312018][21363:21365] CHIP:DMG: 0x0 = 1, + [1705915183.312033][21363:21365] CHIP:DMG: 0x1 = 0, + [1705915183.312047][21363:21365] CHIP:DMG: 0x2 = 0, + [1705915183.312072][21363:21365] CHIP:DMG: 0x3 = false, + [1705915183.312093][21363:21365] CHIP:DMG: 0x4 = 1, + [1705915183.312115][21363:21365] CHIP:DMG: 0xfe = 3, + [1705915183.312134][21363:21365] CHIP:DMG: }, + [1705915183.312154][21363:21365] CHIP:DMG: ], + [1705915183.312170][21363:21365] CHIP:DMG: }, + [1705915183.312197][21363:21365] CHIP:DMG: + [1705915183.312207][21363:21365] CHIP:DMG: }, + [1705915183.312228][21363:21365] CHIP:DMG: + [1705915183.312239][21363:21365] CHIP:DMG: ], + [1705915183.312263][21363:21365] CHIP:DMG: + [1705915183.312274][21363:21365] CHIP:DMG: InteractionModelRevision = 11 + [1705915183.312283][21363:21365] CHIP:DMG: } + [1705915183.312491][21363:21365] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 2122634902 + [1705915183.312553][21363:21365] CHIP:TOO: FabricSceneInfo: 1 entries + [1705915183.312599][21363:21365] CHIP:TOO: [1]: { + [1705915183.312613][21363:21365] CHIP:TOO: SceneCount: 1 + [1705915183.312623][21363:21365] CHIP:TOO: CurrentScene: 0 + [1705915183.312645][21363:21365] CHIP:TOO: CurrentGroup: 0 + [1705915183.312656][21363:21365] CHIP:TOO: SceneValid: FALSE + [1705915183.312669][21363:21365] CHIP:TOO: RemainingCapacity: 1 + [1705915183.312679][21363:21365] CHIP:TOO: FabricIndex: 3 + [1705915183.312690][21363:21365] CHIP:TOO: } + + + ./chip-tool scenesmanagement add-scene 0x0000 0x03 0x0014 scene2 [] 3 1 --commissioner-name gamma + + Verify the AddSceneResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 + SceneID field set to 0x03 on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1705915237.987013][21363:21365] CHIP:DMG: }, + [1705915237.987077][21363:21365] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1705915237.987093][21363:21365] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1705915237.987124][21363:21365] CHIP:TOO: AddSceneResponse: { + [1705915237.987140][21363:21365] CHIP:TOO: status: 0 + [1705915237.987150][21363:21365] CHIP:TOO: groupID: 0 + [1705915237.987161][21363:21365] CHIP:TOO: sceneID: 3 + [1705915237.987171][21363:21365] CHIP:TOO: } + + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 3 1 --commissioner-name gamma + + Verify that the DUT sends report data messages after the MinIntervalFloor time to TH3 for RemainingCapacity field in FabricSceneInfo for that fabric with updated value((decreasing to 0)) on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: + + + [1705915281.585175][21387:21389] CHIP:DMG: ReportDataMessage = + [1705915281.585187][21387:21389] CHIP:DMG: { + [1705915281.585198][21387:21389] CHIP:DMG: SubscriptionId = 0x111160d4, + [1705915281.585206][21387:21389] CHIP:DMG: AttributeReportIBs = + [1705915281.585228][21387:21389] CHIP:DMG: [ + [1705915281.585236][21387:21389] CHIP:DMG: AttributeReportIB = + [1705915281.585263][21387:21389] CHIP:DMG: { + [1705915281.585273][21387:21389] CHIP:DMG: AttributeDataIB = + [1705915281.585285][21387:21389] CHIP:DMG: { + [1705915281.585299][21387:21389] CHIP:DMG: DataVersion = 0x7e84d698, + [1705915281.585310][21387:21389] CHIP:DMG: AttributePathIB = + [1705915281.585323][21387:21389] CHIP:DMG: { + [1705915281.585336][21387:21389] CHIP:DMG: Endpoint = 0x1, + [1705915281.585349][21387:21389] CHIP:DMG: Cluster = 0x62, + [1705915281.585362][21387:21389] CHIP:DMG: Attribute = 0x0000_0002, + [1705915281.585374][21387:21389] CHIP:DMG: } + [1705915281.585390][21387:21389] CHIP:DMG: + [1705915281.585402][21387:21389] CHIP:DMG: Data = [ + [1705915281.585415][21387:21389] CHIP:DMG: + [1705915281.585428][21387:21389] CHIP:DMG: { + [1705915281.585443][21387:21389] CHIP:DMG: 0x0 = 2, + [1705915281.585458][21387:21389] CHIP:DMG: 0x1 = 0, + [1705915281.585472][21387:21389] CHIP:DMG: 0x2 = 0, + [1705915281.585486][21387:21389] CHIP:DMG: 0x3 = false, + [1705915281.585500][21387:21389] CHIP:DMG: 0x4 = 0, + [1705915281.585513][21387:21389] CHIP:DMG: 0xfe = 3, + [1705915281.585527][21387:21389] CHIP:DMG: }, + [1705915281.585539][21387:21389] CHIP:DMG: ], + [1705915281.585550][21387:21389] CHIP:DMG: }, + [1705915281.585573][21387:21389] CHIP:DMG: + [1705915281.585583][21387:21389] CHIP:DMG: }, + [1705915281.585605][21387:21389] CHIP:DMG: + [1705915281.585615][21387:21389] CHIP:DMG: ], + [1705915281.585638][21387:21389] CHIP:DMG: + [1705915281.585648][21387:21389] CHIP:DMG: InteractionModelRevision = 11 + [1705915281.585657][21387:21389] CHIP:DMG: } + [1705915281.585866][21387:21389] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 2122634904 + [1705915281.585940][21387:21389] CHIP:TOO: FabricSceneInfo: 1 entries + [1705915281.586006][21387:21389] CHIP:TOO: [1]: { + [1705915281.586029][21387:21389] CHIP:TOO: SceneCount: 2 + [1705915281.586040][21387:21389] CHIP:TOO: CurrentScene: 0 + [1705915281.586051][21387:21389] CHIP:TOO: CurrentGroup: 0 + [1705915281.586061][21387:21389] CHIP:TOO: SceneValid: FALSE + [1705915281.586073][21387:21389] CHIP:TOO: RemainingCapacity: 0 + [1705915281.586084][21387:21389] CHIP:TOO: FabricIndex: 3 + [1705915281.586095][21387:21389] CHIP:TOO: } disabled: true - label: @@ -334,14 +841,19 @@ tests: set to 20000 20s and no extension field sets." PICS: S.S.C00.Rsp verification: | - ./chip-tool scenesmanagement add-scene 0x0000 0x01 20000 scene301 [] 3 1 --commissioner-name gamma - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0000 - CHIP:TOO: AddSceneResponse: { - CHIP:TOO: status: 137 - CHIP:TOO: groupID: 0 - CHIP:TOO: sceneID: 1 - CHIP:TOO: } + ./chip-tool scenesmanagement add-scene 0x0000 0x01 0x0014 scene [] 3 1 --commissioner-name gamma + + Verify the AddSceneResponse with following fields: + Status is RESOURCE_EXHAUSTED(0x89) on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1705915365.772920][21387:21389] CHIP:DMG: }, + [1705915365.772985][21387:21389] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0000 + [1705915365.773001][21387:21389] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0000 + [1705915365.773063][21387:21389] CHIP:TOO: AddSceneResponse: { + [1705915365.773079][21387:21389] CHIP:TOO: status: 137 + [1705915365.773091][21387:21389] CHIP:TOO: groupID: 0 + [1705915365.773102][21387:21389] CHIP:TOO: sceneID: 1 + [1705915365.773112][21387:21389] CHIP:TOO: } disabled: true - label: @@ -349,31 +861,41 @@ tests: set to 0x0000, the SceneID field set to 0x01." PICS: S.S.C04.Rsp verification: | - ./chip-tool scenesmanagement store-scene 0x0000 0xFE 20000 sceneFE [] 1 1 - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0004 - CHIP:TOO: StoreSceneResponse: { - CHIP:TOO: status: 137 - CHIP:TOO: groupID: 0 - CHIP:TOO: sceneID: 0xFE - CHIP:TOO: } + ./chip-tool scenesmanagement store-scene 0x0000 0x01 3 1 --commissioner-name gamma + + Verify the StoreSceneResponse with following fields: + Status is RESOURCE_EXHAUSTED(0x89) on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1705915551.740537][21417:21419] CHIP:DMG: }, + [1705915551.740557][21417:21419] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0004 + [1705915551.740566][21417:21419] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0004 + [1705915551.740585][21417:21419] CHIP:TOO: StoreSceneResponse: { + [1705915551.740590][21417:21419] CHIP:TOO: status: 137 + [1705915551.740593][21417:21419] CHIP:TOO: groupID: 0 + [1705915551.740596][21417:21419] CHIP:TOO: sceneID: 1 + [1705915551.740598][21417:21419] CHIP:TOO: } disabled: true - label: - "TH sends a CopyScene command to DUT with the mode field set to 0x00, - the group identifier from field set to 0x0000, the scene identifier - from field set to 0x01, the group identifier to field set to 0x0000 - and the scene identifier to field set to 0xFE." + "Step 8: TH sends a CopyScene command to DUT with the mode field set + to 0x00, the group identifier from field set to 0x0000, the scene + identifier from field set to 0x01, the group identifier to field set + to 0x0000 and the scene identifier to field set to 0xFE." PICS: S.S.C40.Rsp verification: | - ./chip-tool scenesmanagement copy-scene 0 0x0000 0x01 0x4E20 sceneFE [] 1 1 - - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0040 - CHIP:TOO: CopySceneResponse: { - CHIP:TOO: status: 137 - CHIP:TOO: groupID: 0 - CHIP:TOO: sceneID: 0xFE - CHIP:TOO: } + ./chip-tool scenesmanagement copy-scene 0x00 0x0000 0x02 0x0000 0x00 3 1 --commissioner-name gamma + + Verify the CopySceneResponse with following fields: + Status is RESOURCE_EXHAUSTED(0x89) on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1705915659.672801][21417:21419] CHIP:DMG: }, + [1705915659.672875][21417:21419] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0040 + [1705915659.672891][21417:21419] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0040 + [1705915659.672923][21417:21419] CHIP:TOO: CopySceneResponse: { + [1705915659.672937][21417:21419] CHIP:TOO: status: 133 + [1705915659.672950][21417:21419] CHIP:TOO: groupIdentifierFrom: 0 + [1705915659.672979][21417:21419] CHIP:TOO: sceneIdentifierFrom: 2 + [1705915659.672991][21417:21419] CHIP:TOO: } disabled: true - label: @@ -383,11 +905,16 @@ tests: verification: | ./chip-tool scenesmanagement remove-all-scenes 0x0000 1 1 - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0003 - CHIP:TOO: RemoveAllScenesResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 0 - CHIP:TOO: } + Verify the RemoveAllScenesResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 on TH1(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1700829746.586347][16198:16200] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0003 + [1700829746.586351][16198:16200] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0003 + [1700829746.586362][16198:16200] CHIP:TOO: RemoveAllScenesResponse: { + [1700829746.586366][16198:16200] CHIP:TOO: status: 0 + [1700829746.586368][16198:16200] CHIP:TOO: groupID: 0 + [1700829746.586370][16198:16200] CHIP:TOO: } disabled: true - label: "Step 9b: Verify that the DUT sends a report data to TH1 for @@ -401,11 +928,21 @@ tests: should send 'empty' report data since there is no update for this attribute for TH2)." verification: | - CHIP:DMG: ReportDataMessage = - CHIP:DMG: { - CHIP:DMG: SubscriptionId = 0xa9f0f186, - CHIP:DMG: InteractionModelRevision = 1 - CHIP:DMG: } + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 1 1 + + Verify that the DUT sends a report data to TH1 for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry the reported in FabricSceneInfo into Remaining1stCapacity; verify Remaining1stCapacity equals (MaxRemainingCapacity) on TH1(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1705915725.959835][21417:21419] CHIP:DMG: } + [1705915725.959889][21417:21419] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 2122634911 + [1705915725.959913][21417:21419] CHIP:TOO: FabricSceneInfo: 1 entries + [1705915725.959926][21417:21419] CHIP:TOO: [1]: { + [1705915725.959929][21417:21419] CHIP:TOO: SceneCount: 0 + [1705915725.959931][21417:21419] CHIP:TOO: CurrentScene: 0 + [1705915725.959935][21417:21419] CHIP:TOO: CurrentGroup: 0 + [1705915725.959939][21417:21419] CHIP:TOO: SceneValid: FALSE + [1705915725.959943][21417:21419] CHIP:TOO: RemainingCapacity: 7 + [1705915725.959945][21417:21419] CHIP:TOO: FabricIndex: 1 + [1705915725.959948][21417:21419] CHIP:TOO: } disabled: true - label: @@ -415,11 +952,17 @@ tests: verification: | ./chip-tool scenesmanagement remove-all-scenes 0x0000 2 1 --commissioner-name beta - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0005 Command 0x0000_0003 - CHIP:TOO: RemoveAllScenesResponse: { - CHIP:TOO: status: 0 - CHIP:TOO: groupID: 0 - CHIP:TOO: } + Verify the RemoveAllScenesResponse with following fields: + Status is SUCCESS + Group ID is 0x0000 on TH2(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1705915798.595482][21433:21435] CHIP:DMG: }, + [1705915798.595500][21433:21435] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0003 + [1705915798.595509][21433:21435] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0003 + [1705915798.595529][21433:21435] CHIP:TOO: RemoveAllScenesResponse: { + [1705915798.595534][21433:21435] CHIP:TOO: status: 0 + [1705915798.595537][21433:21435] CHIP:TOO: groupID: 0 + [1705915798.595540][21433:21435] CHIP:TOO: } disabled: true - label: @@ -429,51 +972,20 @@ tests: Remaining2ndCapacity; verify Remaining2ndCapacity equals (MaxRemainingCapacity). verification: | - CHIP:DMG: ReportDataMessage = - CHIP:DMG: { - CHIP:DMG: SubscriptionId = 0x7049d607, - CHIP:DMG: AttributeReportIBs = - CHIP:DMG: [ - CHIP:DMG: AttributeReportIB = - CHIP:DMG: { - CHIP:DMG: AttributeDataIB = - CHIP:DMG: { - CHIP:DMG: DataVersion = 0x92ecb45d, - CHIP:DMG: AttributePathIB = - CHIP:DMG: { - CHIP:DMG: Endpoint = 0x1, - CHIP:DMG: Cluster = 0x62, - CHIP:DMG: Attribute = 0x0000_0002, - CHIP:DMG: } - CHIP:DMG: - CHIP:DMG: Data = [ - CHIP:DMG: - CHIP:DMG: { - CHIP:DMG: 0x0 = 4, - CHIP:DMG: 0x1 = 4, - CHIP:DMG: 0x2 = 0, - CHIP:DMG: 0x3 = false, - CHIP:DMG: 0x4 = 3, - CHIP:DMG: 0xfe = 1, - CHIP:DMG: }, - CHIP:DMG: ], - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: }, - CHIP:DMG: - CHIP:DMG: ], - CHIP:DMG: - CHIP:DMG: InteractionModelRevision = 11 - CHIP:DMG: } - CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 2464986205 - CHIP:TOO: FabricSceneInfo: 1 entries - CHIP:TOO: [1]: { - CHIP:TOO: SceneCount: 4 - CHIP:TOO: CurrentScene: 4 - CHIP:TOO: CurrentGroup: 0 - CHIP:TOO: SceneValid: FALSE - CHIP:TOO: RemainingCapacity: 7 - CHIP:TOO: FabricIndex: 1 - CHIP:TOO: } - CHIP:DMG: Refresh LivenessCheckTime for 9224 milliseconds with SubscriptionId = 0x7049d607 Peer = 01:0000000000000001 + ./chip-tool scenesmanagement subscribe fabric-scene-info 100 200 2 1 --commissioner-name beta + + Verify that the DUT sends a report data to TH2 for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into Remaining2ndCapacity; verify Remaining2ndCapacity equals (MaxRemainingCapacity) on TH2(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1705915866.717469][21433:21435] CHIP:DMG: } + [1705915866.717543][21433:21435] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 2122634913 + [1705915866.717578][21433:21435] CHIP:TOO: FabricSceneInfo: 1 entries + [1705915866.717600][21433:21435] CHIP:TOO: [1]: { + [1705915866.717607][21433:21435] CHIP:TOO: SceneCount: 0 + [1705915866.717613][21433:21435] CHIP:TOO: CurrentScene: 0 + [1705915866.717619][21433:21435] CHIP:TOO: CurrentGroup: 0 + [1705915866.717624][21433:21435] CHIP:TOO: SceneValid: FALSE + [1705915866.717630][21433:21435] CHIP:TOO: RemainingCapacity: 7 + [1705915866.717635][21433:21435] CHIP:TOO: FabricIndex: 2 + [1705915866.717640][21433:21435] CHIP:TOO: } + disabled: true From 2696bc94657f13358e2205639575a532a8aec1d9 Mon Sep 17 00:00:00 2001 From: simonhmorris1 <112178216+simonhmorris1@users.noreply.github.com> Date: Wed, 14 Feb 2024 22:27:08 +0000 Subject: [PATCH 10/12] Non concurrent mode now sends connect network response as per spec (#31739) * Update Non-concurrent mode to latest spec (#31660) * Handle unused variable (#31660) * Restyled by clang-format * Trigger from BTP, use regular member (#31660) * Fix override (#31660) * Restyled by whitespace * Restyled by clang-format * Use generic OperationalNetworkStarted (#31660) * Replace variable with mState (#31660) Use mState instead of mTerminateOnPacketTxComplete * Sorted namespace out (#31660) * Restyled by clang-format * Address review comments (#31660)ffffffffffffffffffff Close GATT so that BlueZ will disconnect. Add kOperationalNetworkStarted event type * Restyled by clang-format * Access BleLayer mState through function (#31660) * Restyled by clang-format --------- Co-authored-by: Restyled.io --- .../network-commissioning.cpp | 62 +++++++++++++------ .../network-commissioning.h | 3 + src/app/server/CommissioningWindowManager.cpp | 4 +- src/ble/BLEEndPoint.cpp | 1 + src/ble/BleApplicationDelegate.h | 4 ++ src/ble/BleLayer.cpp | 5 ++ src/ble/BleLayer.h | 4 +- src/controller/CHIPDeviceController.cpp | 44 +------------ src/include/platform/CHIPDeviceEvent.h | 3 +- src/include/platform/DeviceControlServer.h | 1 + src/platform/DeviceControlServer.cpp | 7 +++ src/platform/Linux/BLEManagerImpl.cpp | 23 ++++++- src/platform/Linux/BLEManagerImpl.h | 1 + .../Linux/ConnectivityManagerImpl.cpp | 2 +- 14 files changed, 97 insertions(+), 67 deletions(-) diff --git a/src/app/clusters/network-commissioning/network-commissioning.cpp b/src/app/clusters/network-commissioning/network-commissioning.cpp index 6776897efce6fb..ffaff6bd49253a 100644 --- a/src/app/clusters/network-commissioning/network-commissioning.cpp +++ b/src/app/clusters/network-commissioning/network-commissioning.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -135,6 +136,26 @@ void Instance::Shutdown() mpBaseDriver->Shutdown(); } +#if !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION +void Instance::SendNonConcurrentConnectNetworkResponse() +{ + auto commandHandleRef = std::move(mAsyncCommandHandle); + auto commandHandle = commandHandleRef.Get(); + if (commandHandle == nullptr) + { + return; + } + +#if CONFIG_NETWORK_LAYER_BLE + DeviceLayer::ConnectivityMgr().GetBleLayer()->IndicateBleClosing(); +#endif // CONFIG_NETWORK_LAYER_BLE + ChipLogProgress(NetworkProvisioning, "Non-concurrent mode. Send ConnectNetworkResponse(Success)"); + Commands::ConnectNetworkResponse::Type response; + response.networkingStatus = NetworkCommissioning::Status::kSuccess; + commandHandle->AddResponse(mPath, response); +} +#endif // CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION + void Instance::InvokeCommand(HandlerContext & ctxt) { if (mAsyncCommandHandle.Get() != nullptr) @@ -177,12 +198,7 @@ void Instance::InvokeCommand(HandlerContext & ctxt) case Commands::ConnectNetwork::Id: { VerifyOrReturn(mFeatureFlags.Has(Feature::kWiFiNetworkInterface) || mFeatureFlags.Has(Feature::kThreadNetworkInterface)); -#if CONFIG_NETWORK_LAYER_BLE && !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION - // If commissionee does not support Concurrent Connections, request the BLE to be stopped. - // Start the ConnectNetwork, but this will not complete until the BLE is off. - ChipLogProgress(NetworkProvisioning, "Closing BLE connections due to non-concurrent mode"); - DeviceLayer::DeviceControlServer::DeviceControlSvr().PostCloseAllBLEConnectionsToOperationalNetworkEvent(); -#endif + HandleCommand( ctxt, [this](HandlerContext & ctx, const auto & req) { HandleConnectNetwork(ctx, req); }); return; @@ -708,18 +724,22 @@ void Instance::HandleConnectNetwork(HandlerContext & ctx, const Commands::Connec mAsyncCommandHandle = CommandHandler::Handle(&ctx.mCommandHandler); mCurrentOperationBreadcrumb = req.breadcrumb; - // In Non-concurrent mode postpone the final execution of ConnectNetwork until the operational - // network has been fully brought up and kWiFiDeviceAvailable is delivered. - // mConnectingNetworkIDLen and mConnectingNetworkID contains the received SSID #if CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION mpWirelessDriver->ConnectNetwork(req.networkID, this); +#else + // In Non-concurrent mode postpone the final execution of ConnectNetwork until the operational + // network has been fully brought up and kOperationalNetworkStarted is delivered. + // mConnectingNetworkIDLen and mConnectingNetworkID contain the received SSID + // As per spec, send the ConnectNetworkResponse(Success) prior to releasing the commissioning channel + SendNonConcurrentConnectNetworkResponse(); #endif } void Instance::HandleNonConcurrentConnectNetwork() { ByteSpan nonConcurrentNetworkID = ByteSpan(mConnectingNetworkID, mConnectingNetworkIDLen); - ChipLogProgress(NetworkProvisioning, "HandleNonConcurrentConnectNetwork() SSID=%s", mConnectingNetworkID); + ChipLogProgress(NetworkProvisioning, "Non-concurrent mode, Connect to Network SSID=%.*s", mConnectingNetworkIDLen, + mConnectingNetworkID); mpWirelessDriver->ConnectNetwork(nonConcurrentNetworkID, this); } @@ -826,13 +846,19 @@ void Instance::HandleQueryIdentity(HandlerContext & ctx, const Commands::QueryId void Instance::OnResult(Status commissioningError, CharSpan debugText, int32_t interfaceStatus) { auto commandHandleRef = std::move(mAsyncCommandHandle); - auto commandHandle = commandHandleRef.Get(); + + // In Non-concurrent mode the commandHandle will be null here, the ConnectNetworkResponse + // has already been sent and the BLE will have been stopped, however the other functionality + // is still required +#if CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION + auto commandHandle = commandHandleRef.Get(); if (commandHandle == nullptr) { // When the platform shutted down, interaction model engine will invalidate all commandHandle to avoid dangling references. // We may receive the callback after it and should make it noop. return; } +#endif // CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION Commands::ConnectNetworkResponse::Type response; response.networkingStatus = commissioningError; @@ -856,13 +882,10 @@ void Instance::OnResult(Status commissioningError, CharSpan debugText, int32_t i memcpy(mLastNetworkID, mConnectingNetworkID, mLastNetworkIDLen); mLastNetworkingStatusValue.SetNonNull(commissioningError); -#if CONFIG_NETWORK_LAYER_BLE && !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION - ChipLogProgress(NetworkProvisioning, "Non-concurrent mode, ConnectNetworkResponse will NOT be sent"); - // Do not send the ConnectNetworkResponse if in non-concurrent mode - // Issue #30576 raised to modify CommandHandler to notify it if no response required -#else +#if CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION commandHandle->AddResponse(mPath, response); -#endif +#endif // CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION + if (commissioningError == Status::kSuccess) { CommitSavedBreadcrumb(); @@ -1063,8 +1086,11 @@ void Instance::OnPlatformEventHandler(const DeviceLayer::ChipDeviceEvent * event { this_->OnFailSafeTimerExpired(); } - else if (event->Type == DeviceLayer::DeviceEventType::kWiFiDeviceAvailable) + else if ((event->Type == DeviceLayer::DeviceEventType::kWiFiDeviceAvailable) || + (event->Type == DeviceLayer::DeviceEventType::kOperationalNetworkStarted)) + { + // In Non-Concurrent mode connect the operational channel, as BLE has been stopped this_->HandleNonConcurrentConnectNetwork(); } } diff --git a/src/app/clusters/network-commissioning/network-commissioning.h b/src/app/clusters/network-commissioning/network-commissioning.h index 03fa72f6bfbd26..a286b7c79c4f3b 100644 --- a/src/app/clusters/network-commissioning/network-commissioning.h +++ b/src/app/clusters/network-commissioning/network-commissioning.h @@ -78,6 +78,9 @@ class Instance : public CommandHandlerInterface, void OnCommissioningComplete(); void OnFailSafeTimerExpired(); +#if !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION + void SendNonConcurrentConnectNetworkResponse(); +#endif const BitFlags mFeatureFlags; DeviceLayer::NetworkCommissioning::Internal::WirelessDriver * const mpWirelessDriver; diff --git a/src/app/server/CommissioningWindowManager.cpp b/src/app/server/CommissioningWindowManager.cpp index 01509a41a2acd0..c523564382904c 100644 --- a/src/app/server/CommissioningWindowManager.cpp +++ b/src/app/server/CommissioningWindowManager.cpp @@ -89,8 +89,8 @@ void CommissioningWindowManager::OnPlatformEvent(const DeviceLayer::ChipDeviceEv #if CONFIG_NETWORK_LAYER_BLE else if (event->Type == DeviceLayer::DeviceEventType::kCloseAllBleConnections) { - ChipLogProgress(AppServer, "Received kCloseAllBleConnections"); - mServer->GetBleLayerObject()->CloseAllBleConnections(); + ChipLogProgress(AppServer, "Received kCloseAllBleConnections:%d", static_cast(event->Type)); + mServer->GetBleLayerObject()->Shutdown(); } #endif } diff --git a/src/ble/BLEEndPoint.cpp b/src/ble/BLEEndPoint.cpp index 8d68c68ec0b0d8..63708af678efbd 100644 --- a/src/ble/BLEEndPoint.cpp +++ b/src/ble/BLEEndPoint.cpp @@ -1040,6 +1040,7 @@ CHIP_ERROR BLEEndPoint::DriveSending() else { // Nothing to send! + mBle->mApplicationDelegate->CheckNonConcurrentBleClosing(); } } diff --git a/src/ble/BleApplicationDelegate.h b/src/ble/BleApplicationDelegate.h index 542e46b64c4888..2584aeb6b908fd 100644 --- a/src/ble/BleApplicationDelegate.h +++ b/src/ble/BleApplicationDelegate.h @@ -42,6 +42,10 @@ class DLL_EXPORT BleApplicationDelegate // The application can use this callback to e.g. close the underlying BLE connection if it is no longer needed, // decrement the connection's refcount if it has one, or perform any other sort of cleanup as desired. virtual void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT connObj) = 0; + + // Called to determine whether the BLE connection should be closed when in Non-concurrent mode if sending + // ConnectNetworkResponse. The BTP will be in kState_Complete when all fragments have been sent. + virtual void CheckNonConcurrentBleClosing() {} }; } /* namespace Ble */ diff --git a/src/ble/BleLayer.cpp b/src/ble/BleLayer.cpp index 9109924ccd3754..eae49a0bfa8dd1 100644 --- a/src/ble/BleLayer.cpp +++ b/src/ble/BleLayer.cpp @@ -300,6 +300,11 @@ CHIP_ERROR BleLayer::Init(BlePlatformDelegate * platformDelegate, BleApplication return Init(platformDelegate, nullptr, appDelegate, systemLayer); } +void BleLayer::IndicateBleClosing() +{ + mState = kState_Disconnecting; +} + void BleLayer::Shutdown() { mState = kState_NotInitialized; diff --git a/src/ble/BleLayer.h b/src/ble/BleLayer.h index 5ded6c82cc2b46..f175334173ba7f 100644 --- a/src/ble/BleLayer.h +++ b/src/ble/BleLayer.h @@ -226,7 +226,8 @@ class DLL_EXPORT BleLayer enum { kState_NotInitialized = 0, - kState_Initialized = 1 + kState_Initialized = 1, + kState_Disconnecting = 2 } mState; ///< [READ-ONLY] Current state // This app state is not used by ble transport etc, it will be used by external ble implementation like Android @@ -243,6 +244,7 @@ class DLL_EXPORT BleLayer chip::System::Layer * systemLayer); CHIP_ERROR Init(BlePlatformDelegate * platformDelegate, BleConnectionDelegate * connDelegate, BleApplicationDelegate * appDelegate, chip::System::Layer * systemLayer); + void IndicateBleClosing(); void Shutdown(); CHIP_ERROR CancelBleIncompleteConnection(); diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 7cc2c86432f5f9..57c75cd0d813ae 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -1636,27 +1636,6 @@ void OnBasicFailure(void * context, CHIP_ERROR error) commissioner->CommissioningStageComplete(error); } -static void NonConcurrentTimeout(void * context, CHIP_ERROR error) -{ - if (error == CHIP_ERROR_TIMEOUT) - { - ChipLogProgress(Controller, "Non-concurrent mode: Expected NetworkResponse Timeout, do nothing"); - } - else - { - ChipLogProgress(Controller, "Non-concurrent mode: Received failure response %" CHIP_ERROR_FORMAT, error.Format()); - } -} - -static void NonConcurrentNetworkResponse(void * context, - const NetworkCommissioning::Commands::ConnectNetworkResponse::DecodableType & data) -{ - // In Non Concurrent mode the commissioning network should have been shut down and not sent the - // ConnectNetworkResponse. In case it does send it this handles the message - ChipLogError(Controller, "Non-concurrent Mode : Received Unexpected ConnectNetwork response, ignoring. Status=%u", - to_underlying(data.networkingStatus)); -} - void DeviceCommissioner::CleanupCommissioning(DeviceProxy * proxy, NodeId nodeId, const CompletionStatus & completionStatus) { commissioningCompletionStatus = completionStatus; @@ -3061,28 +3040,9 @@ void DeviceCommissioner::PerformCommissioningStep(DeviceProxy * proxy, Commissio request.breadcrumb.Emplace(breadcrumb); CHIP_ERROR err = CHIP_NO_ERROR; - GeneralCommissioning::Attributes::SupportsConcurrentConnection::TypeInfo::Type supportsConcurrentConnection; - supportsConcurrentConnection = params.GetSupportsConcurrentConnection().Value(); ChipLogProgress(Controller, "SendCommand kWiFiNetworkEnable, supportsConcurrentConnection=%d", - supportsConcurrentConnection); - if (supportsConcurrentConnection) - { - err = SendCommand(proxy, request, OnConnectNetworkResponse, OnBasicFailure, endpoint, timeout); - } - else - { - // Concurrent Connections not allowed. Send the ConnectNetwork command but do not wait for the - // ConnectNetworkResponse on the Commissioning network as it will not be present. Log the expected timeout - // and run what would have been in the onConnectNetworkResponse callback. - err = SendCommand(proxy, request, NonConcurrentNetworkResponse, NonConcurrentTimeout, endpoint, NullOptional); - if (err == CHIP_NO_ERROR) - { - // As there will be no ConnectNetworkResponse, it is an implicit kSuccess so a default report is fine - CommissioningDelegate::CommissioningReport report; - CommissioningStageComplete(CHIP_NO_ERROR, report); - return; - } - } + params.GetSupportsConcurrentConnection().Value()); + err = SendCommand(proxy, request, OnConnectNetworkResponse, OnBasicFailure, endpoint, timeout); if (err != CHIP_NO_ERROR) { diff --git a/src/include/platform/CHIPDeviceEvent.h b/src/include/platform/CHIPDeviceEvent.h index a7656fd6cba7fc..dae127ceba1f06 100644 --- a/src/include/platform/CHIPDeviceEvent.h +++ b/src/include/platform/CHIPDeviceEvent.h @@ -169,9 +169,10 @@ enum PublicEventTypes /** * When supportsConcurrentConnection = False, the ConnectNetwork command cannot start until - * the BLE device is closed and the WiFi device has been started. + * the BLE device is closed and the Operation Network device (e.g. WiFi) has been started. */ kWiFiDeviceAvailable, + kOperationalNetworkStarted, /** * Thread State Change diff --git a/src/include/platform/DeviceControlServer.h b/src/include/platform/DeviceControlServer.h index 073f6a035e95b0..2d292cfee261f4 100644 --- a/src/include/platform/DeviceControlServer.h +++ b/src/include/platform/DeviceControlServer.h @@ -38,6 +38,7 @@ class DeviceControlServer final CHIP_ERROR PostConnectedToOperationalNetworkEvent(ByteSpan networkID); CHIP_ERROR PostCloseAllBLEConnectionsToOperationalNetworkEvent(); CHIP_ERROR PostWiFiDeviceAvailableNetworkEvent(); + CHIP_ERROR PostOperationalNetworkStartedEvent(); static DeviceControlServer & DeviceControlSvr(); private: diff --git a/src/platform/DeviceControlServer.cpp b/src/platform/DeviceControlServer.cpp index 76008965498028..ec348669aec213 100644 --- a/src/platform/DeviceControlServer.cpp +++ b/src/platform/DeviceControlServer.cpp @@ -87,5 +87,12 @@ CHIP_ERROR DeviceControlServer::PostWiFiDeviceAvailableNetworkEvent() return PlatformMgr().PostEvent(&event); } +CHIP_ERROR DeviceControlServer::PostOperationalNetworkStartedEvent() +{ + ChipDeviceEvent event; + event.Type = DeviceEventType::kOperationalNetworkStarted; + return PlatformMgr().PostEvent(&event); +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Linux/BLEManagerImpl.cpp b/src/platform/Linux/BLEManagerImpl.cpp index 83cd939dc05f0d..d5129a983f092d 100644 --- a/src/platform/Linux/BLEManagerImpl.cpp +++ b/src/platform/Linux/BLEManagerImpl.cpp @@ -43,6 +43,10 @@ #include "bluez/BluezEndpoint.h" +#if !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION +#include +#endif + using namespace ::nl; using namespace ::chip::Ble; @@ -650,8 +654,23 @@ void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) { ChipLogProgress(Ble, "Got notification regarding chip connection closure"); #if CHIP_DEVICE_CONFIG_ENABLE_WPA && !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION - // In Non-Concurrent mode start the Wi-Fi, as BLE has been stopped - DeviceLayer::ConnectivityMgrImpl().StartNonConcurrentWiFiManagement(); + if (mState == kState_NotInitialized) + { + // Close BLE GATT connections to disconnect BlueZ + CloseConnection(conId); + // In Non-Concurrent mode start the Wi-Fi, as BLE has been stopped + DeviceLayer::ConnectivityMgrImpl().StartNonConcurrentWiFiManagement(); + } +#endif // CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION +} + +void BLEManagerImpl::CheckNonConcurrentBleClosing() +{ +#if CHIP_DEVICE_CONFIG_ENABLE_WPA && !CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION + if (mState == kState_Disconnecting) + { + DeviceLayer::DeviceControlServer::DeviceControlSvr().PostCloseAllBLEConnectionsToOperationalNetworkEvent(); + } #endif } diff --git a/src/platform/Linux/BLEManagerImpl.h b/src/platform/Linux/BLEManagerImpl.h index 1441f2e6573573..61d2dff02757c7 100644 --- a/src/platform/Linux/BLEManagerImpl.h +++ b/src/platform/Linux/BLEManagerImpl.h @@ -133,6 +133,7 @@ class BLEManagerImpl final : public BLEManager, // ===== Members that implement virtual methods on BleApplicationDelegate. void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override; + void CheckNonConcurrentBleClosing() override; // ===== Members that implement virtual methods on BleConnectionDelegate. diff --git a/src/platform/Linux/ConnectivityManagerImpl.cpp b/src/platform/Linux/ConnectivityManagerImpl.cpp index a2566d20f35560..d03cefef4f0ef7 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.cpp +++ b/src/platform/Linux/ConnectivityManagerImpl.cpp @@ -774,7 +774,7 @@ void ConnectivityManagerImpl::StartNonConcurrentWiFiManagement() { if (IsWiFiManagementStarted()) { - DeviceControlServer::DeviceControlSvr().PostWiFiDeviceAvailableNetworkEvent(); + DeviceControlServer::DeviceControlSvr().PostOperationalNetworkStartedEvent(); ChipLogProgress(DeviceLayer, "Non-concurrent mode Wi-Fi Management Started."); return; } From 2619da7cf2d9822c8612d624bdd3098c36f36613 Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Wed, 14 Feb 2024 17:38:46 -0500 Subject: [PATCH 11/12] [Scenes] MaxCapacity fix (#31981) * Added refresh on read to the FabricSceneInfo capacity and patched Resource Exhausted for Copy Scene and Store Scene along with tests * Applied suggested fix on ReturnOnFailure and /* = name*/ --- .../clusters/scenes-server/scenes-server.cpp | 49 +- .../tests/suites/TestScenesMaxCapacity.yaml | 890 ++++++++++++++++++ src/app/tests/suites/ciTests.json | 1 + 3 files changed, 920 insertions(+), 20 deletions(-) create mode 100644 src/app/tests/suites/TestScenesMaxCapacity.yaml diff --git a/src/app/clusters/scenes-server/scenes-server.cpp b/src/app/clusters/scenes-server/scenes-server.cpp index fc0c656d17fffd..d05d7da84f9a53 100644 --- a/src/app/clusters/scenes-server/scenes-server.cpp +++ b/src/app/clusters/scenes-server/scenes-server.cpp @@ -66,6 +66,10 @@ CHIP_ERROR AddResponseOnError(CommandHandlerInterface::HandlerContext & ctx, Res { resp.status = to_underlying(Protocols::InteractionModel::Status::NotFound); } + else if (CHIP_ERROR_NO_MEMORY == err) + { + resp.status = to_underlying(Protocols::InteractionModel::Status::ResourceExhausted); + } else { resp.status = to_underlying(StatusIB(err).mStatus); @@ -168,7 +172,6 @@ CHIP_ERROR UpdateFabricSceneInfo(EndpointId endpoint, FabricIndex fabric, Option /// @brief Gets the SceneInfoStruct array associated to an endpoint /// @param endpoint target endpoint -/// @param fabric target fabric /// @return Optional with no value not found, Span of SceneInfoStruct Span ScenesServer::FabricSceneInfo::GetFabricSceneInfo(EndpointId endpoint) { @@ -675,13 +678,21 @@ void ScenesServer::InvokeCommand(HandlerContext & ctxt) // AttributeAccessInterface CHIP_ERROR ScenesServer::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) { + uint16_t endpointTableSize = 0; + ReturnErrorOnFailure(StatusIB(Attributes::SceneTableSize::Get(aPath.mEndpointId, &endpointTableSize)).ToChipError()); + + // Get Scene Table Instance + SceneTable * sceneTable = scenes::GetSceneTableImpl(aPath.mEndpointId, endpointTableSize); + switch (aPath.mAttributeId) { case Attributes::FabricSceneInfo::Id: { - return aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR { + return aEncoder.EncodeList([&, sceneTable](const auto & encoder) -> CHIP_ERROR { Span fabricSceneInfoSpan = mFabricSceneInfo.GetFabricSceneInfo(aPath.mEndpointId); for (auto & info : fabricSceneInfoSpan) { + // Update the SceneInfoStruct's Capacity in case it's capacity was limited by other fabrics + sceneTable->GetRemainingCapacity(info.fabricIndex, info.remainingCapacity); ReturnErrorOnFailure(encoder.Encode(info)); } return CHIP_NO_ERROR; @@ -918,12 +929,10 @@ void ScenesServer::HandleStoreScene(HandlerContext & ctx, const Commands::StoreS CHIP_ERROR err = StoreSceneParse(ctx.mCommandHandler.GetAccessingFabricIndex(), ctx.mRequestPath.mEndpointId, req.groupID, req.sceneID, mGroupProvider); - if (CHIP_NO_ERROR == err) - { - ReturnOnFailure(UpdateLastConfiguredBy(ctx, response)); - } + ReturnOnFailure(AddResponseOnError(ctx, response, err)); - response.status = to_underlying(StatusIB(err).mStatus); + ReturnOnFailure(UpdateLastConfiguredBy(ctx, response)); + response.status = to_underlying(Protocols::InteractionModel::Status::Success); ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); } @@ -1031,6 +1040,13 @@ void ScenesServer::HandleCopyScene(HandlerContext & ctx, const Commands::CopySce ReturnOnFailure(AddResponseOnError(ctx, response, sceneTable->GetRemainingCapacity(ctx.mCommandHandler.GetAccessingFabricIndex(), capacity))); + if (0 == capacity) + { + response.status = to_underlying(Protocols::InteractionModel::Status::ResourceExhausted); + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + return; + } + // Checks if we copy a single scene or all of them if (req.mode.GetField(app::Clusters::ScenesManagement::CopyModeBitmap::kCopyAllScenes)) { @@ -1043,13 +1059,6 @@ void ScenesServer::HandleCopyScene(HandlerContext & ctx, const Commands::CopySce ctx, response, sceneTable->GetAllSceneIdsInGroup(ctx.mCommandHandler.GetAccessingFabricIndex(), req.groupIdentifierFrom, sceneList))); - if (0 == capacity) - { - response.status = to_underlying(Protocols::InteractionModel::Status::ResourceExhausted); - ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); - return; - } - for (auto & sceneId : sceneList) { SceneTableEntry scene(SceneStorageId(sceneId, req.groupIdentifierFrom)); @@ -1062,13 +1071,13 @@ void ScenesServer::HandleCopyScene(HandlerContext & ctx, const Commands::CopySce ReturnOnFailure(AddResponseOnError( ctx, response, sceneTable->SetSceneTableEntry(ctx.mCommandHandler.GetAccessingFabricIndex(), scene))); - } - // Update SceneInfoStruct Attributes - ReturnOnFailure( - AddResponseOnError(ctx, response, - UpdateFabricSceneInfo(ctx.mRequestPath.mEndpointId, ctx.mCommandHandler.GetAccessingFabricIndex(), - Optional(), Optional(), Optional()))); + // Update SceneInfoStruct Attributes after each insert in case we hit max capacity in the middle of the loop + ReturnOnFailure(AddResponseOnError( + ctx, response, + UpdateFabricSceneInfo(ctx.mRequestPath.mEndpointId, ctx.mCommandHandler.GetAccessingFabricIndex(), + Optional(), Optional(), Optional() /* = sceneValid*/))); + } ReturnOnFailure(UpdateLastConfiguredBy(ctx, response)); diff --git a/src/app/tests/suites/TestScenesMaxCapacity.yaml b/src/app/tests/suites/TestScenesMaxCapacity.yaml new file mode 100644 index 00000000000000..b9ec7593237812 --- /dev/null +++ b/src/app/tests/suites/TestScenesMaxCapacity.yaml @@ -0,0 +1,890 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# !!!!!!!!!! TEST INFORMATION !!!!!!!!!!!!!!!!!! +# This test covers multi fabric support for scenes cluster attributes such as LastConfiguredBy and FabricSceneInfo + +name: Scenes Multi-fabric testing + +PICS: + - MCORE.ROLE.COMMISSIONEE + - APPDEVICE.S + +config: + nodeId: 0x12344321 + cluster: "Scenes Management" + endpoint: 1 + payload: + type: char_string + defaultValue: "MT:-24J0AFN00KA0648G00" + discriminator: + type: int16u + defaultValue: 3840 + waitAfterCommissioning: + type: int16u + defaultValue: 5000 + PakeVerifier: + type: octet_string + defaultValue: "hex:b96170aae803346884724fe9a3b287c30330c2a660375d17bb205a8cf1aecb350457f8ab79ee253ab6a8e46bb09e543ae422736de501e3db37d441fe344920d09548e4c18240630c4ff4913c53513839b7c07fcc0627a1b8573a149fcd1fa466cf" + G1: + type: group_id + defaultValue: 0x0001 + G2: + type: group_id + defaultValue: 0x0002 + +tests: + - label: "Commission DUT to TH1" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "TH1 reads the fabric index" + cluster: "Operational Credentials" + endpoint: 0 + command: "readAttribute" + attribute: "CurrentFabricIndex" + response: + saveAs: th1FabricIndex + + - label: "Read the commissioner node ID from the alpha fabric" + identity: "alpha" + endpoint: 0 + cluster: "CommissionerCommands" + command: "GetCommissionerNodeId" + response: + values: + - name: "nodeId" + saveAs: commissionerNodeIdAlpha + + - label: "Open Commissioning Window from alpha" + endpoint: 0 + cluster: "Administrator Commissioning" + command: "OpenCommissioningWindow" + timedInteractionTimeoutMs: 10000 + arguments: + values: + - name: "CommissioningTimeout" + value: 180 + - name: "PAKEPasscodeVerifier" + value: PakeVerifier + - name: "Discriminator" + value: discriminator + - name: "Iterations" + value: 1000 + - name: "Salt" + value: "SPAKE2P Key Salt" + + - label: "Waiting after opening commissioning window" + cluster: "DelayCommands" + command: "WaitForMs" + arguments: + values: + - name: "ms" + value: waitAfterCommissioning + + - label: "Commission from TH2" + identity: "beta" + endpoint: 0 + cluster: "CommissionerCommands" + command: "PairWithCode" + arguments: + values: + - name: "nodeId" + value: nodeId + - name: "payload" + value: payload + + - label: "Wait for the commissioned device to be retrieved for TH2" + endpoint: 0 + identity: beta + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "TH2 reads the fabric index" + identity: "beta" + endpoint: 0 + cluster: "Operational Credentials" + command: "readAttribute" + attribute: "CurrentFabricIndex" + response: + saveAs: th2FabricIndex + + - label: "Read the commissioner node ID from the beta fabric" + identity: "beta" + endpoint: 0 + cluster: "CommissionerCommands" + command: "GetCommissionerNodeId" + response: + values: + - name: "nodeId" + saveAs: commissionerNodeIdBeta + + - label: "Open Commissioning Window from alpha" + endpoint: 0 + cluster: "Administrator Commissioning" + command: "OpenCommissioningWindow" + timedInteractionTimeoutMs: 10000 + arguments: + values: + - name: "CommissioningTimeout" + value: 180 + - name: "PAKEPasscodeVerifier" + value: PakeVerifier + - name: "Discriminator" + value: discriminator + - name: "Iterations" + value: 1000 + - name: "Salt" + value: "SPAKE2P Key Salt" + + - label: "Waiting after opening commissioning window" + cluster: "DelayCommands" + command: "WaitForMs" + arguments: + values: + - name: "ms" + value: waitAfterCommissioning + + - label: "Commission from TH3" + identity: "gamma" + endpoint: 0 + cluster: "CommissionerCommands" + command: "PairWithCode" + arguments: + values: + - name: "nodeId" + value: nodeId + - name: "payload" + value: payload + + - label: "Wait for the commissioned device to be retrieved for TH3" + endpoint: 0 + identity: gamma + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "TH3 reads the fabric index" + identity: "gamma" + endpoint: 0 + cluster: "Operational Credentials" + command: "readAttribute" + attribute: "CurrentFabricIndex" + response: + saveAs: th3FabricIndex + + - label: "Read the commissioner node ID from the gamma fabric" + identity: "gamma" + endpoint: 0 + cluster: "CommissionerCommands" + command: "GetCommissionerNodeId" + response: + values: + - name: "nodeId" + saveAs: commissionerNodeIdBeta + + - label: "Read the FabricSceneInfo attribute (0x0007) " + command: "readAttribute" + attribute: "FabricSceneInfo" + response: + constraints: + type: list + + - label: "TH reads from the DUT the (0x0006) SceneTableSize attribute" + command: "readAttribute" + attribute: "SceneTableSize" + response: + values: + - name: "SceneTableSize" + saveAs: maxScenes + + - label: "Arithmetic operation to get the maxScenes - 1" + cluster: "Unit Testing" + command: "TestAddArguments" + arguments: + values: + - name: "arg1" + value: maxScenes - 1 + - name: "arg2" + value: 0 + response: + values: + - name: "returnValue" + saveAs: maxScenesMinusOne + value: maxScenes - 1 + + - label: "Arithmetic operation to get the fabric Capacity" + cluster: "Unit Testing" + command: "TestAddArguments" + arguments: + values: + - name: "arg1" + value: maxScenesMinusOne / 2 + - name: "arg2" + value: 0 + response: + values: + - name: "returnValue" + saveAs: fabricCapacity + value: maxScenesMinusOne / 2 + + - label: "Preparation step : TH 1 Add Group KeySet." + cluster: "Group Key Management" + endpoint: 0 + command: "KeySetWrite" + arguments: + values: + - name: "GroupKeySet" + value: + { + GroupKeySetID: 0x01a1, + GroupKeySecurityPolicy: 0, + EpochKey0: "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", + EpochStartTime0: 1110000, + EpochKey1: "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", + EpochStartTime1: 1110001, + EpochKey2: "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", + EpochStartTime2: 1110002, + } + + - label: "Preparation step TH1 Map KeySets to GroupId." + cluster: "Group Key Management" + endpoint: 0 + command: "writeAttribute" + attribute: "GroupKeyMap" + arguments: + value: + [ + { FabricIndex: 0, GroupId: G1, GroupKeySetID: 0x01a1 }, + { FabricIndex: 0, GroupId: G2, GroupKeySetID: 0x01a1 }, + ] + + - label: "TH1 sends a RemoveAllGroups command to DUT." + cluster: "Groups" + command: "RemoveAllGroups" + + - label: "TH1 sends a AddGroup command to DUT for G1." + cluster: "Groups" + command: "AddGroup" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "GroupName" + value: "Group1" + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + + - label: "TH1 sends a AddGroup command to DUT for G2." + cluster: "Groups" + command: "AddGroup" + arguments: + values: + - name: "GroupID" + value: G2 + - name: "GroupName" + value: "Group2" + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G2 + + - label: "Preparation step : TH 2 Add Group KeySet." + identity: "beta" + cluster: "Group Key Management" + endpoint: 0 + command: "KeySetWrite" + arguments: + values: + - name: "GroupKeySet" + value: + { + GroupKeySetID: 0x01a2, + GroupKeySecurityPolicy: 0, + EpochKey0: "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", + EpochStartTime0: 1120000, + EpochKey1: "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", + EpochStartTime1: 1120001, + EpochKey2: "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", + EpochStartTime2: 1120002, + } + + - label: "Preparation step TH2 Map KeySets to GroupId." + identity: "beta" + cluster: "Group Key Management" + endpoint: 0 + command: "writeAttribute" + attribute: "GroupKeyMap" + arguments: + value: + [ + { FabricIndex: 0, GroupId: G1, GroupKeySetID: 0x01a2 }, + { FabricIndex: 0, GroupId: G2, GroupKeySetID: 0x01a2 }, + ] + + - label: "TH2 sends a AddGroup command to DUT for G1." + identity: "beta" + cluster: "Groups" + command: "AddGroup" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "GroupName" + value: "Group1" + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + + - label: "TH2 sends a AddGroup command to DUT for G2." + identity: "beta" + cluster: "Groups" + command: "AddGroup" + arguments: + values: + - name: "GroupID" + value: G2 + - name: "GroupName" + value: "Group1" + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G2 + + - label: "TH2 confirms the Fabric Capacity is Maximum" + command: "GetSceneMembership" + identity: "beta" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "Capacity" + value: fabricCapacity + - name: "GroupID" + value: G1 + + - label: "Preparation step : TH 3 Add Group KeySet." + identity: "gamma" + cluster: "Group Key Management" + endpoint: 0 + command: "KeySetWrite" + arguments: + values: + - name: "GroupKeySet" + value: + { + GroupKeySetID: 0x01a2, + GroupKeySecurityPolicy: 0, + EpochKey0: "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", + EpochStartTime0: 1120000, + EpochKey1: "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", + EpochStartTime1: 1120001, + EpochKey2: "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", + EpochStartTime2: 1120002, + } + + - label: "Preparation step TH3 Map KeySets to GroupId." + identity: "gamma" + cluster: "Group Key Management" + endpoint: 0 + command: "writeAttribute" + attribute: "GroupKeyMap" + arguments: + value: [{ FabricIndex: 0, GroupId: G1, GroupKeySetID: 0x01a2 }] + + - label: "TH3 sends a AddGroup command to DUT for G1." + identity: "gamma" + cluster: "Groups" + command: "AddGroup" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "GroupName" + value: "Group1" + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + + - label: "TH3 confirms the Fabric Capacity is Maximum" + command: "GetSceneMembership" + identity: "gamma" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "Capacity" + value: fabricCapacity + - name: "GroupID" + value: G1 + + - label: "TH1 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0001 + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0001 + + - label: "TH2 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + identity: "beta" + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0001 + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0001 + + - label: "TH3 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + identity: "gamma" + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0001 + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0001 + + - label: "TH1 confirms the Fabric Capacity is 0" + command: "GetSceneMembership" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "Capacity" + value: fabricCapacity - 1 + - name: "GroupID" + value: G1 + + - label: "TH2 confirms the Fabric Capacity is 7" + command: "GetSceneMembership" + identity: "beta" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "Capacity" + value: fabricCapacity - 1 + - name: "GroupID" + value: G1 + + - label: "TH2 confirms the Fabric Capacity is 7" + command: "GetSceneMembership" + identity: "beta" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "Capacity" + value: fabricCapacity - 1 + - name: "GroupID" + value: G1 + + # Now we fill TH1 + - label: "TH1 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0002 + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0002 + + - label: "TH1 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0003 + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0003 + + - label: "TH1 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0004 + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0004 + + - label: "TH1 copies Scenes from G1 to G2" + command: "CopyScene" + arguments: + values: + - name: "Mode" + value: 0x01 + - name: "GroupIdentifierFrom" + value: G1 + - name: "SceneIdentifierFrom" + value: 0x01 + - name: "GroupIdentifierTo" + value: G2 + - name: "SceneIdentifierTo" + value: 0x02 + response: + values: + - name: "Status" + value: 0x89 + - name: "GroupIdentifierFrom" + value: G1 + - name: "SceneIdentifierFrom" + value: 0x01 + + - label: "TH1 Read the FabricSceneInfo attribute (0x0002) " + command: "readAttribute" + attribute: "FabricSceneInfo" + response: + value: + [ + { + SceneCount: 7, + CurrentScene: 0x04, + CurrentGroup: 0x0001, + FabricIndex: th1FabricIndex, + SceneValid: true, + RemainingCapacity: fabricCapacity - 7, + }, + ] + + - label: "TH2 Read the FabricSceneInfo attribute (0x0002) " + identity: "beta" + command: "readAttribute" + attribute: "FabricSceneInfo" + response: + value: + [ + { + SceneCount: 1, + CurrentScene: 0x01, + CurrentGroup: 0x01, + FabricIndex: th2FabricIndex, + SceneValid: true, + RemainingCapacity: fabricCapacity - 1, + }, + ] + + - label: "TH3 Read the FabricSceneInfo attribute (0x0002) " + identity: "gamma" + command: "readAttribute" + attribute: "FabricSceneInfo" + response: + value: + [ + { + SceneCount: 1, + CurrentScene: 0x01, + CurrentGroup: 0x01, + FabricIndex: th3FabricIndex, + SceneValid: true, + RemainingCapacity: fabricCapacity - 1, + }, + ] + + # Now we fill TH2 + - label: "TH2 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + identity: "beta" + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0002 + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0002 + + - label: "TH2 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + identity: "beta" + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0003 + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0003 + + - label: "TH2 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + command: "StoreScene" + identity: "beta" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0004 + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0004 + + - label: "TH2 copies Scenes from G1 to G2" + cluster: "Scenes Management" + identity: "beta" + command: "CopyScene" + arguments: + values: + - name: "Mode" + value: 0x01 + - name: "GroupIdentifierFrom" + value: G1 + - name: "SceneIdentifierFrom" + value: 0x01 + - name: "GroupIdentifierTo" + value: G2 + - name: "SceneIdentifierTo" + value: 0x02 + response: + values: + - name: "Status" + value: 0x89 + - name: "GroupIdentifierFrom" + value: G1 + - name: "SceneIdentifierFrom" + value: 0x01 + + - label: "TH1 Read the FabricSceneInfo attribute (0x0002) " + command: "readAttribute" + attribute: "FabricSceneInfo" + response: + value: + [ + { + SceneCount: 7, + CurrentScene: 0x04, + CurrentGroup: 0x0001, + FabricIndex: th1FabricIndex, + SceneValid: true, + RemainingCapacity: fabricCapacity - 7, + }, + ] + + - label: "TH2 Read the FabricSceneInfo attribute (0x0002) " + identity: "beta" + command: "readAttribute" + attribute: "FabricSceneInfo" + response: + value: + [ + { + SceneCount: 7, + CurrentScene: 0x04, + CurrentGroup: 0x0001, + FabricIndex: th2FabricIndex, + SceneValid: true, + RemainingCapacity: fabricCapacity - 7, + }, + ] + + - label: "TH3 Read the FabricSceneInfo attribute (0x0002) " + identity: "gamma" + command: "readAttribute" + attribute: "FabricSceneInfo" + response: + value: + [ + { + SceneCount: 1, + CurrentScene: 0x01, + CurrentGroup: 0x01, + FabricIndex: th3FabricIndex, + SceneValid: true, + RemainingCapacity: fabricCapacity - 6, + }, + ] + + - label: "TH3 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + identity: "gamma" + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0002 + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0002 + + - label: "TH3 sends a StoreScene command to DUT for G1." + cluster: "Scenes Management" + identity: "gamma" + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0003 + response: + values: + - name: "Status" + value: 0x89 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x0003 + + - label: "TH3 copies Scene 0x01 from G1 to 0x02 in G1" + cluster: "Scenes Management" + identity: "beta" + command: "CopyScene" + arguments: + values: + - name: "Mode" + value: 0x00 + - name: "GroupIdentifierFrom" + value: G1 + - name: "SceneIdentifierFrom" + value: 0x01 + - name: "GroupIdentifierTo" + value: G1 + - name: "SceneIdentifierTo" + value: 0x04 + response: + values: + - name: "Status" + value: 0x89 + - name: "GroupIdentifierFrom" + value: G1 + - name: "SceneIdentifierFrom" + value: 0x01 diff --git a/src/app/tests/suites/ciTests.json b/src/app/tests/suites/ciTests.json index cbd655299f8422..8c17e1876c36ec 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -339,6 +339,7 @@ "TestScenesFabricRemoval", "TestScenesFabricSceneInfo", "TestScenesMultiFabric", + "TestScenesMaxCapacity", "Test_TC_S_1_1", "Test_TC_S_2_1", "Test_TC_S_2_2", From 274719d61fba791632a0c8f710e158ac3c3e22fd Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 14 Feb 2024 18:40:56 -0500 Subject: [PATCH 12/12] Remove PoolCommon::ResetObject (#32120) * Remove PoolCommon: bad name, non-member method, very very limited usage * Restyle * Added comment about returning null on failure * Fix compile on fixed size pools * Restyle * Switch to not use a cast * Fix types ... use auto because types are messy, unsure why * Rename for smaller diff * Rename for smaller diff * Update src/transport/UnauthenticatedSessionTable.h Co-authored-by: Boris Zbarsky --------- Co-authored-by: Boris Zbarsky --- src/lib/support/Pool.h | 16 ++-------------- src/lib/support/PoolWrapper.h | 12 +++--------- src/transport/UnauthenticatedSessionTable.h | 17 +++++++++++++---- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/lib/support/Pool.h b/src/lib/support/Pool.h index c2486f0c0e20b3..a3959fd1e868f9 100644 --- a/src/lib/support/Pool.h +++ b/src/lib/support/Pool.h @@ -104,18 +104,6 @@ class StaticAllocatorBitmap : public internal::StaticAllocatorBase std::atomic * mUsage; }; -template -class PoolCommon -{ -public: - template - void ResetObject(T * element, Args &&... args) - { - element->~T(); - new (element) T(std::forward(args)...); - } -}; - template class LambdaProxy { @@ -211,7 +199,7 @@ struct HeapObjectList : HeapObjectListNode * @tparam N a positive integer max number of elements the pool provides. */ template -class BitMapObjectPool : public internal::StaticAllocatorBitmap, public internal::PoolCommon +class BitMapObjectPool : public internal::StaticAllocatorBitmap { public: BitMapObjectPool() : StaticAllocatorBitmap(mData.mMemory, mUsage, N, sizeof(T)) {} @@ -314,7 +302,7 @@ class HeapObjectPoolExitHandling * @tparam T type to be allocated. */ template -class HeapObjectPool : public internal::Statistics, public internal::PoolCommon, public HeapObjectPoolExitHandling +class HeapObjectPool : public internal::Statistics, public HeapObjectPoolExitHandling { public: HeapObjectPool() {} diff --git a/src/lib/support/PoolWrapper.h b/src/lib/support/PoolWrapper.h index 78b6d838245633..fd9972429d9661 100644 --- a/src/lib/support/PoolWrapper.h +++ b/src/lib/support/PoolWrapper.h @@ -33,10 +33,9 @@ class PoolInterface virtual ~PoolInterface() {} - virtual U * CreateObject(ConstructorArguments... args) = 0; - virtual void ReleaseObject(U * element) = 0; - virtual void ReleaseAll() = 0; - virtual void ResetObject(U * element, ConstructorArguments... args) = 0; + virtual U * CreateObject(ConstructorArguments... args) = 0; + virtual void ReleaseObject(U * element) = 0; + virtual void ReleaseAll() = 0; template Loop ForEachActiveObject(Function && function) @@ -82,11 +81,6 @@ class PoolProxy> : public PoolIn void ReleaseAll() override { Impl().ReleaseAll(); } - void ResetObject(U * element, ConstructorArguments... args) override - { - return Impl().ResetObject(static_cast(element), std::move(args)...); - } - protected: Loop ForEachActiveObjectInner(void * context, typename PoolInterface::Lambda lambda) override { diff --git a/src/transport/UnauthenticatedSessionTable.h b/src/transport/UnauthenticatedSessionTable.h index 48e2025d10a487..f5ba35df533de5 100644 --- a/src/transport/UnauthenticatedSessionTable.h +++ b/src/transport/UnauthenticatedSessionTable.h @@ -285,17 +285,26 @@ class UnauthenticatedSessionTable return CHIP_NO_ERROR; } -#if !CHIP_SYSTEM_CONFIG_POOL_USE_HEAP +#if CHIP_SYSTEM_CONFIG_POOL_USE_HEAP + // permanent failure if heap was insufficient + return CHIP_ERROR_NO_MEMORY; +#else entryToUse = FindLeastRecentUsedEntry(); -#endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP + VerifyOrReturnError(entryToUse != nullptr, CHIP_ERROR_NO_MEMORY); + + // Drop the least recent entry to allow for a new alloc. + mEntries.ReleaseObject(entryToUse); + entryToUse = mEntries.CreateObject(sessionRole, ephemeralInitiatorNodeID, config, *this); + if (entryToUse == nullptr) { - return CHIP_ERROR_NO_MEMORY; + // this is NOT expected: we freed an object to have space + return CHIP_ERROR_INTERNAL; } - mEntries.ResetObject(entryToUse, sessionRole, ephemeralInitiatorNodeID, config, *this); entry = entryToUse; return CHIP_NO_ERROR; +#endif // CHIP_SYSTEM_CONFIG_POOL_USE_HEAP } CHECK_RETURN_VALUE UnauthenticatedSession * FindEntry(UnauthenticatedSession::SessionRole sessionRole,