This tutorial assumes you already have TTS set up. It will not teach you how to set up TTS. If you need assistance in that please search as there are topics on that or create a help thread.
Many thanks to @rlkoshak for helping develop these rules!!
Goal: The goal of this tutorial is to create a method so that random audio messages are played over TTS triggered by rules. The desire for this was to give my home automation system a little more personality instead of the same response every time. The pool of responses is supplied by you so that you can create your own style (proper, sassy, funny, technical, ect.).
Version: OH2
Hardware: Google Home (although another audio sink would work the same)
Bindings: VoiceRSS (or another TTS), Chromecast (for Google Home to act as an audio sink), Expire
There are two methods we will use. One method is to contain the pool of responses within the rule itself. This is helpful when the responses are tailored to the event that will be occurring. In my example, this rule turns on lights at sunset (Astro 2 binding is used in this example).
Rule:
import java.util.concurrent.ThreadLocalRandom;
rule "Lights on at Sunset"
when
Channel 'astro:sun:local:set#event' triggered START
then
if(LightsOnAtSunset.state==ON) {
FrontDoorLight.sendCommand(ON)
FrontDoorDecorations.sendCommand(ON)
FoyerLanternLoadLevelStatus.sendCommand(30)
switch ThreadLocalRandom::current().nextInt(0, 3+ 1): {
case 0: say("I know you're afraid of the dark so here's some lights.")
case 1: say("It's getting dark out so bring in the kids.")
case 2: say("You want some lights, fine. Grumble grumble grumble.")
case 3: say("You know, there are physical switches installed in this house.")
}
}
end
Note the number of cases. There are four total (starts with zero). You can add or subtract any number of messages you want. Your final number of cases must be randomized within the rule. This is done via the part “nextInt(0, 3+ 1)”. Your highest number of case must be where the “3” is. “+1” is added because nextInt is not inclusive of the integer (in this case 3). To make it inclusive you need to add one. For example, if you only had 3 cases (case 0, case 1, case 2) you would have “nextInt(0, 2+ 1)”.
The second method is to create a switch that activates a pool of responses. I use this method for general use, specifically giving voice commands through Google Home. Since it is used for a variety of commands it made more sense to create this once and activate it via a switch than to write them into every rule.
Item:
/* Play Random Response */
Switch RandomResponse "Random Response" {expire="2s,command=OFF"}
Note the Expire binding is used to return to switch to an OFF state.
Rule:
import java.util.concurrent.ThreadLocalRandom;
rule "Play Random Response"
when
Item RandomResponse received command ON
then
switch ThreadLocalRandom::current().nextInt(0, 5+ 1): {
case 0: say("Your wish is my command.")
case 1: say("You know, you could easily do this yourself.")
case 2: say("I live to serve. Apparently")
case 3: say("Just another day in my cold existence.")
case 4: say("What master wants, master gets.")
case 5: say("You only talk to me when you need something.")
}
end
You may add the following to any rule to play a response from the above cases:
RandomResponse.sendCommand(ON)
The same condition applies to the previous method where you must adjust the nextInt command to match the number of cases you have (notice mine is adjusted to be “5+ 1”)
I hope this tutorial allows you to bring a little more personality to your system. I know I chuckle every time I ask “her” to do something and she gives me a snarky response. With this method it is easy to add or change the responses over time giving variety to your experience.