Package org.openhab.core.voice.text
Class AbstractRuleBasedInterpreter
java.lang.Object
org.openhab.core.voice.text.AbstractRuleBasedInterpreter
- All Implemented Interfaces:
HumanLanguageInterpreter
@NonNullByDefault
public abstract class AbstractRuleBasedInterpreter
extends Object
implements HumanLanguageInterpreter
A human language command interpretation service.
- Author:
- Tilman Kamp - Initial contribution, Kai Kreuzer - Improved error handling, Miguel Álvarez - Reduce collisions on exact match and use item synonyms, Miguel Álvarez - Reduce collisions using dialog location
-
Nested Class Summary
Modifier and TypeClassDescriptionprotected static interface
static final record
-
Field Summary
-
Constructor Summary
ConstructorDescriptionAbstractRuleBasedInterpreter
(EventPublisher eventPublisher, ItemRegistry itemRegistry, MetadataRegistry metadataRegistry) -
Method Summary
Modifier and TypeMethodDescriptionprotected void
AddsLocale
specific rules to this interpreter.protected org.openhab.core.voice.text.ExpressionAlternatives
Creates an alternatives expression.protected Expression
Adds a command to the resulting AST tree.protected Expression
Adds a command to the resulting AST tree, if the expression matches.protected Expression
cmd
(Object expression, @Nullable AbstractRuleBasedInterpreter.ItemCommandSupplier command) Adds command resolver to the resulting AST tree, if the expression matches.protected abstract void
createRules
(@Nullable Locale locale) Called whenever the rules are to be (re)generated and added byaddRules(java.util.Locale, org.openhab.core.voice.text.Rule...)
protected Rule
customCommandRule
(AbstractRuleBasedInterpreter.ItemFilter itemFilter, Object cmdExpression, boolean isForced, boolean isSilent) Creates a custom rule on base of a expression.protected Rule
customDynamicRule
(Item item, AbstractRuleBasedInterpreter.ItemFilter itemFilter, Object headExpression, @Nullable Object tailExpression, boolean isForced, boolean isSilent) Creates a custom rule on base of a head and a tail expression, where the middle part of the new rule's expression will consist of a free command to be captured.protected void
protected String
executeCustom
(ResourceBundle language, AbstractRuleBasedInterpreter.ItemCommandSupplier itemCommandSupplier, Rule.InterpretationContext context) Executes a custom rule command.protected String
executeSingle
(ResourceBundle language, String[] labelFragments, AbstractRuleBasedInterpreter.ItemCommandSupplier commandSupplier, Rule.InterpretationContext context) Executes a command on one item that's to be found in the item registry by given name fragments.protected @Nullable Expression
Converts an object to an expression.protected Expression[]
Converts all parameters to an expression array.@Nullable String
getGrammar
(Locale locale, String format) Gets the grammar of all commands of a givenLocale
of the interpretergetMatchingItems
(ResourceBundle language, String[] labelFragments, @Nullable AbstractRuleBasedInterpreter.ItemCommandSupplier commandSupplier, Rule.InterpretationContext context) Filters the item registry by matching each item's name with the provided name fragments.Rule[]
Gets all supported grammar format specifiersInterprets a human language text fragment of a givenLocale
interpret
(Locale locale, String text, @Nullable DialogContext dialogContext) Interprets a human language text fragment of a givenLocale
with optional access to the context of a dialog execution.protected Rule
Creates an item rule on base of an expression, where the tail of the new rule's expression will consist of an item name expression.protected Rule
Creates an item rule on base of a head and a tail expression, where the middle part of the new rule's expression will consist of an item name expression.protected Expression
name()
Creates an item name placeholder expression.protected Expression
name
(@Nullable Expression stopper) Creates an item name placeholder expression.protected ExpressionCardinality
Creates an optional expression.parseItemCustomRules
(Locale locale, Item item, String ruleText, Metadata metadata) Parses a rule as text into aRule
instance.protected ExpressionCardinality
Creates a repeating expression that will match the given expression as often as possible.protected Rule
restrictedDynamicItemRule
(Item item, AbstractRuleBasedInterpreter.ItemFilter itemFilter, Object headExpression, Object midExpression, @Nullable Object tailExpression, boolean isNameFirst, boolean isForced, boolean isSilent) Creates an item rule which two dynamic capture values on base of a head a middle and an optional tail expression, where one of the values is an item name expression and the other a free captured value.protected Rule
restrictedItemRule
(Set<Item> allowedItems, Object headExpression, @Nullable Object tailExpression) Creates an item rule on base of a head and a tail expression, where the middle part of the new rule's expression will consist of an item name expression.protected Rule
restrictedItemRule
(AbstractRuleBasedInterpreter.ItemFilter itemFilter, Object headExpression, @Nullable Object tailExpression, boolean isForced, boolean isSilent) Creates an item rule on base of a head and a tail expression, where the middle part of the new rule's ex ression will consist of an item name expression.protected ExpressionSequence
Creates a sequence expression.protected ExpressionCardinality
Creates a repeating expression that will match the given expression as often as possible.protected Expression
Adds a name and a tag to the resulting AST tree, if the given expression matches.protected Expression
Adds a value to the resulting AST tree, if the given expression matches.protected Expression
Adds a name to the resulting AST tree, if the given expression matches.Tokenizes text.Tokenizes text.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface org.openhab.core.voice.text.HumanLanguageInterpreter
getId, getLabel, getSupportedLocales
-
Field Details
-
IS_TEMPLATE_CONFIGURATION
- See Also:
-
IS_SILENT_CONFIGURATION
- See Also:
-
IS_FORCED_CONFIGURATION
- See Also:
-
-
Constructor Details
-
AbstractRuleBasedInterpreter
public AbstractRuleBasedInterpreter(EventPublisher eventPublisher, ItemRegistry itemRegistry, MetadataRegistry metadataRegistry)
-
-
Method Details
-
deactivate
protected void deactivate() -
createRules
Called whenever the rules are to be (re)generated and added byaddRules(java.util.Locale, org.openhab.core.voice.text.Rule...)
-
interpret
Description copied from interface:HumanLanguageInterpreter
Interprets a human language text fragment of a givenLocale
- Specified by:
interpret
in interfaceHumanLanguageInterpreter
- Parameters:
locale
- language of the text (given by aLocale
)text
- the text to interpret- Returns:
- a human language response
- Throws:
InterpretationException
-
interpret
public String interpret(Locale locale, String text, @Nullable DialogContext dialogContext) throws InterpretationException Description copied from interface:HumanLanguageInterpreter
Interprets a human language text fragment of a givenLocale
with optional access to the context of a dialog execution.- Specified by:
interpret
in interfaceHumanLanguageInterpreter
- Parameters:
locale
- language of the text (given by aLocale
)text
- the text to interpret- Returns:
- a human language response
- Throws:
InterpretationException
-
name
Creates an item name placeholder expression. This expression is greedy: Only use it, if there are no other expressions following this one. It's safer to useitemRule(java.lang.Object)
instead.- Returns:
- Expression that represents a name of an item.
-
name
Creates an item name placeholder expression. This expression is greedy: Only use it, if you are able to pass in all possible stop tokens as excludes. It's safer to useitemRule(java.lang.Object)
instead.- Parameters:
stopper
- Stop expression that, if matching, will stop this expression from consuming further tokens.- Returns:
- Expression that represents a name of an item.
-
getRules
Retrieves allRule
s to a givenLocale
. It also retrieves all the same-language rules into greater indexes of the array (lower match priority).- Parameters:
locale
- Locale filter- Returns:
- Rules in descending match priority order.
-
addRules
AddsLocale
specific rules to this interpreter. To be called from withincreateRules(java.util.Locale)
.- Parameters:
locale
- Locale of the rules.rules
- Rules to add.
-
itemRule
Creates an item rule on base of an expression, where the tail of the new rule's expression will consist of an item name expression.- Parameters:
headExpression
- The head expression that should contain at least onecmd(java.lang.Object)
generated expression. The correspondingCommand
will in case of a match be sent to the matchingItem
.- Returns:
- The created rule.
-
itemRule
Creates an item rule on base of a head and a tail expression, where the middle part of the new rule's expression will consist of an item name expression. Either the head expression or the tail expression should contain at least onecmd(java.lang.Object)
generated expression.- Parameters:
headExpression
- The head expression.tailExpression
- The tail expression.- Returns:
- The created rule.
-
restrictedItemRule
protected Rule restrictedItemRule(Set<Item> allowedItems, Object headExpression, @Nullable Object tailExpression) Creates an item rule on base of a head and a tail expression, where the middle part of the new rule's expression will consist of an item name expression. Either the head expression or the tail expression should contain at least onecmd(java.lang.Object)
generated expression.- Parameters:
allowedItems
- Allowed item targets.headExpression
- The head expression.tailExpression
- The tail expression.- Returns:
- The created rule.
-
restrictedItemRule
protected Rule restrictedItemRule(AbstractRuleBasedInterpreter.ItemFilter itemFilter, Object headExpression, @Nullable Object tailExpression, boolean isForced, boolean isSilent) Creates an item rule on base of a head and a tail expression, where the middle part of the new rule's ex ression will consist of an item name expression. Either the head expression or the tail expression should contain at least onecmd(java.lang.Object)
generated expression. Rule will be restricted by the provided filter.- Parameters:
itemFilter
- Filters allowed items.headExpression
- The head expression.tailExpression
- The tail expression.- Returns:
- The created rule.
-
restrictedDynamicItemRule
protected Rule restrictedDynamicItemRule(Item item, AbstractRuleBasedInterpreter.ItemFilter itemFilter, Object headExpression, Object midExpression, @Nullable Object tailExpression, boolean isNameFirst, boolean isForced, boolean isSilent) Creates an item rule which two dynamic capture values on base of a head a middle and an optional tail expression, where one of the values is an item name expression and the other a free captured value. Rule will be restricted by the provided filter.- Parameters:
item
- Item registering the rule.itemFilter
- Filters allowed items.headExpression
- The head expression.midExpression
- The middle expression.tailExpression
- The optional tail expression.isNameFirst
- Indicates whether the name goes between the head and the middle expressions.- Returns:
- The created rule.
-
customDynamicRule
protected Rule customDynamicRule(Item item, AbstractRuleBasedInterpreter.ItemFilter itemFilter, Object headExpression, @Nullable Object tailExpression, boolean isForced, boolean isSilent) Creates a custom rule on base of a head and a tail expression, where the middle part of the new rule's expression will consist of a free command to be captured. Rule will be restricted to the provided item name.- Parameters:
item
- Item targetheadExpression
- The head expression.tailExpression
- The tail expression.- Returns:
- The created rule.
-
customCommandRule
protected Rule customCommandRule(AbstractRuleBasedInterpreter.ItemFilter itemFilter, Object cmdExpression, boolean isForced, boolean isSilent) Creates a custom rule on base of a expression. The expression should contain at least onecmd(java.lang.Object)
generated expression.- Parameters:
itemFilter
- Filters the allowed items.cmdExpression
- The expression.- Returns:
- The created rule.
-
exp
Converts an object to an expression. Objects that are already instances ofExpression
are just returned. All others are converted toExpression
.- Parameters:
obj
- the object that's to be converted- Returns:
- resulting expression
-
exps
Converts all parameters to an expression array. Objects that are already instances ofExpression
are not touched. All others are converted toExpression
.- Parameters:
objects
- the objects that are to be converted- Returns:
- resulting expression array
-
tag
Adds a name to the resulting AST tree, if the given expression matches.- Parameters:
name
- name to addexpression
- the expression that has to match- Returns:
- resulting expression
-
tag
Adds a value to the resulting AST tree, if the given expression matches.- Parameters:
expression
- the expression that has to matchtag
- the tag that's to be set- Returns:
- resulting expression
-
tag
Adds a name and a tag to the resulting AST tree, if the given expression matches.- Parameters:
name
- name to addexpression
- the expression that has to matchtag
- the tag that's to be set- Returns:
- resulting expression
-
cmd
Adds a command to the resulting AST tree. If the expression evaluates to a numeric value, it will get aDecimalType
, otherwise aStringType
.- Parameters:
expression
- the expression that has to match- Returns:
- resulting expression
-
cmd
Adds a command to the resulting AST tree, if the expression matches.- Parameters:
expression
- the expression that has to matchcommand
- the command that should be added- Returns:
- resulting expression
-
cmd
protected Expression cmd(Object expression, @Nullable AbstractRuleBasedInterpreter.ItemCommandSupplier command) Adds command resolver to the resulting AST tree, if the expression matches.- Parameters:
expression
- the expression that has to matchcommand
- the command that should be added- Returns:
- resulting expression
-
alt
Creates an alternatives expression. Matches, as soon as one of the given expressions matches. They are tested in the provided order. The value of the matching expression will be used for the resulting nodes's value.- Parameters:
expressions
- the expressions (alternatives) that are to be tested- Returns:
- resulting expression
-
seq
Creates a sequence expression. Matches, if all the given expressions match. They are tested in the provided order. The resulting nodes's value will be anObject[]
that contains all values of the matching expressions.- Parameters:
expressions
- the expressions (alternatives) that have to match in sequence- Returns:
- resulting expression
-
opt
Creates an optional expression. Always succeeds. The resulting nodes's value will be the one of the matching expression or null.- Parameters:
expression
- the optionally matching expression- Returns:
- resulting expression
-
star
Creates a repeating expression that will match the given expression as often as possible. Always succeeds. The resulting node's value will be anObject[]
that contains all values of the matches.- Parameters:
expression
- the repeating expression- Returns:
- resulting expression
-
plus
Creates a repeating expression that will match the given expression as often as possible. Only succeeds, if there is at least one match. The resulting node's value will be anObject[]
that contains all values of the matches.- Parameters:
expression
- the repeating expression- Returns:
- resulting expression
-
executeSingle
protected String executeSingle(ResourceBundle language, String[] labelFragments, AbstractRuleBasedInterpreter.ItemCommandSupplier commandSupplier, Rule.InterpretationContext context) throws InterpretationException Executes a command on one item that's to be found in the item registry by given name fragments. Fails, if there is more than on item.- Parameters:
language
- resource bundle used for producing localized response textslabelFragments
- label fragments that are used to match an item's label. For a positive match, the item's label has to contain every fragment - independently of their order. They are treated case insensitive.commandSupplier
- supplies the command to be executed.- Returns:
- response text
- Throws:
InterpretationException
- in case that there is no or more than on item matching the fragments
-
executeCustom
protected String executeCustom(ResourceBundle language, AbstractRuleBasedInterpreter.ItemCommandSupplier itemCommandSupplier, Rule.InterpretationContext context) throws InterpretationException Executes a custom rule command.- Parameters:
language
- resource bundle used for producing localized response textsitemCommandSupplier
- the rule command supplier.context
- to propagate the interpretation context.- Returns:
- response text
- Throws:
InterpretationException
- in case that there is no or more than on item matching the fragments
-
getMatchingItems
protected List<Item> getMatchingItems(ResourceBundle language, String[] labelFragments, @Nullable AbstractRuleBasedInterpreter.ItemCommandSupplier commandSupplier, Rule.InterpretationContext context) Filters the item registry by matching each item's name with the provided name fragments. The item's label and its parent group's labels aretokenized
and then altogether looked up by each and every provided fragment. For the item to get included into the result list, every provided fragment has to be found among the label tokens. If a command type is provided, the item also has to support it. In case of channels and their owners being ambiguous due to sharing most of the label sequence, only the top most item with support for the given command type is kept.- Parameters:
language
- Language information that is used for matchinglabelFragments
- label fragments that are used to match an item's label. For a positive match, the item's label has to contain every fragment - independently of their order. They are treated case-insensitive.commandSupplier
- optional command supplier to access the command types an item have to support. Provide {null} if there is no need for a certain command type to be supported.- Returns:
- All matching items from the item registry.
-
tokenize
Tokenizes text. Filters out all unsupported punctuation. Tokens will be lowercase.- Parameters:
locale
- the locale that should be used for lower casingtext
- the text that should be tokenized- Returns:
- resulting tokens
-
tokenize
Tokenizes text. Filters out all unsupported punctuation. Tokens will be lowercase.- Parameters:
locale
- the locale that should be used for lower casingtext
- the text that should be tokenizedcustomRuleCompat
- do not remove characters used on custom rules- Returns:
- resulting tokens
-
parseItemCustomRules
protected List<Rule> parseItemCustomRules(Locale locale, Item item, String ruleText, Metadata metadata) Parses a rule as text into aRule
instance.The rule text should be a list of space separated expressions, one of them but not the first should be the character '*' (which indicates dynamic part to capture), the other expressions can be conformed by a single word, alternative words separated by '|', and can be marked as optional by adding '?' at the end. There must be at least one non-optional expression at the beginning of the rule.
An example of a valid text will be 'watch * on|at? the tv'.
- Parameters:
item
- will be the target of the rule.ruleText
- the text to parse into aRule
metadata
- voiceSystem metadata.- Returns:
- The created rule.
-
getSupportedGrammarFormats
Description copied from interface:HumanLanguageInterpreter
Gets all supported grammar format specifiers- Specified by:
getSupportedGrammarFormats
in interfaceHumanLanguageInterpreter
- Returns:
- Set of supported grammars (each given by a short name)
-
getGrammar
Description copied from interface:HumanLanguageInterpreter
Gets the grammar of all commands of a givenLocale
of the interpreter- Specified by:
getGrammar
in interfaceHumanLanguageInterpreter
- Parameters:
locale
- language of the commands (given by aLocale
)format
- the grammar format- Returns:
- a grammar of the specified format
-