diff --git a/custom_components/localtuya/const.py b/custom_components/localtuya/const.py index d3310fc..2b57240 100644 --- a/custom_components/localtuya/const.py +++ b/custom_components/localtuya/const.py @@ -8,6 +8,10 @@ CONF_LOCAL_KEY = "local_key" CONF_PROTOCOL_VERSION = "protocol_version" CONF_DPS_STRINGS = "dps_strings" +# light +CONF_BRIGHTNESS_LOWER = "brightness_lower" +CONF_BRIGHTNESS_UPPER = "brightness_upper" + # switch CONF_CURRENT = "current" CONF_CURRENT_CONSUMPTION = "current_consumption" diff --git a/custom_components/localtuya/light.py b/custom_components/localtuya/light.py index 39e0a87..e8f4b04 100644 --- a/custom_components/localtuya/light.py +++ b/custom_components/localtuya/light.py @@ -19,18 +19,36 @@ from homeassistant.components.light import ( ) from .common import LocalTuyaEntity, async_setup_entry +from .const import CONF_BRIGHTNESS_LOWER, CONF_BRIGHTNESS_UPPER _LOGGER = logging.getLogger(__name__) MIN_MIRED = 153 MAX_MIRED = 370 +DEFAULT_LOWER_BRIGHTNESS = 29 +DEFAULT_UPPER_BRIGHTNESS = 1000 + + +def map_range(value, from_lower, from_upper, to_lower, to_upper): + """Map a value in one range to another.""" + mapped = (value - from_lower) * (to_upper - to_lower) / ( + from_upper - from_lower + ) + to_lower + return int(min(max(mapped, to_lower), to_upper)) + def flow_schema(dps): """Return schema used in config flow.""" return { vol.Optional(CONF_BRIGHTNESS): vol.In(dps), vol.Optional(CONF_COLOR_TEMP): vol.In(dps), + vol.Optional(CONF_BRIGHTNESS_LOWER, default=DEFAULT_LOWER_BRIGHTNESS): vol.All( + vol.Coerce(int), vol.Range(min=0, max=10000) + ), + vol.Optional(CONF_BRIGHTNESS_UPPER, default=DEFAULT_UPPER_BRIGHTNESS): vol.All( + vol.Coerce(int), vol.Range(min=0, max=10000) + ), } @@ -47,8 +65,14 @@ class LocaltuyaLight(LocalTuyaEntity, LightEntity): """Initialize the Tuya light.""" super().__init__(device, config_entry, lightid, **kwargs) self._state = False - self._brightness = 127 - self._color_temp = 127 + self._brightness = None + self._color_temp = None + self._lower_brightness = self._config.get( + CONF_BRIGHTNESS_LOWER, DEFAULT_LOWER_BRIGHTNESS + ) + self._upper_brightness = self._config.get( + CONF_BRIGHTNESS_UPPER, DEFAULT_UPPER_BRIGHTNESS + ) @property def is_on(self): @@ -63,10 +87,8 @@ class LocaltuyaLight(LocalTuyaEntity, LightEntity): @property def color_temp(self): """Return the color_temp of the light.""" - try: + if self.has_config(CONF_COLOR_TEMP): return int(MAX_MIRED - (((MAX_MIRED - MIN_MIRED) / 255) * self._color_temp)) - except TypeError: - pass @property def min_mireds(self): @@ -81,24 +103,32 @@ class LocaltuyaLight(LocalTuyaEntity, LightEntity): @property def supported_features(self): """Flag supported features.""" - supports = SUPPORT_BRIGHTNESS - if self._color_temp is not None: - supports = supports | SUPPORT_COLOR_TEMP + supports = 0 + if self.has_config(CONF_BRIGHTNESS): + supports |= SUPPORT_BRIGHTNESS + if self.has_config(CONF_COLOR_TEMP): + supports |= SUPPORT_COLOR_TEMP return supports async def async_turn_on(self, **kwargs): """Turn on or control the light.""" - await self._device.set_dp(True, self._dp_id) + self._device.set_dp(True, self._dp_id) + features = self.supported_features - if ATTR_BRIGHTNESS in kwargs: - await self._device.set_dp( - max(int(kwargs[ATTR_BRIGHTNESS]), 25), self._config.get(CONF_BRIGHTNESS) + if ATTR_BRIGHTNESS in kwargs and (features & SUPPORT_BRIGHTNESS): + brightness = map_range( + int(kwargs[ATTR_BRIGHTNESS]), + 0, + 255, + self._lower_brightness, + self._upper_brightness, ) + self._device.set_dp(brightness, self._config.get(CONF_BRIGHTNESS)) if ATTR_HS_COLOR in kwargs: raise ValueError(" TODO implement RGB from HS") - if ATTR_COLOR_TEMP in kwargs: + if ATTR_COLOR_TEMP in kwargs and (features & SUPPORT_COLOR_TEMP): color_temp = int( 255 - (255 / (MAX_MIRED - MIN_MIRED)) @@ -113,14 +143,22 @@ class LocaltuyaLight(LocalTuyaEntity, LightEntity): def status_updated(self): """Device status was updated.""" self._state = self.dps(self._dp_id) + supported = self.supported_features - brightness = self.dps_conf(CONF_BRIGHTNESS) - if brightness is not None: - brightness = min(brightness, 255) - brightness = max(brightness, 25) - self._brightness = brightness + if supported & SUPPORT_BRIGHTNESS: + brightness = self.dps_conf(CONF_BRIGHTNESS) + if brightness is not None: + brightness = map_range( + brightness, + self._lower_brightness, + self._upper_brightness, + 0, + 255, + ) + self._brightness = brightness - self._color_temp = self.dps_conf(CONF_COLOR_TEMP) + if supported & SUPPORT_COLOR_TEMP: + self._color_temp = self.dps_conf(CONF_COLOR_TEMP) async_setup_entry = partial(async_setup_entry, DOMAIN, LocaltuyaLight, flow_schema) diff --git a/custom_components/localtuya/translations/en.json b/custom_components/localtuya/translations/en.json index 5ab3783..3193735 100644 --- a/custom_components/localtuya/translations/en.json +++ b/custom_components/localtuya/translations/en.json @@ -57,6 +57,8 @@ "state_on": "On Value", "state_off": "Off Value", "brightness": "Brightness", + "brightness_lower": "Brightness Lower Value", + "brightness_upper": "Brightness Upper Value", "color_temp": "Color Temperature" } } @@ -94,6 +96,8 @@ "state_on": "On Value", "state_off": "Off Value", "brightness": "Brightness", + "brightness_lower": "Brightness Lower Value", + "brightness_upper": "Brightness Upper Value", "color_temp": "Color Temperature" } },