]> git.basschouten.com Git - openhab-addons.git/blob
2be664af5c302f6fed9284b585f52bad7a6ea739
[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.pilight.internal.handler;
14
15 import static org.openhab.binding.pilight.internal.PilightBindingConstants.CHANNEL_DIMLEVEL;
16
17 import java.math.BigDecimal;
18 import java.math.RoundingMode;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.pilight.internal.dto.Action;
23 import org.openhab.binding.pilight.internal.dto.Code;
24 import org.openhab.binding.pilight.internal.dto.Device;
25 import org.openhab.binding.pilight.internal.dto.Status;
26 import org.openhab.binding.pilight.internal.dto.Values;
27 import org.openhab.core.library.types.OnOffType;
28 import org.openhab.core.library.types.PercentType;
29 import org.openhab.core.thing.ChannelUID;
30 import org.openhab.core.thing.Thing;
31 import org.openhab.core.types.Command;
32 import org.openhab.core.types.State;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 /**
37  * The {@link PilightDimmerHandler} is responsible for handling commands, which are
38  * sent to one of the channels.
39  *
40  * @author Stefan Röllin - Initial contribution
41  * @author Niklas Dörfler - Port pilight binding to openHAB 3 + add device discovery
42  */
43 @NonNullByDefault
44 public class PilightDimmerHandler extends PilightBaseHandler {
45
46     private static final int MAX_DIM_LEVEL_DEFAULT = 15;
47     private static final BigDecimal BIG_DECIMAL_100 = new BigDecimal(100);
48
49     private final Logger logger = LoggerFactory.getLogger(PilightDimmerHandler.class);
50
51     private int maxDimLevel = MAX_DIM_LEVEL_DEFAULT;
52
53     public PilightDimmerHandler(Thing thing) {
54         super(thing);
55     }
56
57     @Override
58     protected void updateFromStatus(Status status) {
59         BigDecimal dimLevel = BigDecimal.ZERO;
60         String dimLevelAsString = status.getValues().get("dimlevel");
61
62         if (dimLevelAsString != null) {
63             dimLevel = getPercentageFromDimLevel(dimLevelAsString);
64         } else {
65             // Dimmer items can can also be switched on or off in pilight.
66             // When this happens, the dimmer value is not reported. At least we know it's on or off.
67             String stateAsString = status.getValues().get("state");
68             if (stateAsString != null) {
69                 State state = OnOffType.valueOf(stateAsString.toUpperCase());
70                 dimLevel = state.equals(OnOffType.ON) ? BIG_DECIMAL_100 : BigDecimal.ZERO;
71             }
72         }
73
74         State state = new PercentType(dimLevel);
75         updateState(CHANNEL_DIMLEVEL, state);
76     }
77
78     @Override
79     protected void updateFromConfigDevice(Device device) {
80         Integer max = device.getDimlevelMaximum();
81
82         if (max != null) {
83             maxDimLevel = max;
84         }
85     }
86
87     @Override
88     protected @Nullable Action createUpdateCommand(ChannelUID unused, Command command) {
89         Code code = new Code();
90         code.setDevice(getName());
91
92         if (command instanceof OnOffType) {
93             code.setState(command.equals(OnOffType.ON) ? Code.STATE_ON : Code.STATE_OFF);
94         } else if (command instanceof PercentType percentCommand) {
95             setDimmerValue(percentCommand, code);
96         } else {
97             logger.warn("Only OnOffType and PercentType are supported by a dimmer.");
98             return null;
99         }
100
101         Action action = new Action(Action.ACTION_CONTROL);
102         action.setCode(code);
103         return action;
104     }
105
106     private BigDecimal getPercentageFromDimLevel(String string) {
107         return new BigDecimal(string).setScale(2).divide(new BigDecimal(maxDimLevel), RoundingMode.HALF_UP)
108                 .multiply(BIG_DECIMAL_100);
109     }
110
111     private void setDimmerValue(PercentType percent, Code code) {
112         if (PercentType.ZERO.equals(percent)) {
113             // pilight is not responding to commands that set both the dimlevel to 0 and state to off.
114             // So, we're only updating the state for now
115             code.setState(Code.STATE_OFF);
116         } else {
117             BigDecimal dimlevel = percent.toBigDecimal().setScale(2).divide(BIG_DECIMAL_100, RoundingMode.HALF_UP)
118                     .multiply(BigDecimal.valueOf(maxDimLevel)).setScale(0, RoundingMode.HALF_UP);
119
120             Values values = new Values();
121             values.setDimlevel(dimlevel.intValue());
122             code.setValues(values);
123             code.setState(dimlevel.compareTo(BigDecimal.ZERO) == 1 ? Code.STATE_ON : Code.STATE_OFF);
124         }
125     }
126 }