added migrated 2.x add-ons

Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
Kai Kreuzer
2020-09-21 01:58:32 +02:00
parent bbf1a7fd29
commit 6df6783b60
11662 changed files with 1302875 additions and 11 deletions

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -0,0 +1 @@
Bundle resources go in here!

View File

@@ -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>";
}

View File

@@ -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);
}
}