Poll : New Actions for Lyrion/Squeezebox integration

As you may have noticed if you’re a squeezebox user, Phil, Raj and I have been working to update the Squeezebox integration recently. One area we’d like to improve is the use of the Squeezebox CLI/API commands in Actions. At present, there are 2 generic actions (call_method and call_query) which allow you to call any CLI command without or with a return value.

However, using these commands requires you to understand the CLI. The good news is that they let you do anything - the bad news is they’re complicated to use. The worse news is that the Home Assistant team have a policy to not allow general APIs like this as they’re considered to mistake-prone and over time, they want us to remove it and cover the common functionality with single use actions instead e.g. an action to play a favorite by name.

So, my question is, what are these common use cases. I’ve been working to add search and play actions for a while now, but what else do you use the CLI for? What are the calls you just couldn’t live without?

Now, don’t take this as a commitment to build all of the things you might ask for, but it’ll be useful to help us build a list of ideas.

Also, don’t panic on the general use API disappearing. I’m going to look into whether it’s possible to add a custom integration (e.g. on HACS) to re-enable the general API access.

4 Likes

I’m using it for search and play scripts that I use to make ui buttons and expose to voice assistants.
Like this:

It’s a bit annoying to use though, and hard to figure out how to do things.

I would, as an example, love to be able to transfer a queue to another player, but I cannot figure out how.

I use these in my automations and scripts:

# Enable line-in
action: squeezebox.call_query
data:
  parameters:
    - enable_linein
    - 00:04:20:99:99:99
  command: squeezeplayadmin
target:
  entity_id: media_player.sqb_radio

# Show message on radioscreen
action: squeezebox.call_method
data_template:
  entity_id: media_player.sqb_radio
  command: show
  parameters:
    - 'line1:Example message'
    - 'line2:Example message!'
    - 'duration:30'
    - 'brightness:1'
    - 'font:huge'
    - 'centered:1
      
# Play preset_6 with volume 15
play_preset6_vol15:
  alias: "Play preset 6 with volume 15"
  sequence:
    - action: squeezebox.call_method
      data:
        command: mixer
        parameters:
          - volume
          - 15
      target:
        entity_id: media_player.sqb_radio
    - action: squeezebox.call_method
      data:
        command: button
        entity_id: media_player.sqb_radio
        parameters: preset_6.single

#DSTM ON
action: squeezebox.call_query
data:
  command: playerpref
  parameters:
    - plugin.dontstopthemusic:provider
    - PLUGIN_LASTMIX_DSTM_LOCAL_ONLY
    - 00:04:20:99:99:99
target:
  entity_id: media_player.sqb_radio

#DSTM OFF
action: squeezebox.call_query
data:
  command: playerpref
  parameters:
    - 00:04:20:99:99:99
    - plugin.dontstopthemusic:provider
    - 0
    - 00:04:20:99:99:99
target:
  entity_id: media_player.sqb_radio

I

Thanks. The search then play stuff is sorted in my search/play update. You can just play a named item, so that should tidy things up quite a bit.

Thanks @Cadster . This shows how damn silly not wanting generic apis is - useful stuff to be sure, but not something general enough to add as a new specific service I think. One thing I could think would be useful would be a button service.

1 Like

@Cadster . Any reason you set the volume via mixer rather than

action: media_player.volume_set
data:
  volume_level: 0.5

Just wanted to make sure we weren’t missing something in the media player integration.

I’m using the CLI (squeezebox.call_method) to do these kind of things:

  • clear the playlist queue
  • add a playlist to the queue
  • start playing.
  • stop playing
  • set to shuffle
  • randomplay tracks
  • play favorites item
  • Using playlistcontrol, load tracks of a random year
      - action: squeezebox.call_method
        data:
          command: playlistcontrol
          parameters:
            - cmd:load
            - year:{{range(1965, 2025)|random}}
        target:
          entity_id: media_player.gramophone

Also use it to send a BBC Sounds URL to the media player to play a given radio station.

      - action: squeezebox.call_method
        data:
          command: playlist
          parameters:
            - add
            - sounds://_LIVE_bbc_radio_fourfm

1 Like

I see it can be used both ways, just consistent use of the actions I guess.

Thanks - that’s fine. Just wanted to check there wasn’t some underlying challenge.

Thanks @zhpub . I think I have most of those cases covered in the search and play actions. I’d missed directly playing a URL, so I’ve just added that. I think playlistcontrol itself probably requires too much of a detailed knowledge of the cli to make use of it for it to make sense as something I could add as a service - i.e. to use it you have to know the api anyway, so you might as well just call the api function. I’ll try and think about the best way to do random.

I think i’ll add a button action - for presets but also to allow setting repeat, shuffle etc.

I’m making extensive use of the API to play & view podcast subscriptions via the podcasts app - although the documentation for that app specifically has been removed starting in Lyrion 9.0 so it’s possible this isn’t actually supported on either end now :joy: It’s the closest thing I’ve found to actually getting podcasts integrated into HA in any meaningful way, so I’d be very sad to see it go away, although I’d be shocked if many other people are using it this way.

Thanks @jenemoore . I don’t know the podcast plugin. If it returns a url (e.g. podcast://xxxxxx) then you should be able to play it with the upcoming play action. Could you give an example of what you mean by viewing the podcast subs - wondering if I can add something to the search action for that and perhaps other apps.

I don’t know what will happen with the general API - depends on how much pressure we get from the HA team, but they won’t even allow us to keep it upto date, so the direction of travel is clear. I’ve written a custom component peteS-UK/lyrion_cli to re-add the general api if and when we use it. Basically the same, but just uses response variable rather than the attribute for the returns from query.

1 Like

Huh; the overall documentation for the podcast browser seems to be in limbo, as it’s missing from the plugin list (although podcast extension, which just adds Apple Podcasts as a source, is there). The API access to podcasts works by drilling down through menus until it finds the individual podcast episode, at which point it can return a URL, so I don’t expect the play action will do it.

The documentation for accessing apps via the API was always pretty bad, so I’m not surprised they don’t want to keep supporting it–but you can still get it from the older version repos. https://raw.githubusercontent.com/LMS-Community/slimserver/refs/heads/public/8.5/HTML/EN/html/docs/cli-api.html

I am a little baffled as to why they’re determined to entirely remove API access, but I’m fine using a custom component to do it if I have to! Is it working now, or still a work in progress?

I’m curious how you use home assistant/lms for podcasts, can you please share you automations/scripts?

Yep - add me to the baffled list… We’re basically bumping up against a desire to make sure things are simple for users - this isn’t limited to media players, it’s a general policy. Whilst I agree with that completely, I don’t really understand why we can’t also support non-novice users but they worry about people getting into things they can’t cope with. However, we don’t make the rules. There’s nothing imminent about it, but it’s clearly the direction of travel. Hence the custom component. Yes, it’s working, so feel free to have a play if you like - it’ll likely continue to evolve.

1 Like

Yes, all the app api access is messy - I had to work through all of that when I added the apps support to the media browser. I’ll try adding the podcast plugin and see if it’s like other apps.

Oh, I didn’t realize apps were being added to media browser support as well! That would be amazing (I’m willing to bet the podcast app is pretty similar to the others, but I also use some other apps that would be nice to have as well). And I salute you; that’s got to be tedious work.

Apps and radios support is in the current 2025.3. Yes, trying to figure out enough patterns of what the apps returned was a pain. Truth be told, I expect quite a few not to work properly and will take several iterations. Radios is actually more useful tbh - able to access things like 7 day playback etc.

1 Like

Right now it’s still pretty manual; I have a script to update the list of subscriptions into an input_select helper:

update script
alias: Update podcasts
sequence:
  - alias: Get list of podcasts from LMS via Squeezebox Radio
    action: squeezebox.call_query
    metadata: {}
    data:
      command: podcasts
      parameters:
        - items
        - 0
        - 20
    target:
      entity_id: media_player.martin_radio
  - variables:
      podcasts: >-
        {{ state_attr('media_player.martin_radio','query_result')['loop_loop']
        }}
          
  - event: lms_podcasts
    event_data:
      result: "{{ podcasts }}"
  - variables:
      podcast_list: >-
        ['Select feed', {% for podcast in podcasts -%}{%- if podcast['id']|int >
        3 -%}'{{podcast['name']}}'{% if not loop.last %}, {% endif %}{%- endif
        %}{%- endfor %}]
  - action: input_select.set_options
    metadata: {}
    data:
      options: "{{ podcast_list }}"
    target:
      entity_id: input_select.podcasts
description: ""
icon: mdi:podcast
fields: {}

and a mushroom-select-card on a dashboard to pick from the list. The goal is to do a recent-episodes selector after that, but I haven’t gotten around to it yet.

I also have a script to play the latest episode of a specific podcast that I can stick in the morning alarm automation; right now it’s hard-coded to assume the list of subscriptions won’t change, but I couldn’t get the conditional working.

play latest
sequence:
  - action: squeezebox.call_query
    metadata: {}
    data:
      command: podcasts
      parameters:
        - items
        - 0
        - 1
        - item_id:7.0.0
    target:
      entity_id: media_player.martin_radio
    enabled: false
  - variables:
      podcast_url: >-
        "{{state_attr('media_player.martin_radio','query_result')['loop_loop'][0]['enclosure_url']}}"
      media_url: "{{ podcast_url[11:] }}"
  - action: media_player.play_media
    metadata: {}
    data:
      media_content_type: music
      media_content_id: "{{ media_url }}"
    target:
      entity_id:
        - media_player.jon_radio
        - media_player.martin_radio
        - media_player.elias_radio
fields: {}
description: ""
mode: restart

But that would work for a button grabbing the latest episode of any podcast if instead of hardcoding item_id:7.0.0 you passed the index number of the subscription you wanted.