diff --git a/bundles/org.openhab.binding.loxone/README.md b/bundles/org.openhab.binding.loxone/README.md index d651859d5b615..29fd9e540e90b 100644 --- a/bundles/org.openhab.binding.loxone/README.md +++ b/bundles/org.openhab.binding.loxone/README.md @@ -88,7 +88,7 @@ The binding supports the following authentication methods, which are selected au | Method | Miniserver Firmware | Authentication | Encryption | Requirements | |-------------|---------------------|--------------------------------------------------------------------------------|------------|-------------------------------------------------------| | Hash-based | 8.x | HMAC-SHA1 hash on user and password | None | None | -| Token-based | 9.x | Token acquired on the first connection and used later instead of the password. | AES-256 | JRE must have unrestricted security policy configured | +| Token-based | From 9.x | Token acquired on the first connection and used later instead of the password. | AES-256 | JRE must have unrestricted security policy configured | For the token-based authentication, the password is required only for the first login and acquiring the token. After the token is acquired, the password is cleared in the binding configuration. @@ -121,7 +121,8 @@ Currently supported controls are presented in the table below. | | | `String` - list of alarm sensors separated with `|` | Read-only channel | | | | `Switch` - acknowledge the alarm - pushbutton | `OnOffType.ON` - acknowledge alarm | | ColorPickerV2 | [RGBW 24v Dimmer Tree](https://www.loxone.com/enen/kb/rgbw-24v-dimmer-tree/) | `Color` | `HSBType` - sets the color of the light, `DecimalType` and `PercentType` - sets the brightness, `IncreaseDecreaseType.*` - increases/decreases the brightness, `OnOffType.*` - switches light on/off | -| Dimmer | [Dimmer](https://www.loxone.com/enen/kb/dimmer/) | `Dimmer` | `OnOffType.*`, `PercentType` | +| Dimmer | [Dimmer](https://www.loxone.com/enen/kb/dimmer/) | `Dimmer` | `OnOffType.*`, `PercentType`, `IncreaseDecreaseType.*` | +| EIBDimmer | EIB Dimmer (undocumented) | `Dimmer` | `OnOffType.*`, `PercentType`, `IncreaseDecreaseType.*` | | InfoOnlyAnalog | Analog [virtual inputs](https://www.loxone.com/enen/kb/virtual-inputs-outputs/) (virtual state) | `Number` | Read-only channel | | InfoOnlyDigital | Digital [virtual inputs](https://www.loxone.com/enen/kb/virtual-inputs-outputs/) (virtual state) | `String` | Read-only channel | | IRoomControllerV2 | [Intelligent Room Controller V2](https://www.loxone.com/enen/kb/irc-v2/) | `Number` - active mode | Read-only channel | diff --git a/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlDimmer.java b/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlDimmer.java index c6aaaa72635f9..700f23e10dfdb 100644 --- a/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlDimmer.java +++ b/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlDimmer.java @@ -12,18 +12,7 @@ */ package org.openhab.binding.loxone.internal.controls; -import static org.openhab.binding.loxone.internal.LxBindingConstants.*; - -import java.io.IOException; - -import org.openhab.binding.loxone.internal.types.LxCategory; -import org.openhab.binding.loxone.internal.types.LxTags; import org.openhab.binding.loxone.internal.types.LxUuid; -import org.openhab.core.library.types.IncreaseDecreaseType; -import org.openhab.core.library.types.OnOffType; -import org.openhab.core.library.types.PercentType; -import org.openhab.core.thing.type.ChannelTypeUID; -import org.openhab.core.types.Command; /** * A dimmer type of control on Loxone Miniserver. @@ -36,7 +25,7 @@ * @author Stephan Brunner - initial contribution * */ -class LxControlDimmer extends LxControl { +class LxControlDimmer extends LxControlEIBDimmer { static class Factory extends LxControlInstance { @Override @@ -51,118 +40,28 @@ String getType() { } /** - * States + * States additionally to EIBDimmer */ - private static final String STATE_POSITION = "position"; private static final String STATE_MIN = "min"; private static final String STATE_MAX = "max"; private static final String STATE_STEP = "step"; - /** - * Command string used to set the dimmer ON - */ - private static final String CMD_ON = "On"; - /** - * Command string used to set the dimmer to OFF - */ - private static final String CMD_OFF = "Off"; - private LxControlDimmer(LxUuid uuid) { super(uuid); } @Override - public void initialize(LxControlConfig config) { - super.initialize(config); - LxCategory category = getCategory(); - if (category != null && category.getType() == LxCategory.CategoryType.LIGHTS) { - tags.addAll(LxTags.LIGHTING); - } - addChannel("Dimmer", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_DIMMER), defaultChannelLabel, - "Dimmer", tags, this::handleCommands, this::getChannelState); - } - - private void handleCommands(Command command) throws IOException { - if (command instanceof OnOffType) { - if (command == OnOffType.ON) { - sendAction(CMD_ON); - } else { - sendAction(CMD_OFF); - } - } else if (command instanceof PercentType) { - PercentType percentCmd = (PercentType) command; - setPosition(percentCmd.doubleValue()); - } else if (command instanceof IncreaseDecreaseType) { - Double value = getStateDoubleValue(STATE_POSITION); - Double min = getStateDoubleValue(STATE_MIN); - Double max = getStateDoubleValue(STATE_MAX); - Double step = getStateDoubleValue(STATE_STEP); - if (value != null && max != null && min != null && step != null && min >= 0 && max >= 0 && max > min) { - if ((IncreaseDecreaseType) command == IncreaseDecreaseType.INCREASE) { - value += step; - if (value > max) { - value = max; - } - } else { - value -= step; - if (value < min) { - value = min; - } - } - sendAction(value.toString()); - } - } + Double getMin() { + return getStateDoubleValue(STATE_MIN); } - private PercentType getChannelState() { - Double value = mapLoxoneToOH(getStateDoubleValue(STATE_POSITION)); - if (value != null && value >= 0 && value <= 100) { - return new PercentType(value.intValue()); - } - return null; - } - - /** - * Sets the current position of the dimmer - * - * @param position position to move to (0-100, 0 - full off, 100 - full on) - * @throws IOException error communicating with the Miniserver - */ - private void setPosition(Double position) throws IOException { - Double loxonePosition = mapOHToLoxone(position); - if (loxonePosition != null) { - sendAction(loxonePosition.toString()); - } - } - - private Double mapLoxoneToOH(Double loxoneValue) { - if (loxoneValue != null) { - // 0 means turn dimmer off, any value above zero should be mapped from min-max range - if (Double.compare(loxoneValue, 0.0) == 0) { - return 0.0; - } - Double max = getStateDoubleValue(STATE_MAX); - Double min = getStateDoubleValue(STATE_MIN); - if (max != null && min != null && max > min && min >= 0 && max >= 0) { - return 100 * (loxoneValue - min) / (max - min); - } - } - return null; + @Override + Double getMax() { + return getStateDoubleValue(STATE_MAX); } - private Double mapOHToLoxone(Double ohValue) { - if (ohValue != null) { - // 0 means turn dimmer off, any value above zero should be mapped to min-max range - if (Double.compare(ohValue, 0.0) == 0) { - return 0.0; - } - Double max = getStateDoubleValue(STATE_MAX); - Double min = getStateDoubleValue(STATE_MIN); - if (max != null && min != null) { - double value = min + ohValue * (max - min) / 100; - return value; // no rounding to integer value is needed as loxone is accepting floating point values - } - } - return null; + @Override + Double getStep() { + return getStateDoubleValue(STATE_STEP); } } diff --git a/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlEIBDimmer.java b/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlEIBDimmer.java new file mode 100644 index 0000000000000..d3601dbf6ac1d --- /dev/null +++ b/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlEIBDimmer.java @@ -0,0 +1,178 @@ +/** + * Copyright (c) 2010-2021 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.loxone.internal.controls; + +import static org.openhab.binding.loxone.internal.LxBindingConstants.*; + +import java.io.IOException; + +import org.openhab.binding.loxone.internal.types.LxCategory; +import org.openhab.binding.loxone.internal.types.LxTags; +import org.openhab.binding.loxone.internal.types.LxUuid; +import org.openhab.core.library.types.IncreaseDecreaseType; +import org.openhab.core.library.types.OnOffType; +import org.openhab.core.library.types.PercentType; +import org.openhab.core.thing.type.ChannelTypeUID; +import org.openhab.core.types.Command; + +/** + * An EIB dimmer type of control on Loxone Miniserver. + *
+ * This control is absent in the API documentation. It looks like it behaves like a normal Dimmer, but it is missing the
+ * information about min, max and step values.
+ *
+ * @author Pawel Pieczul - initial contribution
+ *
+ */
+class LxControlEIBDimmer extends LxControl {
+
+ static class Factory extends LxControlInstance {
+ @Override
+ LxControl create(LxUuid uuid) {
+ return new LxControlEIBDimmer(uuid);
+ }
+
+ @Override
+ String getType() {
+ return "eibdimmer";
+ }
+ }
+
+ /**
+ * States
+ */
+ private static final String STATE_POSITION = "position";
+ private static final Double DEFAULT_MIN = 0.0;
+ private static final Double DEFAULT_MAX = 100.0;
+ private static final Double DEFAULT_STEP = 5.0;
+
+ /**
+ * Command string used to set the dimmer ON
+ */
+ private static final String CMD_ON = "On";
+ /**
+ * Command string used to set the dimmer to OFF
+ */
+ private static final String CMD_OFF = "Off";
+
+ LxControlEIBDimmer(LxUuid uuid) {
+ super(uuid);
+ }
+
+ @Override
+ public void initialize(LxControlConfig config) {
+ super.initialize(config);
+ LxCategory category = getCategory();
+ if (category != null && category.getType() == LxCategory.CategoryType.LIGHTS) {
+ tags.addAll(LxTags.LIGHTING);
+ }
+ addChannel("Dimmer", new ChannelTypeUID(BINDING_ID, MINISERVER_CHANNEL_TYPE_DIMMER), defaultChannelLabel,
+ "Dimmer", tags, this::handleCommands, this::getChannelState);
+ }
+
+ Double getMin() {
+ return DEFAULT_MIN;
+ }
+
+ Double getMax() {
+ return DEFAULT_MAX;
+ }
+
+ Double getStep() {
+ return DEFAULT_STEP;
+ }
+
+ private void handleCommands(Command command) throws IOException {
+ if (command instanceof OnOffType) {
+ if (command == OnOffType.ON) {
+ sendAction(CMD_ON);
+ } else {
+ sendAction(CMD_OFF);
+ }
+ } else if (command instanceof PercentType) {
+ PercentType percentCmd = (PercentType) command;
+ setPosition(percentCmd.doubleValue());
+ } else if (command instanceof IncreaseDecreaseType) {
+ Double value = getStateDoubleValue(STATE_POSITION);
+ Double min = getMin();
+ Double max = getMax();
+ Double step = getStep();
+ if (value != null && max != null && min != null && step != null && min >= 0 && max >= 0 && max > min) {
+ if ((IncreaseDecreaseType) command == IncreaseDecreaseType.INCREASE) {
+ value += step;
+ if (value > max) {
+ value = max;
+ }
+ } else {
+ value -= step;
+ if (value < min) {
+ value = min;
+ }
+ }
+ sendAction(value.toString());
+ }
+ }
+ }
+
+ private PercentType getChannelState() {
+ Double value = mapLoxoneToOH(getStateDoubleValue(STATE_POSITION));
+ if (value != null && value >= 0 && value <= 100) {
+ return new PercentType(value.intValue());
+ }
+ return null;
+ }
+
+ /**
+ * Sets the current position of the dimmer
+ *
+ * @param position position to move to (0-100, 0 - full off, 100 - full on)
+ * @throws IOException error communicating with the Miniserver
+ */
+ private void setPosition(Double position) throws IOException {
+ Double loxonePosition = mapOHToLoxone(position);
+ if (loxonePosition != null) {
+ sendAction(loxonePosition.toString());
+ }
+ }
+
+ private Double mapLoxoneToOH(Double loxoneValue) {
+ if (loxoneValue != null) {
+ // 0 means turn dimmer off, any value above zero should be mapped from min-max range
+ if (Double.compare(loxoneValue, 0.0) == 0) {
+ return 0.0;
+ }
+ Double max = getMax();
+ Double min = getMin();
+ if (max != null && min != null && max > min && min >= 0 && max >= 0) {
+ return 100 * (loxoneValue - min) / (max - min);
+ }
+ }
+ return null;
+ }
+
+ private Double mapOHToLoxone(Double ohValue) {
+ if (ohValue != null) {
+ // 0 means turn dimmer off, any value above zero should be mapped to min-max range
+ if (Double.compare(ohValue, 0.0) == 0) {
+ return 0.0;
+ }
+ Double max = getMax();
+ Double min = getMin();
+ if (max != null && min != null) {
+ double value = min + ohValue * (max - min) / 100;
+ return value; // no rounding to integer value is needed as loxone is accepting floating point values
+ }
+ }
+ return null;
+ }
+}
diff --git a/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlFactory.java b/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlFactory.java
index a83b1ae9fa1f7..8348945406f67 100644
--- a/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlFactory.java
+++ b/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlFactory.java
@@ -31,6 +31,7 @@ class LxControlFactory {
add(new LxControlAlarm.Factory());
add(new LxControlColorPickerV2.Factory());
add(new LxControlDimmer.Factory());
+ add(new LxControlEIBDimmer.Factory());
add(new LxControlInfoOnlyAnalog.Factory());
add(new LxControlInfoOnlyDigital.Factory());
add(new LxControlIRoomControllerV2.Factory());
diff --git a/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlIRoomControllerV2.java b/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlIRoomControllerV2.java
index 7035ec9af53ee..853c1ad3b387a 100644
--- a/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlIRoomControllerV2.java
+++ b/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/controls/LxControlIRoomControllerV2.java
@@ -27,8 +27,6 @@
import org.openhab.core.types.State;
import org.openhab.core.types.StateDescriptionFragment;
import org.openhab.core.types.StateDescriptionFragmentBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* An Intelligent Room Controller V2.
@@ -73,8 +71,6 @@ String getType() {
private static final String CMD_SET_ABSENT_MAX_TEMPERATURE = "setAbsentMaxTemperature/";
private static final String CMD_SET_MANUAL_TEMPERATURE = "setManualTemperature/";
- private final Logger logger = LoggerFactory.getLogger(LxControlIRoomControllerV2.class);
-
private LxControlIRoomControllerV2(LxUuid uuid) {
super(uuid);
}
diff --git a/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/types/LxCategory.java b/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/types/LxCategory.java
index 5bfb8ec8c827f..3950fd61c9dc1 100644
--- a/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/types/LxCategory.java
+++ b/bundles/org.openhab.binding.loxone/src/main/java/org/openhab/binding/loxone/internal/types/LxCategory.java
@@ -57,11 +57,11 @@ public enum CategoryType {
public CategoryType getType() {
if (catType == null && type != null) {
String tl = type.toLowerCase();
- if (tl.equals("lights")) {
+ if ("lights".equals(tl)) {
catType = CategoryType.LIGHTS;
- } else if (tl.equals("shading")) {
+ } else if ("shading".equals(tl)) {
catType = CategoryType.SHADING;
- } else if (tl.equals("indoortemperature")) {
+ } else if ("indoortemperature".equals(tl)) {
catType = CategoryType.TEMPERATURE;
} else {
catType = CategoryType.UNDEFINED;
diff --git a/bundles/org.openhab.binding.loxone/src/test/java/org/openhab/binding/loxone/internal/controls/LxControlAlarmNoPresenceTest.java b/bundles/org.openhab.binding.loxone/src/test/java/org/openhab/binding/loxone/internal/controls/LxControlAlarmNoPresenceTest.java
index c3296d4b8255a..30c15a74054c9 100644
--- a/bundles/org.openhab.binding.loxone/src/test/java/org/openhab/binding/loxone/internal/controls/LxControlAlarmNoPresenceTest.java
+++ b/bundles/org.openhab.binding.loxone/src/test/java/org/openhab/binding/loxone/internal/controls/LxControlAlarmNoPresenceTest.java
@@ -47,7 +47,7 @@ public class LxControlAlarmNoPresenceTest extends LxControlTest {
static final String SENSORS_CHANNEL = " / Sensors";
static final String QUIT_CHANNEL = " / Acknowledge";
- private static final String numberChannels[] = { NEXT_LEVEL_CHANNEL, NEXT_LEVEL_DELAY_CHANNEL,
+ private static final String NUMBER_CHANNELS[] = { NEXT_LEVEL_CHANNEL, NEXT_LEVEL_DELAY_CHANNEL,
NEXT_LEVEL_DELAY_TOTAL_CHANNEL, LEVEL_CHANNEL, ARMED_DELAY_CHANNEL, ARMED_TOTAL_DELAY_CHANNEL };
@BeforeEach
@@ -175,7 +175,7 @@ public void testLevelAndAcknowledge() {
private void testNumberChannel(String channel, String state) {
Map