18
18
// clusters specific header
19
19
#include " level-control.h"
20
20
21
+ #include < algorithm>
22
+
21
23
// this file contains all the common includes for clusters in the util
22
24
#include < app-common/zap-generated/attributes/Accessors.h>
23
25
#include < app-common/zap-generated/cluster-objects.h>
@@ -904,7 +906,7 @@ static Status moveToLevelHandler(EndpointId endpoint, CommandId commandId, uint8
904
906
905
907
// The duration between events will be the transition time divided by the
906
908
// distance we must move.
907
- state->eventDurationMs = state->transitionTimeMs / actualStepSize;
909
+ state->eventDurationMs = state->transitionTimeMs / std::max ( static_cast < uint8_t >( 1u ), actualStepSize) ;
908
910
state->elapsedTimeMs = 0 ;
909
911
910
912
state->storedLevel = storedLevel;
@@ -958,6 +960,14 @@ static void moveHandler(app::CommandHandler * commandObj, const app::ConcreteCom
958
960
goto send_default_response;
959
961
}
960
962
963
+ if (!rate.IsNull () && (rate.Value () == 0 ))
964
+ {
965
+ // Move at a rate of zero is no move at all. Immediately succeed without touching anything.
966
+ ChipLogProgress (Zcl, " Immediate success due to move rate of 0 (would move at no rate)." );
967
+ status = Status::Success;
968
+ goto send_default_response;
969
+ }
970
+
961
971
// Cancel any currently active command before fiddling with the state.
962
972
cancelEndpointTimerCallback (endpoint);
963
973
@@ -1034,12 +1044,13 @@ static void moveHandler(app::CommandHandler * commandObj, const app::ConcreteCom
1034
1044
status = Status::Success;
1035
1045
goto send_default_response;
1036
1046
}
1047
+ // Already checked that defaultMoveRate.Value() != 0.
1037
1048
state->eventDurationMs = MILLISECOND_TICKS_PER_SECOND / defaultMoveRate.Value ();
1038
1049
}
1039
1050
}
1040
1051
else
1041
1052
{
1042
- state->eventDurationMs = MILLISECOND_TICKS_PER_SECOND / rate.Value ();
1053
+ state->eventDurationMs = MILLISECOND_TICKS_PER_SECOND / std::max ( static_cast < uint8_t >( 1u ), rate.Value () );
1043
1054
}
1044
1055
#else
1045
1056
// Transition/rate is not supported so always use fastest transition time and ignore
@@ -1175,7 +1186,7 @@ static void stepHandler(app::CommandHandler * commandObj, const app::ConcreteCom
1175
1186
// milliseconds to reduce rounding errors in integer division.
1176
1187
if (stepSize != actualStepSize)
1177
1188
{
1178
- state->transitionTimeMs = (state->transitionTimeMs * actualStepSize / stepSize);
1189
+ state->transitionTimeMs = (state->transitionTimeMs * actualStepSize / std::max ( static_cast < uint8_t >( 1u ), stepSize) );
1179
1190
}
1180
1191
}
1181
1192
#else
@@ -1187,7 +1198,7 @@ static void stepHandler(app::CommandHandler * commandObj, const app::ConcreteCom
1187
1198
1188
1199
// The duration between events will be the transition time divided by the
1189
1200
// distance we must move.
1190
- state->eventDurationMs = state->transitionTimeMs / actualStepSize;
1201
+ state->eventDurationMs = state->transitionTimeMs / std::max ( static_cast < uint8_t >( 1u ), actualStepSize) ;
1191
1202
state->elapsedTimeMs = 0 ;
1192
1203
1193
1204
// storedLevel is not used for Step commands
0 commit comments