2 * Copyright (c) 2010-2021 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;
19 import org.openhab.binding.loxone.internal.types.LxCategory;
20 import org.openhab.binding.loxone.internal.types.LxTags;
21 import org.openhab.binding.loxone.internal.types.LxUuid;
22 import org.openhab.core.library.types.IncreaseDecreaseType;
23 import org.openhab.core.library.types.OnOffType;
24 import org.openhab.core.library.types.PercentType;
25 import org.openhab.core.thing.type.ChannelTypeUID;
26 import org.openhab.core.types.Command;
29 * A dimmer type of control on Loxone Miniserver.
31 * According to Loxone API documentation, a dimmer control is:
33 * <li>a virtual input of dimmer type
36 * @author Stephan Brunner - initial contribution
39 class LxControlDimmer extends LxControl {
41 static class Factory extends LxControlInstance {
43 LxControl create(LxUuid uuid) {
44 return new LxControlDimmer(uuid);
56 private static final String STATE_POSITION = "position";
57 private static final String STATE_MIN = "min";
58 private static final String STATE_MAX = "max";
59 private static final String STATE_STEP = "step";
62 * Command string used to set the dimmer ON
64 private static final String CMD_ON = "On";
66 * Command string used to set the dimmer to OFF
68 private static final String CMD_OFF = "Off";
70 private LxControlDimmer(LxUuid uuid) {
75 public void initialize(LxControlConfig config) {
76 super.initialize(config);
77 LxCategory category = getCategory();
78 if (category != null && category.getType() == LxCategory.CategoryType.LIGHTS) {
79 tags.addAll(LxTags.LIGHTING);
81 addChannel("Dimmer", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_DIMMER), defaultChannelLabel,
82 "Dimmer", tags, this::handleCommands, this::getChannelState);
85 private void handleCommands(Command command) throws IOException {
86 if (command instanceof OnOffType) {
87 if (command == OnOffType.ON) {
92 } else if (command instanceof PercentType) {
93 PercentType percentCmd = (PercentType) command;
94 setPosition(percentCmd.doubleValue());
95 } else if (command instanceof IncreaseDecreaseType) {
96 Double value = getStateDoubleValue(STATE_POSITION);
97 Double min = getStateDoubleValue(STATE_MIN);
98 Double max = getStateDoubleValue(STATE_MAX);
99 Double step = getStateDoubleValue(STATE_STEP);
100 if (value != null && max != null && min != null && step != null && min >= 0 && max >= 0 && max > min) {
101 if ((IncreaseDecreaseType) command == IncreaseDecreaseType.INCREASE) {
112 sendAction(value.toString());
117 private PercentType getChannelState() {
118 Double value = mapLoxoneToOH(getStateDoubleValue(STATE_POSITION));
119 if (value != null && value >= 0 && value <= 100) {
120 return new PercentType(value.intValue());
126 * Sets the current position of the dimmer
128 * @param position position to move to (0-100, 0 - full off, 100 - full on)
129 * @throws IOException error communicating with the Miniserver
131 private void setPosition(Double position) throws IOException {
132 Double loxonePosition = mapOHToLoxone(position);
133 if (loxonePosition != null) {
134 sendAction(loxonePosition.toString());
138 private Double mapLoxoneToOH(Double loxoneValue) {
139 if (loxoneValue != null) {
140 // 0 means turn dimmer off, any value above zero should be mapped from min-max range
141 if (Double.compare(loxoneValue, 0.0) == 0) {
144 Double max = getStateDoubleValue(STATE_MAX);
145 Double min = getStateDoubleValue(STATE_MIN);
146 if (max != null && min != null && max > min && min >= 0 && max >= 0) {
147 return 100 * (loxoneValue - min) / (max - min);
153 private Double mapOHToLoxone(Double ohValue) {
154 if (ohValue != null) {
155 // 0 means turn dimmer off, any value above zero should be mapped to min-max range
156 if (Double.compare(ohValue, 0.0) == 0) {
159 Double max = getStateDoubleValue(STATE_MAX);
160 Double min = getStateDoubleValue(STATE_MIN);
161 if (max != null && min != null) {
162 double value = min + ohValue * (max - min) / 100;
163 return value; // no rounding to integer value is needed as loxone is accepting floating point values