Skip to content

Devialet browse and play media #134168

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

Draft
wants to merge 23 commits into
base: dev
Choose a base branch
from

Conversation

fwestenberg
Copy link
Contributor

@fwestenberg fwestenberg commented Dec 28, 2024

Breaking change

Proposed change

Add play media and browse media support for Devialet.

Type of change

  • Dependency upgrade
  • 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

  • This PR fixes or closes issue:
  • This PR is related to issue:
  • Link to documentation pull request:

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 Ruff (ruff format 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.

To help with the load of incoming pull requests:

@fwestenberg fwestenberg reopened this Dec 28, 2024
@fwestenberg fwestenberg marked this pull request as ready for review December 28, 2024 21:43
@fwestenberg fwestenberg marked this pull request as draft December 28, 2024 21:49
@fwestenberg fwestenberg marked this pull request as ready for review December 28, 2024 21:49
@fwestenberg fwestenberg marked this pull request as draft December 28, 2024 23:16
@fwestenberg fwestenberg marked this pull request as ready for review December 29, 2024 14:22
@fwestenberg fwestenberg marked this pull request as draft December 29, 2024 23:15
@fwestenberg fwestenberg marked this pull request as ready for review January 6, 2025 09:10
Comment on lines 40 to 45
if await self.client.async_search_allowed():
self.entry.async_create_background_task(
hass=self.hass,
target=self.client.async_discover_upnp_device(),
name=f"{DOMAIN}_UPnP_Discovery",
)
Copy link
Member

Choose a reason for hiding this comment

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

Why do we do this?

Copy link
Contributor Author

@fwestenberg fwestenberg Jan 17, 2025

Choose a reason for hiding this comment

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

At every restart of the speaker, the UPnP port will change. This method finds the UPnP port and initiates the playback capability.

@home-assistant
Copy link

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@home-assistant home-assistant bot marked this pull request as draft January 17, 2025 16:20
@fwestenberg fwestenberg marked this pull request as ready for review January 21, 2025 11:18
@home-assistant home-assistant bot requested a review from joostlek January 21, 2025 11:18
@home-assistant home-assistant bot marked this pull request as draft January 21, 2025 15:24
@fwestenberg fwestenberg marked this pull request as ready for review January 29, 2025 22:00
@home-assistant home-assistant bot requested a review from joostlek January 29, 2025 22:00
},
"exceptions": {
"upnp_error": {
"message": "Unable to play media. UPnP setup not ready for Devialet device."
Copy link
Member

Choose a reason for hiding this comment

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

What can the user do about this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea is, when you select a source (radio browser for example) and playback is not possible, you get noticed instead of waiting and nothing happens...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But usually when UPnP is not available, browsing media is also not supported. This should (almost) never happen.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, but what does UPnP setup not ready mean for the user? What do they need to do to fix it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There is no known solution, beside maybe restart the speaker.

@@ -13,18 +17,19 @@ async def test_load_unload_config_entry(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test the Devialet configuration entry loading and unloading."""
entry = await setup_integration(hass, aioclient_mock)
with patch.object(DevialetApi, "upnp_available", return_value=True):
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
with patch.object(DevialetApi, "upnp_available", return_value=True):
with patch("homeassistant.components.devialet.DevialetApi.upnp_available", return_value=True):

The integration would be a lot nicer if we could patch the library instead of the HTTP calls

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why do you prefer the patch above the patch.object here?

assert entry.state is ConfigEntryState.LOADED

freezer.tick(10)
async_fire_time_changed(hass)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
async_fire_time_changed(hass)
async_fire_time_changed(hass)
await hass.async_block_till_done()

Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to skip time here in the first place? The integration already has state at this point right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If this part is removed, the update has not taken place yet and the attributes are not set.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So without the tick: KeyError: 'volume_level'

Comment on lines 182 to 189
with patch.object(DevialetApi, "equalizer", new_callable=PropertyMock) as mock:
mock.return_value = None

with patch.object(
DevialetApi, "night_mode", new_callable=PropertyMock
) as mock:
mock.return_value = True

Copy link
Member

Choose a reason for hiding this comment

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

Seeing this I would really recommend doing proper mocks, because this isn't ideal. Like, either use library mocks or use http mocks. Don't use both as this becomes hard to maintain

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can improve testing in another PR. It requires a lot of time to me and this is already an existing part.

Copy link
Member

Choose a reason for hiding this comment

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

Yes but the tests themselves can be a lot cleaner than having multiple nested with patches, you can consider patching the full object or merging the patch statements with patch(), patch():

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I merged the patch statements at all locations. It's not perfect, but already a lot cleaner I think. Thanks for the suggestion.

Comment on lines +323 to +326
patch(
"homeassistant.components.media_source.async_browse_media",
return_value=True,
) as mock_browse_media,
Copy link
Member

Choose a reason for hiding this comment

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

Why do we patch this internal?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What would be another solution to test the async browse media function?

Copy link
Member

Choose a reason for hiding this comment

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

I don't know, I did work on the Spotify one, but I am more wondering why we do this so I can see how we would solve this otherwise, hence its just a question rather than a "this should be changed" :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried to patch the first function after the Devialet integration's call. So that's why I've patched this one. Not sure if it's the best way to test it but it seems to work.

@home-assistant home-assistant bot marked this pull request as draft January 31, 2025 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants