]> git.basschouten.com Git - openhab-addons.git/blob
272daf18db23dffe080d52d3bc97c4418489597a
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.http.internal.converter;
14
15 import java.math.BigDecimal;
16 import java.util.function.Consumer;
17 import java.util.regex.Matcher;
18 import java.util.regex.Pattern;
19
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;
29
30 /**
31  * The {@link ColorItemConverter} implements {@link org.openhab.core.library.items.ColorItem} conversions
32  *
33  * @author Jan N. Klug - Initial contribution
34  */
35
36 @NonNullByDefault
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+)");
41
42     private State state = UnDefType.UNDEF;
43
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;
49     }
50
51     @Override
52     protected @Nullable Command toCommand(String value) {
53         return null;
54     }
55
56     @Override
57     public String toString(Command command) {
58         String string = channelConfig.commandToFixedValue(command);
59         if (string != null) {
60             return string;
61         }
62
63         if (command instanceof HSBType) {
64             HSBType newState = (HSBType) command;
65             state = newState;
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);
70             state = newState;
71             return hsbToString(newState);
72         }
73
74         throw new IllegalArgumentException("Command type '" + command.toString() + "' not supported");
75     }
76
77     @Override
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(),
83                         PercentType.HUNDRED);
84             } else {
85                 newState = HSBType.WHITE;
86             }
87         } else if (string.equals(channelConfig.offValue)) {
88             if (state instanceof HSBType) {
89                 newState = new HSBType(((HSBType) state).getHue(), ((HSBType) state).getSaturation(), PercentType.ZERO);
90             } else {
91                 newState = HSBType.BLACK;
92             }
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;
97             }
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;
104             }
105             newState = new HSBType(((HSBType) state).getHue(), ((HSBType) state).getSaturation(),
106                     new PercentType(newBrightness));
107         } else {
108             Matcher matcher = TRIPLE_MATCHER.matcher(string);
109             if (matcher.matches()) {
110                 switch (channelConfig.colorMode) {
111                     case RGB:
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);
116                         break;
117                     case HSB:
118                         newState = new HSBType(string);
119                         break;
120                 }
121             }
122         }
123
124         state = newState;
125         return newState;
126     }
127
128     private String hsbToString(HSBType state) {
129         switch (channelConfig.colorMode) {
130             case RGB:
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());
135             case HSB:
136                 return state.toString();
137         }
138         throw new IllegalStateException("Invalid colorMode setting");
139     }
140
141     public enum ColorMode {
142         RGB,
143         HSB
144     }
145 }