[loxone] Implementation of EIB Dimmer (#10585)
Signed-off-by: Pawel Pieczul <pieczul@gmail.com>
This commit is contained in:
parent
d674814440
commit
f652e329f7
@ -88,7 +88,7 @@ The binding supports the following authentication methods, which are selected au
|
|||||||
| Method | Miniserver Firmware | Authentication | Encryption | Requirements |
|
| Method | Miniserver Firmware | Authentication | Encryption | Requirements |
|
||||||
|-------------|---------------------|--------------------------------------------------------------------------------|------------|-------------------------------------------------------|
|
|-------------|---------------------|--------------------------------------------------------------------------------|------------|-------------------------------------------------------|
|
||||||
| Hash-based | 8.x | HMAC-SHA1 hash on user and password | None | None |
|
| 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.
|
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 |
|
| | | `String` - list of alarm sensors separated with `|` | Read-only channel |
|
||||||
| | | `Switch` - acknowledge the alarm - pushbutton | `OnOffType.ON` - acknowledge alarm |
|
| | | `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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| IRoomControllerV2 | [Intelligent Room Controller V2](https://www.loxone.com/enen/kb/irc-v2/) | `Number` - active mode | Read-only channel |
|
||||||
|
|||||||
@ -12,18 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.loxone.internal.controls;
|
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.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.
|
* A dimmer type of control on Loxone Miniserver.
|
||||||
@ -36,7 +25,7 @@ import org.openhab.core.types.Command;
|
|||||||
* @author Stephan Brunner - initial contribution
|
* @author Stephan Brunner - initial contribution
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class LxControlDimmer extends LxControl {
|
class LxControlDimmer extends LxControlEIBDimmer {
|
||||||
|
|
||||||
static class Factory extends LxControlInstance {
|
static class Factory extends LxControlInstance {
|
||||||
@Override
|
@Override
|
||||||
@ -51,118 +40,28 @@ class LxControlDimmer extends LxControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* States
|
* States additionally to EIBDimmer
|
||||||
*/
|
*/
|
||||||
private static final String STATE_POSITION = "position";
|
|
||||||
private static final String STATE_MIN = "min";
|
private static final String STATE_MIN = "min";
|
||||||
private static final String STATE_MAX = "max";
|
private static final String STATE_MAX = "max";
|
||||||
private static final String STATE_STEP = "step";
|
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) {
|
private LxControlDimmer(LxUuid uuid) {
|
||||||
super(uuid);
|
super(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(LxControlConfig config) {
|
Double getMin() {
|
||||||
super.initialize(config);
|
return getStateDoubleValue(STATE_MIN);
|
||||||
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 {
|
@Override
|
||||||
if (command instanceof OnOffType) {
|
Double getMax() {
|
||||||
if (command == OnOffType.ON) {
|
return getStateDoubleValue(STATE_MAX);
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PercentType getChannelState() {
|
@Override
|
||||||
Double value = mapLoxoneToOH(getStateDoubleValue(STATE_POSITION));
|
Double getStep() {
|
||||||
if (value != null && value >= 0 && value <= 100) {
|
return getStateDoubleValue(STATE_STEP);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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.
|
||||||
|
* <p>
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -31,6 +31,7 @@ class LxControlFactory {
|
|||||||
add(new LxControlAlarm.Factory());
|
add(new LxControlAlarm.Factory());
|
||||||
add(new LxControlColorPickerV2.Factory());
|
add(new LxControlColorPickerV2.Factory());
|
||||||
add(new LxControlDimmer.Factory());
|
add(new LxControlDimmer.Factory());
|
||||||
|
add(new LxControlEIBDimmer.Factory());
|
||||||
add(new LxControlInfoOnlyAnalog.Factory());
|
add(new LxControlInfoOnlyAnalog.Factory());
|
||||||
add(new LxControlInfoOnlyDigital.Factory());
|
add(new LxControlInfoOnlyDigital.Factory());
|
||||||
add(new LxControlIRoomControllerV2.Factory());
|
add(new LxControlIRoomControllerV2.Factory());
|
||||||
|
|||||||
@ -27,8 +27,6 @@ import org.openhab.core.types.Command;
|
|||||||
import org.openhab.core.types.State;
|
import org.openhab.core.types.State;
|
||||||
import org.openhab.core.types.StateDescriptionFragment;
|
import org.openhab.core.types.StateDescriptionFragment;
|
||||||
import org.openhab.core.types.StateDescriptionFragmentBuilder;
|
import org.openhab.core.types.StateDescriptionFragmentBuilder;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An Intelligent Room Controller V2.
|
* An Intelligent Room Controller V2.
|
||||||
@ -73,8 +71,6 @@ class LxControlIRoomControllerV2 extends LxControl {
|
|||||||
private static final String CMD_SET_ABSENT_MAX_TEMPERATURE = "setAbsentMaxTemperature/";
|
private static final String CMD_SET_ABSENT_MAX_TEMPERATURE = "setAbsentMaxTemperature/";
|
||||||
private static final String CMD_SET_MANUAL_TEMPERATURE = "setManualTemperature/";
|
private static final String CMD_SET_MANUAL_TEMPERATURE = "setManualTemperature/";
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(LxControlIRoomControllerV2.class);
|
|
||||||
|
|
||||||
private LxControlIRoomControllerV2(LxUuid uuid) {
|
private LxControlIRoomControllerV2(LxUuid uuid) {
|
||||||
super(uuid);
|
super(uuid);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,11 +57,11 @@ public class LxCategory extends LxContainer {
|
|||||||
public CategoryType getType() {
|
public CategoryType getType() {
|
||||||
if (catType == null && type != null) {
|
if (catType == null && type != null) {
|
||||||
String tl = type.toLowerCase();
|
String tl = type.toLowerCase();
|
||||||
if (tl.equals("lights")) {
|
if ("lights".equals(tl)) {
|
||||||
catType = CategoryType.LIGHTS;
|
catType = CategoryType.LIGHTS;
|
||||||
} else if (tl.equals("shading")) {
|
} else if ("shading".equals(tl)) {
|
||||||
catType = CategoryType.SHADING;
|
catType = CategoryType.SHADING;
|
||||||
} else if (tl.equals("indoortemperature")) {
|
} else if ("indoortemperature".equals(tl)) {
|
||||||
catType = CategoryType.TEMPERATURE;
|
catType = CategoryType.TEMPERATURE;
|
||||||
} else {
|
} else {
|
||||||
catType = CategoryType.UNDEFINED;
|
catType = CategoryType.UNDEFINED;
|
||||||
|
|||||||
@ -47,7 +47,7 @@ public class LxControlAlarmNoPresenceTest extends LxControlTest {
|
|||||||
static final String SENSORS_CHANNEL = " / Sensors";
|
static final String SENSORS_CHANNEL = " / Sensors";
|
||||||
static final String QUIT_CHANNEL = " / Acknowledge";
|
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 };
|
NEXT_LEVEL_DELAY_TOTAL_CHANNEL, LEVEL_CHANNEL, ARMED_DELAY_CHANNEL, ARMED_TOTAL_DELAY_CHANNEL };
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
@ -175,7 +175,7 @@ public class LxControlAlarmNoPresenceTest extends LxControlTest {
|
|||||||
|
|
||||||
private void testNumberChannel(String channel, String state) {
|
private void testNumberChannel(String channel, String state) {
|
||||||
Map<String, State> states = new HashMap<>();
|
Map<String, State> states = new HashMap<>();
|
||||||
for (String s : numberChannels) {
|
for (String s : NUMBER_CHANNELS) {
|
||||||
states.put(s, getChannelState(s));
|
states.put(s, getChannelState(s));
|
||||||
}
|
}
|
||||||
for (Double i = -100.0; i <= 100.0; i += 2.341) {
|
for (Double i = -100.0; i <= 100.0; i += 2.341) {
|
||||||
|
|||||||
@ -0,0 +1,105 @@
|
|||||||
|
/**
|
||||||
|
* 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 org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
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.library.types.StopMoveType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test class for (@link LxControlDimmer}
|
||||||
|
*
|
||||||
|
* @author Pawel Pieczul - initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class LxControlEIBDimmerTest extends LxControlTest {
|
||||||
|
@BeforeEach
|
||||||
|
public void setup() {
|
||||||
|
setupControl("faa30f5c-4b4f-11e2-8928b8ba17ef51ee", "0b734138-037d-034e-ffff403fb0c34b9e",
|
||||||
|
"0fe650c2-0004-d446-ffff504f9410790f", "Kitchen Dimmer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testControlCreation() {
|
||||||
|
testControlCreation(LxControlDimmer.class, 1, 0, 1, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testChannels() {
|
||||||
|
testChannel("Dimmer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoxonePositionChanges() {
|
||||||
|
// filling in missing state values
|
||||||
|
testChannelState(null);
|
||||||
|
for (Double i = 0.0; i <= 100.0; i += 1.0) {
|
||||||
|
changeLoxoneState("position", i);
|
||||||
|
testChannelState(new PercentType(i.intValue()));
|
||||||
|
}
|
||||||
|
// out of range
|
||||||
|
changeLoxoneState("position", 199.9);
|
||||||
|
testChannelState(null);
|
||||||
|
changeLoxoneState("position", 400.1);
|
||||||
|
testChannelState(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnOffPercentCommands() {
|
||||||
|
executeCommand(OnOffType.ON);
|
||||||
|
testAction("On");
|
||||||
|
executeCommand(OnOffType.OFF);
|
||||||
|
testAction("Off");
|
||||||
|
for (Double i = 0.0; i <= 100.0; i += 1.0) {
|
||||||
|
executeCommand(new PercentType(i.intValue()));
|
||||||
|
testAction(i.toString());
|
||||||
|
}
|
||||||
|
executeCommand(StopMoveType.MOVE);
|
||||||
|
testAction(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIncreaseDecreaseCommands() {
|
||||||
|
for (Double i = 0.0; i <= 95.0; i += 1.0) {
|
||||||
|
changeLoxoneState("position", i);
|
||||||
|
testChannelState(new PercentType(i.intValue()));
|
||||||
|
testAction(null);
|
||||||
|
executeCommand(IncreaseDecreaseType.INCREASE);
|
||||||
|
Double j = i + 5.0;
|
||||||
|
testAction(j.toString());
|
||||||
|
}
|
||||||
|
for (Double i = 100.0; i >= 5.0; i -= 1.0) {
|
||||||
|
changeLoxoneState("position", i);
|
||||||
|
testChannelState(new PercentType(i.intValue()));
|
||||||
|
testAction(null);
|
||||||
|
executeCommand(IncreaseDecreaseType.DECREASE);
|
||||||
|
Double j = i - 5.0;
|
||||||
|
testAction(j.toString());
|
||||||
|
}
|
||||||
|
// test not exceeding range
|
||||||
|
changeLoxoneState("position", 100.0);
|
||||||
|
testChannelState(PercentType.HUNDRED);
|
||||||
|
testAction(null);
|
||||||
|
executeCommand(IncreaseDecreaseType.INCREASE);
|
||||||
|
testAction("100.0");
|
||||||
|
|
||||||
|
changeLoxoneState("position", 0.0);
|
||||||
|
testChannelState(PercentType.ZERO);
|
||||||
|
testAction(null);
|
||||||
|
executeCommand(IncreaseDecreaseType.DECREASE);
|
||||||
|
testAction("0.0");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -96,7 +96,6 @@ public class LxServerHandlerDummy implements LxServerHandlerApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setChannelState(ChannelUID channelId, State state) {
|
public void setChannelState(ChannelUID channelId, State state) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -108,13 +107,11 @@ public class LxServerHandlerDummy implements LxServerHandlerApi {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getSetting(String name) {
|
public String getSetting(String name) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSettings(Map<String, String> properties) {
|
public void setSettings(Map<String, String> properties) {
|
||||||
// TODO Auto-generated method stub
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -313,6 +313,19 @@
|
|||||||
"step": "131b19cd-03c0-6407-ffffd2fd15b703b6"
|
"step": "131b19cd-03c0-6407-ffffd2fd15b703b6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"faa30f5c-4b4f-11e2-8928b8ba17ef51ee": {
|
||||||
|
"name": "Kitchen Dimmer",
|
||||||
|
"type": "EIBDimmer",
|
||||||
|
"uuidAction": "faa30f5c-4b4f-11e2-8928b8ba17ef51ee",
|
||||||
|
"room": "0b734138-037d-034e-ffff403fb0c34b9e",
|
||||||
|
"cat": "0fe650c2-0004-d446-ffff504f9410790f",
|
||||||
|
"defaultRating": 0,
|
||||||
|
"isFavorite": false,
|
||||||
|
"isSecured": false,
|
||||||
|
"states": {
|
||||||
|
"position": "faa30f5d-4b4f-11e2-892eb8ba17ef51ee"
|
||||||
|
}
|
||||||
|
},
|
||||||
"0e367c09-0161-e2c1-ffff403fb0c34b9e": {
|
"0e367c09-0161-e2c1-ffff403fb0c34b9e": {
|
||||||
"name": "Window Blinds",
|
"name": "Window Blinds",
|
||||||
"type": "Jalousie",
|
"type": "Jalousie",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user