-
-
Notifications
You must be signed in to change notification settings - Fork 33.1k
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
Add option to LinkPlay to disregard HA hostname and use IP instead #137089
base: dev
Are you sure you want to change the base?
Conversation
…nstead of configured name, fixing TTS.
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.
It seems you haven't yet signed a CLA. Please do so here.
Once you do that we will be able to review and accept this pull request.
Thanks!
Hey there @Velleman, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
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.
Thank you for your deep analysis and contribution trying to address it. I've left some first comments in this review to get started. Some basic test coverage for the option flow will be required to get this merged on the end.
The implementation of the LinkPlay protocol is generic is some form, but the implementation may differ from device to device depending on the manufacturer. Multiple companies have adjusted the firmware, making it hard to know what devices (and the firmwares) are actually affected by this bug.
I'm still thinking if it's required to present this as an option (flow), if the affected devices can be listed, it should be possible to handle all this based on the model ids.
# Register update listener to update config entry when options are updated. | ||
hass_data = dict(entry.data) | ||
unsub_options_update_listener = entry.add_update_listener(options_update_listener) | ||
# Store a reference to the unsubscribe function to cleanup if an entry is unloaded. | ||
hass_data["unsub_options_update_listener"] = unsub_options_update_listener | ||
hass.data[DOMAIN][entry.entry_id] = hass_data | ||
|
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.
You can replace this code with
entry.async_on_unload(entry.add_update_listener(async_update_options))
Add this code after initializing the platforms, so it only unloads after successful setup.
# Modify the the url if required to use IP address instead of hostname. | ||
# This is required for compatibility with some devices. | ||
if self._use_ip_url: | ||
parsed_url = yarl.URL(url) | ||
# Update the parsed URL with the local ip | ||
url = parsed_url.with_host(self.hass.config.api.local_ip) |
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.
Given your analysis in the issue thread, I assume this is only required when you want to play a local(-only) url that isn't externally exposed?
How does this work for music coming from a streaming provider? When the toggle is enabled, it will replace dns always with it's ip address?
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.
On first reading through the code I was under the impression that this function was only called with HA URL's. Upone re-reading I can see that this isn't a valid assumption, so I'll update the code to handle this case and update the PR.
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.
You can use this utility method:
core/homeassistant/helpers/network.py
Line 67 in 9e04f61
def is_hass_url(hass: HomeAssistant, url: str) -> bool: |
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.
Thanks for that, I'm still getting my head around how the options flow testing should work, will try and spend some time in the next couple of days and get that added.
@@ -25,10 +25,12 @@ | |||
MODELS_ARYLIC_A50: Final[str] = "A50" | |||
MODELS_ARYLIC_A50S: Final[str] = "A50+" | |||
MODELS_ARYLIC_UP2STREAM_AMP: Final[str] = "Up2Stream Amp 2.0" | |||
MODELS_ARYLIC_UP2STREAM_AMP_2P1: Final[str] = "Up2Stream Amp 2.1" |
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.
Can you open a preliminary pull request to add these models? Pull requests are as small as possible and should only address one change at a time.
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.
Thanks, I've just submitted a separate PR with these.
"selector": { | ||
"sensor_select": { | ||
"options": { | ||
"use_ip_url": "Force IP in Home Assistant generated URLs to work around bugs in using local domain names with some devices." | ||
} | ||
} | ||
}, |
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.
Use the option flow translation section to let them show up. Something like this:
"selector": { | |
"sensor_select": { | |
"options": { | |
"use_ip_url": "Force IP in Home Assistant generated URLs to work around bugs in using local domain names with some devices." | |
} | |
} | |
}, | |
"options": { | |
"step": { | |
"init": { | |
"title": "LinkPlay options", | |
"data": { | |
"use_ip_url": "Force IP in Home Assistant generated URLs to work around bugs in using local domain names with some devices." | |
} | |
} | |
} | |
}, |
Have you tested if it worked for your devices with any of the custom components available? Some people mentioned that it works with the custom components in the issue thread and they have always been a good source for this core integration from the start. |
From reading online, I was under the impression that the previous custom components had been deprecated in favour of the built in component? I haven't tested with the custom components, I figured that working with the core integration was likely a more reliable path? |
Thanks for answering. Having it fixed in core is definiately the way to go. It's fine if you didn't test any custom integrations, just asking to know. I've went through the code of multiple custom integrations and couldn't spot if they would fix this issue. |
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.
Thanks for taking the time to further improve. At this point, I'm not sure it would be accepted to introduce a option flow for this, we will need to wait until a core reviewer comes by to step in.
# Register update listener to update config entry when options are updated. | ||
entry.async_on_unload(entry.add_update_listener(options_update_listener)) | ||
|
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 needs to be at the bottom of the function, to ensure it only unloads when it was successfully setup.
Proposed change
Digging into the issue related to LinkPlay devices not supporting TTS, it appears the root cause of this is that the devices "ignore" URLs relating to local network resources. From the debugging that I've done (documented in the related issue), overriding this behaviour has not yet been possible through device configuration.
This PR adds in an option to the integraton that overwrites the generated URL's with the local HA IP address instead. By doing this, TTS works on these devices with no further issues. It doesn't feel elegant, but it does work. Due to the nature of the fix I wanted to invite comment before I finalised testing etc, as if this method can't reach the development standards of the project I'll just leave it until someone can find a better method to get this working.
TODO: At present I have been unable to find any documentation on how to change the displayed text adjacent to a boolean option. I would greatly appreciate some pointers on where to find the documentation for this! The tests also require updating at this time.
Type of change
Additional information
Checklist
ruff format 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
.To help with the load of incoming pull requests: