[Serial binding] OH2 Compatibility issue with RegexTransformation service #5184
Conversation
…H2 + Migrated functionality of OH2 RegexTransformationService to OH1 addon + Regex in serial binding can now handle fast rate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Looks pretty good.
I think we need to get a few reviews from existing installations of serial binding users. You should ask for reviewers in the community forum.
@@ -0,0 +1,130 @@ | |||
/** | |||
* Copyright (c) 2010-2016 by the respective copyright holders. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2017
* Pattern matcher to match and cache patterns | ||
* | ||
* @author Marek Halmo | ||
* @see RegexPatternMatcher#getMatches getMatches() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
/** | ||
* Returns true if given regExpression is a substitution pattern | ||
* This fact is indicated by giving |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"indicated by giving" ... what? Please complete this sentence.
} | ||
|
||
/** | ||
* Caches given regexpression, if the expression is substitution pattern it marks is as substitution |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Caches given regExpression. If the expression is a substitution pattern, it marks it as a substitution."
*/ | ||
public static String[] getMatches(String regExpression, String source) throws TransformationException { | ||
if (regExpression == null || source == null) { | ||
throw new TransformationException("the given parameters 'regex' and 'source' must not be null"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"The given" ...
} | ||
} catch (TransformationException e) { | ||
logger.error("Unable to transform!", e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a warn instead of an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not shure, TransformationException is thrown only if you provide null pattern or result.
If the transformation fails due to some regex matching, it will be properly shown as a warning logger.warn("Unable to convert ....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the logging guidelines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, based on guidelines you are right.. changing to warn
Thanx Chris. I will check the forums when i have a bit of time.. i posted the jar here and on an issue report.. so a good feedback from users using regex would be great. I don't want to break compatibility.. |
Hello, Did anyone try the provided JAR? |
Fixed, could you review again? |
@@ -135,7 +140,7 @@ public String getBindingType() { | |||
@Override | |||
public void validateItemType(Item item, String bindingConfig) throws BindingConfigParseException { | |||
if (!(item instanceof SwitchItem || item instanceof StringItem || item instanceof NumberItem | |||
|| item instanceof RollershutterItem)) { | |||
|| item instanceof RollershutterItem || item instanceof ContactItem || item instanceof DimmerItem)) { | |||
throw new BindingConfigParseException("item '" + item.getName() + "' is of type '" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because of the changes to supported item types, this throw message should probably be updated to something like "Items of type {} are not supported."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will modify the message to include proper types, but i thing the user needs to be informed of the wrong item name so i will keep the old format.
*/ | ||
public class RegexPatternMatcher { | ||
private static final Logger logger = LoggerFactory.getLogger(RegexPatternMatcher.class); | ||
private static HashMap<String, Pattern> patternCache = new HashMap<String, Pattern>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new HashMap<>();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point
private static final Pattern SUBST_PATTERN = Pattern.compile("^s/(.*?[^\\\\])/(.*?[^\\\\])/(.*)$"); | ||
|
||
/** | ||
* Returns compiled pattern for specific regeExpression that is stored in patternCache |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"regeExpression" should say "regExpression", or possibly "regular expression".
} | ||
|
||
Matcher matcher = getPattern(regExpression).matcher(source.trim()); | ||
List<String> results = new ArrayList<String>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
= new ArrayList<>();
|
||
if (parameterSplitterAt > 0) { | ||
String[] split = bindingConfig.substring(parameterSplitterAt + 1, bindingConfig.length() - 1).split("\\),"); | ||
if (split.length > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant. Should remove this if block.
Ok.. fixes made. I added even more comments so the functionality is clear + found&fixed a small bug for the replacements. Feel free to review again |
Hello, the reporter of the issue tested the jar, and says it's working. There is not much attention to the thread.. What is next? Will this get merged? |
Yes, looks good to me. Thanks, @marekhalmo ! |
Thank you! |
Hello @kaikreuzer , can you point me to the issue with this? Why did you label this with a bug? |
Correct, I marked it as "bug" as it has been delivered with the 1.10.0 release and through this label it turned up in the release notes. |
When Serial binding is used in OH2 there is no compatible interface to fill the regex transformation to and therefore the Regex functionality is absent if serial binding is used in OH2
Explanation
This is because OH2 RegexTransformationService implements interface org.eclipse.smarthome.core.transform.TransformationService but Serial binding requires implementation of interface org.openhab.core.transform.TransformationService available only in OH1
Because there is no way of including org.eclipse.smarthome.core.transform.TransformationService in the OH1 addons and OH2 will never have org.openhab.core.transform.TransformationService regex implementation the use of transformation service has to be removed and substituted with local code which is a slightly modified RegexTransformationService
This has also the benefit of REGEX functionality working even without the Regex transformation installed
Note
The OH2 RegexTransformationService can't fully cover the required cases for serial devices as serial device with fast communication can send multiple commands to buffer.
Example
Device sends temperature in format "temp:%C" (e.g. "temp:15C\n")
The corresponding regex would be: REGEX(temp:([0-9]{1,3}C)
If device sends temperature too fast, the Serial binding would receive "temp:15C\ntemp:16C\n"
in this case the original regex won't match the regex and therefore won't update the item at all.
This way both values are ignored!
Original issue and discussion can be found here
This patch fixes both issues
A jar for everybody to test can be found here