Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting SRS-X88 source list #5

Open
seanb-uk opened this issue Jan 14, 2018 · 6 comments
Open

Getting SRS-X88 source list #5

seanb-uk opened this issue Jan 14, 2018 · 6 comments

Comments

@seanb-uk
Copy link

I've figured out how to get the list of SRS-X88 sources. You have to get the list for each scheme in turn. First get the schemes:

songpal --endpoint http://192.168.1.18:54480/sony command avContent getSchemeList
Calling avContent.getSchemeList with params None
INFO:songpal.protocol:Calling avContent.getSchemeList(None)
[{'scheme': 'storage'}, {'scheme': 'extInput'}, {'scheme': 'dlna'}]

For each scheme, get the source list:

songpal --endpoint http://192.168.1.18:54480/sony command avContent getSourceList '{ "scheme": "storage" }'
Calling avContent.getSourceList with params {'scheme': 'storage'}
INFO:songpal.protocol:Calling avContent.getSourceList({'scheme': 'storage'})
[{'playAction': 'changeSource', 'isBrowsable': True, 'meta': 'meta:storage:usb', 'isPlayable': True, 'source': 'storage:usb1', 'title': 'USB'}]

songpal --endpoint http://192.168.1.18:54480/sony command avContent getSourceList '{ "scheme": "extInput" }'
Calling avContent.getSourceList with params {'scheme': 'extInput'}
INFO:songpal.protocol:Calling avContent.getSourceList({'scheme': 'extInput'})
[{'isBrowsable': False, 'meta': 'meta:usbdac', 'title': 'USB DAC', 'source': 'extInput:usbDac', 'isPlayable': True, 'playAction': 'startPlay'}, {'isBrowsable': False, 'meta': 'meta:btaudio', 'title': 'Bluetooth Audio', 'source': 'extInput:btAudio', 'isPlayable': True, 'playAction': 'startPlay'}, {'isBrowsable': True, 'meta': 'meta:line', 'title': 'Audio in', 'source': 'extInput:line', 'isPlayable': False, 'playAction': 'startPlay'}]

songpal --endpoint http://192.168.1.18:54480/sony command avContent getSourceList '{ "scheme": "dlna" }'
Calling avContent.getSourceList with params {'scheme': 'dlna'}
INFO:songpal.protocol:Calling avContent.getSourceList({'scheme': 'dlna'})
[{'isBrowsable': False, 'playAction': 'startPlay', 'title': 'Home Network', 'isPlayable': True, 'source': 'dlna:music', 'meta': 'meta:dlna:music'}]

The next problem is that the network option can be set using the "Home Network" or dlna:music URL but the playing source does not match:

songpal --endpoint http://192.168.1.18:54480/sony command avContent getPlayingContentInfo {""}
Calling avContent.getPlayingContentInfo with params {}
INFO:songpal.protocol:Calling avContent.getPlayingContentInfo({})
[{'contentKind': 'service', 'parentUri': '', 'stateInfo': {'supplement': '', 'state': 'STOPPED'}, 'service': 'netService:audio?service=spotify', 'uri': 'netService:audio?service=spotify&contentId=-1', 'fileNo': '255', 'source': 'netService:audio'}]

So that shows which network service is in use, but they are not available as sources. Spotify is the default, by the way, I've never used it. It could also be cast:audio when casting.

I can't think of any way round that other than a sort of bodge where "Home Network" is treated as the source for any netService, at least for the purposes of source selection.

That said, if you cast to the Sony it automatically switches to network input even if another input is currently active so maybe it doesn't need to be explicitly listed in the inputs.

@seanb-uk
Copy link
Author

Incidentally, the clue for the schemes came from a similar project:
https://github.com/pschmitt/pysonyavr

@rytilahti
Copy link
Owner

Hi and thanks for your findings, I'm going to answer a couple of points :-)

First get the schemes:

This is exactly what calling songpal schemes in console does.

For each scheme, get the source list:

Calling songpal source does the same call, doesn't it? It defaults to using storage, so if you want to query another source you need to type e.g. songpal source extInput.

I'm unsure about the network services and their specifics (as mine is completely disconnected from external network), the official API may describe some of that.

Is it currently working otherwise fine for you, or do you have found something else that is misbehaving?

About that pysonyavr, interesting! That's also newer than this project, so maybe that's why I never spotted it while searching for a way to control these devices. Looks like their implementation is much simpler and does not support e.g. changing settings at all. Still, more the merrier I suppose!

@seanb-uk
Copy link
Author

Yes, I'd missed songpal schemes - that does work.

I haven't actually tried the home assistant component yet, I wanted to see how it works before I install onto my HA machine. I think the issue will be that the input list in HA comes from get_inputs which only uses getCurrentExternalTerminalsStatus to get the list of inputs. That will only return the extInput sources and not the sources for the other schemes. The full list of inputs comes from getting the sources from all schemes.

The other issue will be down to the device reporting an input source that is not listed in any of the schemes - i.e. you have to use input dlna:music to put the device onto the network source but then the reported source is different, making it impossible to show the current input in a drop down list without an ugly workaround.

@rytilahti
Copy link
Owner

I just modified the cli tool' source command to iterate over all the schemes when no scheme is given. I'm unsure whether it makes to integrate this to the homeassistant component, but I suppose that'd be okay thing to do.

Have you tested out what happens if you try to activate a source such as dlna:music? `songpal raw_command avContent setPlayContent '{"uri": "dlna:music"}' should probably work.

The information from getPlayingContentInfo could be exposed through the other properties of media_player: media_title, media_content_type etc. That would require more work though (to fix the container for that data).

@seanb-uk
Copy link
Author

OK, so source now gets all 5 sources selectable by the remote, albeit with some errors:

songpal --endpoint http://192.168.1.18:54480/sony source
USB (storage:usb1)
  Got an error for getContentCount: [7, 'not in browsing mode']
  Got an error for getContentList: [7, 'not in browsing mode']
USB DAC (extInput:usbDac)
  Got an error for getContentCount: [15, 'unsupported operation']
  Got an error for getContentList: [15, 'unsupported operation']
Bluetooth Audio (extInput:btAudio)
  Got an error for getContentCount: [15, 'unsupported operation']
  Got an error for getContentList: [15, 'unsupported operation']
Audio in (extInput:line)
  Got an error for getContentCount: [3, 'illegal argument']
   
	extInput:line
   
	extInput:line?port=1
Home Network (dlna:music)
  Got an error for getContentCount: [3, 'illegal argument']
  Got an error for getContentList: [3, 'illegal argument']

I can successfully change input to bluetooth using:

songpal --endpoint http://192.168.1.18:54480/sony command avContent setPlayContent '{"uri": "extInput:btAudio"}'
Calling avContent.setPlayContent with params {'uri': 'extInput:btAudio'}
INFO:songpal.protocol:Calling avContent.setPlayContent({'uri': 'extInput:btAudio'})
True

This also works for extInput:usbDac and storage:usb1 but not for extInput:line or dlna:music, both of which throw:

Exception: Got an error for setPlayContent: [3, 'illegal argument']

Setting to extInput:line manually, getPlayingContentInfo shows the uri is actually set to extInput:line?port=1:

songpal --endpoint http://192.168.1.18:54480/sony command avContent getPlayingContentInfo {""}
Calling avContent.getPlayingContentInfo with params {}
INFO:songpal.protocol:Calling avContent.getPlayingContentInfo({})
[{'parentUri': '', 'contentKind': 'input', 'uri': 'extInput:line?port=1', 'source': 'extInput:line', 'stateInfo': {'supplement': '', 'state': 'STOPPED'}}]

This does work with setPlayContent:

songpal --endpoint http://192.168.1.18:54480/sony command avContent setPlayContent '{"uri": "extInput:line?port=1"}'
Calling avContent.setPlayContent with params {'uri': 'extInput:line?port=1'}
INFO:songpal.protocol:Calling avContent.setPlayContent({'uri': 'extInput:line?port=1'})
True

I did try calling setPlayContent with source instead of uri as the parameter, but that doesn't work.

The network setting is even worse - although it's dlna:music, if I manually switch to network it reports the uri as a specific netService:audio uri:

songpal --endpoint http://192.168.1.18:54480/sony command avContent getPlayingContentInfo {""}
Calling avContent.getPlayingContentInfo with params {}
INFO:songpal.protocol:Calling avContent.getPlayingContentInfo({})
[{'source': 'netService:audio', 'fileNo': '255', 'parentUri': '', 'contentKind': 'service', 'uri': 'netService:audio?service=spotify&contentId=-1', 'stateInfo': {'state': 'STOPPED', 'supplement': ''}, 'service': 'netService:audio?service=spotify'}]

Interesting to note that getCurrentExternalTerminalsStatus, which only reports three out of the five sources, does have the full uri for line input:

songpal --endpoint http://192.168.1.18:54480/sony command avContent getCurrentExternalTerminalsStatus
Calling avContent.getCurrentExternalTerminalsStatus with params None
INFO:songpal.protocol:Calling avContent.getCurrentExternalTerminalsStatus(None)
[{'connection': 'unknown', 'uri': 'extInput:usbDac', 'title': 'USB DAC', 'meta': 'meta:usbdac'}, {'connection': 'unknown', 'uri': 'extInput:btAudio', 'title': 'Bluetooth Audio', 'meta': 'meta:btaudio'}, {'connection': 'unknown', 'uri': 'extInput:line?port=1', 'title': 'Audio in', 'meta': 'meta:line'}]

That might be OK for my needs - I only really need to be able to select bluetooth or line in. The problem is gracefully handling the situation in HA when the uri does not match anything in the dropdown list of sources.

@wanghuangjie
Copy link

wanghuangjie commented May 3, 2018

well. i found a dumb solution.

configuration:yaml

shell_command: 
  sony_srsx77_input_source: 
   bash "sony_srsx77_input_source.sh" {{ states.input_select.x77_source.state }}

input_select:
  x77_source:
    name: Sony SRS-X77 Input Source
    options:
      - 'extInput:btAudio'
      - 'extInput:line?port=1'
      - 'dlna:music'
      - 'extInput:airPlay'`

automation.yaml

input_select:
- id: SONY_SRSX77_INPUT_SOURCE_SYNC
  alias: SONY SRSX77 Input Source Sync
  trigger:
  - platform: state
    entity_id: input_select.x77_source
  action:
    service: shell_command.sony_srsx77_input_source

sony_srsx77_input_source.sh

#!/bin/bash
endpoint="http://x.x.x.xx:54480/sony/avContent"
input_source=$1
curl -s -d '{"method": "setPlayContent","id": 1,"params": [{"uri": "'"$input_source"'"}],"version": "1.2"}'  $endpoint

wechatimg120

reference:
A lesson in poor API design

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants