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
  • Field Details

  • Constructor Details

  • Method Details

    • deactivate

      protected void deactivate()
    • createRules

      protected abstract void createRules(@Nullable Locale locale)
      Called whenever the rules are to be (re)generated and added by addRules(java.util.Locale, org.openhab.core.voice.text.Rule...)
    • interpret

      public String interpret(Locale locale, String text) throws InterpretationException
      Description copied from interface: HumanLanguageInterpreter
      Interprets a human language text fragment of a given Locale
      Specified by:
      interpret in interface HumanLanguageInterpreter
      Parameters:
      locale - language of the text (given by a Locale)
      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 given Locale with optional access to the context of a dialog execution.
      Specified by:
      interpret in interface HumanLanguageInterpreter
      Parameters:
      locale - language of the text (given by a Locale)
      text - the text to interpret
      Returns:
      a human language response
      Throws:
      InterpretationException
    • name

      protected Expression 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 use itemRule(java.lang.Object) instead.
      Returns:
      Expression that represents a name of an item.
    • name

      protected Expression name(@Nullable Expression stopper)
      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 use itemRule(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

      public Rule[] getRules(Locale locale)
      Retrieves all Rules to a given Locale. 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

      protected void addRules(Locale locale, Rule... rules)
      Adds Locale specific rules to this interpreter. To be called from within createRules(java.util.Locale).
      Parameters:
      locale - Locale of the rules.
      rules - Rules to add.
    • itemRule

      protected Rule itemRule(Object headExpression)
      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 one cmd(java.lang.Object) generated expression. The corresponding Command will in case of a match be sent to the matching Item.
      Returns:
      The created rule.
    • itemRule

      protected Rule itemRule(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 one cmd(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 one cmd(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 one cmd(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 target
      headExpression - 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 one cmd(java.lang.Object) generated expression.
      Parameters:
      itemFilter - Filters the allowed items.
      cmdExpression - The expression.
      Returns:
      The created rule.
    • exp

      protected @Nullable Expression exp(@Nullable Object obj)
      Converts an object to an expression. Objects that are already instances of Expression are just returned. All others are converted to Expression.
      Parameters:
      obj - the object that's to be converted
      Returns:
      resulting expression
    • exps

      protected Expression[] exps(Object... objects)
      Converts all parameters to an expression array. Objects that are already instances of Expression are not touched. All others are converted to Expression.
      Parameters:
      objects - the objects that are to be converted
      Returns:
      resulting expression array
    • tag

      protected Expression tag(String name, Object expression)
      Adds a name to the resulting AST tree, if the given expression matches.
      Parameters:
      name - name to add
      expression - the expression that has to match
      Returns:
      resulting expression
    • tag

      protected Expression tag(Object expression, Object tag)
      Adds a value to the resulting AST tree, if the given expression matches.
      Parameters:
      expression - the expression that has to match
      tag - the tag that's to be set
      Returns:
      resulting expression
    • tag

      protected Expression tag(@Nullable String name, Object expression, @Nullable Object tag)
      Adds a name and a tag to the resulting AST tree, if the given expression matches.
      Parameters:
      name - name to add
      expression - the expression that has to match
      tag - the tag that's to be set
      Returns:
      resulting expression
    • cmd

      protected Expression cmd(Object expression)
      Adds a command to the resulting AST tree. If the expression evaluates to a numeric value, it will get a DecimalType, otherwise a StringType.
      Parameters:
      expression - the expression that has to match
      Returns:
      resulting expression
    • cmd

      protected Expression cmd(Object expression, @Nullable Command command)
      Adds a command to the resulting AST tree, if the expression matches.
      Parameters:
      expression - the expression that has to match
      command - 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 match
      command - the command that should be added
      Returns:
      resulting expression
    • alt

      protected org.openhab.core.voice.text.ExpressionAlternatives alt(Object... expressions)
      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

      protected ExpressionSequence seq(Object... expressions)
      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 an Object[] that contains all values of the matching expressions.
      Parameters:
      expressions - the expressions (alternatives) that have to match in sequence
      Returns:
      resulting expression
    • opt

      protected ExpressionCardinality opt(Object expression)
      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

      protected ExpressionCardinality star(Object expression)
      Creates a repeating expression that will match the given expression as often as possible. Always succeeds. The resulting node's value will be an Object[] that contains all values of the matches.
      Parameters:
      expression - the repeating expression
      Returns:
      resulting expression
    • plus

      protected ExpressionCardinality plus(Object expression)
      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 an Object[] 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 texts
      labelFragments - 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 texts
      itemCommandSupplier - 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 are tokenized 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 matching
      labelFragments - 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

      protected List<String> tokenize(Locale locale, @Nullable String text)
      Tokenizes text. Filters out all unsupported punctuation. Tokens will be lowercase.
      Parameters:
      locale - the locale that should be used for lower casing
      text - the text that should be tokenized
      Returns:
      resulting tokens
    • tokenize

      protected List<String> tokenize(Locale locale, @Nullable String text, boolean customRuleCompat)
      Tokenizes text. Filters out all unsupported punctuation. Tokens will be lowercase.
      Parameters:
      locale - the locale that should be used for lower casing
      text - the text that should be tokenized
      customRuleCompat - 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 a Rule 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 a Rule
      metadata - voiceSystem metadata.
      Returns:
      The created rule.
    • getSupportedGrammarFormats

      public Set<String> getSupportedGrammarFormats()
      Description copied from interface: HumanLanguageInterpreter
      Gets all supported grammar format specifiers
      Specified by:
      getSupportedGrammarFormats in interface HumanLanguageInterpreter
      Returns:
      Set of supported grammars (each given by a short name)
    • getGrammar

      public @Nullable String getGrammar(Locale locale, String format)
      Description copied from interface: HumanLanguageInterpreter
      Gets the grammar of all commands of a given Locale of the interpreter
      Specified by:
      getGrammar in interface HumanLanguageInterpreter
      Parameters:
      locale - language of the commands (given by a Locale)
      format - the grammar format
      Returns:
      a grammar of the specified format