How Would You Design a Dynamic Audio Rule?

Any advise would be appreciated.

I have developed some very simple time based rules to assist with keeping pace with our busy lives. Each weekday morning, a set of audio messages play to keep the kids on time.

Children it is time eat breakfast.
Children you have 15 minutes remaining.
Children you have 5 minutes remaining.
Children it is time to find your shoes and jackets.
Children it is time to leave for school.

Much like a school bell, they have adapted quite well to the sequence, and Mom and Dad no longer are the ones giving these repeating directions. We have named our audio prompt voice Charles, he also reminds the children to feed the dog, and when bedtime is approaching. Visitors are amazed when Charles speaks.

I have recently developed a couple of new rules, one for each child that similar to spelling quiz, announce their weekly spelling words. So with a simple switch phrase to Alexa, they can simulate a practice test on command, “Alexa turn on Joey’s spelling test.” The kids seem to like it and it generally pronounces the words well enough for recognition. Below is the Rule that I’m using. Here’s my design question. How can I automate the changing of the words on a weekly basis for each child. I’m thinking of things like emailing the list to OH, or using a MQTT message approach. Other ideas going through my head are copy paste into a HABPanel element, but I’m really just looking for how to inject 10 to 20 elements into an ArrayList so I don’t have to edit two rules each week.

TIA,

Tony

var boolean exitFlag = false

rule "Joeys Spelling Test"
when
   Item JoeySpell changed to ON
then
   logInfo("logSpellingTest","Rule playSound Test")
   val myList = newArrayList(
'agreed','thirteen','dream','sneaky','teeth',
'foresee','peach','easterly','cheese',
'greeting','bleachers','beneath','sleeveless',
'proceed','wheat','pleading','fleece',
'clean','squealed','peaceful'
)
   logInfo("logSpellingTest","Trying to Speak")
      myList.forEach[ str |
         logInfo("logSpellingTest","The word is " + str )
         say("Spell the word.     " + str)
         Thread::sleep(8000)
         say("" + str)
         Thread::sleep(6000)

        if(JoeySpell.state == OFF) {
            logInfo("Spelling Test turned OFF, exiting.")
            return
         }
      ]
   JoeySpell.sendCommand(OFF)

end

1 Like

I love it!

So step back a little bit. This is why I always encourage people to describe what they are really trying to accomplish rather than just asking how to do something the way they think it needs to be done (as you have thankfully).

What you really need is a way to set the state of a String Item. Then use some simple string parsing to convert that String to the list.

If we assume the words are separated by a space then just replace your definition of myList with:

val myList = JoeySpellList.split(" ")

The rest of your rule can remain unchanged.

Now the only challenge is populating that String Item. And there is a myriad of ways you can do this. The best depends on how much effort you want to put into it. Some additional ideas that come to mind:

  • save the list to a file and periodically load that file with a cron triggered rule with a line like JoeySpellList.postUpdate(executeCommandLine("cat /path/to/joey/spelling/list.txt"))
  • Use the REST API to postUpdate the new list from a script or special purpose website
  • There is a Mail Control binding to implement your email idea
  • MQTT may be more trouble than it is worth as once you set up a script to publish to MQTT you have basically done the work to do a REST API call. So if you are not already using MQTT I wouldn’t add it just for this.
  • You could string something together using IFTTT and text messages perhaps.

Basically, anything that lets you set a String Item’s state will work for you.

Personally, I would probably just write them to a file that periodically gets read with the executeCommandLine.

2 Likes

I think another point that should be discussed is how you receive the list of words. If it is a hand written list then manually entering the data into a format discussed above is the best course of action. If the list is available from the school’s website then you can have openHAB fetch and process the data without user interaction. If the list is supplied as a printed list then combining the exec functionality discussed above with a scanner and OCR can streamline the process.