2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.http.internal.converter;
15 import java.math.BigDecimal;
16 import java.util.function.Consumer;
17 import java.util.regex.Matcher;
18 import java.util.regex.Pattern;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.http.internal.config.HttpChannelConfig;
23 import org.openhab.binding.http.internal.transform.ValueTransformation;
24 import org.openhab.core.library.types.HSBType;
25 import org.openhab.core.library.types.PercentType;
26 import org.openhab.core.types.Command;
27 import org.openhab.core.types.State;
28 import org.openhab.core.types.UnDefType;
31 * The {@link ColorItemConverter} implements {@link org.openhab.core.library.items.ColorItem} conversions
33 * @author Jan N. Klug - Initial contribution
37 public class ColorItemConverter extends AbstractTransformingItemConverter {
38 private static final BigDecimal BYTE_FACTOR = BigDecimal.valueOf(2.55);
39 private static final BigDecimal HUNDRED = BigDecimal.valueOf(100);
40 private static final Pattern TRIPLE_MATCHER = Pattern.compile("(\\d+),(\\d+),(\\d+)");
42 private State state = UnDefType.UNDEF;
44 public ColorItemConverter(Consumer<State> updateState, Consumer<Command> postCommand,
45 @Nullable Consumer<String> sendHttpValue, ValueTransformation stateTransformations,
46 ValueTransformation commandTransformations, HttpChannelConfig channelConfig) {
47 super(updateState, postCommand, sendHttpValue, stateTransformations, commandTransformations, channelConfig);
48 this.channelConfig = channelConfig;
52 protected @Nullable Command toCommand(String value) {
57 public String toString(Command command) {
58 String string = channelConfig.commandToFixedValue(command);
63 if (command instanceof HSBType) {
64 HSBType newState = (HSBType) command;
66 return hsbToString(newState);
67 } else if (command instanceof PercentType && state instanceof HSBType) {
68 HSBType newState = new HSBType(((HSBType) state).getBrightness(), ((HSBType) state).getSaturation(),
69 (PercentType) command);
71 return hsbToString(newState);
74 throw new IllegalArgumentException("Command type '" + command.toString() + "' not supported");
78 public State toState(String string) {
79 State newState = UnDefType.UNDEF;
80 if (string.equals(channelConfig.onValue)) {
81 if (state instanceof HSBType) {
82 newState = new HSBType(((HSBType) state).getHue(), ((HSBType) state).getSaturation(),
85 newState = HSBType.WHITE;
87 } else if (string.equals(channelConfig.offValue)) {
88 if (state instanceof HSBType) {
89 newState = new HSBType(((HSBType) state).getHue(), ((HSBType) state).getSaturation(), PercentType.ZERO);
91 newState = HSBType.BLACK;
93 } else if (string.equals(channelConfig.increaseValue) && state instanceof HSBType) {
94 BigDecimal newBrightness = ((HSBType) state).getBrightness().toBigDecimal().add(channelConfig.step);
95 if (HUNDRED.compareTo(newBrightness) < 0) {
96 newBrightness = HUNDRED;
98 newState = new HSBType(((HSBType) state).getHue(), ((HSBType) state).getSaturation(),
99 new PercentType(newBrightness));
100 } else if (string.equals(channelConfig.decreaseValue) && state instanceof HSBType) {
101 BigDecimal newBrightness = ((HSBType) state).getBrightness().toBigDecimal().subtract(channelConfig.step);
102 if (BigDecimal.ZERO.compareTo(newBrightness) > 0) {
103 newBrightness = BigDecimal.ZERO;
105 newState = new HSBType(((HSBType) state).getHue(), ((HSBType) state).getSaturation(),
106 new PercentType(newBrightness));
108 Matcher matcher = TRIPLE_MATCHER.matcher(string);
109 if (matcher.matches()) {
110 switch (channelConfig.colorMode) {
112 int r = Integer.parseInt(matcher.group(1));
113 int g = Integer.parseInt(matcher.group(2));
114 int b = Integer.parseInt(matcher.group(3));
115 newState = HSBType.fromRGB(r, g, b);
118 newState = new HSBType(string);
128 private String hsbToString(HSBType state) {
129 switch (channelConfig.colorMode) {
131 PercentType[] rgb = state.toRGB();
132 return String.format("%1$d,%2$d,%3$d", rgb[0].toBigDecimal().multiply(BYTE_FACTOR).intValue(),
133 rgb[1].toBigDecimal().multiply(BYTE_FACTOR).intValue(),
134 rgb[2].toBigDecimal().multiply(BYTE_FACTOR).intValue());
136 return state.toString();
138 throw new IllegalStateException("Invalid colorMode setting");
141 public enum ColorMode {