Help with Home Assistant Assist sentence triggers

Working on an automation were the action is based on the contents of two input_text helpers. In addition to having finer, more granular controls via a UI in the mobile app, I’d like to use voice commands using Home Assistant Assist for broader “fast actions”.

The automation is for controlling 3 AV matrix switches to route the video signals from 20+ videogame consoles to 2 TVs and two capture cards. The automation works well when controlled through the lovelace UI so now I’m moving on to voice controls. I’d like to be able to change the text of one of the input_text entities with a sentence trigger

For reference, I just started working on the voice automation, so here’s all I have so far.

trigger:
  - platform: conversation
    command: Let's Play {console}
action:
  - service: input_text.set_value
    data:
      value: "{{ trigger.slots.console }}"
    target:
      entity_id: input_text.console_switching_console_name

I have two questions about creating sentence triggers.

1.) Is there a way to limit what values are acceptable for {console}? For example It will take values of NES, SNES, Atari 7800, etc but ignore a value of say, Atari Jaguar or some other non-sense it thinks I said but I didn’t say, and then return an error response?

2.) Is there a way to account for synonyms in my command. For example SNES and Super Nintedo or Xbox 360 and 360 are treated as the same. I’m sure this could be accounted for by tweaking my automation or doing some jinja templating but if there’s anyway to address it built into Assist I’d rather do it there.

I’ve been reading over the documentation, but some of it is going straight over my head, and I’m sure someone here with more experience can point me in the right direction.

Thanks in advance and any input!

You can do that with the template syntax from the Assist integration, see here:

This will look something like this

command: 
  - "Let's play ( snes | atari 7200 | xbox 360 | 360 )"

But I’d suggest not working with the values in triggers, but use lists instead. And to even make it more usable, you can use seprate files for all of this. :slight_smile: If you want to know more, let me know. :slight_smile:

1 Like

You can’t do this currently, but 2023 is HA’s Year of Voice, so it’s early days in their voice “journey” and the year is not over yet. Also, I think if you’re going to ignore mis-hearings, you’re in for a world of pain repeating yourself.

I’m using the Yarvis custom integration, which allows you to define the conversation using regular expressions (and admittedly regex can get complex fast). When I say “add bananas to my shopping list”, Assist often mis-hears “add” as “and” or “pat” or “at” or “head”. If I define the regex sentence including “add|and|pat|at|head”, then it handles all of these cases.

This then also “sort of” handles the synonym case, but then the different values get passed on to your script and you have to deal with them there. Coincidentally yesterday I made a feature request for the integration to solve this problem (so fingers crossed).

You can already use wildcards in sentences, and what you’re doing with the Yarvis component is as well possible in Assist already. :slight_smile:

Your sentence “add bananas to the shopping list” is perfectly configurable with Assists default functions. Yarvis is for really complex situations, where you need almost a wildcard, but want to narrow this down over the regex.

Let’s stay with your example:

  • If you just want to add specific pre definied things to the list, you do this by a slots_list in Assist. Like Milk, Wine or these kind of common items. You are not very flexible with this list in the use case of a shopping list, but it is useful for a list that never changes, like media player names. Or a list with different mis-hearings. :wink:
  • If you want to add more or less specific things to the shopping list, that are loosely pre definied, you use the Yarvis component. E.g. if you name the producer of the Milk, like “Walmart Milk”. To not need to pre define the producer names in a list, you can work with regex, to only specify manufacturer name patterns, that should be allowed.
  • If you want whatever Assist understands added to the list, you use the wildcard. I personally use the wildcard for the shopping list, as I can say specific producer names without any kind of restriction, it just writes what I say, if I got misunderstood, I mostly can remember or guess what I meant.

Ah handy to know, thanks. When I started using Yarvis is was before HA had slots. I had better look into it more. Although I will stick with Yarvis until HA supports “add (whatever) to my shopping list”.

Yeah, lists were one of the things I had trouble understanding how to utilize, so I’d love to learn more about them if you have the time.

