added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.transform.scale-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-transformation-scale" description="Scale Transformation" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="75">mvn:org.openhab.addons.bundles/org.openhab.transform.scale/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.transform.scale.internal;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Range implementation using BigDecimals.
|
||||
*
|
||||
* @author Markus Rathgeb - Initial contribution
|
||||
*/
|
||||
public class Range {
|
||||
|
||||
public static Range open(final BigDecimal lower, final BigDecimal upper) {
|
||||
return new Range(lower, false, upper, false);
|
||||
}
|
||||
|
||||
public static Range closed(final BigDecimal lower, final BigDecimal upper) {
|
||||
return new Range(lower, true, upper, true);
|
||||
}
|
||||
|
||||
public static Range openClosed(final BigDecimal lower, final BigDecimal upper) {
|
||||
return new Range(lower, false, upper, true);
|
||||
}
|
||||
|
||||
public static Range closedOpen(final BigDecimal lower, final BigDecimal upper) {
|
||||
return new Range(lower, true, upper, false);
|
||||
}
|
||||
|
||||
public static Range greaterThan(final BigDecimal lower) {
|
||||
return new Range(lower, false, null, false);
|
||||
}
|
||||
|
||||
public static Range atLeast(final BigDecimal lower) {
|
||||
return new Range(lower, true, null, false);
|
||||
}
|
||||
|
||||
public static Range lessThan(final BigDecimal upper) {
|
||||
return new Range(null, false, upper, false);
|
||||
}
|
||||
|
||||
public static Range atMost(final BigDecimal upper) {
|
||||
return new Range(null, false, upper, true);
|
||||
}
|
||||
|
||||
public static Range all() {
|
||||
return new Range(null, false, null, false);
|
||||
}
|
||||
|
||||
public static Range range(final BigDecimal lower, final boolean lowerInclusive, final BigDecimal upper,
|
||||
final boolean upperInclusive) {
|
||||
return new Range(lower, lowerInclusive, upper, upperInclusive);
|
||||
}
|
||||
|
||||
final BigDecimal min;
|
||||
final boolean minInclusive;
|
||||
final BigDecimal max;
|
||||
final boolean maxInclusive;
|
||||
|
||||
private Range(final BigDecimal min, final boolean minInclusive, final BigDecimal max, final boolean maxInclusive) {
|
||||
this.min = min;
|
||||
this.minInclusive = minInclusive;
|
||||
this.max = max;
|
||||
this.maxInclusive = maxInclusive;
|
||||
}
|
||||
|
||||
public boolean contains(final BigDecimal value) {
|
||||
final boolean minMatch;
|
||||
if (min == null) {
|
||||
minMatch = true;
|
||||
} else {
|
||||
int cmp = value.compareTo(min);
|
||||
if (minInclusive) {
|
||||
minMatch = cmp == 0 || cmp == 1;
|
||||
} else {
|
||||
minMatch = cmp == 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!minMatch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final boolean maxMatch;
|
||||
if (max == null) {
|
||||
maxMatch = true;
|
||||
} else {
|
||||
int cmp = value.compareTo(max);
|
||||
if (maxInclusive) {
|
||||
maxMatch = cmp == 0 || cmp == -1;
|
||||
} else {
|
||||
maxMatch = cmp == -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!maxMatch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.transform.scale.internal;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.transform.AbstractFileTransformationService;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
import org.openhab.core.transform.TransformationService;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The implementation of {@link TransformationService} which transforms the
|
||||
* input by matching it between limits of ranges in a scale file
|
||||
*
|
||||
* @author Gaël L'hopital
|
||||
* @author Markus Rathgeb - drop usage of Guava
|
||||
*/
|
||||
@Component(immediate = true, service = TransformationService.class, property = { "smarthome.transform=SCALE" })
|
||||
public class ScaleTransformationService extends AbstractFileTransformationService<Map<Range, String>> {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ScaleTransformationService.class);
|
||||
|
||||
/** RegEx to extract a scale definition */
|
||||
private static final Pattern LIMITS_PATTERN = Pattern.compile("(\\[|\\])(.*)\\.\\.(.*)(\\[|\\])");
|
||||
|
||||
private static final String NON_NUMBER = "NaN";
|
||||
private static final String FORMAT = "format";
|
||||
private static final String FORMAT_VALUE = "%value%";
|
||||
private static final String FORMAT_LABEL = "%label%";
|
||||
|
||||
/** Inaccessible range used to store presentation format ]0..0[ */
|
||||
private static final Range FORMAT_RANGE = Range.range(BigDecimal.ZERO, false, BigDecimal.ZERO, false);
|
||||
|
||||
/**
|
||||
* The implementation of {@link OrderedProperties} that let access
|
||||
* properties in the same order than presented in the source file
|
||||
* by using the orderedKeys function.
|
||||
*
|
||||
* This implementation is limited to the sole purpose of the class
|
||||
* (e.g. it does not handle removing elements)
|
||||
*
|
||||
* @author Gaël L'hopital
|
||||
*/
|
||||
static class OrderedProperties extends Properties {
|
||||
private static final long serialVersionUID = 3860553217028220119L;
|
||||
private final HashSet<Object> keys = new LinkedHashSet<>();
|
||||
|
||||
Set<Object> orderedKeys() {
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<Object> keys() {
|
||||
return Collections.<Object> enumeration(keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object put(Object key, Object value) {
|
||||
keys.add(key);
|
||||
return super.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs transformation of the input <code>source</code>
|
||||
*
|
||||
* The method transforms the input <code>source</code> by matching searching
|
||||
* the range where it fits i.e. [min..max]=value or ]min..max]=value
|
||||
*
|
||||
* @param properties the list of properties defining all the available ranges
|
||||
* @param source the input to transform
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
protected String internalTransform(Map<Range, String> data, String source) throws TransformationException {
|
||||
try {
|
||||
final BigDecimal value = new BigDecimal(source);
|
||||
|
||||
return formatResult(data, source, value);
|
||||
} catch (NumberFormatException e) {
|
||||
// Scale can only be used with numeric inputs, so lets try to see if ever its a valid quantity type
|
||||
try {
|
||||
final QuantityType<?> quantity = new QuantityType<>(source);
|
||||
return formatResult(data, source, quantity.toBigDecimal());
|
||||
} catch (NumberFormatException e2) {
|
||||
String nonNumeric = data.get(null);
|
||||
if (nonNumeric != null) {
|
||||
return nonNumeric;
|
||||
} else {
|
||||
throw new TransformationException(
|
||||
"Scale must be used with numeric inputs, valid quantity types or a 'NaN' entry.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String formatResult(Map<Range, String> data, String source, final BigDecimal value)
|
||||
throws TransformationException {
|
||||
String format = data.get(FORMAT_RANGE);
|
||||
String result = getScaleResult(data, source, value);
|
||||
return format.replaceAll(FORMAT_VALUE, source).replaceAll(FORMAT_LABEL, result);
|
||||
}
|
||||
|
||||
private String getScaleResult(Map<Range, String> data, String source, final BigDecimal value)
|
||||
throws TransformationException {
|
||||
return data.entrySet().stream().filter(entry -> entry.getKey() != null && entry.getKey().contains(value))
|
||||
.findFirst().map(Map.Entry::getValue)
|
||||
.orElseThrow(() -> new TransformationException("No matching range for '" + source + "'"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Range, String> internalLoadTransform(String filename) throws TransformationException {
|
||||
try (FileReader reader = new FileReader(filename)) {
|
||||
final Map<Range, String> data = new LinkedHashMap<>();
|
||||
data.put(FORMAT_RANGE, FORMAT_LABEL);
|
||||
final OrderedProperties properties = new OrderedProperties();
|
||||
properties.load(reader);
|
||||
|
||||
for (Object orderedKey : properties.orderedKeys()) {
|
||||
final String entry = (String) orderedKey;
|
||||
final String value = properties.getProperty(entry);
|
||||
final Matcher matcher = LIMITS_PATTERN.matcher(entry);
|
||||
if (matcher.matches() && (matcher.groupCount() == 4)) {
|
||||
final boolean lowerInclusive = matcher.group(1).equals("[");
|
||||
final boolean upperInclusive = matcher.group(4).equals("]");
|
||||
|
||||
final String lowLimit = matcher.group(2);
|
||||
final String highLimit = matcher.group(3);
|
||||
|
||||
try {
|
||||
final BigDecimal lowValue = lowLimit.isEmpty() ? null : new BigDecimal(lowLimit);
|
||||
final BigDecimal highValue = highLimit.isEmpty() ? null : new BigDecimal(highLimit);
|
||||
final Range range = Range.range(lowValue, lowerInclusive, highValue, upperInclusive);
|
||||
|
||||
data.put(range, value);
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new TransformationException("Error parsing bounds: " + lowLimit + ".." + highLimit);
|
||||
}
|
||||
} else {
|
||||
if (NON_NUMBER.equals(entry)) {
|
||||
data.put(null, value);
|
||||
} else if (FORMAT.equals(entry)) {
|
||||
data.put(FORMAT_RANGE, value);
|
||||
} else {
|
||||
logger.warn("Scale transform file '{}' does not comply with syntax for entry : '{}', '{}'",
|
||||
filename, entry, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (final IOException ex) {
|
||||
throw new TransformationException("An error occurred while opening file.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.transform.scale.internal.profiles;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.profiles.ProfileCallback;
|
||||
import org.openhab.core.thing.profiles.ProfileContext;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeUID;
|
||||
import org.openhab.core.thing.profiles.StateProfile;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
import org.openhab.core.transform.TransformationHelper;
|
||||
import org.openhab.core.transform.TransformationService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.Type;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Profile to offer the ScaleTransformationservice on a ItemChannelLink
|
||||
*
|
||||
* @author Stefan Triller - initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ScaleTransformationProfile implements StateProfile {
|
||||
|
||||
public static final ProfileTypeUID PROFILE_TYPE_UID = new ProfileTypeUID(
|
||||
TransformationService.TRANSFORM_PROFILE_SCOPE, "SCALE");
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ScaleTransformationProfile.class);
|
||||
|
||||
private final TransformationService service;
|
||||
private final ProfileCallback callback;
|
||||
|
||||
private static final String FUNCTION_PARAM = "function";
|
||||
private static final String SOURCE_FORMAT_PARAM = "sourceFormat";
|
||||
|
||||
@NonNullByDefault({})
|
||||
private final String function;
|
||||
@NonNullByDefault({})
|
||||
private final String sourceFormat;
|
||||
|
||||
public ScaleTransformationProfile(ProfileCallback callback, ProfileContext context, TransformationService service) {
|
||||
this.service = service;
|
||||
this.callback = callback;
|
||||
|
||||
Object paramFunction = context.getConfiguration().get(FUNCTION_PARAM);
|
||||
Object paramSource = context.getConfiguration().get(SOURCE_FORMAT_PARAM);
|
||||
|
||||
logger.debug("Profile configured with '{}'='{}', '{}'={}", FUNCTION_PARAM, paramFunction, SOURCE_FORMAT_PARAM,
|
||||
paramSource);
|
||||
// SOURCE_FORMAT_PARAM is an advanced parameter and we assume "%s" if it is not set
|
||||
if (paramSource == null) {
|
||||
paramSource = "%s";
|
||||
}
|
||||
if (paramFunction instanceof String && paramSource instanceof String) {
|
||||
function = (String) paramFunction;
|
||||
sourceFormat = (String) paramSource;
|
||||
} else {
|
||||
logger.error("Parameter '{}' and '{}' have to be Strings. Profile will be inactive.", FUNCTION_PARAM,
|
||||
SOURCE_FORMAT_PARAM);
|
||||
function = null;
|
||||
sourceFormat = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProfileTypeUID getProfileTypeUID() {
|
||||
return PROFILE_TYPE_UID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateUpdateFromItem(State state) {
|
||||
callback.handleUpdate(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommandFromItem(Command command) {
|
||||
callback.handleCommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommandFromHandler(Command command) {
|
||||
if (function == null || sourceFormat == null) {
|
||||
logger.warn(
|
||||
"Please specify a function and a source format for this Profile in the '{}', and '{}' parameters. Returning the original command now.",
|
||||
FUNCTION_PARAM, SOURCE_FORMAT_PARAM);
|
||||
callback.sendCommand(command);
|
||||
return;
|
||||
}
|
||||
callback.sendCommand((Command) transformState(command));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateUpdateFromHandler(State state) {
|
||||
if (function == null || sourceFormat == null) {
|
||||
logger.warn(
|
||||
"Please specify a function and a source format for this Profile in the '{}' and '{}' parameters. Returning the original state now.",
|
||||
FUNCTION_PARAM, SOURCE_FORMAT_PARAM);
|
||||
callback.sendUpdate(state);
|
||||
return;
|
||||
}
|
||||
callback.sendUpdate((State) transformState(state));
|
||||
}
|
||||
|
||||
private Type transformState(Type state) {
|
||||
String result = state.toFullString();
|
||||
try {
|
||||
result = TransformationHelper.transform(service, function, sourceFormat, state.toFullString());
|
||||
} catch (TransformationException e) {
|
||||
logger.warn("Could not transform state '{}' with function '{}' and format '{}'", state, function,
|
||||
sourceFormat);
|
||||
}
|
||||
StringType resultType = new StringType(result);
|
||||
logger.debug("Transformed '{}' into '{}'", state, resultType);
|
||||
return resultType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.transform.scale.internal.profiles;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.profiles.Profile;
|
||||
import org.openhab.core.thing.profiles.ProfileCallback;
|
||||
import org.openhab.core.thing.profiles.ProfileContext;
|
||||
import org.openhab.core.thing.profiles.ProfileFactory;
|
||||
import org.openhab.core.thing.profiles.ProfileType;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeBuilder;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeProvider;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeUID;
|
||||
import org.openhab.core.transform.TransformationService;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* Profilefactory that creates the transformation profile for the scale transformation service
|
||||
*
|
||||
* @author Stefan Triller - initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = { ProfileFactory.class, ProfileTypeProvider.class })
|
||||
public class ScaleTransformationProfileFactory implements ProfileFactory, ProfileTypeProvider {
|
||||
|
||||
@NonNullByDefault({})
|
||||
private TransformationService service;
|
||||
|
||||
@Override
|
||||
public Collection<ProfileType> getProfileTypes(@Nullable Locale locale) {
|
||||
return Arrays.asList(ProfileTypeBuilder.newState(ScaleTransformationProfile.PROFILE_TYPE_UID,
|
||||
ScaleTransformationProfile.PROFILE_TYPE_UID.getId()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Profile createProfile(ProfileTypeUID profileTypeUID, ProfileCallback callback,
|
||||
ProfileContext profileContext) {
|
||||
return new ScaleTransformationProfile(callback, profileContext, service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ProfileTypeUID> getSupportedProfileTypeUIDs() {
|
||||
return Arrays.asList(ScaleTransformationProfile.PROFILE_TYPE_UID);
|
||||
}
|
||||
|
||||
@Reference(target = "(smarthome.transform=SCALE)")
|
||||
public void addTransformationService(TransformationService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public void removeTransformationService(TransformationService service) {
|
||||
this.service = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<config-description:config-descriptions
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:config-description="https://openhab.org/schemas/config-description/v1.0.0"
|
||||
xsi:schemaLocation="https://openhab.org/schemas/config-description/v1.0.0 https://openhab.org/schemas/config-description-1.0.0.xsd">
|
||||
|
||||
<config-description uri="profile:transform:SCALE">
|
||||
<parameter name="function" type="text" required="true">
|
||||
<label>Filename</label>
|
||||
<description>Filename containing the scale mappings.</description>
|
||||
</parameter>
|
||||
<parameter name="sourceFormat" type="text" required="false">
|
||||
<label>State Formatter</label>
|
||||
<description>How to format the state on the channel before transforming it, i.e. %s or %.1f °C (default is %s)</description>
|
||||
<advanced>true</advanced>
|
||||
</parameter>
|
||||
</config-description>
|
||||
</config-description:config-descriptions>
|
||||
@@ -0,0 +1 @@
|
||||
Bundle resources go in here!
|
||||
@@ -0,0 +1,157 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 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.transform.scale.internal;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.measure.quantity.Dimensionless;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
|
||||
/**
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
public class ScaleTransformServiceTest {
|
||||
private ScaleTransformationService processor;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
processor = new ScaleTransformationService() {
|
||||
@Override
|
||||
protected Locale getLocale() {
|
||||
return Locale.US;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByScale() throws TransformationException {
|
||||
// need to be sure we'll have the german version
|
||||
String existingscale = "scale/humidex_de.scale";
|
||||
String source = "10";
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("nicht wesentlich", transformedResponse);
|
||||
|
||||
existingscale = "scale/limits.scale";
|
||||
source = "10";
|
||||
transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("middle", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByScaleLimits() throws TransformationException {
|
||||
String existingscale = "scale/limits.scale";
|
||||
|
||||
// Testing upper bound opened range
|
||||
String source = "500";
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("extreme", transformedResponse);
|
||||
|
||||
// Testing lower bound opened range
|
||||
source = "-10";
|
||||
transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("low", transformedResponse);
|
||||
|
||||
// Testing unfinite up and down range
|
||||
existingscale = "scale/catchall.scale";
|
||||
source = "-10";
|
||||
transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("catchall", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByScaleUndef() throws TransformationException {
|
||||
// check that for undefined/non numeric value we return empty string
|
||||
// Issue #1107
|
||||
String existingscale = "scale/humidex_fr.scale";
|
||||
String source = "-";
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByScaleErrorInBounds() throws TransformationException {
|
||||
// the tested file contains inputs that generate a conversion error of the bounds
|
||||
// of range
|
||||
String existingscale = "scale/erroneous.scale";
|
||||
String source = "15";
|
||||
try {
|
||||
@SuppressWarnings("unused")
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
fail();
|
||||
} catch (TransformationException e) {
|
||||
// awaited result
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByScaleErrorInValue() throws TransformationException {
|
||||
// checks that an error is raised when trying to scale an erroneous value
|
||||
String existingscale = "scale/evaluationorder.scale";
|
||||
String source = "azerty";
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEvaluationOrder() throws TransformationException {
|
||||
// Ensures that only first matching scale as presented in the file is taken in account
|
||||
String evaluationOrder = "scale/evaluationorder.scale";
|
||||
// This value matches two lines of the scale file
|
||||
String source = "12";
|
||||
|
||||
String transformedResponse = processor.transform(evaluationOrder, source);
|
||||
Assert.assertEquals("first", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformQuantityType() throws TransformationException {
|
||||
QuantityType<Dimensionless> airQuality = new QuantityType<>("992 ppm");
|
||||
String aqScaleFile = "scale/netatmo_aq.scale";
|
||||
String expected = "Correcte (992 ppm) !";
|
||||
|
||||
String transformedResponse = processor.transform(aqScaleFile, airQuality.toString());
|
||||
Assert.assertEquals(expected, transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCatchNonNumericValue() throws TransformationException {
|
||||
// checks that an error is raised when trying to scale an erroneous value
|
||||
String existingscale = "scale/catchnonnumeric.scale";
|
||||
String source = "azerty";
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("Non Numeric", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformAndFormat() throws TransformationException {
|
||||
String existingscale = "scale/netatmo_aq.scale";
|
||||
String source = "992";
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("Correcte (992) !", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValueExceedsRange() throws TransformationException {
|
||||
String existingscale = "scale/humidex.scale";
|
||||
String source = "200";
|
||||
String transformedResponse = processor.transform(existingscale, source);
|
||||
Assert.assertEquals("", transformedResponse);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user