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.loxone.internal.controls;
15 import static org.openhab.binding.loxone.internal.LxBindingConstants.*;
17 import java.io.IOException;
18 import java.util.regex.Matcher;
19 import java.util.regex.Pattern;
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;
32 * A Color Picker V2 type of control on Loxone Miniserver.
34 * According to Loxone API documentation, a color picker control covers:
36 * <li>Color (Hue/Saturation/Brightness)
39 * @author Michael Mattan - initial contribution
42 class LxControlColorPickerV2 extends LxControl {
44 static class Factory extends LxControlInstance {
46 LxControl create(LxUuid uuid) {
47 return new LxControlColorPickerV2(uuid);
52 return "colorpickerv2";
59 private static final String STATE_COLOR = "color";
61 private LxControlColorPickerV2(LxUuid uuid) {
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);
72 private void handleCommands(Command command) throws IOException {
73 if (command instanceof HSBType hsbCommand) {
75 } else if (command instanceof OnOffType) {
76 if (command == OnOffType.ON) {
81 } else if (command instanceof DecimalType decimalCommand) {
82 setBrightness(decimalCommand);
83 } else if (command instanceof PercentType percentCommand) {
84 setBrightness(percentCommand);
85 } else if (command instanceof IncreaseDecreaseType increaseDecreaseCommand) {
86 if (increaseDecreaseCommand.equals(IncreaseDecreaseType.INCREASE)) {
87 increaseDecreaseBrightness(1);
89 increaseDecreaseBrightness(-1);
95 * Gets the current Loxone color in HSBType format
97 * @return the HSBType color
99 private HSBType getColor() {
100 HSBType hsbColor = null;
101 String color = getStateTextValue(STATE_COLOR);
103 hsbColor = this.mapLoxoneToOH(color);
109 * Sets the color of the color picker
111 * @param hsb the color to set
112 * @throws IOException error communicating with the Miniserver
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() + ")");
124 * Sets the color picker to on
126 * @throws IOException error communicating with the Miniserver
128 private void on() throws IOException {
129 HSBType currentColor = getColor();
130 if (currentColor != null) {
131 setColor(new HSBType(currentColor.getHue(), currentColor.getSaturation(), PercentType.HUNDRED));
136 * Sets the color picker to off
138 * @throws IOException error communicating with the Miniserver
140 private void off() throws IOException {
141 HSBType currentColor = getColor();
142 if (currentColor != null) {
143 setColor(new HSBType(currentColor.getHue(), currentColor.getSaturation(), PercentType.ZERO));
148 * set the brightness level
150 * @param p the brightness percentage
151 * @throws IOException error communicating with the Miniserver
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));
161 * set the brightness level from a decimal type
163 * @param d the brightness in decimal
164 * @throws IOException error communicating with the Miniserver
166 private void setBrightness(DecimalType d) throws IOException {
167 setBrightness(new PercentType(d.toBigDecimal()));
171 * Increases/decreases the brightness with a given step
173 * @param step the amount to increase/decrease
174 * @throws IOException error communicating with the Miniserver
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));
184 * Map Loxone color to OpenHab HSBType
186 * @param color color in format hsb(h,s,v) or temp(brightness,kelvin)
189 private HSBType mapLoxoneToOH(String color) {
190 HSBType hsbColor = null;
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);
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));
204 } catch (IllegalArgumentException e) {
205 // an error happened during HSBType creation, we return null