]> git.basschouten.com Git - openhab-addons.git/blob
7d5bc2a0c752302b79cd1ad9942a2a5b241c1875
[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 import java.math.BigDecimal;
19
20 import org.openhab.binding.loxone.internal.types.LxUuid;
21 import org.openhab.core.library.types.DecimalType;
22 import org.openhab.core.thing.ChannelUID;
23 import org.openhab.core.thing.type.ChannelTypeUID;
24 import org.openhab.core.types.Command;
25 import org.openhab.core.types.State;
26 import org.openhab.core.types.StateDescriptionFragmentBuilder;
27 import org.openhab.core.types.UnDefType;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * An UpDownAnalog type of control on Loxone Miniserver.
33  * <p>
34  * According to Loxone API documentation, UpDownAnalog control is a virtual input that is analog and has an input type
35  * up-down buttons. The analog buttons are simulated as a single analog number value.
36  *
37  * @author Pawel Pieczul - initial contribution
38  *
39  */
40 class LxControlUpDownAnalog extends LxControl {
41
42     static class Factory extends LxControlInstance {
43         @Override
44         LxControl create(LxUuid uuid) {
45             return new LxControlUpDownAnalog(uuid);
46         }
47
48         @Override
49         String getType() {
50             return "updownanalog";
51         }
52     }
53
54     private static final String STATE_VALUE = "value";
55     private static final String STATE_ERROR = "error";
56
57     private final Logger logger = LoggerFactory.getLogger(LxControlUpDownAnalog.class);
58
59     private Double minValue;
60     private Double maxValue;
61     private ChannelUID channelId;
62
63     LxControlUpDownAnalog(LxUuid uuid) {
64         super(uuid);
65     }
66
67     @Override
68     public void initialize(LxControlConfig config) {
69         initialize(config, "Up/Down Analog");
70     }
71
72     void initialize(LxControlConfig config, String channelDescription) {
73         super.initialize(config);
74         channelId = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_NUMBER),
75                 defaultChannelLabel, channelDescription, tags, this::handleCommands, this::getChannelState);
76         if (details != null && details.min != null && details.max != null) {
77             if (details.min <= details.max) {
78                 minValue = details.min;
79                 maxValue = details.max;
80                 if (details.step != null) {
81                     addChannelStateDescriptionFragment(channelId,
82                             StateDescriptionFragmentBuilder.create().withMinimum(new BigDecimal(minValue))
83                                     .withMaximum(new BigDecimal(maxValue)).withStep(new BigDecimal(details.step))
84                                     .withPattern(details.format != null ? details.format : "%.1f").withReadOnly(false)
85                                     .build());
86                 }
87             } else {
88                 logger.warn("Received min value > max value: {}, {}", minValue, maxValue);
89             }
90         }
91     }
92
93     private void handleCommands(Command command) throws IOException {
94         if (command instanceof DecimalType) {
95             Double value = ((DecimalType) command).doubleValue();
96             if (minValue != null && maxValue != null && value >= minValue && value <= maxValue) {
97                 sendAction(value.toString());
98             } else {
99                 // we'll update the state value to reflect current real value that has not been changed
100                 setChannelState(channelId, getChannelState());
101             }
102         }
103     }
104
105     private State getChannelState() {
106         Double error = getStateDoubleValue(STATE_ERROR);
107         if (error == null || error == 0.0) {
108             Double value = getStateDoubleValue(STATE_VALUE);
109             if (value != null) {
110                 if (minValue != null && maxValue != null && (minValue > value || maxValue < value)) {
111                     return null;
112                 }
113                 return new DecimalType(value);
114             }
115         } else {
116             return UnDefType.UNDEF;
117         }
118         return null;
119     }
120 }