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;
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 * An EIB dimmer type of control on Loxone Miniserver.
31 * This control is absent in the API documentation. It looks like it behaves like a normal Dimmer, but it is missing the
32 * information about min, max and step values.
34 * @author Pawel Pieczul - initial contribution
37 class LxControlEIBDimmer extends LxControl {
39 static class Factory extends LxControlInstance {
41 LxControl create(LxUuid uuid) {
42 return new LxControlEIBDimmer(uuid);
54 private static final String STATE_POSITION = "position";
55 private static final Double DEFAULT_MIN = 0.0;
56 private static final Double DEFAULT_MAX = 100.0;
57 private static final Double DEFAULT_STEP = 5.0;
60 * Command string used to set the dimmer ON
62 private static final String CMD_ON = "On";
64 * Command string used to set the dimmer to OFF
66 private static final String CMD_OFF = "Off";
68 LxControlEIBDimmer(LxUuid uuid) {
73 public void initialize(LxControlConfig config) {
74 super.initialize(config);
75 LxCategory category = getCategory();
76 if (category != null && category.getType() == LxCategory.CategoryType.LIGHTS) {
77 tags.addAll(LxTags.LIGHTING);
79 addChannel("Dimmer", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_DIMMER), defaultChannelLabel,
80 "Dimmer", tags, this::handleCommands, this::getChannelState);
95 private void handleCommands(Command command) throws IOException {
96 if (command instanceof OnOffType) {
97 if (command == OnOffType.ON) {
102 } else if (command instanceof PercentType percentCommand) {
103 setPosition(percentCommand.doubleValue());
104 } else if (command instanceof IncreaseDecreaseType increaseDecreaseCommand) {
105 Double value = getStateDoubleValue(STATE_POSITION);
106 Double min = getMin();
107 Double max = getMax();
108 Double step = getStep();
109 if (value != null && max != null && min != null && step != null && min >= 0 && max >= 0 && max > min) {
110 if (increaseDecreaseCommand == IncreaseDecreaseType.INCREASE) {
121 sendAction(value.toString());
126 private PercentType getChannelState() {
127 Double value = mapLoxoneToOH(getStateDoubleValue(STATE_POSITION));
128 if (value != null && value >= 0 && value <= 100) {
129 return new PercentType(value.intValue());
135 * Sets the current position of the dimmer
137 * @param position position to move to (0-100, 0 - full off, 100 - full on)
138 * @throws IOException error communicating with the Miniserver
140 private void setPosition(Double position) throws IOException {
141 Double loxonePosition = mapOHToLoxone(position);
142 if (loxonePosition != null) {
143 sendAction(loxonePosition.toString());
147 private Double mapLoxoneToOH(Double loxoneValue) {
148 if (loxoneValue != null) {
149 // 0 means turn dimmer off, any value above zero should be mapped from min-max range
150 if (Double.compare(loxoneValue, 0.0) == 0) {
153 Double max = getMax();
154 Double min = getMin();
155 if (max != null && min != null && max > min && min >= 0 && max >= 0) {
156 return 100 * (loxoneValue - min) / (max - min);
162 private Double mapOHToLoxone(Double ohValue) {
163 if (ohValue != null) {
164 // 0 means turn dimmer off, any value above zero should be mapped to min-max range
165 if (Double.compare(ohValue, 0.0) == 0) {
168 Double max = getMax();
169 Double min = getMin();
170 if (max != null && min != null) {
171 return min + ohValue * (max - min) / 100; // no rounding to integer value is needed as loxone is
172 // accepting floating point values