2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.loxone.internal.controls;
15 import static org.openhab.binding.loxone.internal.LxBindingConstants.*;
17 import java.io.IOException;
18 import java.util.HashSet;
21 import org.openhab.binding.loxone.internal.types.LxTags;
22 import org.openhab.binding.loxone.internal.types.LxUuid;
23 import org.openhab.core.library.types.DecimalType;
24 import org.openhab.core.thing.ChannelUID;
25 import org.openhab.core.thing.type.ChannelTypeUID;
26 import org.openhab.core.types.Command;
27 import org.openhab.core.types.State;
28 import org.openhab.core.types.StateDescriptionFragment;
29 import org.openhab.core.types.StateDescriptionFragmentBuilder;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
34 * An Intelligent Room Controller V2.
35 * This implementation does not support the timers which describe temperature zones during the day.
37 * @author Pawel Pieczul - initial contribution
40 class LxControlIRoomControllerV2 extends LxControl {
42 static class Factory extends LxControlInstance {
44 LxControl create(LxUuid uuid) {
45 return new LxControlIRoomControllerV2(uuid);
50 return "iroomcontrollerv2";
54 private static final String STATE_ACTIVE_MODE = "activemode";
55 private static final String STATE_OPERATING_MODE = "operatingmode";
56 private static final String STATE_PREPARE_STATE = "preparestate";
57 private static final String STATE_OPEN_WINDOW = "openwindow";
58 private static final String STATE_TEMP_ACTUAL = "tempactual";
59 private static final String STATE_TEMP_TARGET = "temptarget";
60 private static final String STATE_COMFORT_TEMPERATURE = "comforttemperature";
61 private static final String STATE_COMFORT_TEMPERATURE_OFFSET = "comforttemperatureoffset";
62 private static final String STATE_COMFORT_TOLERANCE = "comforttolerance";
63 private static final String STATE_ABSENT_MIN_OFFSET = "absentminoffset";
64 private static final String STATE_ABSENT_MAX_OFFSET = "absentmaxoffset";
65 private static final String STATE_FROST_PROTECT_TEMPERATURE = "frostprotecttemperature";
66 private static final String STATE_HEAT_PROTECT_TEMPERATURE = "heatprotecttemperature";
68 private static final String CMD_SET_OPERATING_MODE = "setOperatingMode/";
69 private static final String CMD_SET_COMFORT_TOLERANCE = "setComfortTolerance/";
70 private static final String CMD_SET_COMFORT_TEMPERATURE = "setComfortTemperature/";
71 private static final String CMD_SET_COMFORT_TEMPERATURE_OFFSET = "setComfortModeTemp/";
72 private static final String CMD_SET_ABSENT_MIN_TEMPERATURE = "setAbsentMinTemperature/";
73 private static final String CMD_SET_ABSENT_MAX_TEMPERATURE = "setAbsentMaxTemperature/";
74 private static final String CMD_SET_MANUAL_TEMPERATURE = "setManualTemperature/";
76 private final Logger logger = LoggerFactory.getLogger(LxControlIRoomControllerV2.class);
78 private LxControlIRoomControllerV2(LxUuid uuid) {
83 public void initialize(LxControlConfig config) {
84 super.initialize(config);
86 Set<String> tempTags = new HashSet<>(tags);
87 tempTags.addAll(LxTags.TEMPERATURE);
88 String format = details.format;
89 StateDescriptionFragment patternRoFragment = null;
90 StateDescriptionFragment patternRwFragment = null;
92 patternRoFragment = StateDescriptionFragmentBuilder.create().withPattern(format).withReadOnly(true).build();
93 patternRwFragment = StateDescriptionFragmentBuilder.create().withPattern(format).withReadOnly(false)
97 addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_IROOM_V2_ACTIVE_MODE),
98 defaultChannelLabel + "/ Active Mode", "Active mode", tags, null,
99 () -> getStateDecimalValue(STATE_ACTIVE_MODE));
101 addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_IROOM_V2_OPERATING_MODE),
102 defaultChannelLabel + "/ Operating Mode", "Operating mode", tags, this::setOperatingMode,
103 () -> getStateDecimalValue(STATE_OPERATING_MODE));
105 addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_IROOM_V2_PREPARE_STATE),
106 defaultChannelLabel + "/ Prepare State", "Prepare state", tags, null,
107 () -> getStateDecimalValue(STATE_PREPARE_STATE));
109 addChannel("Switch", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_SWITCH),
110 defaultChannelLabel + "/ Open Window", "Open window", tags, null,
111 () -> getSwitchState(STATE_OPEN_WINDOW));
113 cid = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_ANALOG),
114 defaultChannelLabel + "/ Current Temperature", "Current temperature", tempTags, null,
115 () -> getStateDecimalValue(STATE_TEMP_ACTUAL));
116 addChannelStateDescriptionFragment(cid, patternRoFragment);
118 // manual temperature will affect value of target temperature only in manual operating modes
119 cid = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_NUMBER),
120 defaultChannelLabel + "/ Target Temperature", "Target temperature", tempTags,
121 (c) -> setTemperature(c, CMD_SET_MANUAL_TEMPERATURE), () -> getStateDecimalValue(STATE_TEMP_TARGET));
122 addChannelStateDescriptionFragment(cid, patternRwFragment);
124 cid = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_NUMBER),
125 defaultChannelLabel + "/ Comfort Temperature", "Comfort temperature", tempTags,
126 (c) -> setTemperature(c, CMD_SET_COMFORT_TEMPERATURE),
127 () -> getStateDecimalValue(STATE_COMFORT_TEMPERATURE));
128 addChannelStateDescriptionFragment(cid, patternRwFragment);
130 cid = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_NUMBER),
131 defaultChannelLabel + "/ Comfort Temperature Offset", "Comfort temperature offset", tempTags,
132 (c) -> setTemperature(c, CMD_SET_COMFORT_TEMPERATURE_OFFSET),
133 () -> getStateDecimalValue(STATE_COMFORT_TEMPERATURE_OFFSET));
134 addChannelStateDescriptionFragment(cid, patternRwFragment);
136 cid = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_IROOM_V2_COMFORT_TOLERANCE),
137 defaultChannelLabel + "/ Comfort Tolerance", "Comfort tolerance", tempTags,
138 (c) -> setTemperature(c, CMD_SET_COMFORT_TOLERANCE),
139 () -> getStateDecimalValue(STATE_COMFORT_TOLERANCE));
140 addChannelStateDescriptionFragment(cid, patternRwFragment);
142 cid = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_NUMBER),
143 defaultChannelLabel + "/ Absent Min Offset", "Absent minimum temperature offset", tempTags,
144 (c) -> setTemperature(c, CMD_SET_ABSENT_MIN_TEMPERATURE),
145 () -> getStateDecimalValue(STATE_ABSENT_MIN_OFFSET));
146 addChannelStateDescriptionFragment(cid, patternRwFragment);
148 cid = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_NUMBER),
149 defaultChannelLabel + "/ Absent Max Offset", "Absent maximum temperature offset", tempTags,
150 (c) -> setTemperature(c, CMD_SET_ABSENT_MAX_TEMPERATURE),
151 () -> getStateDecimalValue(STATE_ABSENT_MAX_OFFSET));
152 addChannelStateDescriptionFragment(cid, patternRwFragment);
154 cid = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_ANALOG),
155 defaultChannelLabel + "/ Frost Protect Temperature", "Frost protect temperature", tempTags, null,
156 () -> getStateDecimalValue(STATE_FROST_PROTECT_TEMPERATURE));
157 addChannelStateDescriptionFragment(cid, patternRoFragment);
159 cid = addChannel("Number", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_RO_ANALOG),
160 defaultChannelLabel + "/ Heat Protect Temperature", "Heat protect temperature", tempTags, null,
161 () -> getStateDecimalValue(STATE_HEAT_PROTECT_TEMPERATURE));
162 addChannelStateDescriptionFragment(cid, patternRoFragment);
165 private State getSwitchState(String name) {
166 return LxControlSwitch.convertSwitchState(getStateDoubleValue(name));
169 private void setOperatingMode(Command command) throws IOException {
170 if (command instanceof DecimalType) {
171 DecimalType mode = (DecimalType) command;
172 sendAction(CMD_SET_OPERATING_MODE + String.valueOf(mode.intValue()));
176 private void setTemperature(Command command, String prefix) throws IOException {
177 if (command instanceof DecimalType) {
178 DecimalType temp = (DecimalType) command;
179 sendAction(prefix + String.valueOf(temp.doubleValue()));