]> git.basschouten.com Git - openhab-addons.git/blob
c6aaaa72635f9bc04e7b0c7ca95c5e559b400103
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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  * A dimmer type of control on Loxone Miniserver.
30  * <p>
31  * According to Loxone API documentation, a dimmer control is:
32  * <ul>
33  * <li>a virtual input of dimmer type
34  * </ul>
35  *
36  * @author Stephan Brunner - initial contribution
37  *
38  */
39 class LxControlDimmer extends LxControl {
40
41     static class Factory extends LxControlInstance {
42         @Override
43         LxControl create(LxUuid uuid) {
44             return new LxControlDimmer(uuid);
45         }
46
47         @Override
48         String getType() {
49             return "dimmer";
50         }
51     }
52
53     /**
54      * States
55      */
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";
60
61     /**
62      * Command string used to set the dimmer ON
63      */
64     private static final String CMD_ON = "On";
65     /**
66      * Command string used to set the dimmer to OFF
67      */
68     private static final String CMD_OFF = "Off";
69
70     private LxControlDimmer(LxUuid uuid) {
71         super(uuid);
72     }
73
74     @Override
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);
80         }
81         addChannel("Dimmer", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_DIMMER), defaultChannelLabel,
82                 "Dimmer", tags, this::handleCommands, this::getChannelState);
83     }
84
85     private void handleCommands(Command command) throws IOException {
86         if (command instanceof OnOffType) {
87             if (command == OnOffType.ON) {
88                 sendAction(CMD_ON);
89             } else {
90                 sendAction(CMD_OFF);
91             }
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) {
102                     value += step;
103                     if (value > max) {
104                         value = max;
105                     }
106                 } else {
107                     value -= step;
108                     if (value < min) {
109                         value = min;
110                     }
111                 }
112                 sendAction(value.toString());
113             }
114         }
115     }
116
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());
121         }
122         return null;
123     }
124
125     /**
126      * Sets the current position of the dimmer
127      *
128      * @param position position to move to (0-100, 0 - full off, 100 - full on)
129      * @throws IOException error communicating with the Miniserver
130      */
131     private void setPosition(Double position) throws IOException {
132         Double loxonePosition = mapOHToLoxone(position);
133         if (loxonePosition != null) {
134             sendAction(loxonePosition.toString());
135         }
136     }
137
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) {
142                 return 0.0;
143             }
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);
148             }
149         }
150         return null;
151     }
152
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) {
157                 return 0.0;
158             }
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
164             }
165         }
166         return null;
167     }
168 }