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

Ah, right. I totally forgot I redownloaded spotcast to revert some other changes.
I did just perform a successful resume. Will do some more tests tomorrow

I did apply the changes now. Just did a test and resume worked.
Will do some more tests tomorrow (only tested on Google Home and only the primary account)

I see - now you have the same custom comp spotcast py files as I have…

What redirect URL do you use in Spotify Dev App?
In my case it is “https://my.home-assistant.io/redirect/oauth

I use the same:
https://my.home-assistant.io/redirect/oauth

Unfortunately, didn’t work for me either.

got three errors:

This error originated from a custom integration.

Logger: homeassistant
Source: custom_components/spotcast/spotcast_controller.py:126 
Integration: Spotcast (documentation, issues) 
First occurred: 22:09:36 (1 occurrences) 
Last logged: 22:09:36

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 484, in _async_run
    return await self.script.async_run(script_vars, context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1524, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 409, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 453, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 451, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 923, in _async_if_step
    await self._async_run_script(if_data["if_then"])
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1029, in _async_run_script
    await self._async_run_long_action(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 648, in _async_run_long_action
    long_task.result()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1524, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 409, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 453, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 451, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/trace.py", line 252, in async_wrapper
    await func(*args)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1025, in _async_parallel_step
    raise result
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1017, in async_run_with_trace
    await self._async_run_script(script)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1029, in _async_run_script
    await self._async_run_long_action(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 648, in _async_run_long_action
    long_task.result()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1524, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 409, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 453, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 451, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 923, in _async_if_step
    await self._async_run_script(if_data["if_then"])
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1029, in _async_run_script
    await self._async_run_long_action(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 648, in _async_run_long_action
    long_task.result()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1524, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 409, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 453, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 451, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 896, in _async_choose_step
    await self._async_run_script(script)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1029, in _async_run_script
    await self._async_run_long_action(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 648, in _async_run_long_action
    long_task.result()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1524, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 409, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 453, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 451, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/trace.py", line 252, in async_wrapper
    await func(*args)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 813, in _async_repeat_step
    await async_run_sequence(iteration, extra_msg)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 795, in async_run_sequence
    await self._async_run_script(script)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1029, in _async_run_script
    await self._async_run_long_action(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 648, in _async_run_long_action
    long_task.result()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1524, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 409, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 453, in _async_step
    self._handle_exception(
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 476, in _handle_exception
    raise exception
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 451, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 684, in _async_call_service_step
    await service_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1745, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1788, in _execute_service
    await self._hass.async_add_executor_job(
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/spotcast/__init__.py", line 190, in start_casting
    spotify_device_id = spotcast_controller.get_spotify_device_id(
  File "/config/custom_components/spotcast/spotcast_controller.py", line 243, in get_spotify_device_id
    spotify_device_id = spotify_cast_device.getSpotifyDeviceId(
  File "/config/custom_components/spotcast/spotcast_controller.py", line 126, in getSpotifyDeviceId
    raise HomeAssistantError("Failed to get device id from Spotify")
homeassistant.exceptions.HomeAssistantError: Failed to get device id from Spotify

and

Logger: homeassistant.components.script.google_home_resume_helper
Source: helpers/script.py:409 
Integration: Scripts (documentation, issues) 
First occurred: 22:09:36 (6 occurrences) 
Last logged: 22:09:36

00 - Google Home Resume - Helper Script: If at step 2: Parallel action at step 1: parallel 1: Resume needed?: Resume playing: Spotify?: Error executing script. Error for repeat at pos 2: Failed to get device id from Spotify
00 - Google Home Resume - Helper Script: If at step 2: Parallel action at step 1: parallel 1: Resume needed?: Error executing script. Error for choose at pos 2: Failed to get device id from Spotify
00 - Google Home Resume - Helper Script: If at step 2: Parallel action at step 1: parallel 1: Error executing script. Error for if at pos 9: Failed to get device id from Spotify
00 - Google Home Resume - Helper Script: If at step 2: Error executing script. Error for parallel at pos 1: Failed to get device id from Spotify
00 - Google Home Resume - Helper Script: Error executing script. Error for if at pos 2: Failed to get device id from Spotify

and

This error originated from a custom integration.

Logger: custom_components.spotcast.spotcast_controller
Source: custom_components/spotcast/spotcast_controller.py:243 
Integration: Spotcast (documentation, issues) 
First occurred: 22:09:36 (2 occurrences) 
Last logged: 22:09:36

No device with id "9cded3903bad7e010cdf48e584193cf4" known by Spotify
Known devices: []

1 Like

And the names of your devices in Home Assistant are exactly the same as in the Google Home app?

I just did a test with the non-primary account, which also worked fine. I’m a bit out of options here on why it works for me and not for you guys, I would suggest to maybe try the spotcast topic here on the HA community, or create an issue on the spotcast github.

The names are exactly the same.
OK, I will ask for help in spotcast topic.

Yes, the names are the same too. Hopefully, something transpires from the Spotcast topic.

from what I can tell, it seems that the custom integration cannot find your device that you have configured.

Well, as far as I understand it correctly it’s a bit like this:

  • Spotify assigns a device ID to each device on which it is used, eg a phone, or a Google Home device
  • Spotify also connects the name of the device, for Google Home devices this is the name as configured in the Google Home app. This will also be the name which is shown as source it the Spotify integration
  • When spotcast is used with an entity_id as target, it uses the (friendly) name of the entity, and uses the Spotify api to find the Spotify device id belonging to this name, so that’s why the names of the entities need to match the names as configured in the Google Home app.
  • Spotify seems to remove the stored devices rather quickly, but for resuming after a TTS message this should not be an issue.

But that’s about where my knowledge about how spotcast works stops :slight_smile:

As the name is also shown as the source of the media_player of Spotify integration, I also use it to match the right Spotify media_player to the entity_id which is interrupted (in case multiple Spotify accounts are integrated)

Gotta say that this for the most part has worked flawlessly for me, thank you for all your efforts! I do have one question though… Basically I’m seeing that my TTS announcements are not matching the volume set in the scripts. Upon troubleshooting, I see the volume does get changed (to 20%), but then it immediately shoots back up to the previous volume before actually saying the announcement. This results in sound overlap from Google Homes in other rooms. Any help would be greatly appreciated!

notify_garage_interior_door_open:

  alias: Notify - Garage Interior Door Open

  sequence:

  - service: media_player.volume_set

    target:

      entity_id:

        - media_player.living_room_speaker

        - media_player.office_speaker_pair

        - media_player.family_room_stereo_pair

    data:

      volume_level: 0.2

  - service: tts.google_say

    data:

      entity_id: media_player.living_room_speaker

      message: Garage Interior Door Open

      cache: true

  - service: tts.google_say

    data:

      entity_id: media_player.family_room_stereo_pair

      message: Garage Interior Door Open

      cache: true

  - service: tts.google_say

    data:

      entity_id: media_player.office_speaker_pair

      message: Garage Interior Door Open

      cache: true


2022-12-21 02_19_52-Node-RED – Home Assistant

If you rely on the automation to start the resume script, you need to use the announce_volume_automation setting. That is one generic setting which will be used for all announcements.
If you want to use different volume levels for different announcement, you need to call the resume script directly, and add the volume level there.

Thank you kindly for pointing me in the right direction. Turns out I just needed to remove the announce_volume_automation setting and add the resume script to my NodeRed flow. All is working great now!

notify_garage_interior_door_open:
  alias: Notify - Garage Interior Door Open
  sequence:
  - service: media_player.volume_set
    target:
      entity_id:
        - media_player.office_speaker_pair
        - media_player.family_room_stereo_pair
    data:
      volume_level: 0.2
  - service: media_player.volume_set
    target:
      entity_id:
        - media_player.living_room_speaker
    data:
      volume_level: 0.3
  - service: tts.google_say
    data:
      entity_id: media_player.living_room_speaker
      message: Garage Interior Door Open
      cache: true
  - service: tts.google_say
    data:
      entity_id: media_player.family_room_stereo_pair
      message: Garage Interior Door Open
      cache: true
  - service: tts.google_say
    data:
      entity_id: media_player.office_speaker_pair
      message: Garage Interior Door Open
      cache: true



Hey everyone, first off thanks to @TheFes for building this library, this looks exactly what I’ve been looking for for a while now. I’ve been trying to get this to work on my own now for a couple weeks, but have finally capitulated and created an account to ask for help on this forum. :slight_smile:

I’m trying to do something fairly simple (I think) which is that when the mic from my work laptop goes to active I stop the music from my google home in my office. Then once the call is over I’d like to continue listening to the radio.

Pasting the automation below. It stops both tunein as well as spotify and I can see in the traces that it logs the information what had been playing at that time in the helpler script, but it simply never resumes. 20 secs after I hang up the script simply terminates, but doesn’t trigger the play media action. Any help is much appreciated, thanks in advance!

Automation:

alias: "Arbeitszimmer: Musik Pause wenn Teams call"
description: ""
trigger:
  - platform: state
    entity_id: binary_sensor.microphoneactive
    from: "off"
    to: "on"
condition:
  - condition: state
    state: playing
    entity_id: media_player.googlehome2011
action:
  - service: script.google_home_resume
    data:
      action:
        - service: media_player.media_play
          data: {}
          target:
            entity_id: media_player.googlehome2011
mode: single

Sequence from logbook:

The script relies on actions performed on the Google Home, and you are not playing anything on it.

However, this is a good case for the Event script, which is also included in the package.

Let it store the data when the mic goes on, and resume when the mic goes off.

wow, thanks so much for the fast response! very much appreciated. also thanks for the pointer. I have now tried to set this up exactly the way you have laid it out in the docs with the leaving and coming home example. Unfortunately this neither paused the radio, nor resumed it (after pausing manually to test).

Would very much appreciate if you could add some more advice.

New automation:

alias: "Arbeitszimmer: Musik Pause wenn Teams call"
description: ""
trigger:
  - platform: state
    entity_id: binary_sensor.microphoneactive
    from: "off"
    to: "on"
    id: call started
  - platform: state
    entity_id:
      - binary_sensor.microphoneactive
    from: "on"
    to: "off"
    id: call ended
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: call started
          - condition: device
            device_id: 25bc5cf65f924937af5007d5a73d82f8
            domain: media_player
            entity_id: media_player.googlehome2011
            type: is_playing
        sequence:
          - service: script.google_home_event
            data:
              resume_id: resume_after_call
              target:
                entity_id: media_player.googlehome2011
      - conditions:
          - condition: trigger
            id: call ended
        sequence:
          - service: script.google_home_event
            data:
              resume_id: resume_after_call
              resume: true
              target:
                entity_id: media_player.googlehome2011
mode: single

I would remove the condition you added that the player should be playing. If it’s not, it will not be resumed as it was not playing.

Besides that I will need traces of the event script and resume script to see what’s going wrong here

Thanks for your support!
There is no trace from resume script. Event script trace uploaded here: { "trace": { "last_step": "sequence/2/choose/2/sequence/3", "run_id - Pastebin.com

Thanks!

Hmm, something is not going right here. Let me check if it works for myself…

2023.1 Best wishes for 2023!

Only a small update with some bugfixes right now :slight_smile:

:globe_with_meridians: GENERAL

:star2: Improvements

  • Some changes in how the version numbers are copied over to the different scripts (using YAML anchors)

:recycle: RESUME SCRIPT

:bug: Bug fixes

  • Fix for target_list in case multiple targets are provided as string

:performing_arts: EVENT SCRIPT

:bug: Bug fixes

  • Fix for target_list which was not working if a target was specified
2 Likes