]> git.basschouten.com Git - openhab-addons.git/blob
0be247e3dbcd688bd7e24b5a6703cf577120464c
[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.loxone.internal.controls;
14
15 import static org.openhab.binding.loxone.internal.LxBindingConstants.*;
16
17 import java.io.IOException;
18 import java.util.regex.Matcher;
19 import java.util.regex.Pattern;
20
21 import org.openhab.binding.loxone.internal.types.LxTemperatureHSBType;
22 import org.openhab.binding.loxone.internal.types.LxUuid;
23 import org.openhab.core.library.types.DecimalType;
24 import org.openhab.core.library.types.HSBType;
25 import org.openhab.core.library.types.IncreaseDecreaseType;
26 import org.openhab.core.library.types.OnOffType;
27 import org.openhab.core.library.types.PercentType;
28 import org.openhab.core.thing.type.ChannelTypeUID;
29 import org.openhab.core.types.Command;
30
31 /**
32  * A Color Picker V2 type of control on Loxone Miniserver.
33  * <p>
34  * According to Loxone API documentation, a color picker control covers:
35  * <ul>
36  * <li>Color (Hue/Saturation/Brightness)
37  * </ul>
38  *
39  * @author Michael Mattan - initial contribution
40  *
41  */
42 class LxControlColorPickerV2 extends LxControl {
43
44     static class Factory extends LxControlInstance {
45         @Override
46         LxControl create(LxUuid uuid) {
47             return new LxControlColorPickerV2(uuid);
48         }
49
50         @Override
51         String getType() {
52             return "colorpickerv2";
53         }
54     }
55
56     /**
57      * Color state
58      */
59     private static final String STATE_COLOR = "color";
60
61     private LxControlColorPickerV2(LxUuid uuid) {
62         super(uuid);
63     }
64
65     @Override
66     public void initialize(LxControlConfig config) {
67         super.initialize(config);
68         addChannel("Color", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_COLORPICKER), defaultChannelLabel,
69                 "Color Picker", tags, this::handleCommands, this::getColor);
70     }
71
72     private void handleCommands(Command command) throws IOException {
73         if (command instanceof HSBType) {
74             setColor((HSBType) command);
75         } else if (command instanceof OnOffType) {
76             if (command == OnOffType.ON) {
77                 on();
78             } else {
79                 off();
80             }
81         } else if (command instanceof DecimalType) {
82             setBrightness((DecimalType) command);
83         } else if (command instanceof PercentType) {
84             setBrightness((PercentType) command);
85         } else if (command instanceof IncreaseDecreaseType) {
86             if (((IncreaseDecreaseType) command).equals(IncreaseDecreaseType.INCREASE)) {
87                 increaseDecreaseBrightness(1);
88             } else {
89                 increaseDecreaseBrightness(-1);
90             }
91         }
92     }
93
94     /**
95      * Gets the current Loxone color in HSBType format
96      *
97      * @return the HSBType color
98      */
99     private HSBType getColor() {
100         HSBType hsbColor = null;
101         String color = getStateTextValue(STATE_COLOR);
102         if (color != null) {
103             hsbColor = this.mapLoxoneToOH(color);
104         }
105         return hsbColor;
106     }
107
108     /**
109      * Sets the color of the color picker
110      *
111      * @param hsb the color to set
112      * @throws IOException error communicating with the Miniserver
113      */
114     private void setColor(HSBType hsb) throws IOException {
115         HSBType currentColor = getColor();
116         if (currentColor == null || !currentColor.toString().equals(hsb.toString())) {
117             // only update the color when it changed
118             // this prevents a mood switch in the Light Controller when the color did not change anyway
119             sendAction("hsv(" + hsb.toString() + ")");
120         }
121     }
122
123     /**
124      * Sets the color picker to on
125      *
126      * @throws IOException error communicating with the Miniserver
127      */
128     private void on() throws IOException {
129         HSBType currentColor = getColor();
130         if (currentColor != null) {
131             setColor(new HSBType(currentColor.getHue(), currentColor.getSaturation(), PercentType.HUNDRED));
132         }
133     }
134
135     /**
136      * Sets the color picker to off
137      *
138      * @throws IOException error communicating with the Miniserver
139      */
140     private void off() throws IOException {
141         HSBType currentColor = getColor();
142         if (currentColor != null) {
143             setColor(new HSBType(currentColor.getHue(), currentColor.getSaturation(), PercentType.ZERO));
144         }
145     }
146
147     /**
148      * set the brightness level
149      *
150      * @param p the brightness percentage
151      * @throws IOException error communicating with the Miniserver
152      */
153     private void setBrightness(PercentType p) throws IOException {
154         HSBType currentColor = this.getColor();
155         if (currentColor != null) {
156             setColor(new HSBType(currentColor.getHue(), currentColor.getSaturation(), p));
157         }
158     }
159
160     /**
161      * set the brightness level from a decimal type
162      *
163      * @param d the brightness in decimal
164      * @throws IOException error communicating with the Miniserver
165      */
166     private void setBrightness(DecimalType d) throws IOException {
167         setBrightness(new PercentType(d.toBigDecimal()));
168     }
169
170     /**
171      * Increases/decreases the brightness with a given step
172      *
173      * @param step the amount to increase/decrease
174      * @throws IOException error communicating with the Miniserver
175      */
176     private void increaseDecreaseBrightness(int step) throws IOException {
177         HSBType currentColor = this.getColor();
178         if (currentColor != null) {
179             setBrightness(new PercentType(currentColor.getBrightness().intValue() + step));
180         }
181     }
182
183     /**
184      * Map Loxone color to OpenHab HSBType
185      *
186      * @param color color in format hsb(h,s,v) or temp(brightness,kelvin)
187      * @return HSBType
188      */
189     private HSBType mapLoxoneToOH(String color) {
190         HSBType hsbColor = null;
191
192         try {
193             Pattern hsvPattern = Pattern.compile("^hsv\\([0-9]\\d{0,2},[0-9]\\d{0,2},[0-9]\\d{0,2}\\)");
194             Pattern tempPattern = Pattern.compile("^temp\\([0-9]\\d{0,2},[0-9]\\d{0,4}\\)");
195             Matcher valueMatcher = Pattern.compile("\\((.*?)\\)").matcher(color);
196
197             if (hsvPattern.matcher(color).matches() && valueMatcher.find()) {
198                 // we have a hsv(hue,saturation,value) pattern
199                 hsbColor = new HSBType(valueMatcher.group(1));
200             } else if (tempPattern.matcher(color).matches() && valueMatcher.find()) {
201                 // we have a temp(brightness,kelvin) pattern
202                 hsbColor = LxTemperatureHSBType.fromBrightnessTemperature(valueMatcher.group(1));
203             }
204         } catch (IllegalArgumentException e) {
205             // an error happened during HSBType creation, we return null
206             hsbColor = null;
207         }
208         return hsbColor;
209     }
210 }