From c7e38a2c7c0fe114dbee6f7f0b447638ac527368 Mon Sep 17 00:00:00 2001 From: Cameron Ring Date: Tue, 17 Sep 2024 15:48:07 -0700 Subject: [PATCH 1/5] Make default dim level configurable in Lutron (#122805) --- .../components/lutron/config_flow.py | 42 +++++++++++++++++-- homeassistant/components/lutron/const.py | 4 ++ homeassistant/components/lutron/light.py | 5 ++- homeassistant/components/lutron/strings.json | 9 ++++ 4 files changed, 56 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/lutron/config_flow.py b/homeassistant/components/lutron/config_flow.py index 6a48e0d4b674d..84174a6f90d51 100644 --- a/homeassistant/components/lutron/config_flow.py +++ b/homeassistant/components/lutron/config_flow.py @@ -6,13 +6,14 @@ from typing import Any from urllib.error import HTTPError -from pylutron import Lutron import voluptuous as vol +from pylutron import Lutron -from homeassistant.config_entries import ConfigFlow, ConfigFlowResult +from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME +from homeassistant.core import callback -from .const import DOMAIN +from .const import CONF_DEFAULT_DIMMER_LEVEL, DEFAULT_DIMMER_LEVEL, DOMAIN _LOGGER = logging.getLogger(__name__) @@ -68,3 +69,38 @@ async def async_step_user( ), errors=errors, ) + + @staticmethod + @callback + def async_get_options_flow( + config_entry: ConfigEntry, + ) -> OptionsFlowHandler: + """Get the options flow for this handler.""" + return OptionsFlowHandler(config_entry) + + +class OptionsFlowHandler(OptionsFlow): + """Handle a option flow for esphome.""" + + def __init__(self, config_entry: ConfigEntry) -> None: + """Initialize options flow.""" + self.config_entry = config_entry + + async def async_step_init( + self, user_input: dict[str, Any] | None = None + ) -> ConfigFlowResult: + """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_DEFAULT_DIMMER_LEVEL, + default=self.config_entry.options.get( + CONF_DEFAULT_DIMMER_LEVEL, DEFAULT_DIMMER_LEVEL + ), + ): vol.All(vol.Coerce(int), vol.Range(min=1, max=255)), + } + ) + return self.async_show_form(step_id="init", data_schema=data_schema) diff --git a/homeassistant/components/lutron/const.py b/homeassistant/components/lutron/const.py index 3862f7eb1d813..b69e35f38baa7 100644 --- a/homeassistant/components/lutron/const.py +++ b/homeassistant/components/lutron/const.py @@ -1,3 +1,7 @@ """Lutron constants.""" DOMAIN = "lutron" + +CONF_DEFAULT_DIMMER_LEVEL = "default_dimmer_level" + +DEFAULT_DIMMER_LEVEL = 255 / 2 diff --git a/homeassistant/components/lutron/light.py b/homeassistant/components/lutron/light.py index 58183fb0a38dc..7bd036f7d24f4 100644 --- a/homeassistant/components/lutron/light.py +++ b/homeassistant/components/lutron/light.py @@ -20,6 +20,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import DOMAIN, LutronData +from .const import CONF_DEFAULT_DIMMER_LEVEL, DEFAULT_DIMMER_LEVEL from .entity import LutronDevice @@ -72,7 +73,9 @@ def turn_on(self, **kwargs: Any) -> None: if ATTR_BRIGHTNESS in kwargs and self._lutron_device.is_dimmable: brightness = kwargs[ATTR_BRIGHTNESS] elif self._prev_brightness == 0: - brightness = 255 / 2 + brightness = self.platform.config_entry.options.get( + CONF_DEFAULT_DIMMER_LEVEL, DEFAULT_DIMMER_LEVEL + ) else: brightness = self._prev_brightness self._prev_brightness = brightness diff --git a/homeassistant/components/lutron/strings.json b/homeassistant/components/lutron/strings.json index b73e0bd15ed0f..924349fab2451 100644 --- a/homeassistant/components/lutron/strings.json +++ b/homeassistant/components/lutron/strings.json @@ -19,6 +19,15 @@ } } }, + "options": { + "step": { + "init": { + "data": { + "default_dimmer_level": "Default light level when first turning on a light from HomeAssistant" + } + } + } + }, "entity": { "event": { "button": { From 8d797263afea6439d167601cfb1f74ac0c69c4ff Mon Sep 17 00:00:00 2001 From: Cameron Ring Date: Sat, 1 Feb 2025 20:59:29 +0000 Subject: [PATCH 2/5] Update Lutron OptionFlow to new style --- homeassistant/components/lutron/config_flow.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/lutron/config_flow.py b/homeassistant/components/lutron/config_flow.py index 84174a6f90d51..ce33288ffdaa9 100644 --- a/homeassistant/components/lutron/config_flow.py +++ b/homeassistant/components/lutron/config_flow.py @@ -6,10 +6,15 @@ from typing import Any from urllib.error import HTTPError -import voluptuous as vol from pylutron import Lutron +import voluptuous as vol -from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow +from homeassistant.config_entries import ( + ConfigEntry, + ConfigFlow, + ConfigFlowResult, + OptionsFlow, +) from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME from homeassistant.core import callback @@ -76,16 +81,12 @@ def async_get_options_flow( config_entry: ConfigEntry, ) -> OptionsFlowHandler: """Get the options flow for this handler.""" - return OptionsFlowHandler(config_entry) + return OptionsFlowHandler() class OptionsFlowHandler(OptionsFlow): """Handle a option flow for esphome.""" - def __init__(self, config_entry: ConfigEntry) -> None: - """Initialize options flow.""" - self.config_entry = config_entry - async def async_step_init( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: From fc6470e31f7a0de5f6fcd09e0142bc7c51b525d9 Mon Sep 17 00:00:00 2001 From: Cameron Ring Date: Sun, 2 Feb 2025 19:26:33 +0000 Subject: [PATCH 3/5] Add space in string, fix comment typo --- homeassistant/components/lutron/config_flow.py | 2 +- homeassistant/components/lutron/strings.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/lutron/config_flow.py b/homeassistant/components/lutron/config_flow.py index ce33288ffdaa9..5210e69869d45 100644 --- a/homeassistant/components/lutron/config_flow.py +++ b/homeassistant/components/lutron/config_flow.py @@ -85,7 +85,7 @@ def async_get_options_flow( class OptionsFlowHandler(OptionsFlow): - """Handle a option flow for esphome.""" + """Handle option flow for lutron.""" async def async_step_init( self, user_input: dict[str, Any] | None = None diff --git a/homeassistant/components/lutron/strings.json b/homeassistant/components/lutron/strings.json index 924349fab2451..37db509e29461 100644 --- a/homeassistant/components/lutron/strings.json +++ b/homeassistant/components/lutron/strings.json @@ -23,7 +23,7 @@ "step": { "init": { "data": { - "default_dimmer_level": "Default light level when first turning on a light from HomeAssistant" + "default_dimmer_level": "Default light level when first turning on a light from Home Assistant" } } } From 5cdfe7a7b404352a82a3a3182847f1a826ff61da Mon Sep 17 00:00:00 2001 From: Cameron Ring Date: Sun, 23 Feb 2025 18:38:20 +0000 Subject: [PATCH 4/5] Use NumberSelector --- homeassistant/components/lutron/config_flow.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/lutron/config_flow.py b/homeassistant/components/lutron/config_flow.py index 5210e69869d45..3f55a2b131b12 100644 --- a/homeassistant/components/lutron/config_flow.py +++ b/homeassistant/components/lutron/config_flow.py @@ -17,6 +17,11 @@ ) from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME from homeassistant.core import callback +from homeassistant.helpers.selector import ( + NumberSelector, + NumberSelectorConfig, + NumberSelectorMode, +) from .const import CONF_DEFAULT_DIMMER_LEVEL, DEFAULT_DIMMER_LEVEL, DOMAIN @@ -101,7 +106,9 @@ async def async_step_init( default=self.config_entry.options.get( CONF_DEFAULT_DIMMER_LEVEL, DEFAULT_DIMMER_LEVEL ), - ): vol.All(vol.Coerce(int), vol.Range(min=1, max=255)), + ): NumberSelector( + NumberSelectorConfig(min=1, max=255, mode=NumberSelectorMode.SLIDER) + ) } ) return self.async_show_form(step_id="init", data_schema=data_schema) From c0ba128e457841e3003af461147c16cc5f5834be Mon Sep 17 00:00:00 2001 From: Cameron Ring Date: Sun, 23 Feb 2025 19:13:19 +0000 Subject: [PATCH 5/5] Pass in config_entry --- homeassistant/components/lutron/light.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/lutron/light.py b/homeassistant/components/lutron/light.py index 7bd036f7d24f4..a7489e13b7b10 100644 --- a/homeassistant/components/lutron/light.py +++ b/homeassistant/components/lutron/light.py @@ -5,7 +5,7 @@ from collections.abc import Mapping from typing import Any -from pylutron import Output +from pylutron import Lutron, LutronEntity, Output from homeassistant.components.light import ( ATTR_BRIGHTNESS, @@ -38,7 +38,7 @@ async def async_setup_entry( async_add_entities( ( - LutronLight(area_name, device, entry_data.client) + LutronLight(area_name, device, entry_data.client, config_entry) for area_name, device in entry_data.lights ), True, @@ -65,6 +65,17 @@ class LutronLight(LutronDevice, LightEntity): _prev_brightness: int | None = None _attr_name = None + def __init__( + self, + area_name: str, + lutron_device: LutronEntity, + controller: Lutron, + config_entry: ConfigEntry, + ) -> None: + """Initialize the device.""" + super().__init__(area_name, lutron_device, controller) + self._config_entry = config_entry + def turn_on(self, **kwargs: Any) -> None: """Turn the light on.""" if flash := kwargs.get(ATTR_FLASH): @@ -73,7 +84,7 @@ def turn_on(self, **kwargs: Any) -> None: if ATTR_BRIGHTNESS in kwargs and self._lutron_device.is_dimmable: brightness = kwargs[ATTR_BRIGHTNESS] elif self._prev_brightness == 0: - brightness = self.platform.config_entry.options.get( + brightness = self._config_entry.options.get( CONF_DEFAULT_DIMMER_LEVEL, DEFAULT_DIMMER_LEVEL ) else: