Alexa Speak and Respond

Purpose

This is an example script that can be modified to suit your implementation. It will parse all Alexa voice commands and, if they match the text in the rule, it will send a command to an Item linked to that Alexa device’s TTS Channel. For example, I can ask Alexa “Are the doors locked?” and the device that I asked will respond with “all doors are locked” or a list of the unlocked doors. Additional phrases can be added.

Requires

  • Amazon Echo Control binding

  • A routine setup in the Alexa app that captures the same text you are capturing (I used a volume adjustment for the action)

  • This file will need to be renamed (remove the ‘.example’)

  • Items:

    Group    gAlexa_LastVoiceCommand    "Last Voice Command"
    String    DiningRoom_Dot_LastVoiceCommand    "Dining Room: Last Voice Command [%s]"    (gAlexa_LastVoiceCommand)    {channel="amazonechocontrol:xxxxx:xxxxx:xxxxx:lastVoiceCommand"}
    String    DiningRoom_Dot_TTS    "Dining Room: TTS [%s]"    {channel="amazonechocontrol:xxxxx:xxxxx:xxxxx:textToSpeech"}
    String    FamilyRoom_Dot_LastVoiceCommand    "Famiy Room: Last Voice Command [%s]"    (gAlexa_LastVoiceCommand)    {channel="amazonechocontrol:xxxxx:xxxxx:xxxxx:lastVoiceCommand"}
    String    FamilyRoom_Dot_TTS    "Family Room: TTS [%s]"    (gAlexa_LastVoiceCommand)    {channel="amazonechocontrol:xxxxx:xxxxx:xxxxx:textToSpeech"}
    

The get_lock_states() function can be removed or replaced. It uses a group (gSecurity) that contains all of my outer doors.

from core.triggers import when
from core.rules import rule

def get_lock_states():
    return "all doors are locked" if items["gSecurity"] == ON else "the following doors are not locked, \n{}".format("\n".join(map(lambda unlockedLock: unlockedLock.label, filter(lambda lock: lock.state == OFF, ir.getItem("gSecurity").getAllMembers()))))

@rule("Alert: Voice command alert")
@when("Member of gAlexa_LastVoiceCommand received update")
def last_voice_command_alert(event):
    last_voice_command_alert.log.debug("LastVoiceCommand received [{}]".format(event.itemState))
    if event.itemState.toString() == "are the doors locked":
        events.sendCommand(event.itemName.replace("LastVoiceCommand", "TTS"), get_lock_states())
    #elif event.itemState.toString() == "are the windows closed":
        # do stuff here