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 6a9e7db0e8161e..6e66018e8d43ea 100644 --- a/src/app/clusters/color-control-server/color-control-server.cpp +++ b/src/app/clusters/color-control-server/color-control-server.cpp @@ -358,6 +358,12 @@ bool ColorControlServer::computeNewColor16uValue(ColorControlServer::Color16uTra (p->stepsRemaining)--; + if (p->timeRemaining > 0) + { + // The time remaining is measured in tenths of a second, which is the same as the update timer. + (p->timeRemaining)--; + } + // handle sign if (p->finalValue == p->currentValue) { @@ -625,6 +631,7 @@ void ColorControlServer::startColorLoop(EndpointId endpoint, uint8_t startFromSt colorHueTransitionState->stepsRemaining = static_cast(time * TRANSITION_TIME_1S); colorHueTransitionState->stepsTotal = static_cast(time * TRANSITION_TIME_1S); + colorHueTransitionState->timeRemaining = MAX_INT16U_VALUE; colorHueTransitionState->endpoint = endpoint; Attributes::RemainingTime::Set(endpoint, MAX_INT16U_VALUE); @@ -640,6 +647,7 @@ void ColorControlServer::initHueTransitionState(EndpointId endpoint, ColorHueTra bool isEnhancedHue) { colorHueTransitionState->stepsRemaining = 0; + colorHueTransitionState->timeRemaining = 0; colorHueTransitionState->isEnhancedHue = isEnhancedHue; colorHueTransitionState->endpoint = endpoint; @@ -662,6 +670,7 @@ void ColorControlServer::initHueTransitionState(EndpointId endpoint, ColorHueTra void ColorControlServer::initSaturationTransitionState(chip::EndpointId endpoint, Color16uTransitionState * colorSatTransitionState) { colorSatTransitionState->stepsRemaining = 0; + colorSatTransitionState->timeRemaining = 0; colorSatTransitionState->endpoint = endpoint; colorSatTransitionState->initialValue = colorSatTransitionState->currentValue = getSaturation(endpoint); @@ -675,8 +684,7 @@ void ColorControlServer::SetHSVRemainingTime(chip::EndpointId endpoint) // When the hue transition is loop, RemainingTime stays at MAX_INT16 if (hueTransitionState->repeat == false) { - Attributes::RemainingTime::Set(endpoint, - max(hueTransitionState->stepsRemaining, saturationTransitionState->stepsRemaining)); + Attributes::RemainingTime::Set(endpoint, max(hueTransitionState->timeRemaining, saturationTransitionState->timeRemaining)); } } @@ -700,6 +708,12 @@ bool ColorControlServer::computeNewHueValue(ColorControlServer::ColorHueTransiti (p->stepsRemaining)--; + if (p->timeRemaining > 0 && p->repeat == false) + { + // The time remaining is measured in tenths of a second, which is the same as the update timer. + (p->timeRemaining)--; + } + // are we going up or down? if ((p->isEnhancedHue && p->finalEnhancedHue == p->currentEnhancedHue) || (!p->isEnhancedHue && p->finalHue == p->currentHue)) { @@ -925,6 +939,7 @@ bool ColorControlServer::moveHueCommand(app::CommandHandler * commandObj, const colorHueTransitionState->stepsRemaining = TRANSITION_TIME_1S; colorHueTransitionState->stepsTotal = TRANSITION_TIME_1S; + colorHueTransitionState->timeRemaining = MAX_INT16U_VALUE; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->repeat = true; @@ -987,11 +1002,6 @@ bool ColorControlServer::moveToHueCommand(app::CommandHandler * commandObj, cons currentHue = static_cast(current8bitHue); } - if (transitionTime == 0) - { - transitionTime++; - } - // Convert the ShortestDistance/LongestDistance moveDirection values into Up/Down. switch (moveDirection) { @@ -1059,8 +1069,9 @@ bool ColorControlServer::moveToHueCommand(app::CommandHandler * commandObj, cons colorHueTransitionState->finalHue = static_cast(hue); } - colorHueTransitionState->stepsRemaining = transitionTime; - colorHueTransitionState->stepsTotal = transitionTime; + colorHueTransitionState->stepsRemaining = max(transitionTime, 1); + colorHueTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; + colorHueTransitionState->timeRemaining = transitionTime; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->up = (direction == HueDirection::kUp); colorHueTransitionState->repeat = false; @@ -1068,7 +1079,7 @@ bool ColorControlServer::moveToHueCommand(app::CommandHandler * commandObj, cons SetHSVRemainingTime(endpoint); // kick off the state machine: - scheduleTimerCallbackMs(configureHSVEventControl(endpoint), UPDATE_TIME_MS); + scheduleTimerCallbackMs(configureHSVEventControl(endpoint), transitionTime ? UPDATE_TIME_MS : 0); exit: commandObj->AddStatus(commandPath, status); @@ -1121,11 +1132,6 @@ bool ColorControlServer::moveToHueAndSaturationCommand(app::CommandHandler * com return true; } - if (transitionTime == 0) - { - transitionTime++; - } - // New command. Need to stop any active transitions. stopAllColorTransitions(endpoint); @@ -1164,15 +1170,17 @@ bool ColorControlServer::moveToHueAndSaturationCommand(app::CommandHandler * com } colorHueTransitionState->up = moveUp; - colorHueTransitionState->stepsRemaining = transitionTime; - colorHueTransitionState->stepsTotal = transitionTime; + colorHueTransitionState->stepsRemaining = max(transitionTime, 1); + colorHueTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; + colorHueTransitionState->timeRemaining = transitionTime; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->repeat = false; initSaturationTransitionState(endpoint, colorSaturationTransitionState); colorSaturationTransitionState->finalValue = saturation; - colorSaturationTransitionState->stepsRemaining = transitionTime; - colorSaturationTransitionState->stepsTotal = transitionTime; + colorSaturationTransitionState->stepsRemaining = colorHueTransitionState->stepsRemaining; + colorSaturationTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; + colorSaturationTransitionState->timeRemaining = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1180,7 +1188,7 @@ bool ColorControlServer::moveToHueAndSaturationCommand(app::CommandHandler * com SetHSVRemainingTime(endpoint); // kick off the state machine: - scheduleTimerCallbackMs(configureHSVEventControl(endpoint), UPDATE_TIME_MS); + scheduleTimerCallbackMs(configureHSVEventControl(endpoint), transitionTime ? UPDATE_TIME_MS : 0); exit: commandObj->AddStatus(commandPath, status); @@ -1225,11 +1233,6 @@ bool ColorControlServer::stepHueCommand(app::CommandHandler * commandObj, const return true; } - if (transitionTime == 0) - { - transitionTime++; - } - // New command. Need to stop any active transitions. stopAllColorTransitions(endpoint); @@ -1274,15 +1277,16 @@ bool ColorControlServer::stepHueCommand(app::CommandHandler * commandObj, const } } - colorHueTransitionState->stepsRemaining = transitionTime; - colorHueTransitionState->stepsTotal = transitionTime; + colorHueTransitionState->stepsRemaining = max(transitionTime, 1); + colorHueTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; + colorHueTransitionState->timeRemaining = transitionTime; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->repeat = false; SetHSVRemainingTime(endpoint); // kick off the state machine: - scheduleTimerCallbackMs(configureHSVEventControl(endpoint), UPDATE_TIME_MS); + scheduleTimerCallbackMs(configureHSVEventControl(endpoint), transitionTime ? UPDATE_TIME_MS : 0); exit: commandObj->AddStatus(commandPath, status); @@ -1348,6 +1352,7 @@ bool ColorControlServer::moveSaturationCommand(app::CommandHandler * commandObj, colorSaturationTransitionState->stepsRemaining = transitionTime; colorSaturationTransitionState->stepsTotal = transitionTime; + colorSaturationTransitionState->timeRemaining = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1399,11 +1404,6 @@ bool ColorControlServer::moveToSaturationCommand(app::CommandHandler * commandOb return true; } - if (transitionTime == 0) - { - transitionTime++; - } - // New command. Need to stop any active transitions. stopAllColorTransitions(endpoint); @@ -1413,8 +1413,9 @@ bool ColorControlServer::moveToSaturationCommand(app::CommandHandler * commandOb // now, kick off the state machine. initSaturationTransitionState(endpoint, colorSaturationTransitionState); colorSaturationTransitionState->finalValue = saturation; - colorSaturationTransitionState->stepsRemaining = transitionTime; - colorSaturationTransitionState->stepsTotal = transitionTime; + colorSaturationTransitionState->stepsRemaining = max(transitionTime, 1); + colorSaturationTransitionState->stepsTotal = colorSaturationTransitionState->stepsRemaining; + colorSaturationTransitionState->timeRemaining = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1422,7 +1423,7 @@ bool ColorControlServer::moveToSaturationCommand(app::CommandHandler * commandOb SetHSVRemainingTime(endpoint); // kick off the state machine: - scheduleTimerCallbackMs(configureHSVEventControl(endpoint), UPDATE_TIME_MS); + scheduleTimerCallbackMs(configureHSVEventControl(endpoint), transitionTime ? UPDATE_TIME_MS : 0); exit: commandObj->AddStatus(commandPath, status); @@ -1457,11 +1458,6 @@ bool ColorControlServer::stepSaturationCommand(app::CommandHandler * commandObj, return true; } - if (transitionTime == 0) - { - transitionTime++; - } - // New command. Need to stop any active transitions. stopAllColorTransitions(endpoint); @@ -1480,8 +1476,9 @@ bool ColorControlServer::stepSaturationCommand(app::CommandHandler * commandObj, { colorSaturationTransitionState->finalValue = subtractSaturation(currentSaturation, stepSize); } - colorSaturationTransitionState->stepsRemaining = transitionTime; - colorSaturationTransitionState->stepsTotal = transitionTime; + colorSaturationTransitionState->stepsRemaining = max(transitionTime, 1); + colorSaturationTransitionState->stepsTotal = colorSaturationTransitionState->stepsRemaining; + colorSaturationTransitionState->timeRemaining = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1489,7 +1486,7 @@ bool ColorControlServer::stepSaturationCommand(app::CommandHandler * commandObj, SetHSVRemainingTime(endpoint); // kick off the state machine: - scheduleTimerCallbackMs(configureHSVEventControl(endpoint), UPDATE_TIME_MS); + scheduleTimerCallbackMs(configureHSVEventControl(endpoint), transitionTime ? UPDATE_TIME_MS : 0); exit: commandObj->AddStatus(commandPath, status); @@ -1777,11 +1774,6 @@ bool ColorControlServer::moveToColorCommand(app::CommandHandler * commandObj, co return true; } - if (transitionTime == 0) - { - transitionTime++; - } - // New command. Need to stop any active transitions. stopAllColorTransitions(endpoint); @@ -1792,8 +1784,9 @@ bool ColorControlServer::moveToColorCommand(app::CommandHandler * commandObj, co Attributes::CurrentX::Get(endpoint, &(colorXTransitionState->initialValue)); Attributes::CurrentX::Get(endpoint, &(colorXTransitionState->currentValue)); colorXTransitionState->finalValue = colorX; - colorXTransitionState->stepsRemaining = transitionTime; - colorXTransitionState->stepsTotal = transitionTime; + colorXTransitionState->stepsRemaining = max(transitionTime, 1); + colorXTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; + colorXTransitionState->timeRemaining = transitionTime; colorXTransitionState->endpoint = endpoint; colorXTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorXTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -1801,8 +1794,9 @@ bool ColorControlServer::moveToColorCommand(app::CommandHandler * commandObj, co Attributes::CurrentY::Get(endpoint, &(colorYTransitionState->initialValue)); Attributes::CurrentY::Get(endpoint, &(colorYTransitionState->currentValue)); colorYTransitionState->finalValue = colorY; - colorYTransitionState->stepsRemaining = transitionTime; - colorYTransitionState->stepsTotal = transitionTime; + colorYTransitionState->stepsRemaining = colorXTransitionState->stepsRemaining; + colorYTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; + colorYTransitionState->timeRemaining = transitionTime; colorYTransitionState->endpoint = endpoint; colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -1810,7 +1804,7 @@ bool ColorControlServer::moveToColorCommand(app::CommandHandler * commandObj, co Attributes::RemainingTime::Set(endpoint, transitionTime); // kick off the state machine: - scheduleTimerCallbackMs(configureXYEventControl(endpoint), UPDATE_TIME_MS); + scheduleTimerCallbackMs(configureXYEventControl(endpoint), transitionTime ? UPDATE_TIME_MS : 0); exit: commandObj->AddStatus(commandPath, status); @@ -1870,6 +1864,7 @@ bool ColorControlServer::moveColorCommand(app::CommandHandler * commandObj, cons transitionTimeX = computeTransitionTimeFromStateAndRate(colorXTransitionState, unsignedRate); colorXTransitionState->stepsRemaining = transitionTimeX; colorXTransitionState->stepsTotal = transitionTimeX; + colorXTransitionState->timeRemaining = transitionTimeX; colorXTransitionState->endpoint = endpoint; colorXTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorXTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -1889,6 +1884,7 @@ bool ColorControlServer::moveColorCommand(app::CommandHandler * commandObj, cons transitionTimeY = computeTransitionTimeFromStateAndRate(colorYTransitionState, unsignedRate); colorYTransitionState->stepsRemaining = transitionTimeY; colorYTransitionState->stepsTotal = transitionTimeY; + colorYTransitionState->timeRemaining = transitionTimeY; colorYTransitionState->endpoint = endpoint; colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -1944,11 +1940,6 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons colorX = findNewColorValueFromStep(currentColorX, stepX); colorY = findNewColorValueFromStep(currentColorY, stepY); - if (transitionTime == 0) - { - transitionTime++; - } - // New command. Need to stop any active transitions. stopAllColorTransitions(endpoint); @@ -1959,8 +1950,9 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons colorXTransitionState->initialValue = currentColorX; colorXTransitionState->currentValue = currentColorX; colorXTransitionState->finalValue = colorX; - colorXTransitionState->stepsRemaining = transitionTime; - colorXTransitionState->stepsTotal = transitionTime; + colorXTransitionState->stepsRemaining = max(transitionTime, 1); + colorXTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; + colorXTransitionState->timeRemaining = transitionTime; colorXTransitionState->endpoint = endpoint; colorXTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorXTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -1968,8 +1960,9 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons colorYTransitionState->initialValue = currentColorY; colorYTransitionState->currentValue = currentColorY; colorYTransitionState->finalValue = colorY; - colorYTransitionState->stepsRemaining = transitionTime; - colorYTransitionState->stepsTotal = transitionTime; + colorYTransitionState->stepsRemaining = colorXTransitionState->stepsRemaining; + colorYTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; + colorYTransitionState->timeRemaining = transitionTime; colorYTransitionState->endpoint = endpoint; colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -1977,7 +1970,7 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons Attributes::RemainingTime::Set(endpoint, transitionTime); // kick off the state machine: - scheduleTimerCallbackMs(configureXYEventControl(endpoint), UPDATE_TIME_MS); + scheduleTimerCallbackMs(configureXYEventControl(endpoint), transitionTime ? UPDATE_TIME_MS : 0); exit: commandObj->AddStatus(commandPath, status); @@ -1999,7 +1992,7 @@ void ColorControlServer::updateXYCommand(EndpointId endpoint) isXTransitionDone = computeNewColor16uValue(colorXTransitionState); isYTransitionDone = computeNewColor16uValue(colorYTransitionState); - Attributes::RemainingTime::Set(endpoint, max(colorXTransitionState->stepsRemaining, colorYTransitionState->stepsRemaining)); + Attributes::RemainingTime::Set(endpoint, max(colorXTransitionState->timeRemaining, colorYTransitionState->timeRemaining)); if (isXTransitionDone && isYTransitionDone) { @@ -2062,11 +2055,6 @@ Status ColorControlServer::moveToColorTemp(EndpointId aEndpoint, uint16_t colorT uint16_t temperatureMax = MAX_TEMPERATURE_VALUE; Attributes::ColorTempPhysicalMaxMireds::Get(endpoint, &temperatureMax); - if (transitionTime == 0) - { - transitionTime++; - } - // New command. Need to stop any active transitions. stopAllColorTransitions(endpoint); @@ -2088,14 +2076,15 @@ Status ColorControlServer::moveToColorTemp(EndpointId aEndpoint, uint16_t colorT Attributes::ColorTemperatureMireds::Get(endpoint, &(colorTempTransitionState->currentValue)); colorTempTransitionState->finalValue = colorTemperature; - colorTempTransitionState->stepsRemaining = transitionTime; - colorTempTransitionState->stepsTotal = transitionTime; + colorTempTransitionState->stepsRemaining = max(transitionTime, 1); + colorTempTransitionState->stepsTotal = colorTempTransitionState->stepsRemaining; + colorTempTransitionState->timeRemaining = transitionTime; colorTempTransitionState->endpoint = endpoint; colorTempTransitionState->lowLimit = temperatureMin; colorTempTransitionState->highLimit = temperatureMax; // kick off the state machine - scheduleTimerCallbackMs(configureTempEventControl(endpoint), UPDATE_TIME_MS); + scheduleTimerCallbackMs(configureTempEventControl(endpoint), transitionTime ? UPDATE_TIME_MS : 0); return Status::Success; } @@ -2201,7 +2190,7 @@ void ColorControlServer::updateTempCommand(EndpointId endpoint) isColorTempTransitionDone = computeNewColor16uValue(colorTempTransitionState); - Attributes::RemainingTime::Set(endpoint, colorTempTransitionState->stepsRemaining); + Attributes::RemainingTime::Set(endpoint, colorTempTransitionState->timeRemaining); if (isColorTempTransitionDone) { @@ -2316,6 +2305,7 @@ bool ColorControlServer::moveColorTempCommand(app::CommandHandler * commandObj, transitionTime = computeTransitionTimeFromStateAndRate(colorTempTransitionState, rate); colorTempTransitionState->stepsRemaining = transitionTime; colorTempTransitionState->stepsTotal = transitionTime; + colorTempTransitionState->timeRemaining = transitionTime; colorTempTransitionState->endpoint = endpoint; colorTempTransitionState->lowLimit = colorTemperatureMinimum; colorTempTransitionState->highLimit = colorTemperatureMaximum; @@ -2388,11 +2378,6 @@ bool ColorControlServer::stepColorTempCommand(app::CommandHandler * commandObj, Attributes::ColorTempPhysicalMinMireds::Get(endpoint, &tempPhysicalMin); Attributes::ColorTempPhysicalMaxMireds::Get(endpoint, &tempPhysicalMax); - if (transitionTime == 0) - { - transitionTime++; - } - if (colorTemperatureMinimum < tempPhysicalMin) { colorTemperatureMinimum = tempPhysicalMin; @@ -2434,8 +2419,9 @@ bool ColorControlServer::stepColorTempCommand(app::CommandHandler * commandObj, colorTempTransitionState->finalValue = static_cast(finalValue32u); } } - colorTempTransitionState->stepsRemaining = transitionTime; - colorTempTransitionState->stepsTotal = transitionTime; + colorTempTransitionState->stepsRemaining = max(transitionTime, 1); + colorTempTransitionState->stepsTotal = colorTempTransitionState->stepsRemaining; + colorTempTransitionState->timeRemaining = transitionTime; colorTempTransitionState->endpoint = endpoint; colorTempTransitionState->lowLimit = colorTemperatureMinimum; colorTempTransitionState->highLimit = colorTemperatureMaximum; @@ -2443,7 +2429,7 @@ bool ColorControlServer::stepColorTempCommand(app::CommandHandler * commandObj, Attributes::RemainingTime::Set(endpoint, transitionTime); // kick off the state machine: - scheduleTimerCallbackMs(configureTempEventControl(endpoint), UPDATE_TIME_MS); + scheduleTimerCallbackMs(configureTempEventControl(endpoint), transitionTime ? UPDATE_TIME_MS : 0); exit: commandObj->AddStatus(commandPath, status); 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 5f73e6a37475e3..cc3c03fa5e8e70 100644 --- a/src/app/clusters/color-control-server/color-control-server.h +++ b/src/app/clusters/color-control-server/color-control-server.h @@ -102,6 +102,9 @@ class ColorControlServer uint8_t finalHue; uint16_t stepsRemaining; uint16_t stepsTotal; + // 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; uint16_t initialEnhancedHue; uint16_t currentEnhancedHue; uint16_t finalEnhancedHue; @@ -118,6 +121,8 @@ class ColorControlServer uint16_t finalValue; uint16_t stepsRemaining; uint16_t stepsTotal; + // The amount of time remaining until the transition completes. Measured in tenths of a second. + uint16_t timeRemaining; uint16_t lowLimit; uint16_t highLimit; chip::EndpointId endpoint;