Script to resume Google Cast devices after they have been interrupted by any action

Actually, I must know I don’t know…
media_player.play_media via developer service call is without error

Example: Spotify playing, afterwards TTS message sent to Google Home => error
Here are tracks of relevant scripts:
https://www.codepile.net/pile/P3RwbqOy
https://www.codepile.net/pile/a1MKyRNw
https://www.codepile.net/pile/dW8bQEg5

Error log:

Logger: homeassistant.core
Source: components/cast/media_player.py:658
First occurred: 8:14:45 PM (1 occurrences)
Last logged: 8:14:45 PM

Error executing service: <ServiceCall media_player.play_media (c:6715e04979103a8418b118f2956dd3b0): entity_id=['media_player.google_home'], extra=, media_type=music, media_id=https://ha.malky.sk/api/tts_proxy/969d1f68f268b9be5670236e12eae41c6d953b33_sk-sk_-_microsoft.mp3>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1654, in catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1673, 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 self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 671, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 949, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 708, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/cast/media_player.py", line 658, in async_play_media
    await self.hass.async_add_executor_job(
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.9/site-packages/pychromecast/quick_play.py", line 77, in quick_play
    controller.quick_play(**data)
  File "/usr/local/lib/python3.9/site-packages/pychromecast/controllers/media.py", line 665, in quick_play
    self.play_media(media_id, media_type, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/pychromecast/controllers/media.py", line 566, in play_media
    raise PyChromecastError()
pychromecast.error.PyChromecastError

Nest mini, Google mini, Google home - all with the same delay

Based on the timestamp of the error, and the timestamps in the trace, the error is caused by the TTS service call, which basically creates an mp3 and then send that via media_player.play_media.
Does TTS work without using the script?

Yes, e.g. calling this service:

service: tts.microsoft_say
data:
  message: message
  entity_id: media_player.google_home

Hi

I was on mobile yesterday, so I could not take a good look on the codepile links.
Now I’m behind a PC, which makes it a lot easier to see what is happening.

As far as I can determine from the trace this happened:

  1. You’ve sent a TTS using the TTS Dashboard script
  2. The Google Home Resume script kicked in, and sent the TTS service call at 2022-03-28 18:14:35 (UTC)
  3. At 2022-03-28 18:14:45 (UTC) the Perform Resume script started.
  4. The Perform Resume script then checks if the state of the entity has changed since the Google Home Resume script started, and if the target entity is playing. After 30 seconds it continues anyway, but in that case it doesn’t perform a resume, but just removes the entity from the groups. This is also what happened in this case.

So, from the traces it looks like the TTS service call was sent, HA did it’s best to perform it, but failed after 10 seconds for some reason. This also matches the timestamp of the error, and the timestamp the Perform Resume script started.

The Perform Resume script either did not notice a state change, or the target entity was not playing (I can not see which of those was causing the template to be false), but it did not perform the resume because of that.

All 3 scripts completely finished there actions, there are no errors in the traces.

So my conclusion based on this, is that the TTS fails. I can see in your test you’ve put the entity_id under data: but in the script it was placed under target. Could you run a test like this, if that makes a difference?

service: tts.microsoft_say
data:
  message: message
target:
  entity_id: media_player.google_home

Thank you for effort to understand my situation.
entity_id under target is also working.

Hi Manazer,

I’m not sure why it is not working properly. Assuming the situation as I described it in my previous post is correct, the only media_player.play_media service call associated to the script, is that of the TTS service call (as there was no resume performed).
The TTS service call by itself seems to be performed correctly, as there are no issues in the script trace, and the media_player.play_media service call is a result of the TTS service call.

This is the service call for the TTS from the trace, which looks fine to me:

"result": {
            "params": {
              "domain": "tts",
              "service": "microsoft_say",
              "service_data": {
                "message": "Toto je odkaz pre",
                "entity_id": [
                  "media_player.google_home"
                ]
              },
              "target": {
                "entity_id": [
                  "media_player.google_home"
                ]
              }
            },
            "running_script": false,
            "limit": 10
          }
        }

So I’m afraid there is not much I can do at my end.

Hi, I’ve updated the script after some further testing. I must admit my tests were not that good, I based it on the state of the entity, which showed playing, but it was actually still buffering.
So my choose was also incorrect.

I’ve tested properly now, and I think it should be resolved in 1.7.6.3

Update

Version 1.7.7 - 1 April 2022

:star2: Improvements

  • Added additional media_player.media_play service call after the stream has been sent tot the player, to prevent a delayed start for some streams

:bug: Bug fixes

  • Better handling of empty variable players_screen
  • Fix for wait template to determine if non playing devices should be restored to the old state (it was starting too soon)

Update

Version 1.7.8 - 2 April 2022

:bug: Bug fixes

  • Fixes for missing variables for restoring non playing devices.

Hi TheFes,
just want let you know: everything working after upgrade to 1.7.8
THANK YOU! :pray:

Ah, great! Thanks for letting me know!
No delay anymore as well?

Yep. Without delays.

Update

Version 1.8.0 - 4 April 2022

:star2: Improvements

  • Improved templates on several places to make it more efficient

:receipt: Docs

  • Added information that the target of the service call needs to be provided either under target or under data, not directly in the service call.
3 Likes

This looks awesome, exactly what I was hoping to find - and judging by the amount of code you wrote, a sh*tload of work! Thanks!

I’m relatively new to HA, so maybe I’m really missing something here, but I can’t seem to get it to work. I’ve tried it with (running the actions in) the following automation, when Spotify is playing:

alias: Test
description: Test automation for Spotify Resume, using script by TheFes
trigger:
  - platform: state
    entity_id: input_select.matthijs_status_dropdown
    to: Extended Away
condition: []
action:
  - service: script.google_home_resume
    data:
      variables:
        action:
          service: tts.cloud_say
          target:
            entity_id: media_player.kitchen_speaker
          data:
            message: Test, test 1, test 2, test 3
  - wait_template: '{{ states(''media_player.kitchen_speaker'') in [''idle'', ''off''] }}'
  - service: media_player.volume_set
    target:
      entity_id: media_player.kitchen_speaker
    data:
      volume_level: 0.5

The result is nothing, but I do get some errors in my log:

As in the HA Core log:

The automation trace gives me this:

I’ve tried to make an automation based on the examples, but I’ve probably done something wrong. Would someone be willing to help me out, I’d like to understand a bit more what I did wrong too…

EDIT:

Spotify is playing on the Downstairs Speakers, of which the above mentioned speaker is one. Here is the part of the original script that I modified based on the first post:

(I’ve altered the value for primary_spotcast: but the convention is the same.)

EDIT2: Running HA 2022.3.8

I will look into this, tonight or otherwise tomorrow.
Could you provide a download of the trace from the Google Home resume script?

  • Go to Configuration > Automations & Scenes > Scripts
  • Look for the Google Home Resume script and press the button with the clock and the arrow around it
  • Press the download button in the top right corner
  • Put the contents of the json file on a website like codepile.net
  • Share the link
1 Like

Nevermind, I already see it. When you refer directly to the script in the service call, and you don’t use the service script.turn_on you should put the script variables directly under data: and not first add variables:, so like this:

  - service: script.google_home_resume
    data:
      action:
        - service: tts.cloud_say
          target:
            entity_id: media_player.kitchen_speaker
          data:
            message: Test, test 1, test 2, test 3

But, as I described here, you should use script.turn_on, so actually you should use this:

  - service: script.turn_on
    target:
      entity_id: script.google_home_resume
    data:
      variables:
        action:
          - service: tts.cloud_say
            target:
              entity_id: media_player.kitchen_speaker
            data:
              message: Test, test 1, test 2, test 3

BTW, I’ve changed the action part to a list instead of a dictionary, which is not really required anymore since 1.8.0, but it is what is expected there

1 Like

Thanks for you response. I’ve tried to use your second suggestion:

alias: Test
description: Test automation for Spotify Resume, using script by TheFes
trigger:
  - platform: state
    entity_id: input_select.matthijs_status_dropdown
    to: Extended Away
condition: []
action:
  - service: script.turn_on
    target:
      entity_id: script.google_home_resume
    data:
      variables:
        action:
          - service: tts.cloud_say
            target:
              entity_id: media_player.kitchen_speaker
            data:
              message: Test, test 1, test 2, test 3

But that doesn’t seem to work. The situation is as follows:

  • I’m streaming Spotify to two speakers in a Google speakergroup called “Downstairs”, in it are media_player.kitchen_speaker and media_player.livingroom.
  • I’m executing the code above.
  • All music stops on both speakers
  • Test, test 1, test 2, test 3 sounds from the media_player.kitchen_speaker
  • silence

This is the CodePile link: CodePile | Easily Share Piles of Code

Well, it seems we’re one step further now :slight_smile:
I don’t see any issues with this trace, could you send me the trace for script.google_home_resume_perform_resume.

Until the last step of your situation everything is as it would be expected. If you interrupt one member of a Google Home speaker group, the whole speaker group stops. It should be resumed on the Speaker Group afterwards though, and as far as I can see in the trace provided, it tried to do that :slight_smile:

1 Like

Thanks again!

Trace for script.google_home_resume_perform_resume is on CodePile