Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PyOhNet and generated proxies
08-01-2017, 11:52 PM (This post was last modified: 09-01-2017 06:07 AM by Latka.)
Post: #1
PyOhNet and generated proxies
Hi,

I have used the GenProxy class in PyOhNet to generate files with proxies (from SCPD xml files from a device on my network).

In order to use these proxies with PyOhNet to invoke actions and subscribe to services, where do I put them? Do I import them or do they become part of PyOhNet? Is there anything else that is needed to do to make everything work?

Thanks!!
Find all posts by this user
09-01-2017, 09:26 PM (This post was last modified: 09-01-2017 09:28 PM by Latka.)
Post: #2
RE: PyOhNet and generated proxies
To be a bit more specific,
This is what I've done:

I imported the generated proxy .py file
Then initialize a device instance like this
But when I try to invoke an action or subscribe to an event, I get the following:
Proxy error - 1: Unknown

What am I missing?

Code:
from MusicServices_1 import CpProxySchemasUpnpOrgMusicServices1
device.Start()
proxy = CpProxySchemasUpnpOrgMusicServices1(device)
response = proxy.SyncListAvailableServices()
print response
>>> Proxy error - 1: Unknown
Find all posts by this user
10-01-2017, 02:30 PM
Post: #3
RE: PyOhNet and generated proxies
(09-01-2017 09:26 PM)Latka Wrote:  To be a bit more specific,
This is what I've done:

I imported the generated proxy .py file
Then initialize a device instance like this
But when I try to invoke an action or subscribe to an event, I get the following:
Proxy error - 1: Unknown

What am I missing?

Code:
from MusicServices_1 import CpProxySchemasUpnpOrgMusicServices1
device.Start()
proxy = CpProxySchemasUpnpOrgMusicServices1(device)
response = proxy.SyncListAvailableServices()
print response
>>> Proxy error - 1: Unknown

OK - I think there is some confusion here.....

When using PyOhNet you do not require knowledge of the underlying proxies. They are generated internally when the device is started, at which point they are exposed for use. You should not use GenProxy.py, and you do not need to know about the ..Proxy..py files - these are not available unless you have turned the debugging feature on to output them to disk (they normally remain in memory and are never written out).

As for your example - note that a proxy is generated for a service.
The example indicates that you have a service (singular) called MusicServices (plural) which contains an action called ListAvailableServices. Is it really the case that you have a service with an action to list available services ??? If you need to know the available services, that can be pulled from the device (via device XML)

The example in PyOhNet/Test directory called TestControlEventing.py shows how to create a device and access a service. There is a legacy error in this which I will outline below (and fix so that it will become available when ohNet is next published), but once that is fixed this example works. I was running on Windows, and using the TestDvTestBasic.exe device which is built with ohNet - if you need a copy of this (unable to build it yourself) then let me know.

Change required to TestControlEventing.py
Code:
line 44:
change
            self.testBasic = dev.testBasic
to
            self.testBasic = dev.OpenhomeOrgTestBasic

Expected output when running TestControlEventing.py
Code:
Device _ohNetTestDevice (device-ohNetTestBasic)
  ProxyOpenhomeOrgTestBasic1
    Actions:
      Increment:
        Inputs:
          Value (Uint)
        Outputs:
          Result (Uint)
      EchoAllowedRangeUint:
        Inputs:
          Value (Uint)
        Outputs:
          Result (Uint)
      Decrement:
        Inputs:
          Value (Int)
        Outputs:
          Result (Int)
      Toggle:
        Inputs:
          Value (Bool)
        Outputs:
          Result (Bool)
      EchoString:
        Inputs:
          Value (String)
        Outputs:
          Result (String)
      EchoAllowedValueString:
        Inputs:
          Value (String)
        Outputs:
          Result (String)
      EchoBinary:
        Inputs:
          Value (Binary)
        Outputs:
          Result (Binary)
      SetUint:
        Inputs:
          ValueUint (Uint)
        Outputs:
      GetUint:
        Inputs:
        Outputs:
          ValueUint (Uint)
      SetInt:
        Inputs:
          ValueInt (Int)
        Outputs:
      GetInt:
        Inputs:
        Outputs:
          ValueInt (Int)
      SetBool:
        Inputs:
          ValueBool (Bool)
        Outputs:
      GetBool:
        Inputs:
        Outputs:
          ValueBool (Bool)
      SetMultiple:
        Inputs:
          ValueUint (Uint)
          ValueInt (Int)
          ValueBool (Bool)
        Outputs:
      GetMultiple:
        Inputs:
        Outputs:
          ValueUint (Uint)
          ValueInt (Int)
          ValueBool (Bool)
      SetString:
        Inputs:
          ValueStr (String)
        Outputs:
      GetString:
        Inputs:
        Outputs:
          ValueStr (String)
      SetBinary:
        Inputs:
          ValueBin (Binary)
        Outputs:
      GetBinary:
        Inputs:
        Outputs:
          ValueBin (Binary)
      WriteFile:
        Inputs:
          Data (String)
          FileFullName (String)
        Outputs:
      Shutdown:
        Inputs:
        Outputs:
    Properties:
      VarUint
      VarInt
      VarBool
      VarStr
      VarBin
  ProxyOpenhomeOrgSubscriptionLongPoll1
    Actions:
      Subscribe:
        Inputs:
          ClientId (String)
          Udn (String)
          Service (String)
          RequestedDuration (Uint)
        Outputs:
          Sid (String)
          Duration (Uint)
      Unsubscribe:
        Inputs:
          Sid (String)
        Outputs:
      Renew:
        Inputs:
          Sid (String)
          RequestedDuration (Uint)
        Outputs:
          Duration (Uint)
      GetPropertyUpdates:
        Inputs:
          ClientId (String)
        Outputs:
          Updates (String)
    Properties:

