2 * Copyright (c) 2010-2024 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 newState) {
65 return hsbToString(newState);
66 } else if (command instanceof PercentType percentCommand && state instanceof HSBType hsb) {
67 HSBType newState = new HSBType(hsb.getHue(), hsb.getSaturation(), percentCommand);
69 return hsbToString(newState);
72 throw new IllegalArgumentException("Command type '" + command.toString() + "' not supported");
76 public State toState(String string) {
77 State newState = UnDefType.UNDEF;
78 if (string.equals(channelConfig.onValue)) {
79 if (state instanceof HSBType hsb) {
80 newState = new HSBType(hsb.getHue(), hsb.getSaturation(), PercentType.HUNDRED);
82 newState = HSBType.WHITE;
84 } else if (string.equals(channelConfig.offValue)) {
85 if (state instanceof HSBType hsb) {
86 newState = new HSBType(hsb.getHue(), hsb.getSaturation(), PercentType.ZERO);
88 newState = HSBType.BLACK;
90 } else if (string.equals(channelConfig.increaseValue) && state instanceof HSBType hsb) {
91 BigDecimal newBrightness = hsb.getBrightness().toBigDecimal().add(channelConfig.step);
92 if (HUNDRED.compareTo(newBrightness) < 0) {
93 newBrightness = HUNDRED;
95 newState = new HSBType(hsb.getHue(), hsb.getSaturation(), new PercentType(newBrightness));
96 } else if (string.equals(channelConfig.decreaseValue) && state instanceof HSBType hsb) {
97 BigDecimal newBrightness = hsb.getBrightness().toBigDecimal().subtract(channelConfig.step);
98 if (BigDecimal.ZERO.compareTo(newBrightness) > 0) {
99 newBrightness = BigDecimal.ZERO;
101 newState = new HSBType(hsb.getHue(), hsb.getSaturation(), new PercentType(newBrightness));
103 Matcher matcher = TRIPLE_MATCHER.matcher(string);
104 if (matcher.matches()) {
105 switch (channelConfig.colorMode) {
107 int r = Integer.parseInt(matcher.group(1));
108 int g = Integer.parseInt(matcher.group(2));
109 int b = Integer.parseInt(matcher.group(3));
110 newState = HSBType.fromRGB(r, g, b);
113 newState = new HSBType(string);
123 private String hsbToString(HSBType state) {
124 switch (channelConfig.colorMode) {
126 PercentType[] rgb = state.toRGB();
127 return String.format("%1$d,%2$d,%3$d", rgb[0].toBigDecimal().multiply(BYTE_FACTOR).intValue(),
128 rgb[1].toBigDecimal().multiply(BYTE_FACTOR).intValue(),
129 rgb[2].toBigDecimal().multiply(BYTE_FACTOR).intValue());
131 return state.toString();
133 throw new IllegalStateException("Invalid colorMode setting");
136 public enum ColorMode {