alexmohr / sonyapilib

Contains a python api to control sony devices.
MIT License
20 stars 11 forks source link

Trouble configuring Sony BDP-S590 #3

Closed brgerig closed 4 years ago

brgerig commented 6 years ago

Hi, this seemed like the only place I could find to ask this question. As far as I know, your component is the only one out there that might provide integration with my Sony BluRay player. I pip installed sonyapilib, and it installed 0.3.8. I copied components/media_players/sony.py from your home-assistant fork, and put that in my custom_components/media_players folder. I added the following to my home assistant config:

`media_player:

alexmohr commented 6 years ago

On some devices you have to enable remote access deep down in the settings of the device and on some the registration has to be done in a menu in the settings. If this is not the case for you can try to use the example python code in the readme and provide the output of the script because it should log the http return codes. Have you taken a look in the home assistant log?

brgerig commented 6 years ago

Thanks for responding so quickly!

No errors related to this in the home assistant log.

I ran the example code, and got a "list index out of range" error on trying to read the apps list. So I removed the calls to get_apps() and start_app() and added a print of get_playing_status(). That seems to work just fine and correctly returns the play status. There's a lot in the bluray.json file that it created, which doesn't seem to have anything analogous inside of the home assistant config directory.

alexmohr commented 6 years ago

The out of bound exception can be due to not having any apps installed on the device and does not really matter for the integration in home assistant because the app integration is not implemented in the home assistant side.

With my device the S550 there is a bug in the remote access control which prevents registration after the device has been to standby. Removing and reconnecting the power cord solves this issue for me and makes the registration possible. But because the registration seemed to work from the command line this cannot be the issue for you

The configuration file you mentioned is created by the home assistant integration as soon as the registration went through successfully which does not seem to be the case in your scenario.

If you take a look at the dev branch you'll see a script called convert_to_hass.py which converts the configuration file into the format the home assistant integration uses. The name of the configuration file is currently hard coded in the script and you have to adjust the name of it. After running it will create a file called 'sony.conf'. Copy it into the root directory of your home assistant installation. Thanks for your support.

brgerig commented 6 years ago

That did it!

For some reason it seems that registration on the BluRay player works fine, but it never figures out that it's registered and finishes setting up the device. I suspect it's because I didn't actually have to use a PIN -- I just started the registration process on the player, entered 0000 on the Home Assistant side, and registration completed, but the PIN dialog went away.

I'm happy with it working as-is, but I'm also completely willing to test code. I also have a BDP-S580 that I'll be setting up this evening.

Thanks again for sharing this code... I'm really happy that it exists and works so smoothly (well, once setup is done... :) )

alexmohr commented 6 years ago

Happy to hear that it worked. When a pin dialog is already displayed and you then enter 0000 home assistant will try to authenticate with this pin, which will fail but on the device side there will be no message but the dialog closes. ( at least for my device ) Only enter 0000 if there is no dialog open yet and enter the displayed pin if there is one. Please report back if the S580 works because I am looking into merging the component with the home assistant upstream and really can use tests with other devices.

Thanks for reporting the issue.

brgerig commented 6 years ago

My player didn't need/display a PIN at all... on my BluRay, I went to Network Settings -> Media Remote Device Registration -> "Start Registration", and then it waited for a device to register. Then I entered 0000, and my player registered Home Assistant. The PIN dialog never went away.

The process looks like the 2011-2012 steps here: http://info.tvsideview.sony.net/en_ww/faq/regist_bdp_wfd.html

alexmohr commented 6 years ago

perfect, thanks for providing the link. not requiring any pin was not handled correct in the home assistant side. If you take the component from the home assistant fork it should work, although it is a very crude and ugly fix. I'm going to provide a proper fix in the next couple of days or so. I'll let you know when it's done and I'd be happy if you could test it when its done Thanks again :)

brgerig commented 6 years ago

I tried the new version.

The BDP-S590 configured properly when I used PIN 1234 (even after deregistering on the bluray side). I can't do anything to get the BDP-S580 to register, and I'm not sure why.

BDP-S580 software version: M07.R.0631 BDP-S590 software version: M12.R.0510

Let me know when you want me to test again!

alexmohr commented 6 years ago

The S590 implementation is fixed in a better way now, if that works for you I'd say its fixed.

I need a bit more information about the S580 so solve the issue with that. Could you tell me the output of the following command? curl http://ip_of_device:50001/Ircc.xml | grep av:X_UNR_Version This will give me at least the api version used in the device. I assume you've tested with the script aswell to register the device?

brgerig commented 6 years ago

I'll test the S590 registration soon, but here's some testing of the S580:

The script doesn't work to register it, either, and gives a "connection refused" on retrieving Ircc.xml. Trying to curl the URL also fails. Checking on it with Intel UPnP Device Spy shows that the IRCC service is listening on 52323 instead of 50001, unlike the S590. However, if I try to get Ircc.xml on port 52323, I get a 404. nmap shows that port 50001 on the S580 is closed. Every media server-related feature I've been able to find is turned on. Maybe I should factory-reset it and try again.

brgerig commented 6 years ago

Tested the S590 again: Both '0000' and no PIN displayed "Failed to register, please try again." in Home Assistant, but successfully registered on the BluRay player.

alexmohr commented 6 years ago

I guess you can read "An unknown error occured during registration" in the log of home assistant. Thats the problem with reverse engineering an api where you do not have access to the devices. ( and confusing greater and less than signs ... )
I've removed an error check which I've copied from the original project that did not make much sense anyway and removed a check for the api version which was not necessary anyway at that point.

As for the S580 when only port 52323 is open probably means that the ircc service is not enabled or does not exist on that device and api version. You should be able to get the xml file from ip:52323/dmr.xml Unfortunately the ircc service is essential for the remote control of a device. I have added a script called discover_devices.py in the dev branch. Adjust the ip and post the output of it here. It will enumerate all upnp services with the urls to access them. http://10.0.0.102:50201/dial.xml http://10.0.0.102:52323/dmr.xml http://10.0.0.102:50001/Ircc.xml

These are the services I get on my devices. If you have any that are not listed please post the xml data here.

I'm really sorry for the trial and error here but i really appreciate your work for this project.

alexmohr commented 5 years ago

Closing this issue as the problems probably do not occur anymore. Let me know if this is not correct.

brgerig commented 4 years ago

Hey! I haven't touched this in a while, but decided to get back to trying to get this to work. The S590 registers and works perfectly.

In case you're still interested in working on it, here's the dmr.xml file for the S580:

<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
  <specVersion>
    <major>1</major>
    <minor>0</minor>
  </specVersion>
  <device>
    <deviceType>urn:schemas-upnp-org:device:MediaRenderer:1</deviceType>
    <friendlyName>Blu-ray Disc Player</friendlyName>
    <manufacturer>Sony Corporation</manufacturer>
    <manufacturerURL>http://www.sony.net/</manufacturerURL>
    <modelName>Blu-ray Disc Player</modelName>
    <UDN>uuid:00000000-0000-1010-8000-f0bf97fa548e</UDN>
    <dlna:X_DLNADOC xmlns:dlna="urn:schemas-dlna-org:device-1-0">DMR-1.50</dlna:X_DLNADOC>
    <dlna:X_DLNACAP xmlns:dlna="urn:schemas-dlna-org:device-1-0">playcontainer-1-0</dlna:X_DLNACAP>
    <iconList>
      <icon>
        <mimetype>image/jpeg</mimetype>
        <width>120</width>
        <height>120</height>
        <depth>24</depth>
        <url>/bdp_6g_b_c_device_icon_large.jpg</url>
      </icon>
      <icon>
        <mimetype>image/png</mimetype>
        <width>120</width>
        <height>120</height>
        <depth>24</depth>
        <url>/bdp_6g_b_c_device_icon_large.png</url>
      </icon>
      <icon>
        <mimetype>image/jpeg</mimetype>
        <width>48</width>
        <height>48</height>
        <depth>24</depth>
        <url>/bdp_6g_b_c_device_icon_small.jpg</url>
      </icon>
      <icon>
        <mimetype>image/png</mimetype>
        <width>48</width>
        <height>48</height>
        <depth>24</depth>
        <url>/bdp_6g_b_c_device_icon_small.png</url>
      </icon>
    </iconList>
    <serviceList>
      <service>
        <serviceType>urn:schemas-upnp-org:service:RenderingControl:1</serviceType>
        <serviceId>urn:upnp-org:serviceId:RenderingControl</serviceId>
        <SCPDURL>/RenderingControlBdpSCPD.xml</SCPDURL>
        <controlURL>/upnp/control/RenderingControl</controlURL>
        <eventSubURL>/upnp/event/RenderingControl</eventSubURL>
      </service>
      <service>
        <serviceType>urn:schemas-upnp-org:service:ConnectionManager:1</serviceType>
        <serviceId>urn:upnp-org:serviceId:ConnectionManager</serviceId>
        <SCPDURL>/ConnectionManagerSCPD.xml</SCPDURL>
        <controlURL>/upnp/control/ConnectionManager</controlURL>
        <eventSubURL>/upnp/event/ConnectionManager</eventSubURL>
      </service>
      <service>
        <serviceType>urn:schemas-upnp-org:service:AVTransport:1</serviceType>
        <serviceId>urn:upnp-org:serviceId:AVTransport</serviceId>
        <SCPDURL>/AVTransportSCPD.xml</SCPDURL>
        <controlURL>/upnp/control/AVTransport</controlURL>
        <eventSubURL>/upnp/event/AVTransport</eventSubURL>
      </service>
      <service>
        <serviceType>urn:schemas-sony-com:service:IRCC:1</serviceType>
        <serviceId>urn:schemas-sony-com:serviceId:IRCC</serviceId>
        <SCPDURL>/IRCCSCPD.xml</SCPDURL>
        <controlURL>/upnp/control/IRCC</controlURL>
        <eventSubURL></eventSubURL>
      </service>
      <service>
        <serviceType>urn:schemas-sony-com:service:Party:1</serviceType>
        <serviceId>urn:schemas-sony-com:serviceId:Party</serviceId>
        <SCPDURL>/PartySCPD.xml</SCPDURL>
        <controlURL>/upnp/control/Party</controlURL>
        <eventSubURL>/upnp/event/Party</eventSubURL>
      </service>
    </serviceList>
    <presentationURL></presentationURL>
    <av:X_IRCC_DeviceInfo xmlns:av="urn:schemas-sony-com:av">
      <av:X_IRCC_Version>1.0</av:X_IRCC_Version>
      <av:X_IRCC_CategoryList>
        <av:X_IRCC_Category>
          <av:X_CategoryInfo>AAMAABxa</av:X_CategoryInfo>
        </av:X_IRCC_Category>
      </av:X_IRCC_CategoryList>
    </av:X_IRCC_DeviceInfo>
    <av:X_UNR_DeviceInfo xmlns:av="urn:schemas-sony-com:av">
      <av:X_UNR_Version>1.2</av:X_UNR_Version>
      <av:X_CERS_ActionList_URL>http://192.168.20.114:50002/actionList</av:X_CERS_ActionList_URL>
    </av:X_UNR_DeviceInfo>
    <av:X_S2MTV_DeviceInfo xmlns:av="urn:schemas-sony-com:av">
      <av:X_S2MTV_Version>1.0</av:X_S2MTV_Version>
      <av:X_S2MTV_BaseURL>http://192.168.20.114:50003/</av:X_S2MTV_BaseURL>
    </av:X_S2MTV_DeviceInfo>
    <av:X_MaxBGMCount xmlns:av="urn:schemas-sony-com:av">64</av:X_MaxBGMCount>
    <av:X_StandardDMR xmlns:av="urn:schemas-sony-com:av">1.1</av:X_StandardDMR>
  </device>
</root>

http://192.168.20.114:50002/actionList:

<actionList>
  <action name="register" mode="1" url="http://192.168.20.114:50002/register"/>
  <action name="getText" url="http://192.168.20.114:50002/getText"/>
  <action name="sendText" url="http://192.168.20.114:50002/sendText"/>
  <action name="getContentInformation" url="http://192.168.20.114:50002/getContentInformation"/>
  <action name="getSystemInformation" url="http://192.168.20.114:50002/getSystemInformation"/>
  <action name="getRemoteCommandList" url="http://192.168.20.114:50002/getRemoteCommandList"/>
  <action name="getStatus" url="http://192.168.20.114:50002/getStatus"/>
  <action name="getHistoryList" url="http://192.168.20.114:50002/getHistoryList"/>
</actionList>
alexmohr commented 4 years ago

Do you have access to the Ircc.xml too?

brgerig commented 4 years ago

As far as I can tell, Ircc.xml just doesn't seem to exist on this player. I do have an IRCCSCPD.xml, though:

<?xml version="1.0"?>
<scpd xmlns="urn:schemas-upnp-org:service-1-0">
  <specVersion>
    <major>1</major>
    <minor>0</minor>
  </specVersion>

  <actionList>
    <action>
      <name>X_SendIRCC</name>
      <argumentList>
        <argument>
          <name>IRCCCode</name>
          <direction>in</direction>
          <relatedStateVariable>X_A_ARG_TYPE_IRCCCode</relatedStateVariable>
        </argument>
      </argumentList>
    </action>

    <action>
      <name>X_GetStatus</name>
      <argumentList>
        <argument>
          <name>CategoryCode</name>
          <direction>in</direction>
          <relatedStateVariable>X_A_ARG_TYPE_Category</relatedStateVariable>
        </argument>
        <argument>
          <name>CurrentStatus</name>
          <direction>out</direction>
          <relatedStateVariable>X_A_ARG_TYPE_CurrentStatus</relatedStateVariable>
        </argument>
        <argument>
          <name>CurrentCommandInfo</name>
          <direction>out</direction>
          <relatedStateVariable>X_A_ARG_TYPE_CurrentCommandInfo</relatedStateVariable>
        </argument>
      </argumentList>
    </action>
  </actionList>

  <serviceStateTable>
    <stateVariable sendEvents="no">
      <name>X_A_ARG_TYPE_IRCCCode</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>X_A_ARG_TYPE_Category</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>X_A_ARG_TYPE_CurrentStatus</name>
      <dataType>string</dataType>
    </stateVariable>
    <stateVariable sendEvents="no">
      <name>X_A_ARG_TYPE_CurrentCommandInfo</name>
      <dataType>string</dataType>
    </stateVariable>
  </serviceStateTable>
</scpd>
brgerig commented 4 years ago

Here's what Device Spy shows. It looks like the S580 runs Ircc on port 52323 with everything else, as opposed to the S590 which pots that on 50001 and everything else on 52323.

sony_transports

alexmohr commented 4 years ago

Interesting, probably it's enough to make the ports configurable to get it working

brgerig commented 4 years ago

I've made some progress!

I was able to register Home Assistant by wget-ing the registration URL. Then, I took the entry from sony.conf for my S590, did some editing, and put it back in for my S580 IP. Home Assistant now loads it in as a media_player, and correctly reads its state. I'm getting a 403: Forbidden on getRemoteCommandList, so I can't send any commands to it. Something I did wrong with registering it, maybe?

The relevant (cleaned up for my editing) changes to sony.conf:

  "api_version": 1,
  "app_port": 50202,
  "app_url": "http://192.168.20.114:50202",
  "apps": {},
  "av_transport_url": "http://192.168.20.114:52323/upnp/control/AVTransport",
  "base_url": "http://192.168.20.114/sony/",
  "client_id": "Sony Media Player",
  "commands": {},
  "control_url": "http://192.168.20.114:52323/upnp/control/IRCC",
  "cookies": null,
  "dmr_port": 52323,
  "dmr_url": "http://192.168.20.114:52323/dmr.xml",
  "headers": {},
  "host": "192.168.20.114",
  "ircc_port": 52323,
  "ircc_url": "http://192.168.20.114:52323/dmr.xml",
  "irccscpd_url": "http://192.168.20.114:52323/IRCCSCPD.xml",
  "mac": "00-a0-96-b4-e9-62",
  "nickname": "Sony Media Player",
  "pin": 9999,
  "psk": null
alexmohr commented 4 years ago

Probably something went wrong in the registration process but it's hard to tell what exactly.

Your test look very promising that it is enough to change the ports. I can adjust the media player component later so you can test properly.

brgerig commented 4 years ago

Just solved it!

This one needs: \"headers\":{\"X-CERS-DEVICE-ID\":\"Sony Media Player\"} in its config.

I can now successfully both monitor and send commands to my S580!

I'll be happy to deregister, delete the config, and test the process again once the code is ready.

alexmohr commented 4 years ago

The media player component has a new feature branch that implements the port configuration

brgerig commented 4 years ago

I tried the new version. Got the new sony/media_player.py (also manually updated the manifest to require sonyapilib==0.4.2). Manually pip upgraded sonyapilib to 0.4.2, deleted my registration on the bluray, and removed the entry from sony.conf. I also added ircc_port: 52323 to the yaml config for the S580. When I tried to register I got the following error: HTTPConnectionPool(host='192.168.20.114', port=50001): Max retries exceeded with url: /Ircc.xml So, it's still using port 50001 for ircc even though I overrode that in the config.

I located the problem with the ircc port: on line 140 of media_player.py: sony_device = SonyDevice(host, name, app_port, dmr_port, ircc_port) However, the device.py init is: def __init__(self, host, nickname, psk=None, app_port=50202, dmr_port=52323, ircc_port=50001): So since it's expecting a psk option for the 3rd parameter, which isn't being passed, the port numbers are getting shifted.

After fixing that, it still fails registration because it can't find Ircc.xml, since the S580 doesn't have that url anywhere. Instead, the important bits of the Ircc.xml are contained in the dmr.xml.

I 'fixed' that for mine by adding this code to my sonyapilib device.py:

        if self.ircc_port == self.dmr_port:
            self.ircc_url = self.dmr_url
        else:
            self.ircc_url = urljoin(ircc_base, "/Ircc.xml")

However, I don't at all know if that fix is any good universally!

Full stack trace:

2020-05-04 10:13:05 ERROR (SyncWorker_4) [sonyapilib.device] HTTPError: HTTPConnectionPool(host='192.168.20.114', port=50001): Max retries exceeded with url: /Ircc.xml (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fb046187eb0>: Failed to establish a new connection: [Errno 111] Connection refused'))
2020-05-04 10:13:05 ERROR (SyncWorker_4) [sonyapilib.device] failed to get device information: HTTPConnectionPool(host='192.168.20.114', port=50001): Max retries exceeded with url: /Ircc.xml (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fb046187eb0>: Failed to establish a new connection: [Errno 111] Connection refused'))
2020-05-04 10:13:05 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.140395310608336] Failed to read action list from device.
Traceback (most recent call last):
  File "/opt/homeassistant/lib/python3.8/site-packages/homeassistant/components/websocket_api/commands.py", line 125, in handle_call_service
    await hass.services.async_call(
  File "/opt/homeassistant/lib/python3.8/site-packages/homeassistant/core.py", line 1247, in async_call
    task.result()
  File "/opt/homeassistant/lib/python3.8/site-packages/homeassistant/core.py", line 1282, in _execute_service
    await handler.func(service_call)
  File "/opt/homeassistant/lib/python3.8/site-packages/homeassistant/components/configurator/__init__.py", line 235, in async_handle_service_call
    await self.hass.async_add_job(callback, call.data.get(ATTR_FIELDS, {}))
  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/homeassistant/.homeassistant/custom_components/sony/media_player.py", line 147, in sony_configuration_callback
    register_result = sony_device.register()
  File "/opt/homeassistant/lib/python3.8/site-packages/sonyapilib/device.py", line 571, in register
    registration_action = registration_action = self._get_action(
  File "/opt/homeassistant/lib/python3.8/site-packages/sonyapilib/device.py", line 489, in _get_action
    raise ValueError('Failed to read action list from device.')
ValueError: Failed to read action list from device.

I apologize for not doing this via PRs... I'm not really a programmer, and don't actually know how to use github the right way.

brgerig commented 4 years ago

A couple other things: Registering a second device now seems to overwrite the sony.conf file instead of adding to it, so I can only have one device whose registration persists through restarts.

Despite both of my players having a registration mode == 1, they both need \"headers\": {\"X-CERS-DEVICE-ID\": \"[name]\" in their configs.

alexmohr commented 4 years ago

Thanks for your feedback I'll fix these issue as soon as possible.

Your proposed fix for the port issue seems good enough. Not using the constructor correctly is stupid, but i've added an option to add the psk too.

The inclusion of the header should not break the compatibility with mode 2 or other devices.

I think the registration process of the media player never supported multiple devices. Did you give the devices unique names?

I'd like to add the ports properly to the readme you are using 52323 | 50202 | 50202 for app | dmr | ircc is this correct?

brgerig commented 4 years ago

Previously, my sony.conf had two entries, 1 for each IP address. They do have unique names.

On the S580, the ports are:

app     | dmr    | ircc
50202 | 52323 | 52323

However, neither the S580 or the S590 support anything having to do with the app stuff.

Also, because I'm bored, I'm playing around and trying to see if I can get this working with config flow and SSDP discovery (despite not really knowing what I'm doing!). If I get anywhere with that, I'll actually fork the project and start trying to figure out how to properly do pull requests and stuff.

alexmohr commented 4 years ago

@brgerig Do you have any news on your last comment? Did you make progress or did you get it to work?

alexmohr commented 4 years ago

Closing this due to inactivity

brgerig commented 4 years ago

I unfortunately wasn't able to make any progress on it.