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

Update

2023.6.1

:bug: Bug fixes

  • (2022.6.1) Another bug fix in target determination
1 Like

It is a bit hit and miss wether my google will resume after tts, not sure if its a bug or my system set up. Was working great for a while but last week or so has been patchy. I have attached the traces for the script that failed to resume if you can take a look when/if you have time, please.

Version: 2023.6.1

Goole resume helper script: dpaste/itnzW (Python)

Google resume script: dpaste/BEhfx (Python)

When you rely on the the automation it will always be a race if the automation triggers on time before the tts already stopped the media player. Itā€™s better to call the script directly and not to rely on the automation.

In the next version I will remove the automation from the main file, and place it in a separate file. Iā€™ll also disable it by default.

I will add some small scripts which will make it easier to call the script directly.

1 Like

As always, thank you.

Do you know which example from your list would best suit my set up to call the script directly and not rely on the automation. Iā€™m struggling to get my head around how I do this.

All my TTS scripts are the same (other than the message):

alias: gate announce
sequence:
  - service: script.google_home_resume
    data:
      action:
        - service: tts.cloud_say
          data:
            entity_id:
              - media_player.main_bedroom_room_speaker
              - media_player.living_room_speaker
              - media_player.grace_bedroom_speaker
              - media_player.kitchen_display
            message: The gate has been opened
mode: single

Thank you @TheFes for this wonderful package. Iā€™ve been using and enjoying this package for over a year now. Keep it up!

1 Like

Sorry forgot to reply to this.
Your YAML looks fine

This was my error as well. Sounds like the sp_dc and sp_key changes ever so often. Perhaps add this common error to the documentation in a FAQ Error Troubleshooting section, even though itā€™s primarily a Spotcast related issue.

I just received the following errors when the script failed for me, is this also related to relying on the automation?

Logger: homeassistant.components.script.you_have_mail_gmail
Source: components/cast/media_player.py:730
Integration: Scripts (documentation, issues)
First occurred: 11:09:56 (1 occurrences)
Last logged: 11:09:56

you have mail gmail: Error executing script. Unexpected error for call_service at pos 1:
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 703, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 665, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 1965, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2005, in _execute_service
    return await cast(
           ^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 607, in _service_handler
    response = await self._async_start_run(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 566, in _async_start_run
    return await coro
           ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 596, in _async_run
    return await self.script.async_run(script_vars, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1569, in async_run
    return await asyncio.shield(run.async_run())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 420, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 470, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 493, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/trace.py", line 255, in async_wrapper
    await func(*args)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 871, in _async_repeat_step
    await async_run_sequence(iteration, extra_msg)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 822, in async_run_sequence
    await self._async_run_script(script)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1067, in _async_run_script
    await self._async_run_long_action(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 665, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1569, in async_run
    return await asyncio.shield(run.async_run())
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 420, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 470, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 516, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 703, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 665, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 1965, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2005, in _execute_service
    return await cast(
           ^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/tts/legacy.py", line 147, in async_say_handle
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1965, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2005, in _execute_service
    return await cast(
           ^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 235, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 848, in entity_service_call
    response_data = task.result()  # pop exception if have
                    ^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1192, in async_request_call
    return await coro
           ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 892, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/cast/media_player.py", line 730, in async_play_media
    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/local/lib/python3.11/site-packages/pychromecast/quick_play.py", line 78, in quick_play
    controller.quick_play(**data)
  File "/usr/local/lib/python3.11/site-packages/pychromecast/controllers/media.py", line 547, in quick_play
    raise PyChromecastError()  # pylint: disable=broad-exception-raised
    ^^^^^^^^^^^^^^^^^^^^^^^^^
pychromecast.error.PyChromecastError

and

Logger: homeassistant.components.script.google_home_resume
Source: components/cast/media_player.py:730
Integration: Scripts (documentation, issues)
First occurred: 11:13:23 (2 occurrences)
Last logged: 11:13:23

00 - Google Home Resume: Perform service calls defined in action: Error executing script. Unexpected error for call_service at pos 6:
00 - Google Home Resume: Error executing script. Unexpected error for repeat at pos 20:
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 468, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 703, in _async_call_service_step
    response_data = await self._async_run_long_action(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 665, in _async_run_long_action
    return long_task.result()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 1965, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2005, in _execute_service
    return await cast(
           ^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/tts/legacy.py", line 147, in async_say_handle
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1965, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2005, in _execute_service
    return await cast(
           ^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 235, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 848, in entity_service_call
    response_data = task.result()  # pop exception if have
                    ^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1192, in async_request_call
    return await coro
           ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 892, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/cast/media_player.py", line 730, in async_play_media
    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/local/lib/python3.11/site-packages/pychromecast/quick_play.py", line 78, in quick_play
    controller.quick_play(**data)
  File "/usr/local/lib/python3.11/site-packages/pychromecast/controllers/media.py", line 547, in quick_play
    raise PyChromecastError()  # pylint: disable=broad-exception-raised
    ^^^^^^^^^^^^^^^^^^^^^^^^^
pychromecast.error.PyChromecastError

Is it somehow possible to make the music from spotify not stop but just mute in the background? I think it would be much better and avoid a lot of problems. Sometimes it happens that the music doesnā€™t start again or it only starts on one google speaker while playing in a groupā€¦

No, because it canā€™t play two sources at the same time. Spotify is stopped when you send a TTS or other audio file. And also Spotify and the TTS use the same volume setting.

What you ask can only be done using the broadcast functionality

Ah, maybe some thought for HE developers to be able to send services at once and set different volumes for themā€¦

There is only one media volume setting on the device, nothing the HA devs can do about that. I also donā€™t expect there is a way to play two audio sources at the same time. Both are limitations of the device, which canā€™t be bypassed by HA

hmm, I donā€™t understand why it sometimes happens that after restoring spotify playback, spotify switches to only one google speaker when the whole group was playing, it just happens sometimesā€¦ otherwise the script works fine

If you can send me script traces when that happens, I might be able to troubleshoot it

I donā€™t know where to find the exact log, but this is from the system log. Spotify played until 18:00 on the repro group. At 18:00 the sound started for 15 seconds. Then spotify came back using your script, but it was only playing on one speaker.

2023-08-01 17:59:14.434 WARNING (Thread-10) [pychromecast.socket_client] [(10.55.254.51):8009] Heartbeat timeout, resetting connection
2023-08-01 17:59:20.210 ERROR (MainThread) [custom_components.tapo.coordinators] Error fetching tapo data: Unexpected exception: 
2023-08-01 18:00:26.249 ERROR (Thread-22) [pychromecast.socket_client] [([::ffff:a37:fe1f]):8009] Failed to connect to service ServiceInfo(type='host', data=('[::ffff:a37:fe1f]', 8009)), retrying in 5.0s
2023-08-01 18:01:10.214 ERROR (MainThread) [custom_components.tapo.coordinators] Error fetching tapo data: Unexpected exception: 
2023-08-01 18:01:12.985 WARNING (Thread-10) [pychromecast.socket_client] [(10.55.254.51):8009] Heartbeat timeout, resetting connection
2023-08-01 18:01:17.717 WARNING (MainThread) [homeassistant.components.androidtv_remote] Disconnected from AI PONT at 10.55.254.51
2023-08-01 18:01:43.018 ERROR (Thread-10) [pychromecast.socket_client] [(10.55.254.51):8009] Failed to connect to service ServiceInfo(type='host', data=('10.55.254.51', 8009)), retrying in 5.0s
2023-08-01 18:02:59.349 WARNING (Thread-10) [pychromecast.socket_client] [(10.55.254.51):8009] Heartbeat timeout, resetting connection
2023-08-01 18:03:01.029 WARNING (MainThread) [homeassistant.components.androidtv_remote] Disconnected from AI PONT at 10.55.254.51

Again, I need script traces. See this section in the documentation

Well, what if none of the scripts from you were run? then what to trace?

Then spotify came back using your script, but it was only playing on one speaker.

This implies the scripts were started. There should be a trace then.

Iā€™m very excited about this script, as I am a big fan and user of the Chromecast Audio in my house, but I need a little help here. Pretty sure Iā€™m doing something dumb. Iā€™m trying to execute the script from NodeRed, and while it appears to be running, nothing happens. So, can it be executed in this manner, and if so is there soemthing Iā€™ve goofed up here in the call:

Thank you!!!

Your action should be a complete service call, not only the service itself.

Maybe this will help