Skip to content

Commit 49d6fcc

Browse files
committed
Treat gradients with equal points as single color state
1 parent 7938fd6 commit 49d6fcc

5 files changed

Lines changed: 316 additions & 17 deletions

File tree

src/main/java/at/sv/hue/InputConfigurationParser.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,15 @@ public List<ScheduledState> parse(String input) {
163163
.map(point -> parseColorValue(point, capabilities))
164164
.map(color -> Pair.of(color.x(), color.y()))
165165
.toList();
166-
gradient = Gradient.builder()
167-
.points(points)
168-
.mode(m.group("mode"))
169-
.build();
166+
if (points.stream().distinct().count() == 1) {
167+
x = points.getFirst().first();
168+
y = points.getFirst().second();
169+
} else {
170+
gradient = Gradient.builder()
171+
.points(points)
172+
.mode(m.group("mode"))
173+
.build();
174+
}
170175
break;
171176
case "effect":
172177
value = value.trim();

src/main/java/at/sv/hue/api/hue/HueApiImpl.java

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -740,13 +740,19 @@ private ScheduledLightState createScheduledLightState(SceneAction sceneAction) {
740740
}
741741
if (action.getGradient() != null) {
742742
Action.Gradient gradient = action.getGradient();
743-
List<Pair<Double, Double>> points = gradient.getPoints()
744-
.stream()
745-
.map(point ->
746-
Pair.of(point.getColor().getXy().getX(),
747-
point.getColor().getXy().getY()))
748-
.toList();
749-
state.gradient(new Gradient(points, gradient.getMode()));
743+
if (gradient.getPoints().stream().distinct().count() == 1) {
744+
XY xy = gradient.getPoints().getFirst().getColor().getXy();
745+
state.x(xy.getX());
746+
state.y(xy.getY());
747+
} else {
748+
List<Pair<Double, Double>> points = gradient.getPoints()
749+
.stream()
750+
.map(point ->
751+
Pair.of(point.getColor().getXy().getX(),
752+
point.getColor().getXy().getY()))
753+
.toList();
754+
state.gradient(new Gradient(points, gradient.getMode()));
755+
}
750756
}
751757
// todo: transition time?
752758
return state.build();

src/main/java/at/sv/hue/api/hue/Light.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ private at.sv.hue.Gradient getGradient() {
8383
if (gradient == null) {
8484
return null;
8585
}
86+
if (gradient.getPoints().stream().distinct().count() == 1) {
87+
return null;
88+
}
8689
return gradient.getGradient();
8790
}
8891

src/test/java/at/sv/hue/HueSchedulerTest.java

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3685,13 +3685,16 @@ void parse_gradient_invalidFormat_exception() {
36853685
}
36863686

36873687
@Test
3688-
void parse_gradient_rgb_justOnePoint_exception() {
3688+
void parse_gradient_rgb_justOnePoint_convertedToXY() {
36893689
addKnownLightIdsWithDefaultCapabilities(1);
3690+
addStateNow("1", "gradient:[xy(0.3 0.4)]");
3691+
ScheduledRunnable scheduledRunnable = startAndGetSingleRunnable();
36903692

3691-
assertThatThrownBy(() -> addStateNow("1", "gradient:[rgb(94 186 125)]"))
3692-
.isInstanceOf(InvalidPropertyValue.class)
3693-
.hasMessageStartingWith("Invalid gradient")
3694-
.hasMessageContaining("A gradient must contain at least two colors.");
3693+
advanceTimeAndRunAndAssertPutCalls(scheduledRunnable,
3694+
expectedPutCall(1).x(0.3).y(0.4)
3695+
);
3696+
3697+
ensureRunnable(initialNow.plusDays(1));
36953698
}
36963699

36973700
@Test
@@ -3700,7 +3703,7 @@ void parse_gradient_rgb_twoManyPoints_exception() {
37003703
.maxGradientPoints(2)
37013704
.capabilities(EnumSet.of(Capability.GRADIENT)));
37023705

3703-
assertThatThrownBy(() -> addStateNow("1", "gradient:[rgb(94 186 125),rgb(94 186 125),rgb(94 186 125)]"))
3706+
assertThatThrownBy(() -> addStateNow("1", "gradient:[rgb(94 186 125),rgb(94 186 125),rgb(94 186 166)]"))
37043707
.isInstanceOf(InvalidPropertyValue.class)
37053708
.hasMessageStartingWith("Invalid gradient")
37063709
.hasMessageContaining("The maximum number of gradient points for this light is 2.");
@@ -3816,6 +3819,20 @@ void parse_gradient_rgb_twoPoints() {
38163819
ensureRunnable(initialNow.plusDays(1));
38173820
}
38183821

3822+
@Test
3823+
void parse_gradient_xy_twoPoints_same_convertedToXY() {
3824+
addKnownLightIdsWithDefaultCapabilities(1);
3825+
addStateNow( "1", "bri:100", "gradient:[xy(0.3 0.4),xy(0.3 0.4)]");
3826+
3827+
ScheduledRunnable scheduledRunnable = startAndGetSingleRunnable();
3828+
3829+
advanceTimeAndRunAndAssertPutCalls(scheduledRunnable,
3830+
expectedPutCall(1).bri(100).x(0.3).y(0.4)
3831+
);
3832+
3833+
ensureRunnable(initialNow.plusDays(1));
3834+
}
3835+
38193836
@Test
38203837
void parse_gradient_rgb_twoPoints_withMode_correctlyParsed() {
38213838
addKnownLightIdsWithDefaultCapabilities(1);
@@ -4518,6 +4535,20 @@ void parse_sunset_withSmooth_inSpring_handlesDST() {
45184535
);
45194536
}
45204537

4538+
@Test
4539+
void parse_complexStartTimeExpression_canBeParsed() {
4540+
addKnownLightIdsWithDefaultCapabilities(1);
4541+
addState(1, now, "bri:100%");
4542+
addState(1, "clamp(smooth(mix(sunset+20, 21:15, 70%), 10d), max(18:30, mix(sunset-15, 19:00, 40%)), min(22:45, mix(sunset+150, 21:45, 50%)))", "bri:50%");
4543+
// normal sunset: 16:14:29
4544+
ZonedDateTime modifiedSunset = now.with(LocalTime.of(19, 49, 22));
4545+
4546+
startScheduler(
4547+
expectedRunnable(now, modifiedSunset),
4548+
expectedRunnable(modifiedSunset, now.plusDays(1))
4549+
);
4550+
}
4551+
45214552
@Test
45224553
void parse_sunrise_callsStartTimeProvider_usesUpdatedSunriseTimeNextDay() {
45234554
addKnownLightIdsWithDefaultCapabilities(1);

0 commit comments

Comments
 (0)