]> git.basschouten.com Git - openhab-addons.git/blob
36c061398f65f47dcbbc4f9a9cfdd657c261f831
[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
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;
27
28 /**
29  * An EIB dimmer type of control on Loxone Miniserver.
30  * <p>
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.
33  *
34  * @author Pawel Pieczul - initial contribution
35  *
36  */
37 class LxControlEIBDimmer extends LxControl {
38
39     static class Factory extends LxControlInstance {
40         @Override
41         LxControl create(LxUuid uuid) {
42             return new LxControlEIBDimmer(uuid);
43         }
44
45         @Override
46         String getType() {
47             return "eibdimmer";
48         }
49     }
50
51     /**
52      * States
53      */
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;
58
59     /**
60      * Command string used to set the dimmer ON
61      */
62     private static final String CMD_ON = "On";
63     /**
64      * Command string used to set the dimmer to OFF
65      */
66     private static final String CMD_OFF = "Off";
67
68     LxControlEIBDimmer(LxUuid uuid) {
69         super(uuid);
70     }
71
72     @Override
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);
78         }
79         addChannel("Dimmer", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_DIMMER), defaultChannelLabel,
80                 "Dimmer", tags, this::handleCommands, this::getChannelState);
81     }
82
83     Double getMin() {
84         return DEFAULT_MIN;
85     }
86
87     Double getMax() {
88         return DEFAULT_MAX;
89     }
90
91     Double getStep() {
92         return DEFAULT_STEP;
93     }
94
95     private void handleCommands(Command command) throws IOException {
96         if (command instanceof OnOffType) {
97             if (command == OnOffType.ON) {
98                 sendAction(CMD_ON);
99             } else {
100                 sendAction(CMD_OFF);
101             }
102         } else if (command instanceof PercentType) {
103             PercentType percentCmd = (PercentType) command;
104             setPosition(percentCmd.doubleValue());
105         } else if (command instanceof IncreaseDecreaseType) {
106             Double value = getStateDoubleValue(STATE_POSITION);
107             Double min = getMin();
108             Double max = getMax();
109             Double step = getStep();
110             if (value != null && max != null && min != null && step != null && min >= 0 && max >= 0 && max > min) {
111                 if ((IncreaseDecreaseType) command == IncreaseDecreaseType.INCREASE) {
112                     value += step;
113                     if (value > max) {
114                         value = max;
115                     }
116                 } else {
117                     value -= step;
118                     if (value < min) {
119                         value = min;
120                     }
121                 }
122                 sendAction(value.toString());
123             }
124         }
125     }
126
127     private PercentType getChannelState() {
128         Double value = mapLoxoneToOH(getStateDoubleValue(STATE_POSITION));
129         if (value != null && value >= 0 && value <= 100) {
130             return new PercentType(value.intValue());
131         }
132         return null;
133     }
134
135     /**
136      * Sets the current position of the dimmer
137      *
138      * @param position position to move to (0-100, 0 - full off, 100 - full on)
139      * @throws IOException error communicating with the Miniserver
140      */
141     private void setPosition(Double position) throws IOException {
142         Double loxonePosition = mapOHToLoxone(position);
143         if (loxonePosition != null) {
144             sendAction(loxonePosition.toString());
145         }
146     }
147
148     private Double mapLoxoneToOH(Double loxoneValue) {
149         if (loxoneValue != null) {
150             // 0 means turn dimmer off, any value above zero should be mapped from min-max range
151             if (Double.compare(loxoneValue, 0.0) == 0) {
152                 return 0.0;
153             }
154             Double max = getMax();
155             Double min = getMin();
156             if (max != null && min != null && max > min && min >= 0 && max >= 0) {
157                 return 100 * (loxoneValue - min) / (max - min);
158             }
159         }
160         return null;
161     }
162
163     private Double mapOHToLoxone(Double ohValue) {
164         if (ohValue != null) {
165             // 0 means turn dimmer off, any value above zero should be mapped to min-max range
166             if (Double.compare(ohValue, 0.0) == 0) {
167                 return 0.0;
168             }
169             Double max = getMax();
170             Double min = getMin();
171             if (max != null && min != null) {
172                 double value = min + ohValue * (max - min) / 100;
173                 return value; // no rounding to integer value is needed as loxone is accepting floating point values
174             }
175         }
176         return null;
177     }
178 }