Issue loading scripts.yaml code

I found a great tutorial on creating an integration that pushes a predefined audio stream to a selectable set of speakers. The setup is pretty straightforward, but I’m getting stuck on an error in the logs.

All items show properly in the veritcal-stack card, except for the “radio_play” script which is in scripts.yaml file. Script.radio_play doesn’t appear as an option as an available entity.

Checking the logs, I see this:

Logger: homeassistant.config
Source: config.py:820
First occurred: 12:15:39 AM (1 occurrences)
Last logged: 12:15:39 AM
Invalid config for [script]: template value should be a string for dictionary value @ data['sequence'][0]['data']. Got None. (See /config/configuration.yaml, line 25).

Line 25 in configuration.yaml is:

automation: !include automations.yaml

Confused on why, if there’s a problem with automations, why is scripts not loading? Reading a similar post in the past, it sounds like the 1st sequence of an automation is missing a data? I have zero errors in my automations.yaml file.

Line numbers in text editors count lines from 1. e.g.

1 Text a
2 Text b
3 Text c
...
25 automation: !include automations.yaml
...

Home Assistant counts lines from 0. e.g.

0 Text a
1 Text b
2 Text c
...
24 automation: !include automations.yaml
...

So I’m guessing your script include is directly after your automations include. That is what Home Assistant is pointing to.

Confusing, but that makes sense. So, the next line then is

script: !include scripts.yaml

Am I interpreting correctly, then, that the first ‘sequence’ is missing a ‘data’? Studio code server isn’t highlighting any code errors.

Here are the first 12 lines of scripts.yaml:

# Soundscape play script
radio_play:
  alias: Play Soundscape on Room Speaker
  sequence:
  - service: media_player.volume_set
    data:
      entity_id: >
        {% if is_state("input_select.radio_speaker", "Bedroom Display") %} media_player.bedroom_display
        {% elif is_state("input_select.radio_speaker", "Girls Room Speaker") %} media_player.girls_room_speaker
        {% elif is_state("input_select.radio_speaker", "Living Room Display") %} media_player.living_room_speaker
        {% endif %}
      volume_level: '{{ states{"input_number.radio_volume"} }}'

What happens if it is none of these select options?

    data:
      entity_id: >
        {% if is_state("input_select.radio_speaker", "Bedroom Display") %} media_player.bedroom_display
        {% elif is_state("input_select.radio_speaker", "Girls Room Speaker") %} media_player.girls_room_speaker
        {% elif is_state("input_select.radio_speaker", "Living Room Display") %} media_player.living_room_speaker
        {% endif %}

You get a null entity_id so you get the error value should be a string for dictionary value @ data['sequence'][0]['data']. Got None.

Have a look at the script trace to see why you are not getting one of these select options.

You should include an else statement in your template for a default entity. If you can’t do that then use a choose action instead. It can be structured to not return any action (not just entity id) so that no error occurs.

I found a coding error on my part on line 13. I had a volume_level states entity wrapped in braces instead of parentheses. I corrected that. Now I get this in the logs:

should be a string for dictionary value @ data['sequence'][1]['data']

Now, for audio, speaker, and volume, I do have an initial values set in an input_select.yaml file as outlined below (volume settings and initial value are in input_number.yaml). These reflect properly in the card.

# Radio stations
radio_station:
  name: 'Select Soundscape'
  options:
    - 'Thunderstorm'
    - 'Crickets'
    - 'Distant Ocean Surf'
    - 'Wind in Pines'
  initial: Thunderstorm
  icon: mdi:radio

radio_speaker:
  name: 'Select Speaker'
  options:
    - 'Girls Room Speaker'
    - 'Bedroom Display'
    - 'Living Room Display'
  initial: 'Girls Room Speaker'
  icon: mdi:speaker-wireless

Nowhere near enough information for me to help you. Full error message please.

That does not fix your template. What if the input select integration isn’t loaded due to some other error?

Put an else case in your script template. Use 'Girls Room Speaker' you may never need it but if you do you will be thankful you did. It’s cheap insurance.

  sequence:
  - service: media_player.volume_set
    data:
      entity_id: >
        {% if is_state("input_select.radio_speaker", "Bedroom Display") %}
          media_player.bedroom_display
        {% elif is_state("input_select.radio_speaker", "Girls Room Speaker") %}
          media_player.girls_room_speaker
        {% elif is_state("input_select.radio_speaker", "Living Room Display") %}
          media_player.living_room_speaker
        {% else %}
          media_player.girls_room_speaker
        {% endif %}
      volume_level: '{{ states{"input_number.radio_volume"} }}'

Thanks, @tom_l. Makes sense to have an else safety net.

I added the else statement and rebooted. Unfortunately, it’s still complaining about the dictionary value.

Logger: homeassistant.config
Source: config.py:820
First occurred: 11:02:57 PM (1 occurrences)
Last logged: 11:02:57 PM

Invalid config for [script]: template value should be a string for dictionary value @ data['sequence'][1]['data']. Got None. (See /config/configuration.yaml, line 25).

Here’s the tut I was following to set this up.

Essentially, it’s compartmentalizing the input_select, input_number, and play functions into separate yaml files. Here’s a little more insight into the other yaml files. Let me know if you need something more specific.

input_select.yaml:

# Radio stations
radio_station:
  name: 'Select Soundscape'
  options:
    - 'Thunderstorm'
    - 'Crickets'
    - 'Distant Ocean Surf'
    - 'Wind in Pines'
  initial: Thunderstorm
  icon: mdi:radio

radio_speaker:
  name: 'Select Speaker'
  options:
    - 'Girls Room Speaker'
    - 'Bedroom Display'
    - 'Living Room Display'
  initial: 'Girls Room Speaker'
  icon: mdi:speaker-wireless

