added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.transform.regex/.classpath
Normal file
32
bundles/org.openhab.transform.regex/.classpath
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.transform.regex/.project
Normal file
23
bundles/org.openhab.transform.regex/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.transform.regex</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
13
bundles/org.openhab.transform.regex/NOTICE
Normal file
13
bundles/org.openhab.transform.regex/NOTICE
Normal file
@@ -0,0 +1,13 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
106
bundles/org.openhab.transform.regex/README.md
Normal file
106
bundles/org.openhab.transform.regex/README.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# RegEx Transformation Service
|
||||
|
||||
Transforms a source string on basis of the regular expression (regex) search pattern to a defined result string.
|
||||
|
||||
The simplest regex is in the form `<regex>` and transforms the input string on basis of the regex pattern to a result string.
|
||||
A full regex is in the form `s/<regex>/<substitution>/g` whereat the delimiter `s` and the regex flag `g` have a special meaning.
|
||||
|
||||
The regular expression in the format `s/<regex>/result/g`, replaces all occurrences of `<regex>` in the source string with `result`.
|
||||
The regular expression in the format `s/<regex>/result/` (without `g`), replaces the first occurrence of `<regex>` in the source string with `result`.
|
||||
|
||||
If the regular expression contains a [capture group](https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#cg) defined by `()`, it returns the captured string.
|
||||
Multiple capture groups can be used to retrieve multiple strings and can be combined as a result string defined in the `substitution`.
|
||||
|
||||
The transformation can be set to be restricted to only match if the input string begins with a character by prepending `^` to the beginning of a pattern or to only match if the input string ends with a specified character by appending `$` at the end.
|
||||
So the regex `^I.*b$` only matches when the input string starts with `I` and ends with `b`, like in `I'm Bob`. Both can be used alone or in combination.
|
||||
|
||||
The special characters `\.[]{}()*+-?^$|` have to be escaped when they should be used as literal characters.
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic Examples
|
||||
|
||||
| Input String | Regular Expression | Output String | Explanation |
|
||||
|---------------------------|------------------------|----------------------------|--------------------------|
|
||||
| `My network does not work.` | `s/work/cast/g` | `"My netcast does not cast."` | Replaces all matches of the string "work" with the string "cast". |
|
||||
| `My network does not work.` | `.*(\snot).*` | `" not"` | Returns only the first match and strips of the rest, "\s" defines a whitespace. |
|
||||
| `temp=44.0'C` | `temp=(.*?)'C)` | `44.0` | Matches whole string and returns the content of the captcha group `(.?)`. |
|
||||
| `48312` | `s/(.{2})(.{3})/$1.$2/g` | `48.312` | Captures 2 and 3 character, returns first capture group adds a dot and the second capture group. This divides by 1000. |
|
||||
|
||||
### Example In Setup
|
||||
|
||||
**Input String**
|
||||
|
||||
```shell
|
||||
temp=44.0'C
|
||||
```
|
||||
|
||||
the regex transformation can be used to extract the value to display it on the label.
|
||||
|
||||
**.items**
|
||||
|
||||
```csv
|
||||
String Temperature_str "Temperature [REGEX(.*=(\\d*.\\d*).*):%s °C]" {...}
|
||||
Number Temperature "Temperature [%.1f °C]"
|
||||
```
|
||||
|
||||
The regex pattern is is defined as follows
|
||||
* `.*` match any character, zero and unlimited times
|
||||
* `=` match the equal sign literally, used to find the position
|
||||
* `()` capture group match
|
||||
* `\d*` match a digit (equal to [0-9]), zero and unlimited times, the backslash has to be escaped see [string vs plain](#Differences-to-plain-Regex)
|
||||
* `.` match the dot literally
|
||||
* `\w*` match a word character (equal to [a-zA-Z_0-9]), zero and unlimited times, the backslash has to be escaped see [string vs plain](#Differences-to-plain-Regex)
|
||||
* `.*` match any character, zero and unlimited times
|
||||
|
||||
The result will be `44.0` and displayed on the label as `Temperature 44.0°C`.
|
||||
A better solution would be to use the regex on the result from the binding either in a rule or when the binding allows it on the output channel.
|
||||
Thus the value `44.0` would be saved as a number.
|
||||
|
||||
**.rules**
|
||||
|
||||
```php
|
||||
rule "Convert String to Item Number"
|
||||
when
|
||||
Item Temperature_str changed
|
||||
then
|
||||
// use the transformation service to retrieve the value
|
||||
val newValue = transform("REGEX", ".*=(\\d*.\\d*).*", Temperature_str.state.toString)
|
||||
|
||||
// post the new value to the Number Item
|
||||
Temperature.postUpdate( newValue )
|
||||
end
|
||||
```
|
||||
|
||||
Now the resulting Number can also be used in the label to [change the color](https://docs.openhab.org/configuration/sitemaps.html#label-and-value-colors) or in a rule as value for comparison.
|
||||
|
||||
## Differences to plain Regex
|
||||
|
||||
The regex is embedded in a string so when double quotes `"` are used in a regex they need to be escaped `\"` to keep the string intact.
|
||||
As the escape character of strings is the backslash this has to be escaped additionally.
|
||||
To use a dot as literal in the regex it has to be escape `\.`, but in a string it has to be escaped twice `"\\."`.
|
||||
The first backslash escapes the second backslash in the string so it can be used in the regex.
|
||||
Using a backslash in a Regex as literal `\\` will have this form `"\\\\"`.
|
||||
|
||||
## Usage as a Profile
|
||||
|
||||
The functionality of this `TransformationService` can be used in a `Profile` on an `ItemChannelLink` too.
|
||||
To do so, it can be configured in the `.items` file as follows:
|
||||
|
||||
```java
|
||||
String <itemName> { channel="<channelUID>"[profile="transform:REGEX", function="<regex>", sourceFormat="<valueFormat>"]}
|
||||
```
|
||||
|
||||
The regular expression to be executed has to be set in the `function` parameter.
|
||||
The parameter `sourceFormat` is optional and can be used to format the input value **before** the transformation, i.e. `%.3f`.
|
||||
If omitted the default is `%s`, so the input value will be put into the transformation without any format changes.
|
||||
|
||||
Please note: This profile is a one-way transformation, i.e. only values from a device towards the item are changed, the other direction is left untouched.
|
||||
|
||||
## Further Reading
|
||||
|
||||
* A full [introduction](https://www.w3schools.com/jsref/jsref_obj_regexp.asp) for regular expression is available at W3School.
|
||||
* Online validator help to check the syntax of a regex and give information how to design it.
|
||||
* [Regex 101](https://regex101.com/)
|
||||
* [Regex R](https://regexr.com/)
|
||||
* [ExtendsClass](https://extendsclass.com/regex-tester.html)
|
||||
17
bundles/org.openhab.transform.regex/pom.xml
Normal file
17
bundles/org.openhab.transform.regex/pom.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.transform.regex</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: Transformation Service :: RegEx</name>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.transform.regex-${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-regex" description="RegEx Transformation" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="75">mvn:org.openhab.addons.bundles/org.openhab.transform.regex/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* 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.regex.internal;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
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;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* The implementation of {@link TransformationService} which transforms the input by Regular Expressions.
|
||||
*
|
||||
* <p>
|
||||
* <b>Note:</b> the given Regular Expression must contain exactly one group!
|
||||
*
|
||||
* @author Thomas.Eichstaedt-Engelen
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, property = { "smarthome.transform=REGEX" })
|
||||
public class RegExTransformationService implements TransformationService {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(RegExTransformationService.class);
|
||||
|
||||
private static final Pattern SUBSTR_PATTERN = Pattern.compile("^s/(.*?[^\\\\])/(.*?[^\\\\])/(.*)$");
|
||||
|
||||
@Override
|
||||
public @Nullable String transform(String regExpression, String source) throws TransformationException {
|
||||
if (regExpression == null || source == null) {
|
||||
throw new TransformationException("the given parameters 'regex' and 'source' must not be null");
|
||||
}
|
||||
|
||||
logger.debug("about to transform '{}' by the function '{}'", source, regExpression);
|
||||
|
||||
String result = "";
|
||||
|
||||
Matcher substMatcher = SUBSTR_PATTERN.matcher(regExpression);
|
||||
if (substMatcher.matches()) {
|
||||
logger.debug("Using substitution form of regex transformation");
|
||||
String regex = substMatcher.group(1);
|
||||
String substitution = substMatcher.group(2);
|
||||
String options = substMatcher.group(3);
|
||||
if (options.equals("g")) {
|
||||
result = source.trim().replaceAll(regex, substitution);
|
||||
} else {
|
||||
result = source.trim().replaceFirst(regex, substitution);
|
||||
}
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Matcher matcher = Pattern.compile("^" + regExpression + "$", Pattern.DOTALL).matcher(source.trim());
|
||||
if (!matcher.matches()) {
|
||||
logger.debug(
|
||||
"the given regex '^{}$' doesn't match the given content '{}' -> couldn't compute transformation",
|
||||
regExpression, source);
|
||||
return null;
|
||||
}
|
||||
matcher.reset();
|
||||
|
||||
while (matcher.find()) {
|
||||
if (matcher.groupCount() == 0) {
|
||||
logger.info(
|
||||
"the given regular expression '^{}$' doesn't contain a group. No content will be extracted and returned!",
|
||||
regExpression);
|
||||
continue;
|
||||
}
|
||||
|
||||
result = matcher.group(1);
|
||||
|
||||
if (matcher.groupCount() > 1) {
|
||||
logger.debug(
|
||||
"the given regular expression '^{}$' contains more than one group. Only the first group will be returned!",
|
||||
regExpression);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -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.regex.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 RegexTransformationservice on a ItemChannelLink
|
||||
*
|
||||
* @author Stefan Triller - initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RegexTransformationProfile implements StateProfile {
|
||||
|
||||
public static final ProfileTypeUID PROFILE_TYPE_UID = new ProfileTypeUID(
|
||||
TransformationService.TRANSFORM_PROFILE_SCOPE, "REGEX");
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(RegexTransformationProfile.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 RegexTransformationProfile(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.regex.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 regex transformation service
|
||||
*
|
||||
* @author Stefan Triller - initial contribution
|
||||
*
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(service = { ProfileFactory.class, ProfileTypeProvider.class })
|
||||
public class RegexTransformationProfileFactory implements ProfileFactory, ProfileTypeProvider {
|
||||
|
||||
@NonNullByDefault({})
|
||||
private TransformationService service;
|
||||
|
||||
@Override
|
||||
public Collection<ProfileType> getProfileTypes(@Nullable Locale locale) {
|
||||
return Arrays.asList(ProfileTypeBuilder.newState(RegexTransformationProfile.PROFILE_TYPE_UID,
|
||||
RegexTransformationProfile.PROFILE_TYPE_UID.getId()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Profile createProfile(ProfileTypeUID profileTypeUID, ProfileCallback callback,
|
||||
ProfileContext profileContext) {
|
||||
return new RegexTransformationProfile(callback, profileContext, service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ProfileTypeUID> getSupportedProfileTypeUIDs() {
|
||||
return Arrays.asList(RegexTransformationProfile.PROFILE_TYPE_UID);
|
||||
}
|
||||
|
||||
@Reference(target = "(smarthome.transform=REGEX)")
|
||||
public void addTransformationService(TransformationService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public void removeTransformationService(TransformationService service) {
|
||||
this.service = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?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:REGEX">
|
||||
<parameter name="function" type="text" required="true">
|
||||
<label>Regular Expression</label>
|
||||
<description>Regular expression to be applied on the state. Should contain a capture group whose outcome will be the
|
||||
result. For example: .*=(\\d*.\\d*).* extracts the 23.5 from temp=23.5°C</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,35 @@
|
||||
/**
|
||||
* 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.regex.internal;
|
||||
|
||||
/**
|
||||
* @author Thomas.Eichstaedt-Engelen
|
||||
*/
|
||||
public abstract class AbstractTransformationServiceTest {
|
||||
|
||||
protected String source = "<?xml version=\"1.0\"?><xml_api_reply version=\"1\"><weather module_id=\"0\""
|
||||
+ " tab_id=\"0\" mobile_row=\"0\" mobile_zipped=\"1\" row=\"0\" section=\"0\" ><forecast_information>"
|
||||
+ "<city data=\"Krefeld, North Rhine-Westphalia\"/><postal_code data=\"Krefeld Germany\"/>"
|
||||
+ "<latitude_e6 data=\"\"/><longitude_e6 data=\"\"/><forecast_date data=\"2011-03-01\"/>"
|
||||
+ "<current_date_time data=\"2011-03-01 15:20:00 +0000\"/><unit_system data=\"SI\"/></forecast_information>"
|
||||
+ "<current_conditions><condition data=\"Meistens bew<65>lkt\"/><temp_f data=\"46\"/><temp_c data=\"8\"/>"
|
||||
+ "<humidity data=\"Feuchtigkeit: 66 %\"/><icon data=\"/ig/images/weather/mostly_cloudy.gif\"/>"
|
||||
+ "<wind_condition data=\"Wind: N mit 26 km/h\"/></current_conditions><forecast_conditions><day_of_week data=\"Di.\"/>"
|
||||
+ "<low data=\"-1\"/><high data=\"6\"/><icon data=\"/ig/images/weather/sunny.gif\"/><condition data=\"Klar\"/>"
|
||||
+ "</forecast_conditions><forecast_conditions><day_of_week data=\"Mi.\"/><low data=\"-1\"/><high data=\"8\"/>"
|
||||
+ "<icon data=\"/ig/images/weather/sunny.gif\"/><condition data=\"Klar\"/></forecast_conditions><forecast_conditions>"
|
||||
+ "<day_of_week data=\"Do.\"/><low data=\"-1\"/><high data=\"8\"/><icon data=\"/ig/images/weather/sunny.gif\"/>"
|
||||
+ "<condition data=\"Klar\"/></forecast_conditions><forecast_conditions><day_of_week data=\"Fr.\"/><low data=\"0\"/>"
|
||||
+ "<high data=\"8\"/><icon data=\"/ig/images/weather/sunny.gif\"/><condition data=\"Klar\"/></forecast_conditions>"
|
||||
+ "</weather></xml_api_reply>";
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* 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.regex.internal;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.openhab.core.transform.TransformationException;
|
||||
|
||||
/**
|
||||
* @author Thomas.Eichstaedt-Engelen
|
||||
*/
|
||||
public class RegExTransformationServiceTest extends AbstractTransformationServiceTest {
|
||||
|
||||
private RegExTransformationService processor;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
processor = new RegExTransformationService();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByRegex() throws TransformationException {
|
||||
// method under test
|
||||
String transformedResponse = processor.transform(".*?<current_conditions>.*?<temp_c data=\"(.*?)\".*", source);
|
||||
|
||||
// Asserts
|
||||
assertEquals("8", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByRegex_noGroup() throws TransformationException {
|
||||
// method under test
|
||||
String transformedResponse = processor.transform(".*", source);
|
||||
|
||||
// Asserts
|
||||
assertEquals("", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByRegex_moreThanOneGroup() throws TransformationException {
|
||||
// method under test
|
||||
String transformedResponse = processor.transform(".*?<current_conditions>.*?<temp_c data=\"(.*?)\"(.*)",
|
||||
source);
|
||||
|
||||
// Asserts
|
||||
assertEquals("8", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByRegex_substituteFirst() throws TransformationException {
|
||||
// method under test
|
||||
String transformedResponse = processor.transform("s/^OP:(.*?),ARG:(.*)$/$1($2)/", "OP:SetMode,ARG:42");
|
||||
|
||||
// Asserts
|
||||
assertEquals("SetMode(42)", transformedResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformByRegex_substituteAll() throws TransformationException {
|
||||
// method under test
|
||||
String transformedResponse = processor.transform("s/([A-Z]+)([0-9]+),*/var$1=$2 /g", "X12,Y54");
|
||||
|
||||
// Asserts
|
||||
assertEquals("varX=12 varY=54 ", transformedResponse);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user