-
-
Notifications
You must be signed in to change notification settings - Fork 37.4k
Add config flow support to songpal integration #34714
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
Merged
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
875d112
Add config flow to songpal
shenxn 387b523
Add config flow to songpal
shenxn 818f42f
Add songpal to migrated service in discovery
shenxn cd1e17c
Improve songpal/set_sound_setting service
shenxn 0ba6220
Remove songpal config flow from .coveragerc omit
shenxn 042e9b6
Bump python-songpal to 0.12 and fix exception handling
shenxn 6a5f0e2
Revert "Improve songpal/set_sound_setting service"
shenxn 9ab1d57
Code style fix
shenxn d67b5d7
Add connections to device_info
shenxn d4b173d
Fix pylint
shenxn 3fcc46e
Ignore braava tv
shenxn a22a2ab
Fix test warning
shenxn b821994
Add @shenxn as codeowner
shenxn 3199a56
Remove model from configuration data
shenxn a79e36a
Get name from device in user step
shenxn ac386fa
Add unload entry support
shenxn 0732fda
Delete translations as it will get generated as part of CI
raman325 c3b6f62
Code cleanup
shenxn 6c88b9b
Fix typo
shenxn 410f960
Remove _show_setup_form
shenxn bf01b2b
Change configuration from media_player to songpal
shenxn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,50 @@ | ||
| """The songpal component.""" | ||
| from collections import OrderedDict | ||
| import logging | ||
|
|
||
| import voluptuous as vol | ||
|
|
||
| from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry | ||
| from homeassistant.const import CONF_NAME | ||
| from homeassistant.helpers import config_validation as cv | ||
| from homeassistant.helpers.typing import HomeAssistantType | ||
|
|
||
| from .const import CONF_ENDPOINT, DOMAIN | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
| SONGPAL_CONFIG_SCHEMA = vol.Schema( | ||
| {vol.Optional(CONF_NAME): cv.string, vol.Required(CONF_ENDPOINT): cv.string} | ||
| ) | ||
|
|
||
| CONFIG_SCHEMA = vol.Schema( | ||
| {vol.Optional(DOMAIN): vol.All(cv.ensure_list, [SONGPAL_CONFIG_SCHEMA])}, | ||
| extra=vol.ALLOW_EXTRA, | ||
| ) | ||
|
|
||
|
|
||
| async def async_setup(hass: HomeAssistantType, config: OrderedDict) -> bool: | ||
| """Set up songpal environment.""" | ||
| conf = config.get(DOMAIN) | ||
| if conf is None: | ||
| return True | ||
| for config_entry in conf: | ||
| hass.async_create_task( | ||
| hass.config_entries.flow.async_init( | ||
| DOMAIN, context={"source": SOURCE_IMPORT}, data=config_entry, | ||
| ), | ||
| ) | ||
| return True | ||
|
|
||
|
|
||
| async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool: | ||
| """Set up songpal media player.""" | ||
| hass.async_create_task( | ||
| hass.config_entries.async_forward_entry_setup(entry, "media_player") | ||
| ) | ||
| return True | ||
|
|
||
|
|
||
| async def async_unload_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool: | ||
| """Unload songpal media player.""" | ||
| return await hass.config_entries.async_forward_entry_unload(entry, "media_player") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| """Config flow to configure songpal component.""" | ||
| import logging | ||
| from typing import Optional | ||
| from urllib.parse import urlparse | ||
|
|
||
| from songpal import Device, SongpalException | ||
| import voluptuous as vol | ||
|
|
||
| from homeassistant import config_entries | ||
| from homeassistant.components import ssdp | ||
| from homeassistant.const import CONF_HOST, CONF_NAME | ||
|
|
||
| from .const import CONF_ENDPOINT, DOMAIN # pylint: disable=unused-import | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| class SongpalConfig: | ||
| """Device Configuration.""" | ||
|
|
||
| def __init__(self, name, host, endpoint): | ||
| """Initialize Configuration.""" | ||
| self.name = name | ||
| self.host = host | ||
| self.endpoint = endpoint | ||
|
|
||
|
|
||
| class SongpalConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): | ||
| """Songpal configuration flow.""" | ||
|
|
||
| VERSION = 1 | ||
| CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_PUSH | ||
|
|
||
| def __init__(self): | ||
| """Initialize the flow.""" | ||
| self.conf: Optional[SongpalConfig] = None | ||
|
|
||
| async def async_step_user(self, user_input=None): | ||
| """Handle a flow initiated by the user.""" | ||
| if user_input is None: | ||
| return self.async_show_form( | ||
| step_id="user", | ||
| data_schema=vol.Schema({vol.Required(CONF_ENDPOINT): str}), | ||
| ) | ||
|
|
||
| # Validate input | ||
| endpoint = user_input[CONF_ENDPOINT] | ||
| parsed_url = urlparse(endpoint) | ||
|
|
||
| # Try to connect and get device name | ||
| try: | ||
| device = Device(endpoint) | ||
| await device.get_supported_methods() | ||
| interface_info = await device.get_interface_information() | ||
| name = interface_info.modelName | ||
| except SongpalException as ex: | ||
| _LOGGER.debug("Connection failed: %s", ex) | ||
| return self.async_show_form( | ||
| step_id="user", | ||
| data_schema=vol.Schema( | ||
| { | ||
| vol.Required( | ||
| CONF_ENDPOINT, default=user_input.get(CONF_ENDPOINT, "") | ||
| ): str, | ||
| } | ||
| ), | ||
| errors={"base": "connection"}, | ||
| ) | ||
|
|
||
| self.conf = SongpalConfig(name, parsed_url.hostname, endpoint) | ||
|
|
||
| return await self.async_step_init(user_input) | ||
|
|
||
| async def async_step_init(self, user_input=None): | ||
| """Handle a flow start.""" | ||
| # Check if already configured | ||
| if self._endpoint_already_configured(): | ||
| return self.async_abort(reason="already_configured") | ||
|
|
||
| if user_input is None: | ||
| return self.async_show_form( | ||
| step_id="init", | ||
| description_placeholders={ | ||
| CONF_NAME: self.conf.name, | ||
| CONF_HOST: self.conf.host, | ||
| }, | ||
| ) | ||
|
|
||
| await self.async_set_unique_id(self.conf.endpoint) | ||
| self._abort_if_unique_id_configured() | ||
|
|
||
| return self.async_create_entry( | ||
| title=self.conf.name, | ||
| data={CONF_NAME: self.conf.name, CONF_ENDPOINT: self.conf.endpoint}, | ||
| ) | ||
|
|
||
| async def async_step_ssdp(self, discovery_info): | ||
| """Handle a discovered Songpal device.""" | ||
| await self.async_set_unique_id(discovery_info[ssdp.ATTR_UPNP_UDN]) | ||
| self._abort_if_unique_id_configured() | ||
|
|
||
| _LOGGER.debug("Discovered: %s", discovery_info) | ||
|
|
||
| friendly_name = discovery_info[ssdp.ATTR_UPNP_FRIENDLY_NAME] | ||
| parsed_url = urlparse(discovery_info[ssdp.ATTR_SSDP_LOCATION]) | ||
| scalarweb_info = discovery_info["X_ScalarWebAPI_DeviceInfo"] | ||
| endpoint = scalarweb_info["X_ScalarWebAPI_BaseURL"] | ||
| service_types = scalarweb_info["X_ScalarWebAPI_ServiceList"][ | ||
| "X_ScalarWebAPI_ServiceType" | ||
| ] | ||
|
|
||
| # Ignore Bravia TVs | ||
| if "videoScreen" in service_types: | ||
| return self.async_abort(reason="not_songpal_device") | ||
|
|
||
| # pylint: disable=no-member | ||
| self.context["title_placeholders"] = { | ||
| CONF_NAME: friendly_name, | ||
| CONF_HOST: parsed_url.hostname, | ||
| } | ||
|
|
||
| self.conf = SongpalConfig(friendly_name, parsed_url.hostname, endpoint) | ||
|
|
||
| return await self.async_step_init() | ||
|
|
||
| async def async_step_import(self, user_input=None): | ||
| """Import a config entry.""" | ||
| name = user_input.get(CONF_NAME) | ||
| endpoint = user_input.get(CONF_ENDPOINT) | ||
| parsed_url = urlparse(endpoint) | ||
|
|
||
| # Try to connect to test the endpoint | ||
| try: | ||
| device = Device(endpoint) | ||
| await device.get_supported_methods() | ||
| # Get name | ||
| if name is None: | ||
| interface_info = await device.get_interface_information() | ||
| name = interface_info.modelName | ||
| except SongpalException as ex: | ||
| _LOGGER.error("Import from yaml configuration failed: %s", ex) | ||
| return self.async_abort(reason="connection") | ||
|
|
||
| self.conf = SongpalConfig(name, parsed_url.hostname, endpoint) | ||
|
|
||
| return await self.async_step_init(user_input) | ||
|
|
||
| def _endpoint_already_configured(self): | ||
| """See if we already have an endpoint matching user input configured.""" | ||
| existing_endpoints = [ | ||
| entry.data[CONF_ENDPOINT] for entry in self._async_current_entries() | ||
|
shenxn marked this conversation as resolved.
|
||
| ] | ||
| return self.conf.endpoint in existing_endpoints | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| """Constants for the Songpal component.""" | ||
| DOMAIN = "songpal" | ||
| SET_SOUND_SETTING = "set_sound_setting" | ||
|
|
||
| CONF_ENDPOINT = "endpoint" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,14 @@ | ||
| { | ||
| "domain": "songpal", | ||
| "name": "Sony Songpal", | ||
| "config_flow": true, | ||
| "documentation": "https://www.home-assistant.io/integrations/songpal", | ||
| "requirements": ["python-songpal==0.11.2"], | ||
| "codeowners": ["@rytilahti"] | ||
| "requirements": ["python-songpal==0.12"], | ||
| "codeowners": ["@rytilahti", "@shenxn"], | ||
| "ssdp": [ | ||
| { | ||
| "st": "urn:schemas-sony-com:service:ScalarWebAPI:1", | ||
| "manufacturer": "Sony Corporation" | ||
| } | ||
| ] | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.