spotcast icon indicating copy to clipboard operation
spotcast copied to clipboard

Launching v5 Beta

Open fcusson opened this issue 1 year ago • 37 comments

[!NOTE] I am launching the open beta for spotcast v5.0.0-b0. If you are interested in testing the newest build. Starting today, you will have access to pre-release builds for v5 .

This one was something to build. This here is the first pre-release for Spotcast Version 5. This new version of Spotcast is a complete rewrite of the application to modernise the project to current expectation from Home Assistant and also remove our dependency on the main Spotify Integration as much as possible. There are still a few items to solve, but I feel the code is at a place where testing by a larger audience will be a benefit. For anyone wanting to test out this new version.

Roadmap

  • [x] Rewrite of the core system with its own OAuth manager
  • [x] Separation of spotcast functionalities is separate services
  • [x] Rebuild of the websocket API
  • [x] Creation of spotify connect device media_players
  • [x] Creation of Service Sensors
  • [ ] Creating our own media library browser
  • [ ] Creation of a dedicated podcast service
  • [ ] Creation of a yaml config import
  • [x] Creation of a configuration flow to enable configuring Spotcast from the UI
  • [x] Creation of an option flow to permit modifying options without restarting Home Assistant
  • [x] Creation of a reauth process for when credentials expires
  • [ ] Provide a comprehensive UI text definition
  • [ ] Provide translations for the different Spotcast Interfaces
  • [x] Creation of a logo and icon for Spotcast
  • [ ] Register the icons and logos in Home Assistant branding

Configuration

The configuration for Spotcast has changed drastically in this build. YAML configuration is no longer available and has been replaced with a UI configuration. Expect the following:

  1. As there is no YAML import at the moment, you will have to remove your entry for spotcast in the configuration.yaml
  2. A Spotify Developper Application is now required to manage the OAuth token. If you have the official Spotify Integration, you can use the same.
  3. All documentation about the new version of spotcast can be found in the dev branch
  4. Expect frequent change in the coming weeks.

Thank you in advance for anyone wanting to test out this pre-release. I have been stress testing it for a bit now and have had very good result, especially in terms of performance for starting playback. I'll be waiting for bugs report, as I am sure there are a lot of edge cases that I did not anticipate

fcusson avatar Nov 25 '24 18:11 fcusson

Spotcast was already my favorite and most useful integration among the 58 integrstions and add-ons I use on my HASS instance. Now testing the v5 and I have to say, this is truly amazing and has huge potential for other use cases. Thanks again for all this great work and the last quick upgrades. You're on fire!!!

wildenrou avatar Nov 26 '24 19:11 wildenrou

I have a very niche requirement for this as part of a custom alarm clock blueprint I designed. For some reason updating to HA 2024.11.x broke Spotcast so I figured I'd use the beta and thankfully it works. V5.x seems to be a fantastic evolution so far and my automation seems to be back to working too! Keep up the great work!

The only thing I've come stuck on is that I use a select helper to determine the account to use, this had a template that set the account dynamically but with the move to the integration ID being used I have no idea how to retrieve this as part of a template, can anyone advise how I do this?

BeastleeUK avatar Nov 27 '24 13:11 BeastleeUK

Hi @BeastleeUK,

The entry id was supposed to be part of the profile sensor. I'll add it in the next build. Sorry my mistake. You should be able with that to use templating to fetch the proper attributes based on the profile sensor used.

fcusson avatar Nov 27 '24 14:11 fcusson

@fcusson I am writing a new version of the spotify card at the moment for the V5 integration. It seems to be that the spotcast/castdevicesspotcast/castdevices doesn't return anything at the moment. If I am not mistaken this does not require any account to be passed to the socket right?

mikevanes avatar Nov 27 '24 14:11 mikevanes

@mikevanes castdevices is not looking into an account, it is simply calling the cast integration and returning results from that domain.

@websocket_wrapper
async def async_get_cast_devices(
    hass: HomeAssistant,
    connection: ActiveConnection,
    msg: dict
):
    """Gets a list playlists from an account

    Args:
        - hass(HomeAssistant): the Home Assistant Instance
        - connection(ActiveConnection): the Active Websocket connection
            object
        - msg(dict): the message received through the websocket API
    """

    entities: dict[str, CastDevice] = await async_entities_from_integration(
        hass,
        "cast",
        ["media_player"],
    )

    devices = []

    for id, entity in entities.items():

        cast_info = entity._cast_info.cast_info

        devices.append({
            "entity_id": id,
            "uuid": str(cast_info.uuid),
            "model_name": cast_info.model_name,
            "friendly_name": cast_info.friendly_name,
            "manufacturer": cast_info.manufacturer,
        })

    connection.send_result(
        msg["id"],
        {
            "total": len(devices),
            "devices": devices
        },
    )

