Some q's re SoCo and always-running applications.

42 views
Skip to first unread message

Barry4679

unread,
Apr 22, 2020, 10:54:11 AM4/22/20
to SoCo - Sonos Controller
I am looking at writing an always-running app to observe my Sonos units. SoCo looks good for this purpose.
Is SoCo safe for a always-running app? ... Has it ever been used in this mode?

What is the recommended way to handle a situation where Sonos zones newly appear, or go missing from the network while my app is running? Or a zone changes its "visibility" state?

I was hoping for something like NewDevice and LostDevice events, which I could subscribe to.

Is a SoCo UPnP event subscription, at the whole Sonos household, or at the individual zone level? I am presuming that it is at the device level, right?

If a Sonos device leaves the network. is there anything that I need do regarding events that I had already subscribed to, for that zone? ... eg. unsubscribe, or do something to your subscription_map object?

A see the section titled "Autorenew failure, here http://docs.python-soco.com/en/latest/advanced/events.html.

The function's comment mentions the twisted module.
I was not planing upon using twisted.

Is Autorenew failure option available in soco.events mode? Does the exception identify the zone which failed to auto-renew? 

"This function must be threadsafe (unless soco.events_twisted is being used)." .
 I am not yet sure whether this is a household-wide option, or is it set for each Sonos zone? ... Assuming that it is per Sonos device, is it OK if all zones callback a single common function, which just posts an entry onto a single queue?

thanks for SoCo, and for the great documentation.  
 


 

Barry4679

unread,
Apr 30, 2020, 10:21:05 AM4/30/20
to SoCo - Sonos Controller
Have made some progress, so my questions have changed.
I found that recognising lost or new zones is made easy by the fact that the SoCo object is a set,, ie. use set differences function. ... That's nice :)
I have my eval app subscribing to my Sonos zones, and recognising new and lost Sonos zones.

I am currently making everything thread safe, and crash testing by turning my zones off and on.

I have some difficulty if I turn a zone off just before I start my app. Sometimes the powered down zone happens to coincide with the zone which Sonos has decided should be the one that responds to the SoCo discovery function.
When this happens, there is along delay before SoCp returns to my app following my call to discovery.

In the meantime I  see a series of error from the utility libraries that SoCo uses:
  • TimeoutError
  • urllib3.exceptions.NewConnectionError
  • urllib3.exceptions.MaxRetryError
  • and requests.exceptions.ConnectionError 
A repeat call of the discovery function gives exactly the same result. ... It only gets fixed if I re-power the Sonos zone, which was powered off before my app starts btw.

If I power down a Sonos zone, after my app has started, there is a long delay before SoCo notices that the zone is missing. ... I haven't measured yet, but I guess that it could be around half an hour.
It is good that the SoCo discovery call responds so quickly, but the slow detection of a lost zone is not so good. ... Could you also have the option of a more expensive, but more thorough type of discovery?

When the device is powered off, it device within the SoCo set becomes damaged. device.ip_address responds Ok, but any attempt to access anything deeper, eg. the device.player_name property, raises the slow series of exceptions listed above.

Is there a way that my app could check that a specific SoCo device instance is damaged, because there is a longish delay using a try except block.

thanks.


Barry4679

unread,
May 11, 2020, 11:15:35 AM5/11/20
to SoCo - Sonos Controller
I have had some time to get back to this, so am answering my own question again.

I now see that the problem is different to what I described.
    • I power down a Sonos zone
    • and then a few minutes later, I start my app which does a SoCo discovery
    • the SoCo discovery generates exceptions into the log, and returns OK, but the set object contains a device member for the powered down device, because it was included it in the zoneGroupTopology response that SoCo read
    • I try to subscribe to this dead device, and subscription fails after timeout
    • I try to output a message to the log re the subscription failure ... the message contains ip_address and player_name
    • SoCO knows both of these things because they were in the zoneGroupTopology response
    • but if I try to read from the device.player name property, Soco tries to read from the device again, which throws me back into the same 3 nested exceptions from Requests and urllib3 ... and another timeout delay
    • I can workaround the problem by reading your private variable instead of the player_name property ... ie use device._player_name instead  
    Questions:
    1. SoCo knew that the device was AWOL before sending me it in the SoCo object ... ie. you got exceptions ... is there any property where I can see that, before trying to access its player_name property? Or can you exclude it from the SoCo set?
    2. Could there be a player-name property that doesn't trigger a re-read from Sonos ... in this situation I am able to access the Ip_address property, but not player_name, even though both are known to you? .

    thanks
    Reply all
    Reply to author
    Forward
    0 new messages