From d9bcdd3f986c9905c3d78d91f9d09179c75a48a3 Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Mon, 29 Jul 2024 10:23:09 -0400 Subject: [PATCH] =?UTF-8?q?[ColorControl]Add=20Quiet=20reporting=20to=20th?= =?UTF-8?q?e=20CurrentHue,=20CurrentSaturation,=20EnhancedCur=E2=80=A6=20?= =?UTF-8?q?=20=20=20(#34544)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * WIP * Add Quiet reporting to the CurrentHue, CurrentSaturation, EnhancedCurrentHue, CurrentX, CurrentY and RemainingTime attributes of the colorcontrol cluster server implementation * Add a constructor in QuieterReporting that works with arrays * address comment --- .../QuieterReporting.h | 2 + .../color-control-server.cpp | 344 +++++++++++++----- .../color-control-server.h | 40 +- 3 files changed, 303 insertions(+), 83 deletions(-) diff --git a/src/app/cluster-building-blocks/QuieterReporting.h b/src/app/cluster-building-blocks/QuieterReporting.h index bf6b4fe36346d2..e64d56cd2b1c72 100644 --- a/src/app/cluster-building-blocks/QuieterReporting.h +++ b/src/app/cluster-building-blocks/QuieterReporting.h @@ -112,6 +112,8 @@ class QuieterReportingAttribute { public: explicit QuieterReportingAttribute(const Nullable & initialValue) : mValue(initialValue), mLastDirtyValue(initialValue) {} + // constructor that works with arrays of QuieterReportingAttribute + explicit QuieterReportingAttribute() : mValue(DataModel::NullNullable), mLastDirtyValue(DataModel::NullNullable) {} struct SufficientChangePredicateCandidate { diff --git a/src/app/clusters/color-control-server/color-control-server.cpp b/src/app/clusters/color-control-server/color-control-server.cpp index 55c8cd9e7a77de..c4de9f9d9461ef 100644 --- a/src/app/clusters/color-control-server/color-control-server.cpp +++ b/src/app/clusters/color-control-server/color-control-server.cpp @@ -30,6 +30,7 @@ #endif using namespace chip; +using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::ColorControl; using chip::Protocols::InteractionModel::Status; @@ -204,22 +205,24 @@ class DefaultColorControlSceneHandler : public scenes::DefaultSceneHandlerImpl // The color control cluster should have a maximum of 9 scenable attributes ReturnErrorOnFailure(attributeValueList.ComputeSize(&attributeCount)); VerifyOrReturnError(attributeCount <= kColorControlScenableAttributesCount, CHIP_ERROR_BUFFER_TOO_SMALL); + + uint16_t epIndex = ColorControlServer::Instance().getEndpointIndex(endpoint); // Retrieve the buffers for different modes #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_HSV ColorControlServer::ColorHueTransitionState * colorHueTransitionState = - ColorControlServer::Instance().getColorHueTransitionState(endpoint); + ColorControlServer::Instance().getColorHueTransitionStateByIndex(epIndex); ColorControlServer::Color16uTransitionState * colorSaturationTransitionState = - ColorControlServer::Instance().getSaturationTransitionState(endpoint); + ColorControlServer::Instance().getSaturationTransitionStateByIndex(epIndex); #endif #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_XY ColorControlServer::Color16uTransitionState * colorXTransitionState = - ColorControlServer::Instance().getXTransitionState(endpoint); + ColorControlServer::Instance().getXTransitionStateByIndex(epIndex); ColorControlServer::Color16uTransitionState * colorYTransitionState = - ColorControlServer::Instance().getYTransitionState(endpoint); + ColorControlServer::Instance().getYTransitionStateByIndex(epIndex); #endif #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP ColorControlServer::Color16uTransitionState * colorTempTransitionState = - ColorControlServer::Instance().getTempTransitionState(endpoint); + ColorControlServer::Instance().getTempTransitionStateByIndex(epIndex); #endif // Initialize action attributes to default values in case they are not in the scene @@ -456,6 +459,11 @@ ColorControlServer & ColorControlServer::Instance() return instance; } +uint16_t ColorControlServer::getEndpointIndex(EndpointId endpoint) +{ + return emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); +} + #ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT chip::scenes::SceneHandler * ColorControlServer::GetSceneHandler() { @@ -513,8 +521,9 @@ bool ColorControlServer::stopMoveStepCommand(app::CommandHandler * commandObj, c // Init both transition states on stop command to prevent that. if (status == Status::Success) { - ColorHueTransitionState * hueState = getColorHueTransitionState(endpoint); - Color16uTransitionState * saturationState = getSaturationTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + ColorHueTransitionState * hueState = getColorHueTransitionStateByIndex(epIndex); + Color16uTransitionState * saturationState = getSaturationTransitionStateByIndex(epIndex); initHueTransitionState(endpoint, hueState, false /*isEnhancedHue don't care*/); initSaturationTransitionState(endpoint, saturationState); } @@ -702,8 +711,7 @@ uint16_t ColorControlServer::computeTransitionTimeFromStateAndRate(ColorControlS */ EmberEventControl * ColorControlServer::getEventControl(EndpointId endpoint) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); + uint16_t index = getEndpointIndex(endpoint); EmberEventControl * event = nullptr; if (index < ArraySize(eventControls)) @@ -825,15 +833,13 @@ bool ColorControlServer::computeNewColor16uValue(ColorControlServer::Color16uTra #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_HSV /** - * @brief Returns ColorHueTransititionState associated to an endpoint + * @brief Returns ColorHueTransititionState associated to an endpoint index * * @param[in] endpoint * @return ColorControlServer::ColorHueTransitionState* */ -ColorControlServer::ColorHueTransitionState * ColorControlServer::getColorHueTransitionState(EndpointId endpoint) +ColorControlServer::ColorHueTransitionState * ColorControlServer::getColorHueTransitionStateByIndex(uint16_t index) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); ColorHueTransitionState * state = nullptr; if (index < ArraySize(colorHueTransitionStates)) @@ -844,15 +850,24 @@ ColorControlServer::ColorHueTransitionState * ColorControlServer::getColorHueTra } /** - * @brief Returns Color16uTransitionState for saturation associated to an endpoint + * @brief Returns ColorHueTransititionState associated to an endpoint + * + * @param[in] endpoint + * @return ColorControlServer::ColorHueTransitionState* + */ +ColorControlServer::ColorHueTransitionState * ColorControlServer::getColorHueTransitionState(EndpointId endpoint) +{ + return getColorHueTransitionStateByIndex(getEndpointIndex(endpoint)); +} + +/** + * @brief Returns the saturation Color16uTransitionState associated to an endpoint index * * @param[in] endpoint * @return ColorControlServer::Color16uTransitionState* */ -ColorControlServer::Color16uTransitionState * ColorControlServer::getSaturationTransitionState(EndpointId endpoint) +ColorControlServer::Color16uTransitionState * ColorControlServer::getSaturationTransitionStateByIndex(uint16_t index) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); Color16uTransitionState * state = nullptr; if (index < ArraySize(colorSatTransitionStates)) @@ -862,6 +877,17 @@ ColorControlServer::Color16uTransitionState * ColorControlServer::getSaturationT return state; } +/** + * @brief Returns the saturation Color16uTransitionState associated to an endpoint + * + * @param[in] endpoint + * @return ColorControlServer::Color16uTransitionState* + */ +ColorControlServer::Color16uTransitionState * ColorControlServer::getSaturationTransitionState(EndpointId endpoint) +{ + return getSaturationTransitionStateByIndex(getEndpointIndex(endpoint)); +} + /** * @brief Returns current saturation for a specified endpoint * @@ -1033,9 +1059,10 @@ void ColorControlServer::startColorLoop(EndpointId endpoint, uint8_t startFromSt colorHueTransitionState->stepsRemaining = static_cast(time * TRANSITION_STEPS_PER_1S); colorHueTransitionState->stepsTotal = static_cast(time * TRANSITION_STEPS_PER_1S); colorHueTransitionState->timeRemaining = MAX_INT16U_VALUE; + colorHueTransitionState->transitionTime = MAX_INT16U_VALUE; colorHueTransitionState->endpoint = endpoint; - Attributes::RemainingTime::Set(endpoint, MAX_INT16U_VALUE); + SetQuietReportRemainingTime(endpoint, MAX_INT16U_VALUE); scheduleTimerCallbackMs(configureHSVEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); } @@ -1079,13 +1106,14 @@ void ColorControlServer::initSaturationTransitionState(chip::EndpointId endpoint void ColorControlServer::SetHSVRemainingTime(chip::EndpointId endpoint) { - ColorHueTransitionState * hueTransitionState = getColorHueTransitionState(endpoint); - Color16uTransitionState * saturationTransitionState = getSaturationTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + ColorHueTransitionState * hueTransitionState = getColorHueTransitionStateByIndex(epIndex); + Color16uTransitionState * saturationTransitionState = getSaturationTransitionStateByIndex(epIndex); // When the hue transition is loop, RemainingTime stays at MAX_INT16 if (hueTransitionState->repeat == false) { - Attributes::RemainingTime::Set(endpoint, max(hueTransitionState->timeRemaining, saturationTransitionState->timeRemaining)); + SetQuietReportRemainingTime(endpoint, max(hueTransitionState->timeRemaining, saturationTransitionState->timeRemaining)); } } @@ -1277,6 +1305,7 @@ Status ColorControlServer::moveToSaturation(uint8_t saturation, uint16_t transit colorSaturationTransitionState->stepsRemaining = max(transitionTime, 1); colorSaturationTransitionState->stepsTotal = colorSaturationTransitionState->stepsRemaining; colorSaturationTransitionState->timeRemaining = transitionTime; + colorSaturationTransitionState->transitionTime = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1308,8 +1337,9 @@ Status ColorControlServer::moveToHueAndSaturation(uint16_t hue, uint8_t saturati uint16_t halfWay = isEnhanced ? HALF_MAX_UINT16T : HALF_MAX_UINT8T; bool moveUp; - Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionState(endpoint); - ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionStateByIndex(epIndex); + ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionStateByIndex(epIndex); VerifyOrReturnError(nullptr != colorSaturationTransitionState, Status::UnsupportedEndpoint); VerifyOrReturnError(nullptr != colorHueTransitionState, Status::UnsupportedEndpoint); @@ -1355,6 +1385,7 @@ Status ColorControlServer::moveToHueAndSaturation(uint16_t hue, uint8_t saturati colorHueTransitionState->stepsRemaining = max(transitionTime, 1); colorHueTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; colorHueTransitionState->timeRemaining = transitionTime; + colorHueTransitionState->transitionTime = transitionTime; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->repeat = false; @@ -1363,6 +1394,7 @@ Status ColorControlServer::moveToHueAndSaturation(uint16_t hue, uint8_t saturati colorSaturationTransitionState->stepsRemaining = colorHueTransitionState->stepsRemaining; colorSaturationTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; colorSaturationTransitionState->timeRemaining = transitionTime; + colorSaturationTransitionState->transitionTime = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1393,9 +1425,11 @@ bool ColorControlServer::moveHueCommand(app::CommandHandler * commandObj, const bool isEnhanced) { MATTER_TRACE_SCOPE("moveHue", "ColorControl"); - EndpointId endpoint = commandPath.mEndpointId; - Status status = Status::Success; - ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionState(endpoint); + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + uint16_t epIndex = getEndpointIndex(endpoint); + ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionStateByIndex(epIndex); VerifyOrExit(colorHueTransitionState != nullptr, status = Status::UnsupportedEndpoint); @@ -1421,7 +1455,7 @@ bool ColorControlServer::moveHueCommand(app::CommandHandler * commandObj, const if (moveMode == HueMoveMode::kStop) { // Per spec any saturation transition must also be cancelled. - Color16uTransitionState * saturationState = getSaturationTransitionState(endpoint); + Color16uTransitionState * saturationState = getSaturationTransitionStateByIndex(epIndex); initSaturationTransitionState(endpoint, saturationState); commandObj->AddStatus(commandPath, Status::Success); return true; @@ -1467,11 +1501,12 @@ bool ColorControlServer::moveHueCommand(app::CommandHandler * commandObj, const colorHueTransitionState->stepsRemaining = TRANSITION_STEPS_PER_1S; colorHueTransitionState->stepsTotal = TRANSITION_STEPS_PER_1S; colorHueTransitionState->timeRemaining = MAX_INT16U_VALUE; + colorHueTransitionState->transitionTime = MAX_INT16U_VALUE; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->repeat = true; // hue movement can last forever. Indicate this with a remaining time of maxint - Attributes::RemainingTime::Set(endpoint, MAX_INT16U_VALUE); + SetQuietReportRemainingTime(endpoint, MAX_INT16U_VALUE); // kick off the state machine: scheduleTimerCallbackMs(configureHSVEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); @@ -1600,6 +1635,7 @@ bool ColorControlServer::moveToHueCommand(app::CommandHandler * commandObj, cons colorHueTransitionState->stepsRemaining = max(transitionTime, 1); colorHueTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; colorHueTransitionState->timeRemaining = transitionTime; + colorHueTransitionState->transitionTime = transitionTime; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->up = (direction == HueDirection::kUp); colorHueTransitionState->repeat = false; @@ -1742,6 +1778,7 @@ bool ColorControlServer::stepHueCommand(app::CommandHandler * commandObj, const colorHueTransitionState->stepsRemaining = max(transitionTime, 1); colorHueTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; colorHueTransitionState->timeRemaining = transitionTime; + colorHueTransitionState->transitionTime = transitionTime; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->repeat = false; @@ -1766,7 +1803,8 @@ bool ColorControlServer::moveSaturationCommand(app::CommandHandler * commandObj, EndpointId endpoint = commandPath.mEndpointId; Status status = Status::Success; - Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionStateByIndex(epIndex); VerifyOrExit(colorSaturationTransitionState != nullptr, status = Status::UnsupportedEndpoint); // check moveMode and rate before any operation is done on the transition states @@ -1794,7 +1832,7 @@ bool ColorControlServer::moveSaturationCommand(app::CommandHandler * commandObj, if (moveMode == SaturationMoveMode::kStop) { // Per spec any hue transition must also be cancelled. - ColorHueTransitionState * hueState = getColorHueTransitionState(endpoint); + ColorHueTransitionState * hueState = getColorHueTransitionStateByIndex(epIndex); initHueTransitionState(endpoint, hueState, false /*isEnhancedHue don't care*/); commandObj->AddStatus(commandPath, Status::Success); return true; @@ -1817,6 +1855,7 @@ bool ColorControlServer::moveSaturationCommand(app::CommandHandler * commandObj, colorSaturationTransitionState->stepsRemaining = transitionTime; colorSaturationTransitionState->stepsTotal = transitionTime; colorSaturationTransitionState->timeRemaining = transitionTime; + colorSaturationTransitionState->transitionTime = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1915,6 +1954,7 @@ bool ColorControlServer::stepSaturationCommand(app::CommandHandler * commandObj, colorSaturationTransitionState->stepsRemaining = max(transitionTime, 1); colorSaturationTransitionState->stepsTotal = colorSaturationTransitionState->stepsRemaining; colorSaturationTransitionState->timeRemaining = transitionTime; + colorSaturationTransitionState->transitionTime = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1945,7 +1985,8 @@ bool ColorControlServer::colorLoopCommand(app::CommandHandler * commandObj, cons uint8_t isColorLoopActive = 0; uint8_t deactiveColorLoop = 0; - ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionStateByIndex(epIndex); VerifyOrExit(colorHueTransitionState != nullptr, status = Status::UnsupportedEndpoint); // Validate the action and direction parameters of the command @@ -2030,7 +2071,9 @@ bool ColorControlServer::colorLoopCommand(app::CommandHandler * commandObj, cons uint16_t storedEnhancedHue = 0; Attributes::ColorLoopStoredEnhancedHue::Get(endpoint, &storedEnhancedHue); - Attributes::EnhancedCurrentHue::Set(endpoint, storedEnhancedHue); + MarkAttributeDirty markDirty = + SetQuietReportAttribute(quietEnhancedHue[epIndex], storedEnhancedHue, true /*isStartOrEndOfTransition*/, 0); + Attributes::EnhancedCurrentHue::Set(endpoint, quietEnhancedHue[epIndex].value().Value(), markDirty); } else { @@ -2063,13 +2106,18 @@ bool ColorControlServer::colorLoopCommand(app::CommandHandler * commandObj, cons void ColorControlServer::updateHueSatCommand(EndpointId endpoint) { MATTER_TRACE_SCOPE("updateHueSat", "ColorControl"); - ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionState(endpoint); - Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionStateByIndex(epIndex); + Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionStateByIndex(epIndex); uint8_t previousHue = colorHueTransitionState->currentHue; uint16_t previousSaturation = colorSaturationTransitionState->currentValue; uint16_t previousEnhancedhue = colorHueTransitionState->currentEnhancedHue; + bool isHueTansitionStart = (colorHueTransitionState->stepsRemaining == colorHueTransitionState->stepsTotal); + bool isSaturationTransitionStart = + (colorSaturationTransitionState->stepsRemaining == colorSaturationTransitionState->stepsTotal); + bool isHueTansitionDone = computeNewHueValue(colorHueTransitionState); bool isSaturationTransitionDone = computeNewColor16uValue(colorSaturationTransitionState); @@ -2084,32 +2132,43 @@ void ColorControlServer::updateHueSatCommand(EndpointId endpoint) scheduleTimerCallbackMs(configureHSVEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); } + uint8_t currentHue; + MarkAttributeDirty markDirty; if (colorHueTransitionState->isEnhancedHue) { + markDirty = SetQuietReportAttribute(quietEnhancedHue[epIndex], colorHueTransitionState->currentEnhancedHue, + (isHueTansitionStart || isHueTansitionDone), colorHueTransitionState->transitionTime); + Attributes::EnhancedCurrentHue::Set(endpoint, quietEnhancedHue[epIndex].value().Value(), markDirty); + currentHue = static_cast(colorHueTransitionState->currentEnhancedHue >> 8); + if (previousEnhancedhue != colorHueTransitionState->currentEnhancedHue) { - Attributes::EnhancedCurrentHue::Set(endpoint, colorHueTransitionState->currentEnhancedHue); - Attributes::CurrentHue::Set(endpoint, static_cast(colorHueTransitionState->currentEnhancedHue >> 8)); - ChipLogProgress(Zcl, "Enhanced Hue %d endpoint %d", colorHueTransitionState->currentEnhancedHue, endpoint); } } else { + currentHue = colorHueTransitionState->currentHue; if (previousHue != colorHueTransitionState->currentHue) { - Attributes::CurrentHue::Set(colorHueTransitionState->endpoint, colorHueTransitionState->currentHue); ChipLogProgress(Zcl, "Hue %d endpoint %d", colorHueTransitionState->currentHue, endpoint); } } + markDirty = SetQuietReportAttribute(quietHue[epIndex], currentHue, (isHueTansitionStart || isHueTansitionDone), + colorHueTransitionState->transitionTime); + Attributes::CurrentHue::Set(endpoint, quietHue[epIndex].value().Value(), markDirty); + if (previousSaturation != colorSaturationTransitionState->currentValue) { - Attributes::CurrentSaturation::Set(colorSaturationTransitionState->endpoint, - (uint8_t) colorSaturationTransitionState->currentValue); ChipLogProgress(Zcl, "Saturation %d endpoint %d", colorSaturationTransitionState->currentValue, endpoint); } + markDirty = SetQuietReportAttribute(quietSaturation[epIndex], colorSaturationTransitionState->currentValue, + (isSaturationTransitionStart || isSaturationTransitionDone), + colorSaturationTransitionState->transitionTime); + Attributes::CurrentSaturation::Set(endpoint, quietSaturation[epIndex].value().Value(), markDirty); + computePwmFromHsv(endpoint); } @@ -2118,16 +2177,13 @@ void ColorControlServer::updateHueSatCommand(EndpointId endpoint) #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_XY /** - * @brief Returns Color16uTransitionState for X color associated to an endpoint + * @brief Returns Color16uTransitionState for X color associated to an endpoint index * * @param endpoint * @return ColorControlServer::Color16uTransitionState* */ -ColorControlServer::Color16uTransitionState * ColorControlServer::getXTransitionState(EndpointId endpoint) +ColorControlServer::Color16uTransitionState * ColorControlServer::getXTransitionStateByIndex(uint16_t index) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); - Color16uTransitionState * state = nullptr; if (index < ArraySize(colorXtransitionStates)) { @@ -2138,16 +2194,24 @@ ColorControlServer::Color16uTransitionState * ColorControlServer::getXTransition } /** - * @brief Returns Color16uTransitionState for Y color associated to an endpoint + * @brief Returns Color16uTransitionState for X color associated to an endpoint * * @param endpoint * @return ColorControlServer::Color16uTransitionState* */ -ColorControlServer::Color16uTransitionState * ColorControlServer::getYTransitionState(EndpointId endpoint) +ColorControlServer::Color16uTransitionState * ColorControlServer::getXTransitionState(EndpointId endpoint) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); + return getXTransitionStateByIndex(getEndpointIndex(endpoint)); +} +/** + * @brief Returns Color16uTransitionState for Y color associated to an endpoint index + * + * @param endpoint + * @return ColorControlServer::Color16uTransitionState* + */ +ColorControlServer::Color16uTransitionState * ColorControlServer::getYTransitionStateByIndex(uint16_t index) +{ Color16uTransitionState * state = nullptr; if (index < ArraySize(colorYtransitionStates)) { @@ -2157,6 +2221,17 @@ ColorControlServer::Color16uTransitionState * ColorControlServer::getYTransition return state; } +/** + * @brief Returns Color16uTransitionState for Y color associated to an endpoint + * + * @param endpoint + * @return ColorControlServer::Color16uTransitionState* + */ +ColorControlServer::Color16uTransitionState * ColorControlServer::getYTransitionState(EndpointId endpoint) +{ + return getYTransitionStateByIndex(getEndpointIndex(endpoint)); +} + uint16_t ColorControlServer::findNewColorValueFromStep(uint16_t oldValue, int16_t step) { uint16_t newValue; @@ -2207,8 +2282,9 @@ EmberEventControl * ColorControlServer::configureXYEventControl(EndpointId endpo */ Status ColorControlServer::moveToColor(uint16_t colorX, uint16_t colorY, uint16_t transitionTime, EndpointId endpoint) { - Color16uTransitionState * colorXTransitionState = getXTransitionState(endpoint); - Color16uTransitionState * colorYTransitionState = getYTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorXTransitionState = getXTransitionStateByIndex(epIndex); + Color16uTransitionState * colorYTransitionState = getYTransitionStateByIndex(epIndex); VerifyOrReturnError(nullptr != colorXTransitionState, Status::UnsupportedEndpoint); VerifyOrReturnError(nullptr != colorYTransitionState, Status::UnsupportedEndpoint); @@ -2226,6 +2302,7 @@ Status ColorControlServer::moveToColor(uint16_t colorX, uint16_t colorY, uint16_ colorXTransitionState->stepsRemaining = max(transitionTime, 1); colorXTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; colorXTransitionState->timeRemaining = transitionTime; + colorXTransitionState->transitionTime = transitionTime; colorXTransitionState->endpoint = endpoint; colorXTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorXTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -2236,11 +2313,12 @@ Status ColorControlServer::moveToColor(uint16_t colorX, uint16_t colorY, uint16_ colorYTransitionState->stepsRemaining = colorXTransitionState->stepsRemaining; colorYTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; colorYTransitionState->timeRemaining = transitionTime; + colorYTransitionState->transitionTime = transitionTime; colorYTransitionState->endpoint = endpoint; colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; - Attributes::RemainingTime::Set(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime); // kick off the state machine: scheduleTimerCallbackMs(configureXYEventControl(endpoint), transitionTime ? TRANSITION_UPDATE_TIME_MS.count() : 0); @@ -2275,8 +2353,9 @@ bool ColorControlServer::moveColorCommand(app::CommandHandler * commandObj, cons EndpointId endpoint = commandPath.mEndpointId; Status status = Status::Success; - Color16uTransitionState * colorXTransitionState = getXTransitionState(endpoint); - Color16uTransitionState * colorYTransitionState = getYTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorXTransitionState = getXTransitionStateByIndex(epIndex); + Color16uTransitionState * colorYTransitionState = getYTransitionStateByIndex(epIndex); VerifyOrExit(colorXTransitionState != nullptr, status = Status::UnsupportedEndpoint); VerifyOrExit(colorYTransitionState != nullptr, status = Status::UnsupportedEndpoint); @@ -2320,6 +2399,7 @@ bool ColorControlServer::moveColorCommand(app::CommandHandler * commandObj, cons colorXTransitionState->stepsRemaining = transitionTimeX; colorXTransitionState->stepsTotal = transitionTimeX; colorXTransitionState->timeRemaining = transitionTimeX; + colorXTransitionState->transitionTime = transitionTimeX; colorXTransitionState->endpoint = endpoint; colorXTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorXTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -2340,18 +2420,12 @@ bool ColorControlServer::moveColorCommand(app::CommandHandler * commandObj, cons colorYTransitionState->stepsRemaining = transitionTimeY; colorYTransitionState->stepsTotal = transitionTimeY; colorYTransitionState->timeRemaining = transitionTimeY; + colorYTransitionState->transitionTime = transitionTimeY; colorYTransitionState->endpoint = endpoint; colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; - if (transitionTimeX < transitionTimeY) - { - Attributes::RemainingTime::Set(endpoint, transitionTimeX); - } - else - { - Attributes::RemainingTime::Set(endpoint, transitionTimeY); - } + SetQuietReportRemainingTime(endpoint, max(transitionTimeX, transitionTimeY)); // kick off the state machine: scheduleTimerCallbackMs(configureXYEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); @@ -2377,8 +2451,9 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons Status status = Status::Success; - Color16uTransitionState * colorXTransitionState = getXTransitionState(endpoint); - Color16uTransitionState * colorYTransitionState = getYTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorXTransitionState = getXTransitionStateByIndex(epIndex); + Color16uTransitionState * colorYTransitionState = getYTransitionStateByIndex(epIndex); VerifyOrExit(colorXTransitionState != nullptr, status = Status::UnsupportedEndpoint); VerifyOrExit(colorYTransitionState != nullptr, status = Status::UnsupportedEndpoint); @@ -2414,6 +2489,7 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons colorXTransitionState->stepsRemaining = max(transitionTime, 1); colorXTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; colorXTransitionState->timeRemaining = transitionTime; + colorXTransitionState->transitionTime = transitionTime; colorXTransitionState->endpoint = endpoint; colorXTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorXTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -2424,11 +2500,12 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons colorYTransitionState->stepsRemaining = colorXTransitionState->stepsRemaining; colorYTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; colorYTransitionState->timeRemaining = transitionTime; + colorYTransitionState->transitionTime = transitionTime; colorYTransitionState->endpoint = endpoint; colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; - Attributes::RemainingTime::Set(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime); // kick off the state machine: scheduleTimerCallbackMs(configureXYEventControl(endpoint), transitionTime ? TRANSITION_UPDATE_TIME_MS.count() : 0); @@ -2445,15 +2522,15 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons */ void ColorControlServer::updateXYCommand(EndpointId endpoint) { - Color16uTransitionState * colorXTransitionState = getXTransitionState(endpoint); - Color16uTransitionState * colorYTransitionState = getYTransitionState(endpoint); - bool isXTransitionDone, isYTransitionDone; + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorXTransitionState = getXTransitionStateByIndex(epIndex); + Color16uTransitionState * colorYTransitionState = getYTransitionStateByIndex(epIndex); // compute new values for X and Y. - isXTransitionDone = computeNewColor16uValue(colorXTransitionState); - isYTransitionDone = computeNewColor16uValue(colorYTransitionState); + bool isXTransitionDone = computeNewColor16uValue(colorXTransitionState); + bool isYTransitionDone = computeNewColor16uValue(colorYTransitionState); - Attributes::RemainingTime::Set(endpoint, max(colorXTransitionState->timeRemaining, colorYTransitionState->timeRemaining)); + SetQuietReportRemainingTime(endpoint, max(colorXTransitionState->timeRemaining, colorYTransitionState->timeRemaining)); if (isXTransitionDone && isYTransitionDone) { @@ -2464,9 +2541,18 @@ void ColorControlServer::updateXYCommand(EndpointId endpoint) scheduleTimerCallbackMs(configureXYEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); } - // update the attributes - Attributes::CurrentX::Set(endpoint, colorXTransitionState->currentValue); - Attributes::CurrentY::Set(endpoint, colorYTransitionState->currentValue); + bool isXTransitionStart = (colorXTransitionState->stepsRemaining == colorXTransitionState->stepsTotal); + bool isYTransitionStart = (colorYTransitionState->stepsRemaining == colorYTransitionState->stepsTotal); + + MarkAttributeDirty markXDirty = + SetQuietReportAttribute(quietColorX[epIndex], colorXTransitionState->currentValue, + (isXTransitionStart || isXTransitionDone), colorXTransitionState->transitionTime); + MarkAttributeDirty markYDirty = + SetQuietReportAttribute(quietColorY[epIndex], colorYTransitionState->currentValue, + (isYTransitionStart || isYTransitionDone), colorYTransitionState->transitionTime); + + Attributes::CurrentX::Set(endpoint, quietColorX[epIndex].value().Value(), markXDirty); + Attributes::CurrentY::Set(endpoint, quietColorY[epIndex].value().Value(), markYDirty); ChipLogProgress(Zcl, "Color X %d Color Y %d", colorXTransitionState->currentValue, colorYTransitionState->currentValue); @@ -2477,16 +2563,13 @@ void ColorControlServer::updateXYCommand(EndpointId endpoint) #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP /** - * @brief Get the Temp Transition State object associated to the endpoint + * @brief Get the Temp Transition State object associated to the endpoint index * * @param endpoint * @return Color16uTransitionState* */ -ColorControlServer::Color16uTransitionState * ColorControlServer::getTempTransitionState(EndpointId endpoint) +ColorControlServer::Color16uTransitionState * ColorControlServer::getTempTransitionStateByIndex(uint16_t index) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); - Color16uTransitionState * state = nullptr; if (index < ArraySize(colorTempTransitionStates)) { @@ -2496,6 +2579,17 @@ ColorControlServer::Color16uTransitionState * ColorControlServer::getTempTransit return state; } +/** + * @brief Get the Temp Transition State object associated to the endpoint + * + * @param endpoint + * @return Color16uTransitionState* + */ +ColorControlServer::Color16uTransitionState * ColorControlServer::getTempTransitionState(EndpointId endpoint) +{ + return getTempTransitionStateByIndex(getEndpointIndex(endpoint)); +} + /** * @brief executes move to color temp logic * @@ -2541,6 +2635,7 @@ Status ColorControlServer::moveToColorTemp(EndpointId aEndpoint, uint16_t colorT colorTempTransitionState->stepsRemaining = max(transitionTime, 1); colorTempTransitionState->stepsTotal = colorTempTransitionState->stepsRemaining; colorTempTransitionState->timeRemaining = transitionTime; + colorTempTransitionState->transitionTime = transitionTime; colorTempTransitionState->endpoint = endpoint; colorTempTransitionState->lowLimit = temperatureMin; colorTempTransitionState->highLimit = temperatureMax; @@ -2670,7 +2765,7 @@ void ColorControlServer::updateTempCommand(EndpointId endpoint) } } - Attributes::RemainingTime::Set(endpoint, colorTempTransitionState->timeRemaining); + SetQuietReportRemainingTime(endpoint, colorTempTransitionState->timeRemaining); if (isColorTempTransitionDone) { @@ -2792,11 +2887,12 @@ bool ColorControlServer::moveColorTempCommand(app::CommandHandler * commandObj, colorTempTransitionState->stepsRemaining = transitionTime; colorTempTransitionState->stepsTotal = transitionTime; colorTempTransitionState->timeRemaining = transitionTime; + colorTempTransitionState->transitionTime = transitionTime; colorTempTransitionState->endpoint = endpoint; colorTempTransitionState->lowLimit = colorTemperatureMinimum; colorTempTransitionState->highLimit = colorTemperatureMaximum; - Attributes::RemainingTime::Set(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime); // kick off the state machine: scheduleTimerCallbackMs(configureTempEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); @@ -2909,11 +3005,12 @@ bool ColorControlServer::stepColorTempCommand(app::CommandHandler * commandObj, colorTempTransitionState->stepsRemaining = max(transitionTime, 1); colorTempTransitionState->stepsTotal = colorTempTransitionState->stepsRemaining; colorTempTransitionState->timeRemaining = transitionTime; + colorTempTransitionState->transitionTime = transitionTime; colorTempTransitionState->endpoint = endpoint; colorTempTransitionState->lowLimit = colorTemperatureMinimum; colorTempTransitionState->highLimit = colorTemperatureMaximum; - Attributes::RemainingTime::Set(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime); // kick off the state machine: scheduleTimerCallbackMs(configureTempEventControl(endpoint), transitionTime ? TRANSITION_UPDATE_TIME_MS.count() : 0); @@ -3006,6 +3103,89 @@ void ColorControlServer::levelControlColorTempChangeCommand(EndpointId endpoint) #endif // MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP +/* + * @brief + * Utility function used to update a color control attribute which has the quiet reporting quality. + * matching the following report conditions: + * - At most once per second, or + * - At the start of the movement/transition, or + * - At the end of the movement/transition, or + * - When it changes from null to any other value and vice versa. (Implicit to the QuieterReportingAttribute class) + * + * The QuietReportAttribute class is updated with the new value and when the report conditions are met, + * this function will return MarkAttributeDirty::kIfChanged. + * It is expected that the user will use this return value to trigger a reporting mechanism for the attribute with the new value + * (Which was updated in the quietReporter) + * + * @param quietReporter: The QuieterReportingAttribute object for the attribute to update. + * @param newValue: Value to update the attribute with + * @param isStartOrEndOfTransition: Boolean that indicatse whether the update is occurring at the start or end of a level transition + * @return MarkAttributeDirty::kIfChanged when the attribute must be maredk dirty and be reported. MarkAttributeDirty::kNo when it + * when it no report is needed. + */ +template +MarkAttributeDirty ColorControlServer::SetQuietReportAttribute(QuieterReportingAttribute & quietReporter, V newValue, + bool isStartOrEndOfTransition, uint16_t transitionTime) +{ + AttributeDirtyState dirtyState; + auto now = System::SystemClock().GetMonotonicTimestamp(); + + if (isStartOrEndOfTransition) + { + // At the start or end of the movement/transition we must report + auto predicate = [](const typename QuieterReportingAttribute::SufficientChangePredicateCandidate &) -> bool { + return true; + }; + dirtyState = quietReporter.SetValue(newValue, now, predicate); + } + else + { + // During transitions, reports should be at most once per second + + // For "infinite" transition, default reports interval to 10s (100 1/10ths of a second ) + if (transitionTime == MAX_INT16U_VALUE) + { + transitionTime = 100; + } + + // Opt for the longest interval between reports, 1s or (transitionTime / 4). + // Since transitionTime is in 1/10th of a second, convert it to ms (x 100), thus * 100/4 -> * 25 + System::Clock::Milliseconds64 reportInterval = System::Clock::Milliseconds64(std::max(1000, transitionTime * 25)); + auto predicate = quietReporter.GetPredicateForSufficientTimeSinceLastDirty(reportInterval); + dirtyState = quietReporter.SetValue(newValue, now, predicate); + } + + return (dirtyState == AttributeDirtyState::kMustReport) ? MarkAttributeDirty::kIfChanged : MarkAttributeDirty::kNo; +} + +/* + * @brief + * Function used to set the remaining time based on quiet reporting conditions. + * It will update the attribute storage and report the attribute if it is determined dirty. + * The condition on which the attribute must be reported are defined by the set QuieterReportingPolicyFlags + * of the quietRemainingTime object and the implicit conditions of the QuieterReportingAttribute class + * + * @param endpoint: Endpoint of the RemainingTime attribute to set + * @param newRemainingTime: Value to update the RemainingTime attribute with + * @return Success in setting the attribute value or the IM error code for the failure. + */ +Status ColorControlServer::SetQuietReportRemainingTime(EndpointId endpoint, uint16_t newRemainingTime) +{ + uint16_t epIndex = getEndpointIndex(endpoint); + auto markDirty = MarkAttributeDirty::kNo; + auto now = System::SystemClock().GetMonotonicTimestamp(); + // Establish the quiet report condition for the RemainingTime Attribute + // The quiet report is by the previously set policies : + // - kMarkDirtyOnChangeToFromZero : When the value changes from 0 to any other value and vice versa, or + // - kMarkDirtyOnIncrement : When the value increases. + if (quietRemainingTime[epIndex].SetValue(newRemainingTime, now) == AttributeDirtyState::kMustReport) + { + markDirty = MarkAttributeDirty::kIfChanged; + } + + return Attributes::RemainingTime::Set(endpoint, quietRemainingTime[epIndex].value().Value(), markDirty); +} + /********************************************************** * Callbacks Implementation *********************************************************/ diff --git a/src/app/clusters/color-control-server/color-control-server.h b/src/app/clusters/color-control-server/color-control-server.h index f453c6f02872e4..4238fed1dd8b2d 100644 --- a/src/app/clusters/color-control-server/color-control-server.h +++ b/src/app/clusters/color-control-server/color-control-server.h @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -109,6 +111,8 @@ class ColorControlServer // The amount of time remaining until the transition completes. Measured in tenths of a second. // When the transition repeats indefinitely, this will hold the maximum value possible. uint16_t timeRemaining; + // The total transitionTime in 1/10th of a seconds + uint16_t transitionTime; uint16_t initialEnhancedHue; uint16_t currentEnhancedHue; uint16_t finalEnhancedHue; @@ -127,6 +131,8 @@ class ColorControlServer uint16_t stepsTotal; // The amount of time remaining until the transition completes. Measured in tenths of a second. uint16_t timeRemaining; + // The total transitionTime in 1/10th of a seconds + uint16_t transitionTime; uint16_t lowLimit; uint16_t highLimit; chip::EndpointId endpoint; @@ -194,12 +200,30 @@ class ColorControlServer void cancelEndpointTimerCallback(chip::EndpointId endpoint); + template + chip::app::MarkAttributeDirty SetQuietReportAttribute(chip::app::QuieterReportingAttribute & quietReporter, V newValue, + bool isStartOrEndOfTransition, uint16_t transitionTime); + chip::Protocols::InteractionModel::Status SetQuietReportRemainingTime(chip::EndpointId endpoint, uint16_t newRemainingTime); + private: /********************************************************** * Functions Definitions *********************************************************/ - ColorControlServer() {} + ColorControlServer() + { + for (size_t i = 0; i < kColorControlClusterServerMaxEndpointCount; i++) + { + // Set the quiet report policies for the RemaininTime Attribute on all endpoint + // - kMarkDirtyOnChangeToFromZero : When the value changes from 0 to any other value and vice versa, or + // - kMarkDirtyOnIncrement : When the value increases. + quietRemainingTime[i] + .policy() + .Set(chip::app::QuieterReportingPolicyEnum::kMarkDirtyOnIncrement) + .Set(chip::app::QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero); + } + } + bool shouldExecuteIfOff(chip::EndpointId endpoint, uint8_t optionMask, uint8_t optionOverride); void handleModeSwitch(chip::EndpointId endpoint, uint8_t newColorMode); uint16_t computeTransitionTimeFromStateAndRate(Color16uTransitionState * p, uint16_t rate); @@ -213,6 +237,7 @@ class ColorControlServer static void timerCallback(chip::System::Layer *, void * callbackContext); void scheduleTimerCallbackMs(EmberEventControl * control, uint32_t delayMs); void cancelEndpointTimerCallback(EmberEventControl * control); + uint16_t getEndpointIndex(chip::EndpointId); #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_HSV chip::Protocols::InteractionModel::Status moveToSaturation(uint8_t saturation, uint16_t transitionTime, @@ -221,6 +246,8 @@ class ColorControlServer bool isEnhanced, chip::EndpointId endpoint); ColorHueTransitionState * getColorHueTransitionState(chip::EndpointId endpoint); Color16uTransitionState * getSaturationTransitionState(chip::EndpointId endpoint); + ColorHueTransitionState * getColorHueTransitionStateByIndex(uint16_t index); + Color16uTransitionState * getSaturationTransitionStateByIndex(uint16_t index); uint8_t getSaturation(chip::EndpointId endpoint); uint8_t addHue(uint8_t hue1, uint8_t hue2); uint8_t subtractHue(uint8_t hue1, uint8_t hue2); @@ -241,12 +268,15 @@ class ColorControlServer chip::EndpointId endpoint); Color16uTransitionState * getXTransitionState(chip::EndpointId endpoint); Color16uTransitionState * getYTransitionState(chip::EndpointId endpoint); + Color16uTransitionState * getXTransitionStateByIndex(uint16_t index); + Color16uTransitionState * getYTransitionStateByIndex(uint16_t index); uint16_t findNewColorValueFromStep(uint16_t oldValue, int16_t step); EmberEventControl * configureXYEventControl(chip::EndpointId); #endif // #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_XY #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP Color16uTransitionState * getTempTransitionState(chip::EndpointId endpoint); + Color16uTransitionState * getTempTransitionStateByIndex(uint16_t index); chip::Protocols::InteractionModel::Status moveToColorTemp(chip::EndpointId aEndpoint, uint16_t colorTemperature, uint16_t transitionTime); uint16_t getTemperatureCoupleToLevelMin(chip::EndpointId endpoint); @@ -264,11 +294,18 @@ class ColorControlServer #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_HSV ColorHueTransitionState colorHueTransitionStates[kColorControlClusterServerMaxEndpointCount]; Color16uTransitionState colorSatTransitionStates[kColorControlClusterServerMaxEndpointCount]; + + chip::app::QuieterReportingAttribute quietHue[kColorControlClusterServerMaxEndpointCount]; + chip::app::QuieterReportingAttribute quietSaturation[kColorControlClusterServerMaxEndpointCount]; + chip::app::QuieterReportingAttribute quietEnhancedHue[kColorControlClusterServerMaxEndpointCount]; #endif #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_XY Color16uTransitionState colorXtransitionStates[kColorControlClusterServerMaxEndpointCount]; Color16uTransitionState colorYtransitionStates[kColorControlClusterServerMaxEndpointCount]; + + chip::app::QuieterReportingAttribute quietColorX[kColorControlClusterServerMaxEndpointCount]; + chip::app::QuieterReportingAttribute quietColorY[kColorControlClusterServerMaxEndpointCount]; #endif // MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_XY #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP @@ -276,6 +313,7 @@ class ColorControlServer #endif // MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP EmberEventControl eventControls[kColorControlClusterServerMaxEndpointCount]; + chip::app::QuieterReportingAttribute quietRemainingTime[kColorControlClusterServerMaxEndpointCount]; #ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT friend class DefaultColorControlSceneHandler;