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

Improve handling of roon media players with fixed and incremental volume #99819

Merged
merged 4 commits into from Oct 12, 2023

Conversation

pavoni
Copy link
Contributor

@pavoni pavoni commented Sep 7, 2023

Proposed change

The current HA roon integration assumes that roon media players have the ability to set volume, and increment volume (up and down). However in fact roon has endpoints with fixed volume, and incremental only volume, as well as more conventional volume.

This PR does two things:

  • Set the supported features correctly based on the abilities of the roon endpoint
  • Fix bugs when using incremental only roon endpoints

Incremental endpoints are not common (which is why the bugs haven't been reported) - but will be used if #99684 is merged.

This PR should be merged regardless of the PR above (as it fixes bugs). But it is required to release the PR above.

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: fixes #
  • 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 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:

Comment on lines 125 to 126
self._attr_volume_fixed = True
self._attr_volume_incremental = False
Copy link
Contributor

Choose a reason for hiding this comment

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

Please give other names to these to not confuse with the _attr- used as shorthand for entity properties

Comment on lines 377 to 379
if self._attr_volume_fixed:
_LOGGER.error("Cannot change volume for %s, volume is fixed", self.name)
return
Copy link
Contributor

Choose a reason for hiding this comment

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

This check should be unnecessary, set_volume_level won't be called for an entity which does not set MediaPlayerEntityFeature.VOLUME_SET

Comment on lines 390 to 392
if self._attr_volume_fixed:
_LOGGER.error("Cannot change volume for %s, volume is fixed", self.name)
return
Copy link
Contributor

Choose a reason for hiding this comment

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

This check should be unnecessary, volume_up won't be called for an entity which does not set MediaPlayerEntityFeature.VOLUME_SET or MediaPlayerEntityFeature.VOLUME_STEP

Comment on lines 401 to 403
if self._attr_volume_fixed:
_LOGGER.error("Cannot change volume for %s, volume is fixed", self.name)
return
Copy link
Contributor

Choose a reason for hiding this comment

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

This check should be unnecessary, volume_down won't be called for an entity which does not set MediaPlayerEntityFeature.VOLUME_SET or MediaPlayerEntityFeature.VOLUME_STEP

@home-assistant home-assistant bot marked this pull request as draft September 28, 2023 09:42
@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.

@pavoni pavoni marked this pull request as ready for review September 28, 2023 13:56
@pavoni
Copy link
Contributor Author

pavoni commented Sep 28, 2023

Thanks for your help @emontnemery - I did wonder if those checks were not required.

Now updated.

Comment on lines 304 to 313
self.volume_fixed = volume["fixed"]
self.volume_incremental = volume["incremental"]
if not self.volume_fixed:
self._attr_supported_features = (
self._attr_supported_features | MediaPlayerEntityFeature.VOLUME_STEP
)
if not self.volume_incremental:
self._attr_supported_features = (
self._attr_supported_features | MediaPlayerEntityFeature.VOLUME_SET
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need to be done every time the state is updated, or can we do it once, preferably in __init__?

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 media_player number and state are updated in an async way by roon, so this can change as endpoints are enabled and disabled (this can be as simple as powering on a USB dac - which will enable the connected endpoint).

The volume type can also be changed by the user in roon - so I think it is safest to leave this as updating on every update, since that way it will never be wrong!

Comment on lines 125 to 126
self.volume_fixed = True
self.volume_incremental = False
Copy link
Contributor

Choose a reason for hiding this comment

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

Make these _protected or __private:

Suggested change
self.volume_fixed = True
self.volume_incremental = False
self._volume_fixed = True
self._volume_incremental = False

Comment on lines 304 to 305
self.volume_fixed = volume["fixed"]
self.volume_incremental = volume["incremental"]
Copy link
Contributor

Choose a reason for hiding this comment

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

How does this work?
volume["fixed"] and volume["incremental"] is only set in the else clause of the try-except above, is it OK to access them unconditionally here?

Comment on lines 197 to 204
try:
volume_data = player_data["volume"]
volume_muted = volume_data["is_muted"]
volume_step = convert(volume_data["step"], int, 0)
volume_max = volume_data["max"]
volume_min = volume_data["min"]
raw_level = convert(volume_data["value"], float, 0)

volume_range = volume_max - volume_min
volume_percentage_factor = volume_range / 100
volume_fixed = False
volume_incremental = volume_data["type"] == "incremental"
volume_muted = volume_data.get("is_muted", False)

level = (raw_level - volume_min) / volume_percentage_factor
volume_level = convert(level, int, 0) / 100
try:
Copy link
Contributor

Choose a reason for hiding this comment

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

Two nested try-blocks, both catching KeyError is a bit hard to read IMHO.
Could you try to rewrite it? Maybe add helpers fixed_volume +incremental_volume which return True if certain keys are missing?

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 leave the previous code (which was quite carefully crafted) - but agree that this now isn't at all easy to understand.

I'll take another look!

@home-assistant home-assistant bot marked this pull request as draft September 28, 2023 14:56
@frenck frenck modified the milestones: 2023.10.0, 2023.10.1, 2023.10.2 Oct 4, 2023
@pavoni pavoni marked this pull request as ready for review October 12, 2023 10:19
@pavoni
Copy link
Contributor Author

pavoni commented Oct 12, 2023

@emontnemery Have refactored the scary block. I think it's much better!

Copy link
Contributor

@emontnemery emontnemery left a comment

Choose a reason for hiding this comment

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

LGTM, thanks @pavoni 👍

@frenck frenck merged commit dcb3dc2 into dev Oct 12, 2023
23 checks passed
@frenck frenck deleted the roon_volume_improvements branch October 12, 2023 10:52
@pavoni
Copy link
Contributor Author

pavoni commented Oct 12, 2023

Thanks for your help on this @emontnemery

@frenck frenck mentioned this pull request Oct 12, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Oct 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants