Synology Audio Station Media Player

Could someone help build out a component for Audio Station on running on a Synology NAS? I have HASS.io running on a rPi, but also use Audio Station. I have several airport expresses attached to speakers throughout the house, and I’d like to make a simple selector to pick a playlist to play on a remote player. Similar to this for Chromcast - Chromecast Radio with station and player selection

There are a couple random forum threads and projects related to controlling Audio Station, but I don’t know where to start in HA:

https://www.synology.com/en-us/support/developer#tool

https://forum.synology.com/enu/viewtopic.php?t=102647

https://1drv.ms/f/s!AhSV8BnLHqYImitlCFD5B-CMn9w0

The following links work when typed directly in a browser:
Authenticate: https://IP:Port/webapi/auth.cgi?api=SYNO.API.Auth&method=Login&version=1&account=USER&passwd=PWD

List Players: https://IP:Port/webapi/AudioStation/remote_player.cgi?api=SYNO.AudioStation.RemotePlayer&version=2&method=list

List Playlists: https://IP:Port/webapi/AudioStation/playlist.cgi?api=SYNO.AudioStation.Playlist&version=2&method=list

Play: https://IP:Port/webapi/AudioStation/remote_player.cgi?api=SYNO.AudioStation.RemotePlayer&method=control&id=PLAYERID&version=2&action=play

Stop: https://IP:Port/webapi/AudioStation/remote_player.cgi?api=SYNO.AudioStation.RemotePlayer&method=control&id=PLAYERID&version=2&action=stop

Set playlist: https://IP:Port/webapi/AudioStation/remote_player.cgi?api=SYNO.AudioStation.RemotePlayer&method=updateplaylist&library=shared&id=PLAYERID&offset=0&limit=0&play=true&version=2&containers_json=%5B%7B%22type%22%3A%22playlist%22%2C%22id%22%3A%22PLAYLISTID%22%7D%5D

This is a great idea. I don’t know the languages or platform yet, so I will probably never finish - but I am going to see what can be achieved by reverse engineering something else.

At the very least there is the ability to create some switches to stop playback when a phone rings etc.

Awesome. I’d be happy to test out anything you can pull together. Just don’t have the free time to try to learn the coding effort myself. Currently, I’m just running both Audio Station and Logitech Music Server from my NAS (although this isn’t a great solution).

I’ve been engrossed in other things - but I have automated the audio station successfully; happy to share code. I’ve got multiple playlists playing to multiple remote speakers, triggered by voice commands from my android phone, and by our “return home”.

In regards to a web interface, I am going to assign various commands to a “custom UI tiles” interface.

Once I have finished that, I will attempt to reverse engineer an existing media-player template - but I will have much to learn, so don’t hold your breath :slight_smile:

1 Like

Awesome work! Dis you use the cli component? Would you mind sharing the code tou have to date? Thanks

Because I don’t have a media_player ‘component’ set up, I have scripts querying the APIs and sending info to HTTP sensors for feedback, and other automations/switches are triggering scripts with arguments ( using the shell_command option in the configuration.yaml ) - all relying on some complex templates etc… so it’s still very complicated to be honest… with a little more time I can hopefully simplify it. Ideally it needs to be written as a ‘media_player’ component, but I haven’t looked far into that yet.

Rather than me send a mess of code, and configurations. how about you tell me what you first want to implement, and I can send you the relevant bits?

I have a home-made voice activation setup using Tasker, MQTT and scripts; but maybe a better interface to use is the tiles interface - that lends itself to buttons, and which currently looks like the image below on mine. The first four tiles on the top row are both for setting and displaying which remote speaker is set; the other four are skip, ‘find active’, play/pause, and delete (skips then deletes the playing song). The tiles interface is highly customise-able - if you are interested, check here: Custom UI: Tiles

Hello,

I’m interested about this option, something new? someone have added a synology media player in their home assistant?

thanks

I am also very interested, and I hope to figure out how to add a component.

I have the Audio Station well controlled using scripts and 'commandline switches" with Home Assistant, but yes it needs to be added as a media_player component.

Does anyone know of any ‘friendly’ guides on how to go about this?

Hi,
I wopuld just like the ability to:

  1. Browse media library (By same filters as in DS audio - folder, artist, album etc)
  2. Select output speaker
  3. Play selected media to selected speakers

Do you have these snipets?

Any chance you could share how you did this? I’m setting up lovelace and would like to finally get Audio Station integrated. I can play with the interface, but need to understand how to set up the different scripts. At a basic level I just want to be able to select a playlist and a speaker to start playing.

Hi @dad , @uiguy (apologies for missing your post above, uiguy!)

What I did in the end was quite simple. I set up a bash script to accept a number of commands, called via the “shell command” component in Home Assistant. Rather than try to isolate a few functions, how about I just send you the whole lot?

shell_command:
  syno_audio_controls: 'bash /config/Scripts/SynoAudio/SynoAudio.sh {{ action }} {{ data }} {{ targetplayer }} {{ extra }} '

I only use this approach for playlists - playlists I have made beforehand. I mainly call the script’s actions from the web interface - a separate ‘View’ within Home Assistant ( see image below). I can choose the remote speaker (a drop-down which is dynamically populated from a query against Audio Station), I click an image that matches a playlist I want, and there are the standard control buttons you see as well. It also grabs the song info, allowing you to delete a song file in more confidence. The star button allows me to gradually build up a “5 star” smart playlist by adding a 5* rating to the currently playing song.

I have tried to find the initial scripts again, so I can give credit - but I cannot find that anywhere. I have almost completely rewritten it, but I would ideally give credit where it’s due, for the bones of the API calls.

https://mega.nz/#F!JYJihQTA!wIuYLAMjTMaa7WjK8BZI4w

Anyway, above is a link to the files. I have made no effort to make it professional, optimised etc so lower your expectations :slight_smile: plus there are a few variables specific to my setup so I hope you feel comfortable with bash scripts - you will need to change variables at the very least.

The script updates info in Home Assistant via sending JSON to the HTTP sensor function, for example the rest command which updates the available players, works off a sensor populated in this way (sensor.synoplayers). Calling the shell command with the {{ action }} argument “updatePlayers” will cause the script to send a JSON object to populate this sensor.

rest_command:
  update_syno_players:
    url: "https://noirdsm.ddns.net:8123/api/services/input_select/set_options"
    method: POST
    headers:
      content-type: application/json
      x-ha-access: lastnightcarrotfight9
    content_type: application/json
    payload: >-
      {
        "entity_id": "input_select.syno_players",
        "options": [
      {%- for item in states.sensor.synoplayers.attributes.players %}
        "{{ (item.name).split(" ")[0] | replace("TX-NR609","Onkyo") | replace("TV_LCD60","Lounge TV") | replace("BDRM_TV","Bedroom TV")}}"
        {% if not loop.last %}, {% endif %}
      {%- endfor %}
        ]
      }

So anyway, if you can make use of all this experimental fudgery, feel free to download the script and have a go. I will try to help out if you want to create something for your needs. Happy to share hints on the web UI, automations etc. if you want.

2 Likes

Awesome, thank you! I downloaded the scripts and updated the variables for a couple of my players and playlists. Could you help with the basic instructions for executing the scripts from the frontend?

When I first tried (using Squeezebox instead of Audio Station), I created input selection boxes to pick a player and a playlist (both hard coded). Then I had a script that could be executed to start playing based on the selections.

I will paste some snippets when I’m back home, but the gist of it is to make a script or switch that calls the shell_command and provides the variables.

Unless you have also implemented the Tiles UI, I’m not sure how you are best to present the switches and scripts within your UI?

UPDATE: some snippets. Hope these help.

The process relies on “Input Select” for Player and Protocol, which the scripts and switches use as variables. The REST Command in the post above will re-populate this list with all players that the Audio Station actually discovers.

    input_select:
      syno_players:
        name: "Remote Speakers"
        options:
          - 'None'
          - 'Pioneer'
          - 'Onkyo'
        initial: 'Pioneer'
        icon: mdi:speaker-wireless
      syno_protocol:
        name: Synology Audio Protocol
        options:
          - DLNA
          - AirPlay
        initial: DLNA
        icon: mdi:airplay

