]> git.basschouten.com Git - openhab-addons.git/blob
7b4854e75504e253c12a123bd3648db68900a87d
[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.LxUuid;
20 import org.openhab.core.library.types.DecimalType;
21 import org.openhab.core.library.types.OnOffType;
22 import org.openhab.core.thing.type.ChannelTypeUID;
23 import org.openhab.core.types.Command;
24 import org.openhab.core.types.State;
25
26 /**
27  * Loxone Miniserver's Sauna
28  *
29  * @author Pawel Pieczul - initial contribution
30  *
31  */
32 class LxControlSauna extends LxControl {
33
34     static class Factory extends LxControlInstance {
35         @Override
36         LxControl create(LxUuid uuid) {
37             return new LxControlSauna(uuid);
38         }
39
40         @Override
41         String getType() {
42             return "sauna";
43         }
44     }
45
46     private static final String STATE_ACTIVE = "active";
47     private static final String STATE_POWER_LEVEL = "power";
48     private static final String STATE_TEMP_ACTUAL = "tempactual";
49     private static final String STATE_TEMP_BENCH = "tempbench";
50     private static final String STATE_TEMP_TARGET = "temptarget";
51     private static final String STATE_FAN = "fan";
52     private static final String STATE_DRYING = "drying";
53     private static final String STATE_DOOR_CLOSED = "doorclosed";
54     private static final String STATE_ERROR = "error";
55     private static final String STATE_VAPOR_POWER_LEVEL = "vaporpower";
56     private static final String STATE_SAUNA_ERROR = "saunaerror";
57     private static final String STATE_TIMER = "timer";
58     private static final String STATE_TIMER_TOTAL = "timertotal";
59     private static final String STATE_OUT_OF_WATER = "lesswater";
60     private static final String STATE_HUMIDITY_ACTUAL = "humidityactual";
61     private static final String STATE_HUMIDITY_TARGET = "humiditytarget";
62     private static final String STATE_EVAPORATOR_MODE = "mode";
63
64     private static final String CMD_ON = "on";
65     private static final String CMD_OFF = "off";
66     private static final String CMD_FAN_ON = "fanon";
67     private static final String CMD_FAN_OFF = "fanoff";
68     private static final String CMD_SET_TEMP_TARGET = "temp/";
69     private static final String CMD_SET_HUMIDITY_TARGET = "humidity/";
70     private static final String CMD_SET_EVAPORATOR_MODE = "mode/";
71     private static final String CMD_NEXT_STATE = "pulse";
72     private static final String CMD_START_TIMER = "starttimer";
73
74     LxControlSauna(LxUuid uuid) {
75         super(uuid);
76     }
77
78     @Override
79     public void initialize(LxControlConfig config) {
80         super.initialize(config);
81         addChannel("Switch", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_SWITCH),
82                 defaultChannelLabel + " / Active", "Sauna Active", tags, this::handleSaunaActivateCommands,
83                 () -> getStateOnOffValue(STATE_ACTIVE));
84         addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_NUMBER),
85                 defaultChannelLabel + " / Power", "Sauna Power Level", tags, null,
86                 () -> getStatePercentValue(STATE_POWER_LEVEL));
87         addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_NUMBER),
88                 defaultChannelLabel + " / Temperature / Actual", "Actual Temperature", tags, null,
89                 () -> getStateDecimalValue(STATE_TEMP_ACTUAL));
90         addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_NUMBER),
91                 defaultChannelLabel + " / Temperature / Bench", "Bench Temperature", tags, null,
92                 () -> getStateDecimalValue(STATE_TEMP_BENCH));
93         addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_NUMBER),
94                 defaultChannelLabel + " / Temperature / Target", "Target Temperature", tags,
95                 (cmd) -> handleSetNumberCommands(cmd, CMD_SET_TEMP_TARGET),
96                 () -> getStateDecimalValue(STATE_TEMP_TARGET));
97         addChannel("Switch", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_SWITCH),
98                 defaultChannelLabel + " / Fan", "Fan", tags, this::handleFanCommands,
99                 () -> getStateOnOffValue(STATE_FAN));
100         addChannel("Switch", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_SWITCH),
101                 defaultChannelLabel + " / Drying", "Drying", tags, null, () -> getStateOnOffValue(STATE_DRYING));
102         if (details != null && details.hasDoorSensor != null && details.hasDoorSensor) {
103             addChannel("Switch", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_SWITCH),
104                     defaultChannelLabel + " / Door Closed", "Door Closed", tags, null,
105                     () -> getStateOnOffValue(STATE_DOOR_CLOSED));
106         }
107         addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_NUMBER),
108                 defaultChannelLabel + " / Error Code", "Error Code", tags, null, () -> getStateErrorValue());
109         addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_NUMBER),
110                 defaultChannelLabel + " / Timer / Current", "Current Timer Value", tags, null,
111                 () -> getStateDecimalValue(STATE_TIMER));
112         addChannel("Switch", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_SWITCH),
113                 defaultChannelLabel + " / Timer / Trigger", "Start Timer", tags,
114                 (cmd) -> handleTriggerCommands(cmd, CMD_START_TIMER), () -> OnOffType.OFF);
115         addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_NUMBER),
116                 defaultChannelLabel + " / Timer / Total", "Total Timer Value", tags, null,
117                 () -> getStateDecimalValue(STATE_TIMER_TOTAL));
118         if (details != null && details.hasVaporizer != null && details.hasVaporizer) {
119             addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_NUMBER),
120                     defaultChannelLabel + " / Evaporator / Power", "Evaporator Power Level", tags, null,
121                     () -> getStatePercentValue(STATE_VAPOR_POWER_LEVEL));
122             addChannel("Switch", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_SWITCH),
123                     defaultChannelLabel + " / Evaporator / Out Of Water", "Evaporator Out Of Water", tags, null,
124                     () -> getStateOnOffValue(STATE_OUT_OF_WATER));
125             addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_NUMBER),
126                     defaultChannelLabel + " / Evaporator / Humidity / Actual", "Actual Humidity", tags, null,
127                     () -> getStateDecimalValue(STATE_HUMIDITY_ACTUAL));
128             addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_NUMBER),
129                     defaultChannelLabel + " / Evaporator / Humidity / Target", "Target Humidity", tags,
130                     (cmd) -> handleSetNumberCommands(cmd, CMD_SET_HUMIDITY_TARGET),
131                     () -> getStateDecimalValue(STATE_HUMIDITY_TARGET));
132             addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_NUMBER),
133                     defaultChannelLabel + " / Evaporator / Mode", "Evaporator Mode", tags, this::handleModeCommands,
134                     () -> getStateDecimalValue(STATE_EVAPORATOR_MODE));
135         }
136         addChannel("Switch", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_SWITCH),
137                 defaultChannelLabel + " / Next State", "Trigger Next State", tags,
138                 (cmd) -> handleTriggerCommands(cmd, CMD_NEXT_STATE), () -> OnOffType.OFF);
139     }
140
141     private void handleSaunaActivateCommands(Command command) throws IOException {
142         if (command instanceof OnOffType onOffCommand) {
143             if (onOffCommand == OnOffType.ON) {
144                 sendAction(CMD_ON);
145             } else {
146                 sendAction(CMD_OFF);
147             }
148         }
149     }
150
151     private void handleSetNumberCommands(Command command, String prefix) throws IOException {
152         if (command instanceof DecimalType decimalCommand) {
153             Double value = decimalCommand.doubleValue();
154             sendAction(prefix + value.toString());
155         }
156     }
157
158     private void handleFanCommands(Command command) throws IOException {
159         if (command instanceof OnOffType onOffCommand) {
160             if (onOffCommand == OnOffType.ON) {
161                 sendAction(CMD_FAN_ON);
162             } else {
163                 sendAction(CMD_FAN_OFF);
164             }
165         }
166     }
167
168     private void handleTriggerCommands(Command command, String prefix) throws IOException {
169         if (command instanceof OnOffType onOffCommand && onOffCommand == OnOffType.ON) {
170             sendAction(prefix);
171         }
172     }
173
174     private void handleModeCommands(Command command) throws IOException {
175         if (command instanceof DecimalType decimalCommand) {
176             Double value = decimalCommand.doubleValue();
177             // per API there are 7 evaporator modes selected with number 0-6
178             if (value % 1 == 0 && value >= 0.0 && value <= 6.0) {
179                 sendAction(CMD_SET_EVAPORATOR_MODE + value.toString());
180             }
181         }
182     }
183
184     private State getStateErrorValue() {
185         Double val = getStateDoubleValue(STATE_ERROR);
186         if (val != null && val != 0.0) {
187             return getStateDecimalValue(STATE_SAUNA_ERROR);
188         }
189         return DecimalType.ZERO;
190     }
191 }