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
Conversation
self._attr_volume_fixed = True | ||
self._attr_volume_incremental = False |
There was a problem hiding this comment.
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
if self._attr_volume_fixed: | ||
_LOGGER.error("Cannot change volume for %s, volume is fixed", self.name) | ||
return |
There was a problem hiding this comment.
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
if self._attr_volume_fixed: | ||
_LOGGER.error("Cannot change volume for %s, volume is fixed", self.name) | ||
return |
There was a problem hiding this comment.
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
if self._attr_volume_fixed: | ||
_LOGGER.error("Cannot change volume for %s, volume is fixed", self.name) | ||
return |
There was a problem hiding this comment.
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
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
Thanks for your help @emontnemery - I did wonder if those checks were not required. Now updated. |
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 | ||
) |
There was a problem hiding this comment.
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__
?
There was a problem hiding this comment.
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!
self.volume_fixed = True | ||
self.volume_incremental = False |
There was a problem hiding this comment.
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:
self.volume_fixed = True | |
self.volume_incremental = False | |
self._volume_fixed = True | |
self._volume_incremental = False |
self.volume_fixed = volume["fixed"] | ||
self.volume_incremental = volume["incremental"] |
There was a problem hiding this comment.
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?
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: |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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!
@emontnemery Have refactored the scary block. I think it's much better! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks @pavoni 👍
Thanks for your help on this @emontnemery |
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:
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
Additional information
Checklist
black --fast homeassistant tests
)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest
.requirements_all.txt
.Updated by running
python3 -m script.gen_requirements_all
..coveragerc
.To help with the load of incoming pull requests: