]> git.basschouten.com Git - openhab-addons.git/blob
e21b3ffd692fff2132cd8defe777fb7b202e3af1
[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 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) {
111                     value += step;
112                     if (value > max) {
113                         value = max;
114                     }
115                 } else {
116                     value -= step;
117                     if (value < min) {
118                         value = min;
119                     }
120                 }
121                 sendAction(value.toString());
122             }
123         }
124     }
125
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());
130         }
131         return null;
132     }
133
134     /**
135      * Sets the current position of the dimmer
136      *
137      * @param position position to move to (0-100, 0 - full off, 100 - full on)
138      * @throws IOException error communicating with the Miniserver
139      */
140     private void setPosition(Double position) throws IOException {
141         Double loxonePosition = mapOHToLoxone(position);
142         if (loxonePosition != null) {
143             sendAction(loxonePosition.toString());
144         }
145     }
146
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) {
151                 return 0.0;
152             }
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);
157             }
158         }
159         return null;
160     }
161
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) {
166                 return 0.0;
167             }
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
173             }
174         }
175         return null;
176     }
177 }