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

SoCo seems not work if there are more than 24 Sonos devices in one household #935

Closed
tomhht opened this issue Nov 15, 2022 · 12 comments
Closed
Assignees

Comments

@tomhht
Copy link

tomhht commented Nov 15, 2022

Hi,
My English is poor, any inconvenience caused is regretted.
SoCo could do nothing when there are more than 24 devices in one household. The discover feature would fail, throwing SoCoUPnPException. None is contactable (soco.discovery.contactable).
I'm not sure if I missed some answers about it. Have you ever met this?

Cheers
Tom

@pwt pwt self-assigned this Nov 15, 2022
@pwt
Copy link
Contributor

pwt commented Nov 15, 2022

I haven't seen this reported before. Could you try discovery using:

soco.discovery.scan_network()

and see what that returns? Thanks.

It's possible we may need to do something specific to handle large populations of speakers; perhaps Sonos works differently for large systems.

In the meantime, if you know the IP address of a speaker, you can circumvent discovery by creating a SoCo object directly, e.g.:

from soco import SoCo
speaker = SoCo("192.168.0.50")
zones = speaker.all_zones

@amelchio
Copy link
Contributor

It's possible we may need to do something specific to handle large populations of speakers; perhaps Sonos works differently for large systems.

#518 (comment)

@tomhht
Copy link
Author

tomhht commented Nov 15, 2022

@pwt
Probably I have exactly the same issue as that @amelchio mentioned. soco.discover soco.discovery.scan_network and creating SoCo object directly all throw soco.exceptions.SoCoUPnPException: UPnP Error 501 received: Action Failed from 192.168.1.5.

Many thanks to you both.

I'm fresh meat here, so not sure if I should close this issue? Since it seems no update regarding #518 for now.

@pwt
Copy link
Contributor

pwt commented Nov 15, 2022

I'm fresh meat here, so not sure if I should close this issue? Since it seems no update regarding #518 for now.

Hi @tomhht : Thanks for checking. Leave it open for now. I'll take a look when I get a bit of time, and reconcile the two issues.

The issue I'll face is that I won't be able to test any solutions, since I don't have the required population of speakers. You may be able to help with testing.

@tomhht
Copy link
Author

tomhht commented Nov 16, 2022

@pwt
I'm glad if I could be helpful.

@jjlawren
Copy link
Contributor

(Cross-posting from home-assistant/core#82513 (comment))

Based on nothing but a hunch, I'm wondering if there's a limitation in the Sonos firmware which causes it to fail when ZoneGroupState payloads exceed some set size. Since it seems like the native Sonos app can get away without polling this endpoint, perhaps the subscription callbacks don't have this limitation.

I wrote a quick script to test this theory: https://gist.github.com/jjlawren/0489bca6701e62c4da52ff39fe7410b9. It requires soco installed along with Python 3.8+. Replace the IP in the script with one of your own Sonos devices and simply run as python zgs_test.py.

If you have a large Sonos network and see the 501 error frequently, please try this and report back. And for extra credit if the polling fails, try to group your speakers into large groups and try again. I believe this should reduce the payload size and perhaps will allow it to succeed.

pwt added a commit to pwt/SoCo that referenced this issue Dec 18, 2022
@pwt
Copy link
Contributor

pwt commented Dec 18, 2022

Thanks @jjlawren. It would be great to have a fix for this.

I tried your script on my Sonos systems (neither of which has more than ten players), and both ZGS variants worked.

So, I've created a tentative PR that does a simple fallback to using events if a player throws an error when interrogated for its ZGS. It works on my systems if I force the exception: #937.

@pwt
Copy link
Contributor

pwt commented Dec 19, 2022

Hi @tomhht: Just wondering whether you'd be able to test my in-progress PR (#937) on your system? You can use something like:

pip install "git+https://github.com/SoCo/SoCo@refs/pull/937/head"

(Note that this requires git to be installed.)

@tomhht
Copy link
Author

tomhht commented Dec 21, 2022 via email

@cmaglio
Copy link

cmaglio commented Dec 23, 2022

(Cross-posting from home-assistant/core#82513)

For anyone following this thread, I was able to use @jjlawren 's test script to reproduce the UPnP 501 errors and this is what I found:

After a lot of trial and error... I think @jjlawren is on to something with the payload size being the determining factor causing the UPnP 501 error. I tried many different configurations to get different payload sizes and whenever the payload was 16403 or above, polling ZGS would fail, and I would get the UPnP 501. If the payload was 16313 or lower, polling ZGS would succeed and no error. I don't know exactly what the max payload for polling is, but it is somewhere between 16314 and 16403. These results are very repeatable, I can change the system configuration by one Sonos device to either go above or drop below these values and the polling either fails or succeeds based on the payload size of the polling callback. Of course, I tried many other payload sizes above and below the range here (with the same results), but here is the relevant data to determine max payload of the polling callback:

15487 Success
15996 Success
16313 Success
16403 Fail
16418 Fail
16594 Fail
16608 Fail
16823 Fail

One other note on this, I think the reason I was able to power cycle the system and then use the HA integration for a while is that if all the Sonos devices get powered off and then powered on again, the payload size is going to be effectively "reset". It will take time for the system to rebuild and for the payload to get above ~16313, so I believe I was just seeing the integration working while Sonos was rebuilding it's network. Once the payload got above that max size, I would start seeing those UPnP 501 errors again.

Also, the subscription callbacks never fail regardless of payload size... only polling ZGS fails above a max payload that is somewhere between 16314 and 16403.

@jjlawren
Copy link
Contributor

Thanks @cmaglio for the very thorough testing! These results are starting to make sense of the situation.

That tipping point range is interesting as 16384 is right in the middle of it. That seems to imply a 16K buffer is backing this operation. Once that's filled up it aborts and throws the 501 error.

The results also show that the subscription callbacks do not seem to have this limitation and should be reliable. However subscriptions are a bit trickier to work with and don't succeed in every network setup, so we'll need to be careful relying on them.

@pwt
Copy link
Contributor

pwt commented Jan 7, 2023

Please try out the changes included in SoCo v0.29.0 (https://github.com/SoCo/SoCo/releases/tag/v0.29.0). It would be good to know if the changes are effective or not. Thanks!

@pwt pwt closed this as completed Jan 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants