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

Sonos setup fails with unhandled exceptions on discovery messages #90648

Merged
merged 22 commits into from May 30, 2023
Merged

Sonos setup fails with unhandled exceptions on discovery messages #90648

merged 22 commits into from May 30, 2023

Conversation

PeteRager
Copy link
Contributor

@PeteRager PeteRager commented Apr 1, 2023

Proposed change

During setup of manually configured Sonos devices, if the devices are offline setup of the integration may fail. There were several issues in the code that needed to be resolved.

  1. Exceptions were not being handled when the device was unable to be pinged and were flowing back to HASS during setup. Now the exceptions are handled and logged, setup will complete, and the devices will be periodically retried.
  2. During initialization, a blocking call to soco.uuid was occurring within the HASS event loop, this issue is mitigated by not attempting the ping if the prior call to get the uuid via async_add_executor_job failed.
  3. If an exception occurred when pinging the device, the call to async_call_later (to retry it) would not occur and hence the device would never come back on-line without a HASS restart.
  4. In the attached issues asyncio.TimeoutError was unhandled, during my testing I saw RequestException occur. Added these to the existing exception handler to make them consistent.

Type of change

  • Dependency upgrade
  • [X ] Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Black (black --fast homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.
  • Untested files have been added to .coveragerc.

To help with the load of incoming pull requests:

@home-assistant
Copy link

home-assistant bot commented Apr 1, 2023

Hey there @cgtobi, @jjlawren, mind taking a look at this pull request as it has been labeled with an integration (sonos) you are listed as a code owner for? Thanks!

Code owner commands

Code owners of sonos can trigger bot actions by commenting:

  • @home-assistant close Closes the pull request.
  • @home-assistant rename Awesome new title Renames the pull request.
  • @home-assistant reopen Reopen the pull request.
  • @home-assistant unassign sonos Removes the current integration label and assignees on the pull request, add the integration domain after the command.

@PeteRager PeteRager marked this pull request as draft April 1, 2023 17:49
@PeteRager PeteRager marked this pull request as ready for review April 1, 2023 17:54
@PeteRager PeteRager marked this pull request as draft April 2, 2023 13:56
homeassistant/components/sonos/__init__.py Outdated Show resolved Hide resolved
homeassistant/components/sonos/__init__.py Outdated Show resolved Hide resolved
homeassistant/components/sonos/__init__.py Outdated Show resolved Hide resolved
1. Speaker activity messages were being sent for speakers whose pings fail, resulting in the speaker remaining available in HASS.  Now the activity message is only sent after a successful ping.
2.  Remove RequestException from except handler as its a derived class of OSError()
3. If the second host in a list of two hosts was unavailable, then a blocking call would occur in the event loop.  Now, fully process the lists of hosts in the first loop; and only process hosts there are not in error in the second loop.
@PeteRager PeteRager marked this pull request as ready for review April 7, 2023 13:56
@PeteRager PeteRager requested a review from jjlawren April 7, 2023 13:57
@PeteRager
Copy link
Contributor Author

PeteRager commented Apr 10, 2023

@jjlawren changes are complete, please review when you have a couple

A question you may have is why I moved the async_dispatcher_send after the ping. What I found is when I unplugged a speaker that message would get sent and that was keeping the speaker alive beyond the ~270 second timeout so it would not get marked unavailable. Moving it after a successful ping eliminates that problem at which point that message makes the speaker become available.

Copy link
Contributor

@jjlawren jjlawren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for testing thoroughly. Getting the failure scenarios for Sonos devices is tricky as network layouts and behaviors vary wildly. This manual polling code should only be necessary when the various discovery methods are not operational. I have tested many similar scenarios by forcibly breaking discovery on my network but it's not a setup I enjoy re-testing.

homeassistant/components/sonos/__init__.py Show resolved Hide resolved
Copy link
Contributor

@jjlawren jjlawren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see how this helps during startup. Should be a good improvement. Thanks again for testing and the PR 👍

@frenck frenck added the smash Indicator this PR is close to finish for merging or closing label Apr 22, 2023
@PeteRager
Copy link
Contributor Author

Thank you for the review. While I don't expect any issues as we now have much better unit tests. If for some reason an issue is reported on this piece of code, tag me and I'll get right on it.

@bdraco bdraco added the second-opinion-wanted Add this label when a reviewer needs a second opinion from another member. label May 1, 2023
@bdraco
Copy link
Member

bdraco commented May 1, 2023

Second opinion request is for #90648 (comment)

@bdraco bdraco removed the second-opinion-wanted Add this label when a reviewer needs a second opinion from another member. label May 21, 2023
Don't use event wait for
Simplify waiting on multiple events
@@ -84,7 +99,9 @@ async def test_async_poll_manual_hosts_warnings(
manager.hosts.add("10.10.10.10")
with caplog.at_level(logging.DEBUG), patch.object(
manager, "_async_handle_discovery_message"
), patch("homeassistant.components.sonos.async_call_later"), patch(
), patch(
"homeassistant.components.sonos.async_call_later"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably shouldn’t be patching async_call_later here but that’s an existing issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, that's from a prior test. I'll get that fixed in a new pull request.

@bdraco bdraco requested a review from jjlawren May 21, 2023 22:57
@PeteRager
Copy link
Contributor Author

@jjlawren please review when you have 5.

Copy link
Contributor

@jjlawren jjlawren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This codepath should only be needed when network discovery is failing and manually configured hosts are required. Tests are a bit more complex now, but the previous limitation of a single mocked device is good to relax. Thanks for the thorough testing here 👍

@bdraco
Copy link
Member

bdraco commented May 30, 2023

Pushed to my production to verify that it didn't cause any side effects. All good 👍

@bdraco
Copy link
Member

bdraco commented May 30, 2023

Merging in dev to get a clean CI run before merging

@bdraco
Copy link
Member

bdraco commented May 30, 2023

Thanks @PeteRager

@bdraco bdraco merged commit 6a8d18a into home-assistant:dev May 30, 2023
20 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators May 31, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sonos integration fails upon HA restart, if any device is powered off
5 participants