diff --git a/homeassistant/components/philips_js/__init__.py b/homeassistant/components/philips_js/__init__.py index 587a5f8c4f2..1006df699f4 100644 --- a/homeassistant/components/philips_js/__init__.py +++ b/homeassistant/components/philips_js/__init__.py @@ -20,7 +20,7 @@ from homeassistant.core import CALLBACK_TYPE, Context, HassJob, HomeAssistant, c from homeassistant.helpers.debounce import Debouncer from homeassistant.helpers.update_coordinator import DataUpdateCoordinator -from .const import DOMAIN +from .const import CONF_ALLOW_NOTIFY, DOMAIN PLATFORMS = ["media_player", "light", "remote"] @@ -36,8 +36,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: username=entry.data.get(CONF_USERNAME), password=entry.data.get(CONF_PASSWORD), ) - - coordinator = PhilipsTVDataUpdateCoordinator(hass, tvapi) + coordinator = PhilipsTVDataUpdateCoordinator(hass, tvapi, entry.options) await coordinator.async_refresh() hass.data.setdefault(DOMAIN, {}) @@ -45,9 +44,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: hass.config_entries.async_setup_platforms(entry, PLATFORMS) + entry.async_on_unload(entry.add_update_listener(async_update_entry)) + return True +async def async_update_entry(hass: HomeAssistant, entry: ConfigEntry) -> None: + """Update options.""" + await hass.config_entries.async_reload(entry.entry_id) + + async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): """Unload a config entry.""" unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) @@ -94,9 +100,10 @@ class PluggableAction: class PhilipsTVDataUpdateCoordinator(DataUpdateCoordinator[None]): """Coordinator to update data.""" - def __init__(self, hass, api: PhilipsTV) -> None: + def __init__(self, hass, api: PhilipsTV, options: dict) -> None: """Set up the coordinator.""" self.api = api + self.options = options self._notify_future: asyncio.Task | None = None @callback @@ -127,6 +134,7 @@ class PhilipsTVDataUpdateCoordinator(DataUpdateCoordinator[None]): self.api.on and self.api.powerstate == "On" and self.api.notify_change_supported + and self.options.get(CONF_ALLOW_NOTIFY, False) ) async def _notify_task(self): diff --git a/homeassistant/components/philips_js/config_flow.py b/homeassistant/components/philips_js/config_flow.py index 84303e6ca92..59403b2ec86 100644 --- a/homeassistant/components/philips_js/config_flow.py +++ b/homeassistant/components/philips_js/config_flow.py @@ -17,7 +17,7 @@ from homeassistant.const import ( ) from . import LOGGER -from .const import CONF_SYSTEM, CONST_APP_ID, CONST_APP_NAME, DOMAIN +from .const import CONF_ALLOW_NOTIFY, CONF_SYSTEM, CONST_APP_ID, CONST_APP_NAME, DOMAIN async def validate_input( @@ -154,3 +154,32 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): } ) return self.async_show_form(step_id="user", data_schema=schema, errors=errors) + + @staticmethod + @core.callback + def async_get_options_flow(config_entry): + """Get the options flow for this handler.""" + return OptionsFlowHandler(config_entry) + + +class OptionsFlowHandler(config_entries.OptionsFlow): + """Handle a option flow for AEMET.""" + + def __init__(self, config_entry: config_entries.ConfigEntry) -> None: + """Initialize options flow.""" + self.config_entry = config_entry + + async def async_step_init(self, user_input=None): + """Handle options flow.""" + if user_input is not None: + return self.async_create_entry(title="", data=user_input) + + data_schema = vol.Schema( + { + vol.Required( + CONF_ALLOW_NOTIFY, + default=self.config_entry.options.get(CONF_ALLOW_NOTIFY), + ): bool, + } + ) + return self.async_show_form(step_id="init", data_schema=data_schema) diff --git a/homeassistant/components/philips_js/const.py b/homeassistant/components/philips_js/const.py index 5769a8979ce..5d1141a8fb9 100644 --- a/homeassistant/components/philips_js/const.py +++ b/homeassistant/components/philips_js/const.py @@ -2,6 +2,7 @@ DOMAIN = "philips_js" CONF_SYSTEM = "system" +CONF_ALLOW_NOTIFY = "allow_notify" CONST_APP_ID = "homeassistant.io" CONST_APP_NAME = "Home Assistant" diff --git a/homeassistant/components/philips_js/strings.json b/homeassistant/components/philips_js/strings.json index 5c8f08eff6a..3e6d4f494d3 100644 --- a/homeassistant/components/philips_js/strings.json +++ b/homeassistant/components/philips_js/strings.json @@ -20,11 +20,20 @@ "unknown": "[%key:common::config_flow::error::unknown%]", "pairing_failure": "Unable to pair: {error_id}", "invalid_pin": "Invalid PIN" -}, + }, "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" } }, + "options": { + "step": { + "init": { + "data": { + "allow_notify": "Allow usage of data notification service." + } + } + } + }, "device_automation": { "trigger_type": { "turn_on": "Device is requested to turn on" diff --git a/homeassistant/components/philips_js/translations/en.json b/homeassistant/components/philips_js/translations/en.json index ea254a3873d..2cc009d4f39 100644 --- a/homeassistant/components/philips_js/translations/en.json +++ b/homeassistant/components/philips_js/translations/en.json @@ -25,6 +25,15 @@ } } }, + "options": { + "step": { + "init": { + "data": { + "allow_notify": "Allow usage of data notification service." + } + } + } + }, "device_automation": { "trigger_type": { "turn_on": "Device is requested to turn on" diff --git a/tests/components/philips_js/test_config_flow.py b/tests/components/philips_js/test_config_flow.py index 4841cd5a940..f3ab44844a2 100644 --- a/tests/components/philips_js/test_config_flow.py +++ b/tests/components/philips_js/test_config_flow.py @@ -4,8 +4,8 @@ from unittest.mock import ANY, patch from haphilipsjs import PairingFailure from pytest import fixture -from homeassistant import config_entries -from homeassistant.components.philips_js.const import DOMAIN +from homeassistant import config_entries, data_entry_flow +from homeassistant.components.philips_js.const import CONF_ALLOW_NOTIFY, DOMAIN from . import ( MOCK_CONFIG, @@ -17,13 +17,17 @@ from . import ( MOCK_USERNAME, ) +from tests.common import MockConfigEntry -@fixture(autouse=True) -def mock_setup_entry(): + +@fixture(autouse=True, name="mock_setup_entry") +def mock_setup_entry_fixture(): """Disable component setup.""" with patch( "homeassistant.components.philips_js.async_setup_entry", return_value=True - ) as mock_setup_entry: + ) as mock_setup_entry, patch( + "homeassistant.components.philips_js.async_unload_entry", return_value=True + ): yield mock_setup_entry @@ -226,3 +230,28 @@ async def test_pair_grant_failed(hass, mock_tv_pairable, mock_setup_entry): "reason": "pairing_failure", "type": "abort", } + + +async def test_options_flow(hass): + """Test config flow options.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + unique_id="123456", + data=MOCK_CONFIG_PAIRED, + ) + config_entry.add_to_hass(hass) + + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + result = await hass.config_entries.options.async_init(config_entry.entry_id) + + assert result["type"] == data_entry_flow.RESULT_TYPE_FORM + assert result["step_id"] == "init" + + result = await hass.config_entries.options.async_configure( + result["flow_id"], user_input={CONF_ALLOW_NOTIFY: True} + ) + + assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + assert config_entry.options == {CONF_ALLOW_NOTIFY: True}