In case the format of the number in the phonebook and the format of the number from the channel are different (e.g. regarding country prefixes), the `matchCount` parameter can be used.
The configured `matchCount` is counted from the right end and denotes the number of matching characters needed to consider this number as matching.
A `matchCount` of `0` is considered as "match everything".
+Matching is done on normalized versions of the numbers that have all characters except digits, '+' and '*' removed.
## Rule Action
`phonebook` and `matchCount` are optional parameters.
You can omit one or both of these parameters.
The configured `matchCount` is counted from the right end and denotes the number of matching characters needed to consider this number as matching.
-A `matchCount` of `0` is considered as "match everything" and is used as default if no other value is given.
+A `matchCount` of `0` is considered as "match everything" and is used as default if no other value is given.
+As in the phonebook profile, matching is done on normalized versions of the numbers that have all characters except digits, '+' and '*' removed.
The return value is either the phonebook entry (if found) or the input number.
Example (use all phonebooks, match 5 digits from right):
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.http.HttpMethod;
-import org.openhab.binding.tr064.internal.dto.additions.NumberType;
import org.openhab.binding.tr064.internal.dto.additions.PhonebooksType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
phonebook = phonebooksType.getPhonebook().getContact().stream().map(contact -> {
String contactName = contact.getPerson().getRealName();
return contact.getTelephony().getNumber().stream()
- .collect(Collectors.toMap(NumberType::getValue, number -> contactName));
+ .collect(Collectors.toMap(number -> normalizeNumber(number.getValue()), number -> contactName));
}).collect(HashMap::new, HashMap::putAll, HashMap::putAll);
logger.debug("Downloaded phonebook {}: {}", phonebookName, phonebook);
} catch (JAXBException | InterruptedException | ExecutionException | TimeoutException e) {
@Override
public Optional<String> lookupNumber(String number, int matchCount) {
- String matchString = matchCount > 0 && matchCount < number.length()
- ? number.substring(number.length() - matchCount)
- : number;
- logger.trace("matchString for '{}' is '{}'", number, matchString);
+ String normalized = normalizeNumber(number);
+ String matchString = matchCount > 0 && matchCount < normalized.length()
+ ? normalized.substring(normalized.length() - matchCount)
+ : normalized;
+ logger.trace("Normalized '{}' to '{}', matchString is '{}'", number, normalized, matchString);
return matchString.isBlank() ? Optional.empty()
: phonebook.keySet().stream().filter(n -> n.endsWith(matchString)).findFirst().map(phonebook::get);
}
public String toString() {
return "Phonebook{" + "phonebookName='" + phonebookName + "', phonebook=" + phonebook + '}';
}
+
+ private String normalizeNumber(String number) {
+ // Naive normalization: remove all non-digit characters
+ return number.replaceAll("[^0-9]\\+\\*", "");
+ }
}