Repeatable bug in wait_template

Or of course, user error. Either way can someone shed some light on this please?

I want a wait_template based on the contents of an input_text.

In the following four examples,

input_text.sonos_group_master

contains the string

media_player.pool_room

but none of them work. They wait forever despite it being True

The last one does work but doesn’t meet my requirements.

Thanks for looking and for any comments even if it’s to tell me I’m doing something wrong :wink:

      - wait_template: >
          {{ is_state(states('input_text.sonos_group_master'), 'playing') }}
      - wait_template: >
          {% if states(states('input_text.sonos_group_master')) == 'playing' %}
            True
          {% else %}
            False
          {% endif %}
      - wait_template: >
          {% set master = states('input_text.sonos_group_master') %}
          {% if states(master) == 'playing' %}
            True
          {% else %}
            False
          {% endif %}
      - wait_template: >
          {% set master = states('input_text.sonos_group_master') %}
          {{ is_state(master, 'playing') }}

This works

      - wait_template: >
          {{ is_state('media_player.pool_room', 'playing') }}

EDIT: So, if I create a sensor based on the state of media_player.pool_room like this,

  - platform: template
    sensors:
      sonos_master_state:
        friendly_name: Sonos Master state
        value_template: >
          {{ states('media_player.pool_room') }}

then use a wait_template like this,

          {% if states('sensor.sonos_master_state') == 'playing' %}
            True
          {% else %}
            False
          {% endif %}

Then it works.

Surely this is a bug or at least a deficiency?

You’re sending the state to is_state(). Not the entity id.

      - wait_template: >
          {% if states(states('input_text.sonos_group_master')) == 'playing' %}
            True
          {% else %}
            False
          {% endif %}

You’re sending the state to states(), not the entity_id

You’re again sending the state to states(), not the entity_id

You’re sending the state not the entity_id to is_state()

so.

is_state() requires 2 arguements, entity_id and state that you want to match.
state() requires 1 arguement, entity_id.

Both cases would look like this:

      - wait_template: >
          {{ is_state('media_player.pool_room', 'playing') }}

or

      - wait_template: >
          {{ states('media_player.pool_room') == 'playing' }}

I don’t think so, just need to get the syntax right

And just to break down the issue you kept doing:

                    You get the state with this states()
                            |
                            v
          {% set master = states('input_text.sonos_group_master') %}
          {% if states(master) == 'playing' %}
                  ^
                  | 
      Then you pass the state (not entity_id) into this states().

which essentially would always result in:

   'None' == 'playing'

not exactly the same, but just to show the template itself can work, I use this for a delay:

  play_sound_bite:
    alias: Play sound bite
    sequence:
      - service: script.sound_bite
      - delay:
          seconds: >
           {{state_attr(states('sensor.sound_bite_player'),'media_duration')|int}}
      - condition: template
        value_template: >
          {{is_state('input_boolean.loop_sound_bite','on')}}
      - service: script.play_sound_bite_loop

the sensor.sound_bite_player is defiance as follows, and has either the name of an activated media_player, or the broadcast group, which holds them all:

      sound_bite_player:
        friendly_name: Sound bite player
        value_template: >
          {% set state = states('input_select.sound_bite_player') %}
          {% if state in ['Woonkamer','Hobbykamer','Hall','Master bedroom','Office','Dorm'] %}
            media_player.googlehome_{{(state)|lower|replace(' ','_')}}
          {% elif state == 'Gym' %} media_player.chromecastaudio_gym
          {% else %} group.broadcast
          {% endif %}

I do remember having issues using:

      - wait_template: >
          {{states(states('sensor.intercom')) != 'playing'}}

which sensor does the same, but then for my intercoms. It might be because the sensor doesn’t update correctly without entity_id’s, but I rewrote the automations using subscripts, which took care of the timings…

Did ya read my post? His syntax is wrong

does not work because states() is inside states()

If you have that anywhere, it won’t work ever. For example, that will always pass because states(states('sensor.intercom')) will always 100% of the time return None and nothing else.

49

well, my system shows a True…which is correct since there’s no playing intercom.
Didn’t read yet, we might have crossposted. Will do so now.

Because 'None' != 'Playing'… It will always be true. Even when it’s playing!

I think I understand what you are saying but given that, I don’t understand why I get this…

No it is perfectly showing 20
when my intercom messages are playing.

@klogg @Mariusthvdb

You guys are welcome to continue to use the wrong syntax all day. Go for it. But see where that is getting you.

the difference with your templates is that is is referring to an individual media_player. In my setup a sensor is used, which is referring to that selected media_player, and is dynamically populated through other settings (input_booleans switching these media_players on, or input_selects, selecting them from a list)

I understood @klogg’s post that he too had that scenario, so hoped my templates could help, since they work perfectly in a wider set of situations in mine. If that should not be the case because of syntax errors, I will reinvestigate.

Maybe I’m misinterpreting the intention here but I think Klogg is attempting to use input_text’s state to pass an entity_id. Therefore input_text’s state is serving as a pointer.

I’m going to try this on my test system to understand how it works (or does not work).

If it’s the case that the entity_id is infact getting pulled from the state of another sensor/device, then you probably just need to strip the trailing whitespace on the entity_id if there is any.

          {% set master = states('input_text.sonos_group_master').strip() %}
          {{ is_state(master, 'playing') }}

Also, if this is coming from an input_text and you are populating the input text, you need to make sure the input_text loses focus after entering text. It’s really annoying but, fill in the input_text, then click elsewhere in the ui (Not a button or anything, just click in whitespace). Then click or perform your action.

Input_texts only populate thier state after they lose focus. Losing focus in a UI refers to clicking elsewhere in the UI or giving some other item focus.

@petro Hang on a sec, I’m not questioning you, I’m assuming you’re right. your knowledge is clearly a lot deeper than mine. which leads me to genuinely not understand why I get the results I do in the template editor.

@123, yes that is exactly what I am doing. Or at least trying to.

This works for me:

Screenshot%20from%202019-06-21%2009-48-47

input_text:
  text1:
    name: Text 1
    initial: sensor.date

On this specific point, the input-text is populated by a script.

@123 Yes, it works for me too in the template editor. But not in a wait_template

have you tried reverse logic? Have the script continue when the wait_template finds a False?

Also, what happens if you replace the wait_template with a delay (I know, not the same, but to see if the template is alright)

This didn’t work either but the fact that you suggested it proves my point that

:stuck_out_tongue_winking_eye:

I’m not sure what you mean here. I can make it work by using an intermediate sensor which holds the state of the entity media_player.pool_room i.e in this case the string ‘playing’ or ‘paused’.

what’s the full automation?