@michaelblight
Then you’ll have a busy afternoon! :laughing: This is already possible. The shopping list is set to wildcard in the code since 2023.8.x. :slight_smile:

See here:

These are the possible sentences, on how you could add whatever to the shopping list. :slight_smile:

@Zevin_Mars
Sure thing! :slight_smile:

One thing upfront: there are numerous ways, to include these into HA, depending on how you’ve setup your config. I’m just using my system as example, if you have problems including, let me know. :slight_smile:

  1. If not already there, make a new folder under your config folder, called custom_sentences. The config folder is, where your configuration.yaml lives. :slight_smile:

  2. In this folder, make another new folder, named after the language you’re using, in my case it’s german, so the folder is called de. If you’re using english, than it would be en. You get, where I’m going with this. :slight_smile:

  3. In this folder you can setup as many different files as you want, eg. one for your custom sentences regarding the climate control, one for blinds, one for …! This is up to you, you can bundle all sentences in one file or split it up. Do it to your liking. For the example we go with a file named consoles.yaml.

  4. Every file in here needs to start with this (change the language to your language, needs to be the same as the folder name):

    language: "de"
    intents:
    
  5. After the “header” we now setup our first custom_sentence. :+1:
    Call it, whatever you like, I do some naming convention, so my sentence will be called CustomConsolePlay. I use Custom to differentiate between my real custom sentences and the inbuilt sentences. You can as well call it ZevinConsolePlay or whatever. Just use a system, you can later remember and that makes it easy to find for future changes!

    CustomConsolePlay:
      data:
        - sentences: 
            - "Let's play { consoles }"
    

    Now we have configured our first custom sentence, but we need to fill the list consoles with some content, so Assist knows, what is allowed.

  6. Add this to this file as well:

    lists:
      consoles:
        values:
          - in: "(xbox360 | 360 | xbox)"
            out: "xbox"
          - in: "(nintendo | supernintendo | snes)"
            out: "nintendo"
          - in: "atari"
            out: "atari"
    

    So what are we doing here? We configure the list consoles with some input values, so your custom sentence will now be able to read like

    • Let’s play xbox
    • Let’s play 360
    • Let’s play Atari

    • What we are doing here as well, is to give a specific output from that list. This is super useful, as you don’t have to “translate” the custom name to the specific name you choose under HA. Let’s assume, your console list is a input_select, so here you don’t have to setup all different names in the select.
  7. The complete file should now look like this:

    # /config/custom_sentences/en/consoles.yaml
    language: "en"
    intents:
      CustomConsolePlay:
        data:
          - sentences: 
              - "Let's play {consoles}"
    
    lists:
      consoles:
        values:
          - in: "(xbox360 | 360 | xbox)"
            out: "xbox"
          - in: "(nintendo | supernintendo | snes)"
            out: "nintendo"
          - in: "atari"
            out: "atari"
    
  8. Now we need to setup the intent for this. It’s nice, that we now have Assist recognizing our sentence, but it should do something with it, shouldn’t it?
    This is done in configuration.yaml under the intent integration. You can set this up in a seperate file, or as a package file. This depends on your setup, and we leave this out for now, as this is a whole other subject. So for now we work with configuration.yaml, just to get it running.

  9. Open configuration.yaml and add this:

    # /config/configuration.yaml
    intent_script:
      CustomConsolePlay:
        speech:
          text: "Starting console"
        action:
          service: script.turn_on #use whatever service you need
          target:
            entity_id: script.my_console_starting_script #the script you have to start
    

i hope I didn’t forget anything, but it should show the way this works. You can now use the custom sentence to start a script or whatever you like, and let it work through. You can as well use all the variables that get send with it, like the name you set under out.

Let me know, if I forgot something, or if something is not clear. :slight_smile: And for sure let me know how you get along! :slight_smile: :wave:

5 Likes

Alright, I tried following your write up and I’m getting an Unexpected error during intent recognition response from Assist.

Here’s the contents of /config/custom_sentences/en/consoles.yaml

language: "en"
intents:
  CustomConsolePlay:
    data:
      - sentences:
          - "Let's play { consoles }"