An example of a HA “script” - it kicks off the chilled playlist based on the player and protocol set (it either uses DLNA or AirPlay).

play_chilled:
  alias: play chillout
  sequence:
  - service: media_player.turn_on 
    data_template:
      entity_id: '{{ states.input_select.syno_players.state }}'
  - service: shell_command.syno_audio_controls
    data_template:
      action: playlist
      data: chilled
      targetplayer: '{{ states.input_select.syno_players.state }}'
      extra: '{{ states.input_select.syno_protocol.state }}'
  - service: input_select.select_option
    data_template:
      entity_id: '{% if (states.input_select.syno_players.state) == "Onkyo" %}input_select.onkyo_source{% elif (states.input_select.syno_players.state) == "Pioneer" %}input_select.pioneer_source{%- endif %}'
      option: '{% if (states.input_select.syno_players.state) == "Onkyo" %}DLNA{% else %}H.M.G{% endif %}'

Example of a switch (you don’t need to rely on a sensor for the value_template like I have, the only affect is that the switch shows as On/Off):

sas_skip:
  value_template: "{{ is_state_attr('sensor.sas','state','playing') }}"
  turn_on:
    service: shell_command.syno_audio_controls
    data_template:
      action: "next"
      data: "null"
      targetplayer: '{{ states.input_select.syno_players.state }}'
      extra: '{{ states.input_select.syno_protocol.state }}'
  turn_off:
    service: shell_command.syno_audio_controls
    data_template:
      action: "next"
      data: "null"
      targetplayer: '{{ states.input_select.syno_players.state }}'
      extra: '{{ states.input_select.syno_protocol.state }}'

Thanks. I’m traveling this week, but should be able to give this a shot when I get home. My first challenge was just figuring out how to set up the scripts with the right variables. This should get me started.

For UI I’m looking to pull together a basic card in lovelace with input selections and then buttons to start/pause. Once that’s in place I’ll look to get more creative.

If I knew of a walkthrough for creating a python component I might have had a go at that.

Oh hey - another thing - to make good use of all the JSON arrays from the APIs - I used a utility called ‘jq’. .

Basic instructions:

# Run within docker: docker exec -ti hass /bin/bash
wget http://stedolan.github.io/jq/download/linux64/jq
chmod +x ./jq # not sure if that will be the right path to the .jq file
cp jq /usr/bin

Interesting new features in this homeassistant release that may work well with Synology.
Media library
Music streaming component
Will be trying to figure this out unless some figures out YouTubeMusic streaming API first

I would love to see that integration!

Do you know if there’s anyway to clear the play queue using the api? I’m not actually using the script you posted as I have no idea how to alter it for my specific player but am using:

wget -qO - --load-cookies cookies.txt --post-data "api=SYNO.AudioStation.RemotePlayer&method=updateplaylist&library=shared&id=PALYERID&offset=0&limit=1&play=true&version=3&updated_index=-1&containers_json=PLAYLISTID" http://API:PORT/webapi/AudioStation/remote_player.cgi

Anytime I try to play a playlist, it actually just adds all songs to the queue, but doesn’t remove the songs of the previous playlist. Is there anything I can add or change to it to remove previous songs from the queue?
edit: I read through your script and can’t understand most of it, but I see that it says

forcePlaylist=0                  # if force = 1 then will clear and update playlist

But just adding &forcePlaylist=1 to the api doesn’t do anything. Is it supposed be other words? I’ve tried total=0, total=1, limit=0, limit=1, forceplaylist=1, forceplaylist=0

1 Like

Hey - I’ve not had trouble with this, I thought there was something on the code for this… I have a Hass button for toggling Add&Replace… I will be back home in a few days, if you don’t hear from me feel free to nudge.

1 Like

Took me a while but I finally figured it out.
Part I was missing was: &limit={{playlist_total}}.

In case anyone else is having this issue and reads this, you can clear the playlist with:

curl --cookie cookies.txt "http://IP:PORT/webapi/AudioStation/remote_player.cgi?api=SYNO.AudioStation.RemotePlayer&method=updateplaylist&library=shared&id=PLAYERID&offset=0&updated_index=-1&limit=PLAYLIST_TOTAL&play=false&version=2&songs="