New replies should look as documented here. I tested and can confirm I am receiving the expected reply from the websocket with this call:

{
    "id": 5,
    "type": "spotcast/castdevices"
}

fcusson avatar Nov 27 '24 14:11 fcusson

@mikevanes are you trying to manipulate the reply in anyway? I harmonized all the responses format, so that might be why its not working as expected

fcusson avatar Nov 27 '24 14:11 fcusson

@fcusson No I am not casting the reply in any way. The reply I am getting is:

{ "total": 0, "devices": [] }

So it looks like my call is working as expected, no errors.

mikevanes avatar Nov 27 '24 14:11 mikevanes

hmmm, very weird, and you have cast devices available in Home Assistant?

The only way to get that reply without error from the websocket handler would be for async_entities_from_integration to provide an empty dictionary, which would mean HomeAssistant couldn't provide any media_players that are part of the cast domain. Lets move that to a separate ticket, I'll want that to be a specific point of discussion. You can open it under re-enabling spotify-card, we'll use that thread for any issue with what you need for your component

fcusson avatar Nov 27 '24 14:11 fcusson

@DwainTR. Didn't want to continue the conversation on the spotify integration ticket.

Just wanted to clarify, Spotcast is a custom integration not an Add-On, if you have HACS, you can simply search for it and install.

fcusson avatar Dec 02 '24 18:12 fcusson

Hi @BeastleeUK,

The entry id was supposed to be part of the profile sensor. I'll add it in the next build. Sorry my mistake. You should be able with that to use templating to fetch the proper attributes based on the profile sensor used.

Thanks for this, I can now find the Id, however I still can't use my automation as the only sensors spotcast provides have the name of the account in them so can't be dynamically selected. Is it possible to have a sensor that lists all the accounts as objects, i.e. spotcast.accounts with each account having the name and id as attributes? Happy to put this as a separate FR if you think it's feasible.

Basically I want to make the account selectable via an input select helper, this then gets looked at by the the alarm clock routine and plays the music of the selected account on the device, selected from a different helper. The plan will be to have a n automation that dynamically updates the input select helper with the data from the account list so that it's always in sync. This will allow me to manage multiple alarms in the household. The alarm fades in Spotify and Hue lighting for a gradual wake up.

BeastleeUK avatar Dec 02 '24 20:12 BeastleeUK

@BeastleeUK

Basically I want to make the account selectable via an input select helper, this then gets looked at by the the alarm clock routine and plays the music of the selected account on the device,

Didn't implement a global sensor because for something like that I use jinja templates. You could use something of the kind for your usecase:

edit: found a much cleaner way with label_entities

{% for entity in label_entities('spotcast_account') %}
  {% if state_attr(entity, 'display_name') == states('input_select.spotcast_user') %}
    {{ state_attr(entity, 'entry_id') }}
  {% endif %}
{% endfor %}

That could either be a template sensor that listen to the spotcast_user input select or directly in your automation. I would prefer the first option, because then its easy to use elsewhere.

If you still believe adding it to the code base would be important, make a PR, but your sensor will have to be global, so ensure you are not rebuilding it on a second account setup.

fcusson avatar Dec 02 '24 21:12 fcusson

@BeastleeUK

Basically I want to make the account selectable via an input select helper, this then gets looked at by the the alarm clock routine and plays the music of the selected account on the device,

Didn't implement a global sensor because for something like that I use jinja templates. You could use something of the kind for your usecase:

edit: found a much cleaner way with label_entities

{% for entity in label_entities('spotcast_account') %}
  {% if state_attr(entity, 'display_name') == states('input_select.spotcast_user') %}
    {{ state_attr(entity, 'entry_id') }}
  {% endif %}
{% endfor %}

That could either be a template sensor that listen to the spotcast_user input select or directly in your automation. I would prefer the first option, because then its easy to use elsewhere.

If you still believe adding it to the code base would be important, make a PR, but your sensor will have to be global, so ensure you are not rebuilding it on a second account setup.

Sorry for the slow response, I ran out of time on the day and only just back to laptop.

Thank you for the script, and the original one you posted. I'm reviewing how the label_entities works, then I can put this into place on the alarm automation itself. I've used the first script you posted to enable me to update the options in the input_select, I've had to run it manually as there's no trigger option for 'new entity added' but it works a treat!

BeastleeUK avatar Dec 04 '24 21:12 BeastleeUK

I've got that working with the above code and applying the label to the profile entity, thanks so much. Next job will be to make it a template sensor and just reference that in the automation.

When testing this change it reported 'Error: Account xxxxxxxxx has no known or active playback. Nothing to transfer' even though it normally just picks up where I left off. I hit play and pause on my phone then it transferred fine but I've not had to do this previously. Hopefully it will work in the morning and this was just a Spotify glitch.

BeastleeUK avatar Dec 04 '24 22:12 BeastleeUK

@BeastleeUK, Spotify seem to have changed the way they report long lasting playback now. They provide an empty reply as soon as you close the app that was playing. It was possible on the past to restart the playback long after the app was closed.

I've implemented a way to restart playback from a long gone playback state in the latest build, that should solve your issue. Currently it only works for album or playlist but I'm working on implementing a solution for artists and podcasts

fcusson avatar Dec 05 '24 00:12 fcusson

Weird that it was fine Tuesday but not last night/this morning. I rarely play anything other than my liked songs list on repeat with suggestions. I'll see what I can do with the latest build to make it work for this setup.

Thanks again.

BeastleeUK avatar Dec 05 '24 12:12 BeastleeUK

Can we have support for "recently played" playlist on the websocket api? A while back I added this functionality into the previous version of spotcast but it's been dropped it seems. https://github.com/fondberg/spotcast/pull/257

gmcmicken avatar Jan 27 '25 05:01 gmcmicken

@gmcmicken using the view websocket endpoint you can retrieve the recently played playlists. It should have documentation on how to do so.

mikevanes avatar Jan 27 '25 07:01 mikevanes

@gmcmicken using the view websocket endpoint you can retrieve the recently played playlists. It should have documentation on how to do so.

Wonderful, my apologies

gmcmicken avatar Jan 27 '25 08:01 gmcmicken

When I start a podcast with the script below, only the first episode plays and then it stops. This is what version 4.x did. Is there a workaround to keep it going to the next episode? Thanks!

- action: spotcast.play_media
    data:
      media_player:
        entity_id: media_player.kitchen
      spotify_uri: spotify:show:xxxxxxxxxxxxxxxxxxxxxxx

litecross91 avatar Feb 11 '25 13:02 litecross91

@litecross91, This is not normal behavior, please open a ticket

I just tested and I am not seeing this behavior. When calling spotacst.play_media with a show URI the podcast started to play at my current episode, at the current timestamp I was at with shows in queue.

fcusson avatar Feb 11 '25 14:02 fcusson

@fcusson The current episode starts for me too. When this episode is over, it does not switch to the next one. This is my problem. Can you check this one too? Thanks! please use this show for the test: https://open.spotify.com/show/6vgwu6GE3ACjEFRtckHVSu

litecross91 avatar Feb 11 '25 14:02 litecross91

@litecross91 as mention, please open a new ticket, this is not a thread to resolve issues. I need your diagnostic details before going further

fcusson avatar Feb 11 '25 14:02 fcusson

I opened: https://github.com/fondberg/spotcast/issues/516 Thank you!

litecross91 avatar Feb 11 '25 14:02 litecross91

@fcusson : in V4 there was an option by adding 'random_song: true' to the data to shuffle the music. Is this also available in V5? If yes, what should be added? Except for the shuffle modus, everything is working perfectly.

Many thanks in advance and for all the support.

Kind regards,

Robin

XalaTheShepard avatar Mar 19 '25 12:03 XalaTheShepard

@XalaTheShepard that's part of the data option now. See documentation.

fcusson avatar Mar 19 '25 12:03 fcusson

Hello, the integration is working great for me. Thanks. 😃

Quick question: How to update sp_dc and sp_key in the v5 integration when they expire? I don't see them in "Configure".

Mincka avatar Mar 19 '25 12:03 Mincka

@XalaTheShepard that's part of the data option now. See documentation.

@fcusson : many thanks. Everything is working like before again. :)

XalaTheShepard avatar Mar 19 '25 13:03 XalaTheShepard

Hi! The integration is working great, thanks! One feature that I was using of V4 was the ability to transfer playback to my Sonos devices through the transfer id. The new transfer playback action limits to devices it has discovered, which sadly my Sonos devices are not discovered.

Stefterv avatar Mar 20 '25 08:03 Stefterv

@Stefterv for devices to be transferable it needs to be registered to the account and part of the available list from the API. Otherwise there is a registration blob that must be created and sent to the unregistered device.

As we were never creating that handshake in the past with unregistered devices, it shouldn't be working if the device was not preregistered and if it was preregistered it should show up in your spotcast media players

fcusson avatar Mar 20 '25 09:03 fcusson

That's the fun part with Sonos devices, they are not visible in the API but are visible in the Spotify app and website more details It seems like they use an older (private) API

Stefterv avatar Mar 20 '25 09:03 Stefterv