lists:
  consoles:
    values:
      - in: "( Atari | Atari 7800 | 7800)"
        out: "Atari 7800"
      - in: "( NES | Nintendo Entertainment System )"
        out: "NES"
      - in: "( SNES | Super Nintendo Entertainement System)"
        out: "SNES"
      - in: "( N64 | Nintendo 64 )"
        out: "N64"
      - in: "Gamecube"
        out: "Gamecube"
      - in: "Wii"
        out: "Wii"
      - in: "Wii U"
        out: "Wii U"
      - in: "( Switch | Nintendo Switch )"
        out: "Switch"
      - in: "( PC Engine | Turbo Grafx )"
        out: "PC Engine"
      - in: "( Neogeo AES | AES )"
        out: "Neogeo AES"
      - in: "Neogeo CD"
        out: "Neogeo CD"
      - in: "3DO"
        out: "3DO"
      - in: "( Genesis | Megadrive | Sega Genesis | Sega Megadrive )"
        out: "Genesis"
      - in: "( Saturn | Sega Saturn )"
        out: "Saturn"
      - in: "( Dreamcast | Sega Dreamcast )"
        out: "Dreamcast"
      - in: "( PS1 | PlayStation 1 | PlayStation )"
        out: "PS1"
      - in: "( PS2 | PlayStation 2 )"
        out: "PS2"
      - in: "( PS3 | PlayStation 3 )"
        out: "PS3"
      - in: "( PS4 | PlayStation 4 )"
        out: "PS4"
      - in: "( PSP Go | PlayStation Portable Go )"
        out: "PSP Go"
      - in: "( PSTV | PlayStation TV )"
        out: "PlayStation TV"
      - in: "( Xbox | OG Xbox | Original Xbox )"
        out: "Xbox"
      - in: "( Xbox 360 | 360 )"
        out: "Xbox 360"
      - in: "( MiSTer FPGA | MiSTer )"
        out: "MiSTer FPGA"

Here’s what I added to my configuration.yaml

intent_script:
  CustomConsolePlay:
    speech:
      text: "Starting console"
    action:
      service: input_text.set_value
      data:
        value: "{{ consoles }}"
      target:
        entity_id: input_text.console_switching_console_name

Finally, here’s the full error from my logs.

Logger: homeassistant.components.assist_pipeline.pipeline
Source: components/conversation/default_agent.py:286
Integration: Assist pipeline (documentation, issues)
First occurred: 2:18:54 PM (7 occurrences)
Last logged: 2:20:14 PM

Unexpected error during intent recognition
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/assist_pipeline/pipeline.py", line 522, in recognize_intent
    conversation_result = await conversation.async_converse(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/conversation/__init__.py", line 467, in async_converse
    result = await agent.async_process(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/conversation/default_agent.py", line 210, in async_process
    result = await self.async_recognize(user_input)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/conversation/default_agent.py", line 193, in async_recognize
    result = await self.hass.async_add_executor_job(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/conversation/default_agent.py", line 286, in _recognize
    for result in recognize_all(
  File "/usr/local/lib/python3.11/site-packages/hassil/recognize.py", line 406, in recognize_all
    for maybe_match_context in maybe_match_contexts:
  File "/usr/local/lib/python3.11/site-packages/hassil/recognize.py", line 807, in match_expression
    group_contexts = [
                     ^
  File "/usr/local/lib/python3.11/site-packages/hassil/recognize.py", line 807, in <listcomp>
    group_contexts = [
                     ^
  File "/usr/local/lib/python3.11/site-packages/hassil/recognize.py", line 826, in match_expression
    raise MissingListError(f"Missing slot list {{{list_ref.list_name}}}")
hassil.recognize.MissingListError: Missing slot list { consoles }

Hopefully we’re getting closer on this one. Thanks again for taking the time to help with this.

That’s good, we’re getting there! :wink: I know, sounds dump, but did you do a restart of HA? A reload of YAML doesn’t do it. :slight_smile:

But before you restart, let’s check, if other things might be missing. :slight_smile: In configuration.yaml do you have assist_pipeline: (only needed, if you don’t have default_config:) and conversation: added? If not, please do so and restart HA.

I’m quite sure, that should do the trick or at least get rid of that error, hopefully there isn’t another one coming up instead :laughing:

Edit: I got it working. I think the problem was the spaces in { consoles } here:

language: "en"
intents:
  CustomConsolePlay:
    data:
      - sentences: 
          - "[Let's] play { consoles }"

Removing those got it working, I think?

Here’s the current working YAML for the consoles.yaml file:

language: "en"
intents:
  CustomConsolePlay:
    data:
      - sentences: 
          - "[Let's] play {consoles}"

lists:
  consoles:
    values:
      - in: "(Atari | Atari 7800 | 7800)"
        out: "Atari 7800"
      - in: "( NES | Nintendo Entertainement System )"
        out: "NES"
      - in: "( SNES | Super Nintendo Entertainement System)"
        out: "SNES"
      - in: "( N64 | Nintendo 64 )"
        out: "N64"
      - in: "Gamecube"
        out: "Gamecube"
      - in: "Wii"
        out: "Wii"
      - in: "Wii U"
        out: "Wii U"
      - in: "( Switch | Nintendo Switch )"
        out: "Switch"
      - in: "( PC Engine | Turbo Grafx )"
        out: "PC Engine"
      - in: "( Neogeo AES | AES )"
        out: "Neogeo AES"
      - in: "Neogeo CD"
        out: "Neogeo CD"
      - in: "3DO"
        out: "3DO"
      - in: "( Genesis | Megadrive | Sega Genesis | Sega Megadrive )"
        out: "Genesis"
      - in: "( Saturn | Sega Saturn )"
        out: "Saturn"
      - in: "( Dreamcast | Sega Dreamcast )"
        out: "Dreamcast"
      - in: "( PS1 | PlayStation 1 | PlayStation )"
        out: "PS1"
      - in: "( PS2 | PlayStation 2 )"
        out: "PS2"
      - in: "( PS3 | PlayStation 3 )"
        out: "PS3"
      - in: "( PS4 | PlayStation 4 )"
        out: "PS4"
      - in: "( PSP Go | PlayStation Portable Go )"
        out: "PSP Go"
      - in: "( PSTV | PlayStation TV )"
        out: "PlayStation TV"
      - in: "( Xbox | OG Xbox | Original Xbox )"
        out: "Xbox"
      - in: "( Xbox 360 | 360 )"
        out: "Xbox 360"
      - in: "( MiSTer FPGA | MiSTer )"
        out: "MiSTer FPGA"

And here is the current working YAML I added to cofiguration.yaml

intent_script:
  CustomConsolePlay:
    speech:
      text: "Starting console"
    action:
      service: input_text.set_value
      data:
        value: "{{consoles}}"
      target:
        entity_id: input_text.console_switching_console_name

Plan to continue working with this but the most basic feature I needed works!

I added those to my configuration.yaml like you said and I’m still getting this error.

Logger: homeassistant.components.assist_pipeline.pipeline
Source: components/conversation/default_agent.py:286
Integration: Assist pipeline (documentation, issues)
First occurred: 7:03:06 PM (1 occurrences)
Last logged: 7:03:06 PM

Unexpected error during intent recognition
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/assist_pipeline/pipeline.py", line 522, in recognize_intent
    conversation_result = await conversation.async_converse(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/conversation/__init__.py", line 467, in async_converse
    result = await agent.async_process(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/conversation/default_agent.py", line 210, in async_process
    result = await self.async_recognize(user_input)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/conversation/default_agent.py", line 193, in async_recognize
    result = await self.hass.async_add_executor_job(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/conversation/default_agent.py", line 286, in _recognize
    for result in recognize_all(
  File "/usr/local/lib/python3.11/site-packages/hassil/recognize.py", line 406, in recognize_all
    for maybe_match_context in maybe_match_contexts:
  File "/usr/local/lib/python3.11/site-packages/hassil/recognize.py", line 807, in match_expression
    group_contexts = [
                     ^
  File "/usr/local/lib/python3.11/site-packages/hassil/recognize.py", line 807, in <listcomp>
    group_contexts = [
                     ^
  File "/usr/local/lib/python3.11/site-packages/hassil/recognize.py", line 826, in match_expression
    raise MissingListError(f"Missing slot list {{{list_ref.list_name}}}")
hassil.recognize.MissingListError: Missing slot list { consoles }

Is the last bit where it says this…

  File "/usr/local/lib/python3.11/site-packages/hassil/recognize.py", line 826, in match_expression
    raise MissingListError(f"Missing slot list {{{list_ref.list_name}}}")
hassil.recognize.MissingListError: Missing slot list { consoles }

as important as it seems to me? I’m reading over the documentation again to see if I can figure this out on my own but again, any help is appreciated.

2 Likes

That’s great news - I must have missed it in the release notes and have not upgraded yet. So even more work for the weekend!

1 Like

Great to hear it’s working for you! :+1:

Have fun with it, there are so many more possibilities to explore. Assist is getting better and better with every release! :slight_smile:

1 Like

Okay, next question:

Currently I’ve got this working:

intent_script:
  CustomConsolePlay:
    speech:
      text: "Starting console"
    action:
       service: input_text.set_value
       data:
         value: "{{consoles}}"
       target:
          entity_id: input_text.console_switching_console_name

But what I’d like to do is something like this:

intent_script:
  CustomConsolePlay:
    speech:
      text: "Starting console"
    action:
      service: script.turn_on
    target:
        entity_id: script.console_switching_voice_script

with a script like this:

alias: Console Switching Voice Script
sequence:
  - service: input_text.set_value
    data:
      value: |
        {{ console }}
    target:
      entity_id: input_text.console_switching_console_name
  - service: input_button.press
    data: {}
    target:
      entity_id: input_button.console_switching_trigger
mode: single
icon: mdi:controller-classic

So that I don’t have to edit my configuration.yaml file every time I have to tweak how this works. Problem is, what do I put in in the value: data so that the script updates the input_text entity the same way my current working intent script does. Any tips there?

Your message is a little confusing.
Do you want a script that has a custom response based on what console was identified in the original request?

If that is the case I think you need to use the

{{ slots.name }}

In the response message and it will use this.
The documents are not very intuitive on this and it is still early days, but I think it is something with the slots name and it will be replaced by your

out:

Response.
Also Looking at all your different

in:

configurations there may be a way to optimize this with using the sentence template syntax.

1 Like

Just pass the variable to the script as usual. :slight_smile:

intent_script:
  CustomConsolePlay:
    speech:
      text: "Starting console"
    action:
      service: script.turn_on
      target:
        entity_id: script.console_switching_voice_script
      data:
        variables:
          console: {{ consoles }}

Or did I misunderstand you? :thinking:

EDIT: Just for reference

1 Like

Yeah, I actually solved it a few hours after I posted. Sometimes the documentation doesn’t make sense to me unless I fiddle around with it until I get a working configuration lol. Now I can tell Assist what console I want to play and my AV matrixes and TV will switch to the correct settings automatically. It’s pretty great with how complicated my setup can feel sometimes. :slightly_smiling_face:

For reference…

Here’s the custom sentence I have…

language: "en"
intents:
  CustomConsolePlay:
    data:
      - sentences: 
          - "[Let's] play {consoles}"
          - "Switch to {consoles}"
          - "{consoles}"

lists:
  consoles:
    values:
      - in: "(Atari | Atari 7800 | 7800)"
        out: "Atari 7800"
      - in: "( NES | Nintendo Entertainement System )"
        out: "NES"
      - in: "( SNES | Super Nintendo Entertainement System | Super Nintendo)"
        out: "SNES"
      - in: "( N64 | Nintendo 64 )"
        out: "N64"
      - in: "Gamecube"
        out: "Gamecube"
      - in: "Wii"
        out: "Wii"
      - in: "Wii U"
        out: "Wii U"
      - in: "( Switch | Nintendo Switch )"
        out: "Switch"
      - in: "( PC Engine | Turbo Grafx )"
        out: "PC Engine"
      - in: "( Neogeo AES | AES | Neo Geo AEF | Neo-Geo-A-E-S )"
        out: "Neogeo AES"
      - in: "( Neogeo CD | Neo Geo CD )"
        out: "Neogeo CD"
      - in: "3DO"
        out: "3DO"
      - in: "( Genesis | Megadrive | Sega Genesis | Sega Megadrive )"
        out: "Genesis"
      - in: "( Saturn | Sega Saturn )"
        out: "Saturn"
      - in: "( Dreamcast | Sega Dreamcast )"
        out: "Dreamcast"
      - in: "( PS1 | PlayStation 1 | PlayStation )"
        out: "PS1"
      - in: "( PS2 | PlayStation 2 )"
        out: "PS2"
      - in: "( PS3 | PlayStation 3 )"
        out: "PS3"
      - in: "( PS4 | PlayStation 4 )"
        out: "PS4"
      - in: "( PSP Go | PlayStation Portable Go )"
        out: "PSP Go"
      - in: "( PSTV | PlayStation TV )"
        out: "PlayStation TV"
      - in: "( Xbox | OG Xbox | Original Xbox )"
        out: "Xbox"
      - in: "( Xbox 360 | 360 )"
        out: "Xbox 360"
      - in: "( MiSTer FPGA | MiSTer | Mr | Mr. FPGA )"
        out: "MiSTer FPGA"
  displays:
    values:
      - in: "(Flat Screen | TV | HDTV | LGTV )"
        out: "WebOS TV"
      - in: "(PVM | CRT )"
        out: "PVM 14m4U"
      - in: "( HD Capture Card | Live Gamer Ultra )"
        out: "Live Gamer Ultra"
      - in: "( Vision E2S | Vision | Datapath)"
        out: "VisionRGB-E2S"

Here’s the Intent script I have…

intent_script:
  CustomConsolePlay:
    speech:
      text: "Switching to {{consoles}}"
    action:
      service: script.turn_on
      target:
        entity_id: script.console_switching_voice_script
      data:
        variables:
          console: "{{consoles}}"

and here’s the script it calls…

alias: Console Switching Voice Script
sequence:
  - service: input_text.set_value
    data:
      value: |
        {{ console }}
    target:
      entity_id: input_text.console_switching_console_name
  - service: input_text.set_value
    data:
      value: WebOS TV
    target:
      entity_id: input_text.console_switching_display_name
  - service: input_button.press
    data: {}
    target:
      entity_id: input_button.console_switching_trigger
mode: single
icon: mdi:controller-classic

Which triggers this automation…

alias: Console Switching 1.0
description: ""
trigger:
  - platform: state
    entity_id:
      - input_button.console_switching_trigger
condition: []
action:
  - if:
      - condition: state
        entity_id: sensor.console_switching_states_sensor
        state: Extron Crosspoint Ultra 128
    then:
      - service: shell_command.console_switching_extron_crosspoint_i_o_tie_1
        data:
          input: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_crosspoint_input') }}
          output: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_crosspoint_output') }}
      - if:
          - condition: state
            entity_id: input_text.console_switching_display_name
            state: WebOS TV
        then:
          - service: media_player.turn_on
            data: {}
            target:
              entity_id: media_player.zack_s_tv
          - wait_template: "{{ is_state('media_player.zack_s_tv', 'on') }}"
            continue_on_timeout: true
            timeout: "15"
          - service: media_player.select_source
            data:
              source: >
                {{ state_attr('sensor.console_switching_states_sensor',
                'webos_hdmi_input') }}
            target:
              entity_id: media_player.zack_s_tv
      - condition: or
        conditions:
          - condition: state
            entity_id: input_text.console_switching_display_name
            state: WebOS TV
          - condition: state
            entity_id: input_text.console_switching_display_name
            state: Live Gamer Ultra
      - service: shell_command.console_switching_vertex2_1
        data:
          input: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'hd_fury_vertex2_input') }}
          output: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'hd_fury_vertex2_output') }}
  - if:
      - condition: state
        entity_id: sensor.console_switching_states_sensor
        state: Extron Crosspoint SMX - Analogue
    then:
      - service: shell_command.console_switching_extron_smx_hdmi_i_o_tie_1
        data:
          plane: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_smx_video_plane') }}
          input: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_smx_video_plane_input') }}
          output: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_smx_video_plane_output') }}
      - delay:
          hours: 0
          minutes: 0
          seconds: 2
          milliseconds: 0
      - service: shell_command.console_switching_extron_smx_hdmi_i_o_tie_1
        data:
          plane: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_smx_audio_plane') }}
          input: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_smx_audio_plane_input') }}
          output: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_smx_audio_plane_output') }}
      - if:
          - condition: state
            entity_id: input_text.console_switching_display_name
            state: WebOS TV
        then:
          - service: media_player.turn_on
            data: {}
            target:
              entity_id: media_player.zack_s_tv
          - wait_template: "{{ is_state('media_player.zack_s_tv', 'on') }}"
            continue_on_timeout: true
            timeout: "15"
          - service: media_player.select_source
            data:
              source: >
                {{ state_attr('sensor.console_switching_states_sensor',
                'webos_hdmi_input') }}
            target:
              entity_id: media_player.zack_s_tv
      - condition: or
        conditions:
          - condition: state
            entity_id: input_text.console_switching_display_name
            state: WebOS TV
          - condition: state
            entity_id: input_text.console_switching_display_name
            state: Live Gamer Ultra
      - service: shell_command.console_switching_vertex2_1
        data:
          input: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'hd_fury_vertex2_input') }}
          output: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'hd_fury_vertex2_output') }}
  - if:
      - condition: state
        entity_id: sensor.console_switching_states_sensor
        state: Extron Crosspoint SMX - HDMI
    then:
      - service: shell_command.console_switching_extron_smx_hdmi_i_o_tie_1
        data:
          plane: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_smx_video_plane') }}
          input: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_smx_video_plane_input') }}
          output: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'extron_smx_video_plane_output') }}
      - if:
          - condition: state
            entity_id: input_text.console_switching_display_name
            state: WebOS TV
        then:
          - service: media_player.turn_on
            data: {}
            target:
              entity_id: media_player.zack_s_tv
          - wait_template: "{{ is_state('media_player.zack_s_tv', 'on') }}"
            continue_on_timeout: true
            timeout: "15"
          - service: media_player.select_source
            data:
              source: >
                {{ state_attr('sensor.console_switching_states_sensor',
                'webos_hdmi_input') }}
            target:
              entity_id: media_player.zack_s_tv
  - if:
      - condition: state
        entity_id: sensor.console_switching_states_sensor
        state: HD Fury Vertx2
    then:
      - service: shell_command.console_switching_vertex2_1
        data:
          input: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'hd_fury_vertex2_input') }}
          output: >
            {{ state_attr('sensor.console_switching_states_sensor',
            'hd_fury_vertex2_output') }}
      - if:
          - condition: state
            entity_id: input_text.console_switching_display_name
            state: WebOS TV
        then:
          - service: media_player.turn_on
            data: {}
            target:
              entity_id: media_player.zack_s_tv
          - wait_template: "{{ is_state('media_player.zack_s_tv', 'on') }}"
            continue_on_timeout: true
            timeout: "15"
          - service: media_player.select_source
            data:
              source: >
                {{ state_attr('sensor.console_switching_states_sensor',
                'webos_hdmi_input') }}
            target:
              entity_id: media_player.zack_s_tv
mode: Single
3 Likes

This is fantastic and has got me thinking about a lot of possibilities!

I have a question, it looks like the code has a speech: and text: property. What do those do?

Is there a way to have it play an MP3 as a response? Either a sound or in my case pre-recorded responses so my voice assistant doesn’t have to use TTS to respond?