StevenLooman / async_upnp_client

Async UPnP Client for Python
Other
46 stars 37 forks source link

Accessing service description from UpnpDevice #24

Closed rytilahti closed 5 years ago

rytilahti commented 5 years ago

Hi Steven,

it would be nice if there would be a way to access the XML tree of the parsed device description. In my case I would like to access some custom elements (see https://github.com/rytilahti/python-songpal/blob/master/songpal/main.py#L180). Do you think it'd be feasible to pass the parsed tree onwards to UPnpDevice?

StevenLooman commented 5 years ago

Certainly. Also, I'll store it on to the UpnpService and other relevant parts (UpnpActions/UpnpStateVariables).

I think you want to parse the additional properties. I'm thinking if we shouldn't (also) parse these in async_upnp_client and store these. What do you think, and how would you like to see this?

rytilahti commented 5 years ago

I think one way would be to store the encountered, non-standard elements into a parsed extras (better-naming-wanted(tm)) dictionary of the corresponding class (UPnPDevice, UPnPService, ..).

So on songpal's end the call would look something like:

info = device.extras["av:X_ScalarWebAPI_DeviceInfo"]
endpoint = info["av:X_ScalarWebAPI_BaseURL"]

for

  <device>
  ....
    <av:X_ScalarWebAPI_DeviceInfo>
      <av:X_ScalarWebAPI_Version>1.0</av:X_ScalarWebAPI_Version>
      <av:X_ScalarWebAPI_BaseURL>http://192.168.xx:10000/sony</av:X_ScalarWebAPI_BaseURL>
      <av:X_ScalarWebAPI_ServiceList>
        <av:X_ScalarWebAPI_ServiceType>guide</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>system</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>audio</av:X_ScalarWebAPI_ServiceType>
        <av:X_ScalarWebAPI_ServiceType>avContent</av:X_ScalarWebAPI_ServiceType>
      </av:X_ScalarWebAPI_ServiceList>
    </av:X_ScalarWebAPI_DeviceInfo>
  ....
  </device>

Or would it even make sense to store the whole parse-tree as such (and provide those existing shortcuts based on that)? device.parsed["friendlyName"], device.data["UDN"] etc?

I think it's your call what's the most sane way to do this, I'd be perfectly happy with any solution that lets me read that data out without reparsing it myself :-)

StevenLooman commented 5 years ago

Not sure how far we should take this, so for now I'll just store an attribute called xml at the relevant objects. Please check https://github.com/StevenLooman/async_upnp_client/commit/4e490f07c19bef683ffbf90807f8c82fbe3dd968 and let me know if this is usable to you.

If so, do you want me to release 0.13.5?

rytilahti commented 5 years ago

Ok, that's fine, too. I experimented with it a bit (https://github.com/rytilahti/python-songpal/pull/35) and stumbled upon a couple of things:

Anyway, a new release including the exposed xml would be great!

StevenLooman commented 5 years ago

Are you looking for this, with regard to point two?

xmlstr = ElementTree.tostring(xml, encoding='utf8', method='xml')
rytilahti commented 5 years ago

Oops, yes, that's what I was using already (the pretty-printing part was caused by printing out bytes instead of a string). It does seem to mangle the namespaces (uses ns[0-9] instead of the original ones), but it's just debug info so that's fine.

StevenLooman commented 5 years ago

Released 0.13.5.

modelNumber is not included though... next release.

StevenLooman commented 5 years ago

Released 0.13.6.

modelNumber and some friends are now exposed.

StevenLooman commented 5 years ago

Closing the issue. If there is anything else please let me know.

rytilahti commented 5 years ago

Thanks, that'll clean up my parsing code a bit (no need to define the 'device' namespace nor parse it separately)!

StevenLooman commented 5 years ago

Thank you for the review.