input_number.yaml:

# Radio volume
radio_volume:
  name: Volume
  icon: mdi:volume-high
  initial: 0.4
  min: 0
  max: 1
  step: 0.05
  mode: box

Full scripts.yaml code:

# Soundscape play script
radio_play:
  alias: Play Soundscape on Room Speaker
  sequence:
  - service: media_player.volume_set
    data:
      entity_id: >
        {% if is_state("input_select.radio_speaker", "Bedroom Display") %} media_player.bedroom_display
        {% elif is_state("input_select.radio_speaker", "Girls Room Speaker") %} media_player.girls_room_speaker
        {% elif is_state("input_select.radio_speaker", "Living Room Display") %} media_player.living_room_speaker
        {% else %}
          media_player.girls_room_speaker
        {% endif %}
      volume_level: '{{ states("input_number.radio_volume") }}'
  - service: media_player.play_media
    data:
      entity_id: >
        {% if is_state("input_select.radio_speaker", "Bedroom Display") %} media_player.bedroom_display
        {% elif is_state("input_select.radio_speaker", "Girls Room Speaker") %} media_player.girls_room_speaker
        {% elif is_state("input_select.radio_speaker", "Living Room Display") %} media_player.living_room_speaker
        {% endif %}
      media_content_id: >
        {% if is_state("input_select.radio.station", "Thunderstorm") %} https://<url here>
        {% if is_state("input_select.radio.station", "Crickets") %} https://<url here>
        {% if is_state("input_select.radio.station", "Distant Ocean Surf") %} https://<url here>
        {% if is_state("input_select.radio.station", "Wind in Pines") %} https://<url here>
        {% endif %}
      media_content_type: 'music'
      extra:
        thumb: >
          {%- set station = states('input_select.radio_station') -%}
          {% if 'Thunderstorm' in station %}  http://homeassistant.local/local/icons/calm_thunderstorm.PNG
          {% elif 'Crickets' in station %} http://homeassistant.local/local/icons/calm_crickets.PNG
          {% elif 'Distant Ocean Surf' in station %} http://homeassistant.local/local/icons/calm_oceansurf.PNG
          {% elif 'Wind in Pines' in station %} http://homeassistant.local/local/icons/calm_windpines.PNG
          {% endif %}              
      stream_type: LIVE
  - service: media_player.repeat_set
    data:
      entity_id: >
        {% if is_state("input_select.radio_speaker", "Bedroom Display") %} media_player.bedroom_display
        {% elif is_state("input_select.radio_speaker", "Girls Room Speaker") %} media_player.girls_room_speaker
        {% elif is_state("input_select.radio_speaker", "Living Room Display") %} media_player.living_room_speaker
        {% endif %}
      repeat: all

Look at the script trace to see what is going on.

I checked Automations & Scenes → Scripts and the there are no scripts listed.

How is that possible?

Home Assistant ran this script and logged an error:

Unless you have another error and a persistent notification telling you that the script integration was not loaded, because of a configuration error.

I’m honestly not sure on this one. Based on HA consistently logging this entry across reboots, it seems like it’s trying to fire; but I don’t see the script info in Automations & Scenes → Scripts. Is there a specific log I can look at or tail maybe that might give some insight into this nebulous error? How do I run a script trace?

Looked at a number of similar issues posted in the forum, on Reddit, StackExchange, etc. This was a coding error. Subsequent is_state lines under media_content_id needed elif not if.

      media_content_id: >
        {% if is_state("input_select.radio.station", "Thunderstorm") %} https://URL
        {% elif is_state("input_select.radio.station", "Brownian Noise") %} https://URL
        {% elif is_state("input_select.radio.station", "Crickets") %} https://URL
        {% elif is_state("input_select.radio.station", "Distant Ocean Surf") %} https://URL
        {% elif is_state("input_select.radio.station", "Wind in Pines") %} https://URL
        {% endif %}

Now that this code is working, I’ve run into another issue. When I select the speaker, stream, and volume, and push the audio to any speaker, nothing happens. Here are the log outputs for this.

Logger: homeassistant.components.script.radio_play
Source: components/media_player/browse_media.py:46
Integration: Script (documentation, issues)
First occurred: 12:15:15 PM (11 occurrences)
Last logged: 12:15:47 PM
Play Soundscape on Selected Room Speaker: Error executing script. Unexpected error for call_service at pos 2: string index out of range

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 447, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 680, in _async_call_service_step
    await service_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1738, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1775, in _execute_service
    await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 676, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 931, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 713, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/cast/media_player.py", line 692, in async_play_media
    media_id = async_process_play_media_url(self.hass, media_id)
  File "/usr/src/homeassistant/homeassistant/components/media_player/browse_media.py", line 46, in async_process_play_media_url
    if media_content_id[0] != "/":
IndexError: string index out of range

and

Logger: homeassistant
Source: components/media_player/browse_media.py:46
First occurred: 12:15:15 PM (11 occurrences)
Last logged: 12:15:47 PM
Error doing job: Task exception was never retrieved

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 451, in _async_run
    return await self.script.async_run(script_vars, context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1513, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 405, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 449, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 472, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 447, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 680, in _async_call_service_step
    await service_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1738, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1775, in _execute_service
    await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 676, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 931, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 713, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/cast/media_player.py", line 692, in async_play_media
    media_id = async_process_play_media_url(self.hass, media_id)
  File "/usr/src/homeassistant/homeassistant/components/media_player/browse_media.py", line 46, in async_process_play_media_url
    if media_content_id[0] != "/":
IndexError: string index out of range