['OpenhomeOrgSubscriptionLongPoll', 'OpenhomeOrgTestBasic', 'Shutdown', 'Start', '_AddProxy', '_GetAttribute', '_GetDeviceXml', '_GetFriendlyName', '_GetLocatio
n', '_GetServices', '_GetUdn', '__doc__', '__init__', '__module__', '__str__', 'deviceXml', 'friendlyName', 'handle', 'lib', 'location', 'proxies', 'udn']

Subscribe to service
EVENT VarBin: []
EVENT VarBool: False
EVENT VarInt: 0
EVENT VarStr:
EVENT VarUint: 0
EVENT Any
EVENT Init Event
    VarUint: 0
    VarInt:  0
    VarBool: False
    VarStr:
    VarBin : []

SyncSetUint (57921) returned --> NoneEVENT VarUint:
57921
EVENT Any
SyncGetUint returned --> 57921
Waiting for Uint event
++PASS++  Set VarUint to 57921, Get returned 57921
++PASS++  Set VarUint to 57921, Event returned 57921

SyncSetIint (18460) returned --> None
EVENT VarInt: 18460
EVENT Any
SyncGetInt returned --> 18460
Waiting for Int event
++PASS++  Set VarInt to 18460, Get returned 18460
++PASS++  Set VarInt to 18460, Event returned 18460

SyncSetBool (False) returned --> None
SyncGetBool returned --> False
Waiting for Bool event
++PASS++  Set VarBool to False, Get returned False

SyncSetString (Tue Jan 10 13:24:20 2017) returned --> None
EVENT VarStr: Tue Jan 10 13:24:20 2017
EVENT Any
SyncGetString returned --> Tue Jan 10 13:24:20 2017
Waiting for String event
++PASS++  Set VarString to Tue Jan 10 13:24:20 2017, Get returned Tue Jan 10 13:24:20 2017
++PASS++  Set VarString to Tue Jan 10 13:24:20 2017, Event returned Tue Jan 10 13:24:20 2017
EVENT VarBin:
SyncSetBinary ([22, 0, 217, 0, 3, 0]) returned --> None[
22, 0, 217, 0, 3, 0]
EVENT Any
SyncGetBinary returned --> [22, 0, 217, 0, 3, 0]
Waiting for Binary event
++PASS++  Set VarBin to [22, 0, 217, 0, 3, 0], Get returned [22, 0, 217, 0, 3, 0]
++PASS++  Set VarBin to [22, 0, 217, 0, 3, 0], Event returned [22, 0, 217, 0, 3, 0]

SyncSetMultiple (61686, 61004, True) returned --> None
EVENT VarBool: True
EVENT VarInt: 61004
EVENT VarUint: 61686
EVENT Any
SyncGetMultiple returned --> {'ValueBool': True, 'ValueInt': 61004, 'ValueUint': 61686}
SyncGetUint returned --> 61686
SyncGetInt returned --> 61004
SyncGetBool returned --> True
Waiting for ANY event
++PASS++  Set Multiple:VarUint to 61686, Get returned 61686
++PASS++  Set Multiple:VarUint to 61686, Event returned 61686
++PASS++  Set Multiple:VarInt to 61004, Get returned 61004
++PASS++  Set Multiple:VarInt to 61004, Event returned 61004
++PASS++  Set Multiple:VarInt to True, Get returned True

SyncIncrement (42) returned --> 43
++PASS++  SyncIncrement set to 42 returned 43

SyncDecrement (667) returned --> 666
++PASS++  SyncDecrement set to 667 returned 666

SyncToggle (True) returned --> False
++PASS++  SyncToggle set to True returned False

SyncEchoString (Echo..) returned --> Echo..
++PASS++  SyncEchoString set to Echo.. returned Echo..

SyncEchoBinary ([0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0]) returned --> [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0]
++PASS++  SyncEchoBinary set to [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0] returned [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0]

Unsubscribe from service - no further events monitored

SyncEchoAllowedRangeUint (12) returned --> 12
SyncEchoAllowedValueString (One) returned --> One
SyncWriteFile returned --> None

*** PASSED ***
Find all posts by this user
10-01-2017, 02:54 PM (This post was last modified: 10-01-2017 04:48 PM by Latka.)
Post: #4
RE: PyOhNet and generated proxies
Hi rockfather,

Thanks for your reply!

Quote:As for your example - note that a proxy is generated for a service.
The example indicates that you have a service (singular) called MusicServices (plural) which contains an action called ListAvailableServices. Is it really the case that you have a service with an action to list available services ??? If you need to know the available services, that can be pulled from the device (via device XML)
Yes I realize what you're getting at with your comment. However, this is an actual service and action taken from a Sonos device. I Believe a call to ListAvailableServices should return a list of available services like Spotify, TuneIn etc. that the device supports.

Also, I understand the way actions are supposed to be called and subscriptions made with PyOhNet from your previous replies, it works a treat with my Linn devices Tongue (I have written large parts of my application on my Raspberry Pi, and it works great, but I would like to extend functionality to certain other devices as well) Sorry for not being clear here. I can't get my head around how to properly implement custom generated proxies. I realize that my handling of the generated proxies is flawed Huh Cool

So where would I put the generated .py file that contains the new proxies (and otherwise treat them?), so that actions and subscriptions can be called/subscribed in the same way as the built in Openhome proxies?

Thanks a lot for your help Smile

EDIT: I mean proxies generated using GenProxy class and the Write method
Find all posts by this user
11-01-2017, 01:02 PM
Post: #5
RE: PyOhNet and generated proxies
(10-01-2017 02:54 PM)Latka Wrote:  So where would I put the generated .py file that contains the new proxies (and otherwise treat them?), so that actions and subscriptions can be called/subscribed in the same way as the built in Openhome proxies?

Thanks a lot for your help Smile

EDIT: I mean proxies generated using GenProxy class and the Write method

The design of PyOhNet means that you do NOT have to worry about any proxies. These are automatically generated at run-time from the device/service XML and are immediately available for your use.

Taking your example, I would expect the following to work
Code:
device.Start()
m = device.SchemasUpnpOrgMusicServices
response = m.SyncListAvailableServices()
print response

You can check what is available using the 'dir' command
Code:
device.Start()
print dir( device)
m = device.SchemasUpnpOrgMusicServices
print dir( m )
Find all posts by this user
11-01-2017, 10:43 PM (This post was last modified: 11-01-2017 10:47 PM by Latka.)
Post: #6
RE: PyOhNet and generated proxies
Thank you very much rockfather! Everything is working now. I had no idea that PyOhNet generates proxies at runtime. That is so clever!

From reading up on OhNet I drew the conclusion that any other proxies than the ones from OpenHome had to be generated in advance. That was obviously wrong.

Regarding the Proxy Error -1 Unknown i reported in my first post, it seems to be related to the Sonos device I borrowed from my friend. It reports 3 different upnp devices and I seem to have targeted the wrong one when I got that message.
Find all posts by this user
12-01-2017, 02:01 PM
Post: #7
RE: PyOhNet and generated proxies
(11-01-2017 10:43 PM)Latka Wrote:  Thank you very much rockfather! Everything is working now. I had no idea that PyOhNet generates proxies at runtime. That is so clever!

From reading up on OhNet I drew the conclusion that any other proxies than the ones from OpenHome had to be generated in advance. That was obviously wrong.

Regarding the Proxy Error -1 Unknown i reported in my first post, it seems to be related to the Sonos device I borrowed from my friend. It reports 3 different upnp devices and I seem to have targeted the wrong one when I got that message.

Glad you got it working
Find all posts by this user


Forum Jump: