[http] enable UoM for number channels (#9601)
* add unit Signed-off-by: Jan N. Klug <jan.n.klug@rub.de> * documentation an XML Signed-off-by: Jan N. Klug <jan.n.klug@rub.de> * address review comments Signed-off-by: Jan N. Klug <jan.n.klug@rub.de> * improvements Signed-off-by: Jan N. Klug <jan.n.klug@rub.de> * improvements Signed-off-by: Jan N. Klug <jan.n.klug@rub.de>
This commit is contained in:
parent
cb5d659c9e
commit
1480c41606
|
@ -101,6 +101,16 @@ All values that are not `onValue`, `offValue`, `increaseValue`, `decreaseValue`
|
||||||
|
|
||||||
All values that are not `onValue`, `offValue`, `increaseValue`, `decreaseValue` are interpreted as brightness 0-100% and need to be numeric only.
|
All values that are not `onValue`, `offValue`, `increaseValue`, `decreaseValue` are interpreted as brightness 0-100% and need to be numeric only.
|
||||||
|
|
||||||
|
### `number`
|
||||||
|
|
||||||
|
| parameter | optional | default | description |
|
||||||
|
|-------------------------|----------|-------------|-------------|
|
||||||
|
| `unit` | yes | - | The unit label for this channel |
|
||||||
|
|
||||||
|
`number` channels can be used for `DecimalType` or `QuantityType` values.
|
||||||
|
If a unit is given in the `unit` parameter, the binding tries to create a `QuantityType` state before updating the channel, if no unit is present, it creates a `DecimalType`.
|
||||||
|
Please note that incompatible units (e.g. `°C` for a `Number:Density` item) will fail silently, i.e. no error message is logged even if the state update fails.
|
||||||
|
|
||||||
### `player`
|
### `player`
|
||||||
|
|
||||||
| parameter | optional | default | description |
|
| parameter | optional | default | description |
|
||||||
|
|
|
@ -33,19 +33,10 @@ import org.eclipse.jetty.http.HttpMethod;
|
||||||
import org.openhab.binding.http.internal.config.HttpChannelConfig;
|
import org.openhab.binding.http.internal.config.HttpChannelConfig;
|
||||||
import org.openhab.binding.http.internal.config.HttpChannelMode;
|
import org.openhab.binding.http.internal.config.HttpChannelMode;
|
||||||
import org.openhab.binding.http.internal.config.HttpThingConfig;
|
import org.openhab.binding.http.internal.config.HttpThingConfig;
|
||||||
import org.openhab.binding.http.internal.converter.AbstractTransformingItemConverter;
|
import org.openhab.binding.http.internal.converter.*;
|
||||||
import org.openhab.binding.http.internal.converter.ColorItemConverter;
|
|
||||||
import org.openhab.binding.http.internal.converter.DimmerItemConverter;
|
|
||||||
import org.openhab.binding.http.internal.converter.FixedValueMappingItemConverter;
|
|
||||||
import org.openhab.binding.http.internal.converter.GenericItemConverter;
|
|
||||||
import org.openhab.binding.http.internal.converter.ImageItemConverter;
|
|
||||||
import org.openhab.binding.http.internal.converter.ItemValueConverter;
|
|
||||||
import org.openhab.binding.http.internal.converter.PlayerItemConverter;
|
|
||||||
import org.openhab.binding.http.internal.converter.RollershutterItemConverter;
|
|
||||||
import org.openhab.binding.http.internal.http.*;
|
import org.openhab.binding.http.internal.http.*;
|
||||||
import org.openhab.binding.http.internal.transform.ValueTransformationProvider;
|
import org.openhab.binding.http.internal.transform.ValueTransformationProvider;
|
||||||
import org.openhab.core.library.types.DateTimeType;
|
import org.openhab.core.library.types.DateTimeType;
|
||||||
import org.openhab.core.library.types.DecimalType;
|
|
||||||
import org.openhab.core.library.types.PointType;
|
import org.openhab.core.library.types.PointType;
|
||||||
import org.openhab.core.library.types.StringType;
|
import org.openhab.core.library.types.StringType;
|
||||||
import org.openhab.core.thing.Channel;
|
import org.openhab.core.thing.Channel;
|
||||||
|
@ -260,8 +251,8 @@ public class HttpThingHandler extends BaseThingHandler {
|
||||||
itemValueConverter = createGenericItemConverter(commandUrl, channelUID, channelConfig, PointType::new);
|
itemValueConverter = createGenericItemConverter(commandUrl, channelUID, channelConfig, PointType::new);
|
||||||
break;
|
break;
|
||||||
case "Number":
|
case "Number":
|
||||||
itemValueConverter = createGenericItemConverter(commandUrl, channelUID, channelConfig,
|
itemValueConverter = createItemConverter(NumberItemConverter::new, commandUrl, channelUID,
|
||||||
DecimalType::new);
|
channelConfig);
|
||||||
break;
|
break;
|
||||||
case "Player":
|
case "Player":
|
||||||
itemValueConverter = createItemConverter(PlayerItemConverter::new, commandUrl, channelUID,
|
itemValueConverter = createItemConverter(PlayerItemConverter::new, commandUrl, channelUID,
|
||||||
|
|
|
@ -48,6 +48,9 @@ public class HttpChannelConfig {
|
||||||
|
|
||||||
public HttpChannelMode mode = HttpChannelMode.READWRITE;
|
public HttpChannelMode mode = HttpChannelMode.READWRITE;
|
||||||
|
|
||||||
|
// number
|
||||||
|
public @Nullable String unit;
|
||||||
|
|
||||||
// switch, dimmer, color
|
// switch, dimmer, color
|
||||||
public @Nullable String onValue;
|
public @Nullable String onValue;
|
||||||
public @Nullable String offValue;
|
public @Nullable String offValue;
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/**
|
||||||
|
* 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.http.internal.converter;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.http.internal.config.HttpChannelConfig;
|
||||||
|
import org.openhab.binding.http.internal.transform.ValueTransformation;
|
||||||
|
import org.openhab.core.library.types.DecimalType;
|
||||||
|
import org.openhab.core.library.types.QuantityType;
|
||||||
|
import org.openhab.core.types.Command;
|
||||||
|
import org.openhab.core.types.State;
|
||||||
|
import org.openhab.core.types.UnDefType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link NumberItemConverter} implements {@link org.openhab.core.library.items.NumberItem} conversions
|
||||||
|
*
|
||||||
|
* @author Jan N. Klug - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class NumberItemConverter extends AbstractTransformingItemConverter {
|
||||||
|
|
||||||
|
public NumberItemConverter(Consumer<State> updateState, Consumer<Command> postCommand,
|
||||||
|
@Nullable Consumer<String> sendHttpValue, ValueTransformation stateTransformations,
|
||||||
|
ValueTransformation commandTransformations, HttpChannelConfig channelConfig) {
|
||||||
|
super(updateState, postCommand, sendHttpValue, stateTransformations, commandTransformations, channelConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected @Nullable Command toCommand(String value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected State toState(String value) {
|
||||||
|
String trimmedValue = value.trim();
|
||||||
|
if (!trimmedValue.isEmpty()) {
|
||||||
|
try {
|
||||||
|
if (channelConfig.unit != null) {
|
||||||
|
// we have a given unit - use that
|
||||||
|
return new QuantityType<>(trimmedValue + " " + channelConfig.unit);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
// try if we have a simple number
|
||||||
|
return new DecimalType(trimmedValue);
|
||||||
|
} catch (IllegalArgumentException e1) {
|
||||||
|
// not a plain number, maybe with unit?
|
||||||
|
return new QuantityType<>(trimmedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// finally failed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UnDefType.UNDEF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String toString(Command command) {
|
||||||
|
return command.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -202,6 +202,43 @@
|
||||||
</parameter>
|
</parameter>
|
||||||
</config-description>
|
</config-description>
|
||||||
|
|
||||||
|
<config-description uri="channel-type:http:channel-config-number">
|
||||||
|
<parameter name="stateExtension" type="text">
|
||||||
|
<label>State URL Extension</label>
|
||||||
|
<description>This value is added to the base URL configured in the thing for retrieving values.</description>
|
||||||
|
<advanced>true</advanced>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="commandExtension" type="text">
|
||||||
|
<label>Command URL Extension</label>
|
||||||
|
<description>This value is added to the base URL configured in the thing for sending values.</description>
|
||||||
|
<advanced>true</advanced>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="stateTransformation" type="text">
|
||||||
|
<label>State Transformation</label>
|
||||||
|
<description>Transformation pattern used when receiving values.</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="commandTransformation" type="text">
|
||||||
|
<label>Command Transformation</label>
|
||||||
|
<description>Transformation pattern used when sending values.</description>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="mode" type="text">
|
||||||
|
<label>Read/Write Mode</label>
|
||||||
|
<options>
|
||||||
|
<option value="READWRITE">Read/Write</option>
|
||||||
|
<option value="READONLY">Read Only</option>
|
||||||
|
<option value="WRITEONLY">Write Only</option>
|
||||||
|
</options>
|
||||||
|
<limitToOptions>true</limitToOptions>
|
||||||
|
<advanced>true</advanced>
|
||||||
|
<default>READWRITE</default>
|
||||||
|
</parameter>
|
||||||
|
<parameter name="unit" type="text">
|
||||||
|
<label>Unit</label>
|
||||||
|
<description>Unit to append to the (transformed) value.</description>
|
||||||
|
<advanced>true</advanced>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
|
||||||
<config-description uri="channel-type:http:channel-config-player">
|
<config-description uri="channel-type:http:channel-config-player">
|
||||||
<parameter name="stateExtension" type="text">
|
<parameter name="stateExtension" type="text">
|
||||||
<label>State URL Extension</label>
|
<label>State URL Extension</label>
|
||||||
|
|
|
@ -142,7 +142,7 @@
|
||||||
<channel-type id="number">
|
<channel-type id="number">
|
||||||
<item-type>Number</item-type>
|
<item-type>Number</item-type>
|
||||||
<label>Number Channel</label>
|
<label>Number Channel</label>
|
||||||
<config-description-ref uri="channel-type:http:channel-config"/>
|
<config-description-ref uri="channel-type:http:channel-config-number"/>
|
||||||
</channel-type>
|
</channel-type>
|
||||||
|
|
||||||
<channel-type id="player">
|
<channel-type id="player">
|
||||||
|
|
|
@ -21,9 +21,13 @@ import org.openhab.binding.http.internal.config.HttpChannelConfig;
|
||||||
import org.openhab.binding.http.internal.transform.NoOpValueTransformation;
|
import org.openhab.binding.http.internal.transform.NoOpValueTransformation;
|
||||||
import org.openhab.core.library.types.DecimalType;
|
import org.openhab.core.library.types.DecimalType;
|
||||||
import org.openhab.core.library.types.PointType;
|
import org.openhab.core.library.types.PointType;
|
||||||
|
import org.openhab.core.library.types.QuantityType;
|
||||||
import org.openhab.core.library.types.StringType;
|
import org.openhab.core.library.types.StringType;
|
||||||
|
import org.openhab.core.library.unit.SIUnits;
|
||||||
|
import org.openhab.core.library.unit.Units;
|
||||||
import org.openhab.core.types.Command;
|
import org.openhab.core.types.Command;
|
||||||
import org.openhab.core.types.State;
|
import org.openhab.core.types.State;
|
||||||
|
import org.openhab.core.types.UnDefType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link ConverterTest} is a test class for state converters
|
* The {@link ConverterTest} is a test class for state converters
|
||||||
|
@ -33,6 +37,40 @@ import org.openhab.core.types.State;
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class ConverterTest {
|
public class ConverterTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void numberItemConverter() {
|
||||||
|
NumberItemConverter converter = new NumberItemConverter(this::updateState, this::postCommand,
|
||||||
|
this::sendHttpValue, NoOpValueTransformation.getInstance(), NoOpValueTransformation.getInstance(),
|
||||||
|
new HttpChannelConfig());
|
||||||
|
|
||||||
|
// without unit
|
||||||
|
Assertions.assertEquals(new DecimalType(1234), converter.toState("1234"));
|
||||||
|
|
||||||
|
// unit in transformation result
|
||||||
|
Assertions.assertEquals(new QuantityType<>(100, SIUnits.CELSIUS), converter.toState("100°C"));
|
||||||
|
|
||||||
|
// no valid value
|
||||||
|
Assertions.assertEquals(UnDefType.UNDEF, converter.toState("W"));
|
||||||
|
Assertions.assertEquals(UnDefType.UNDEF, converter.toState(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void numberItemConverterWithUnit() {
|
||||||
|
HttpChannelConfig channelConfig = new HttpChannelConfig();
|
||||||
|
channelConfig.unit = "W";
|
||||||
|
NumberItemConverter converter = new NumberItemConverter(this::updateState, this::postCommand,
|
||||||
|
this::sendHttpValue, NoOpValueTransformation.getInstance(), NoOpValueTransformation.getInstance(),
|
||||||
|
channelConfig);
|
||||||
|
|
||||||
|
// without unit
|
||||||
|
Assertions.assertEquals(new QuantityType<>(500, Units.WATT), converter.toState("500"));
|
||||||
|
|
||||||
|
// no valid value
|
||||||
|
Assertions.assertEquals(UnDefType.UNDEF, converter.toState("100°C"));
|
||||||
|
Assertions.assertEquals(UnDefType.UNDEF, converter.toState("foo"));
|
||||||
|
Assertions.assertEquals(UnDefType.UNDEF, converter.toState(""));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void stringTypeConverter() {
|
public void stringTypeConverter() {
|
||||||
GenericItemConverter converter = createConverter(StringType::new);
|
GenericItemConverter converter = createConverter(StringType::new);
|
||||||
|
|
Loading…
Reference in New Issue