question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

discover() fails when sonos device gets unplugged

See original GitHub issue

Discover fails with the following traceback when a previously discovered sonos device gets unplugged:

Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.7/site-packages/urllib3/connection.py", line 170, in _new_conn
    (self._dns_host, self.port), self.timeout, **extra_kw
  File "/home/pi/.local/lib/python3.7/site-packages/urllib3/util/connection.py", line 96, in create_connection
    raise err
  File "/home/pi/.local/lib/python3.7/site-packages/urllib3/util/connection.py", line 86, in create_connection
    sock.connect(sa)
OSError: [Errno 113] No route to host

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 706, in urlopen
    chunked=chunked,
  File "/home/pi/.local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 394, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/home/pi/.local/lib/python3.7/site-packages/urllib3/connection.py", line 234, in request
    super(HTTPConnection, self).request(method, url, body=body, headers=headers)
  File "/usr/lib/python3.7/http/client.py", line 1260, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/usr/lib/python3.7/http/client.py", line 1306, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.7/http/client.py", line 1255, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/usr/lib/python3.7/http/client.py", line 1030, in _send_output
    self.send(msg)
  File "/usr/lib/python3.7/http/client.py", line 970, in send
    self.connect()
  File "/home/pi/.local/lib/python3.7/site-packages/urllib3/connection.py", line 200, in connect
    conn = self._new_conn()
  File "/home/pi/.local/lib/python3.7/site-packages/urllib3/connection.py", line 182, in _new_conn
    self, "Failed to establish a new connection: %s" % e
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0xb18b4070>: Failed to establish a new connection: [Errno 113] No route to host

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/pi/.local/lib/python3.7/site-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/home/pi/.local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 756, in urlopen
    method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
  File "/home/pi/.local/lib/python3.7/site-packages/urllib3/util/retry.py", line 574, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='192.168.178.120', port=1400): Max retries exceeded with url: /xml/ZoneGroupTopology1.xml (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xb18b4070>: Failed to establish a new connection: [Errno 113] No route to host'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "src/__main__.py", line 63, in <module>
    asyncio.run(main())
  File "/usr/lib/python3.7/asyncio/runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "src/__main__.py", line 39, in main
    networking.initial_check(),
  File "src/balancing/manager.py", line 30, in start_discovery
    await self.sonos.discover_loop()
  File "src/balancing/sonos.py", line 25, in discover_loop
    speakers = self.sonos_adapter.discover()
  File "src/sonos/adapter_soco.py", line 29, in discover
    name = speaker.player_name
  File "/home/pi/.local/lib/python3.7/site-packages/soco/core.py", line 321, in player_name
    self._parse_zone_group_state()
  File "/home/pi/.local/lib/python3.7/site-packages/soco/core.py", line 1194, in _parse_zone_group_state
    zgs = self.zoneGroupTopology.GetZoneGroupState(cache=self._zgs_cache)[
  File "/home/pi/.local/lib/python3.7/site-packages/soco/services.py", line 207, in _dispatcher
    return self.send_command(action, *args, **kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/soco/services.py", line 467, in send_command
    args = self.compose_args(action, kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/soco/services.py", line 334, in compose_args
    for action in self.actions:
  File "/home/pi/.local/lib/python3.7/site-packages/soco/services.py", line 664, in actions
    self._actions = list(self.iter_actions())
  File "/home/pi/.local/lib/python3.7/site-packages/soco/services.py", line 691, in iter_actions
    scpd_body = requests.get(self.base_url + self.scpd_url, timeout=10).content
  File "/home/pi/.local/lib/python3.7/site-packages/requests/api.py", line 76, in get
    return request('get', url, params=params, **kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/requests/api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/requests/sessions.py", line 655, in send
    r = adapter.send(request, **kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/requests/adapters.py", line 516, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='192.168.178.120', port=1400): Max retries exceeded with url: /xml/ZoneGroupTopology1.xml (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xb18b4070>: Failed to establish a new connection: [Errno 113] No route to host'))

It might have something to do with the following comment I found in the source:

                    # Now we have an IP, we can build a SoCo instance and query
                    # that player for the topology to find the other players.
                    # It is much more efficient to rely upon the Zone
                    # Player's ability to find the others, than to wait for
                    # query responses from them ourselves.

Is it possible that soco fails with the discovery because it trusts the other Sonos device (which is still plugged in) and which provides outdated topology data?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
pwtcommented, May 19, 2021

@ItsEcholot If you have time to review it, the new contactable() function PR is #834.

1reaction
pwtcommented, May 18, 2021

I now understand the technological reasoning behind this but I just think this isn’t what most users (including me) are expecting. When I receive a SoCo instance from the discovery process I of course assume that this instance has already been successfully contacted (how else would it have been discovered? I now know how but do others?).

Yes, you’re probably right about this.

The Sonos App also doesn’t list unavailable speakers and it seems that opening the app actually forces the Sonos System to update it’s internal topology cache… Not 100% sure on this one though, would have to investigate this further.

Same here … not sure about that, but it’s plausible.

So either the documentation should have a prominent note about this or we could check if the instance can actually be contacted before returning it in discovery. If this carries too much of a performance penalty we could add a discovery parameter that when set to true only returns “confirmed” instances. What is your opinion on this?

Adding a note to the documentation seems prudent. I’ll take a look at that.

The problem with checking for contact-ability at the point of discovery is that a speaker may only be offline briefly (e.g., off the network temporarily, or being rebooted). Conversely, a speaker’s connectivity state can change at any time, so checking it at the point of discovery doesn’t guarantee it will be accessible at a later time.

We could add a simple presence-checker function that takes a set of SoCo objects and returns only the ones that are contactable at that point in time. This could be called at any time, including immediately after discovery.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unable to connect to Sonos
If you're seeing this message, it means that the Sonos app is having trouble connecting to your Sonos products. Tap the “Unable to...
Read more >
Annoyed that devices just disappear - Sonos Community
I have 5 Sonos devices. All been working fine. Half way through the day, 4 disappear from the app. Managed to reconnect most, ......
Read more >
Sonos has been added but may not appear in the systems tab
I get this error message that tells me to unplug and plug back in to finish setup. Happens on all 5 of my...
Read more >
Products missing from the Sonos S1 Controller app
Quick fixes for a missing Sonos product · Use “Find Missing Products” in the Settings tab · Check the power on the missing...
Read more >
Product not found during setup - Sonos Support
If the error persists, try using a different device that has the Sonos app installed and is connected to your system. Wire your...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found