Deduplicate code in MQTT basic light pt4: Add set_optimistic helper (#50774)
This commit is contained in:
parent
2f10f59717
commit
848ab5c2bc
1 changed files with 42 additions and 49 deletions
|
@ -8,7 +8,9 @@ from homeassistant.components.light import (
|
||||||
ATTR_COLOR_TEMP,
|
ATTR_COLOR_TEMP,
|
||||||
ATTR_EFFECT,
|
ATTR_EFFECT,
|
||||||
ATTR_HS_COLOR,
|
ATTR_HS_COLOR,
|
||||||
|
ATTR_RGB_COLOR,
|
||||||
ATTR_WHITE_VALUE,
|
ATTR_WHITE_VALUE,
|
||||||
|
ATTR_XY_COLOR,
|
||||||
SUPPORT_BRIGHTNESS,
|
SUPPORT_BRIGHTNESS,
|
||||||
SUPPORT_COLOR,
|
SUPPORT_COLOR,
|
||||||
SUPPORT_COLOR_TEMP,
|
SUPPORT_COLOR_TEMP,
|
||||||
|
@ -167,13 +169,13 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
self._command_templates = None
|
self._command_templates = None
|
||||||
self._value_templates = None
|
self._value_templates = None
|
||||||
self._optimistic = False
|
self._optimistic = False
|
||||||
self._optimistic_rgb = False
|
self._optimistic_rgb_color = False
|
||||||
self._optimistic_brightness = False
|
self._optimistic_brightness = False
|
||||||
self._optimistic_color_temp = False
|
self._optimistic_color_temp = False
|
||||||
self._optimistic_effect = False
|
self._optimistic_effect = False
|
||||||
self._optimistic_hs = False
|
self._optimistic_hs_color = False
|
||||||
self._optimistic_white_value = False
|
self._optimistic_white_value = False
|
||||||
self._optimistic_xy = False
|
self._optimistic_xy_color = False
|
||||||
|
|
||||||
MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
|
MqttEntity.__init__(self, hass, config, config_entry, discovery_data)
|
||||||
|
|
||||||
|
@ -228,7 +230,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
|
|
||||||
optimistic = config[CONF_OPTIMISTIC]
|
optimistic = config[CONF_OPTIMISTIC]
|
||||||
self._optimistic = optimistic or topic[CONF_STATE_TOPIC] is None
|
self._optimistic = optimistic or topic[CONF_STATE_TOPIC] is None
|
||||||
self._optimistic_rgb = optimistic or topic[CONF_RGB_STATE_TOPIC] is None
|
self._optimistic_rgb_color = optimistic or topic[CONF_RGB_STATE_TOPIC] is None
|
||||||
self._optimistic_brightness = (
|
self._optimistic_brightness = (
|
||||||
optimistic
|
optimistic
|
||||||
or (
|
or (
|
||||||
|
@ -244,11 +246,15 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
optimistic or topic[CONF_COLOR_TEMP_STATE_TOPIC] is None
|
optimistic or topic[CONF_COLOR_TEMP_STATE_TOPIC] is None
|
||||||
)
|
)
|
||||||
self._optimistic_effect = optimistic or topic[CONF_EFFECT_STATE_TOPIC] is None
|
self._optimistic_effect = optimistic or topic[CONF_EFFECT_STATE_TOPIC] is None
|
||||||
self._optimistic_hs = optimistic or topic[CONF_HS_STATE_TOPIC] is None
|
self._optimistic_hs_color = optimistic or topic[CONF_HS_STATE_TOPIC] is None
|
||||||
self._optimistic_white_value = (
|
self._optimistic_white_value = (
|
||||||
optimistic or topic[CONF_WHITE_VALUE_STATE_TOPIC] is None
|
optimistic or topic[CONF_WHITE_VALUE_STATE_TOPIC] is None
|
||||||
)
|
)
|
||||||
self._optimistic_xy = optimistic or topic[CONF_XY_STATE_TOPIC] is None
|
self._optimistic_xy_color = optimistic or topic[CONF_XY_STATE_TOPIC] is None
|
||||||
|
|
||||||
|
def _is_optimistic(self, attribute):
|
||||||
|
"""Return True if the attribute is optimistically updated."""
|
||||||
|
return getattr(self, f"_optimistic_{attribute}")
|
||||||
|
|
||||||
async def _subscribe_topics(self): # noqa: C901
|
async def _subscribe_topics(self): # noqa: C901
|
||||||
"""(Re)Subscribe to topics."""
|
"""(Re)Subscribe to topics."""
|
||||||
|
@ -265,9 +271,12 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
"qos": self._config[CONF_QOS],
|
"qos": self._config[CONF_QOS],
|
||||||
}
|
}
|
||||||
|
|
||||||
def restore_state(attribute, condition):
|
def restore_state(attribute, condition_attribute=None):
|
||||||
"""Restore a state attribute."""
|
"""Restore a state attribute."""
|
||||||
if condition and last_state and last_state.attributes.get(attribute):
|
if condition_attribute is None:
|
||||||
|
condition_attribute = attribute
|
||||||
|
optimistic = self._is_optimistic(condition_attribute)
|
||||||
|
if optimistic and last_state and last_state.attributes.get(attribute):
|
||||||
setattr(self, f"_{attribute}", last_state.attributes[attribute])
|
setattr(self, f"_{attribute}", last_state.attributes[attribute])
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
@ -313,7 +322,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
add_topic(CONF_BRIGHTNESS_STATE_TOPIC, brightness_received)
|
add_topic(CONF_BRIGHTNESS_STATE_TOPIC, brightness_received)
|
||||||
restore_state(ATTR_BRIGHTNESS, self._optimistic_brightness)
|
restore_state(ATTR_BRIGHTNESS)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@log_messages(self.hass, self.entity_id)
|
@log_messages(self.hass, self.entity_id)
|
||||||
|
@ -332,7 +341,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
add_topic(CONF_RGB_STATE_TOPIC, rgb_received)
|
add_topic(CONF_RGB_STATE_TOPIC, rgb_received)
|
||||||
restore_state(ATTR_HS_COLOR, self._optimistic_rgb)
|
restore_state(ATTR_HS_COLOR, ATTR_RGB_COLOR)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@log_messages(self.hass, self.entity_id)
|
@log_messages(self.hass, self.entity_id)
|
||||||
|
@ -349,7 +358,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
add_topic(CONF_COLOR_TEMP_STATE_TOPIC, color_temp_received)
|
add_topic(CONF_COLOR_TEMP_STATE_TOPIC, color_temp_received)
|
||||||
restore_state(ATTR_COLOR_TEMP, self._optimistic_color_temp)
|
restore_state(ATTR_COLOR_TEMP)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@log_messages(self.hass, self.entity_id)
|
@log_messages(self.hass, self.entity_id)
|
||||||
|
@ -366,7 +375,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
add_topic(CONF_EFFECT_STATE_TOPIC, effect_received)
|
add_topic(CONF_EFFECT_STATE_TOPIC, effect_received)
|
||||||
restore_state(ATTR_EFFECT, self._optimistic_effect)
|
restore_state(ATTR_EFFECT)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@log_messages(self.hass, self.entity_id)
|
@log_messages(self.hass, self.entity_id)
|
||||||
|
@ -385,7 +394,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
_LOGGER.debug("Failed to parse hs state update: '%s'", payload)
|
_LOGGER.debug("Failed to parse hs state update: '%s'", payload)
|
||||||
|
|
||||||
add_topic(CONF_HS_STATE_TOPIC, hs_received)
|
add_topic(CONF_HS_STATE_TOPIC, hs_received)
|
||||||
restore_state(ATTR_HS_COLOR, self._optimistic_hs)
|
restore_state(ATTR_HS_COLOR)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@log_messages(self.hass, self.entity_id)
|
@log_messages(self.hass, self.entity_id)
|
||||||
|
@ -404,7 +413,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
add_topic(CONF_WHITE_VALUE_STATE_TOPIC, white_value_received)
|
add_topic(CONF_WHITE_VALUE_STATE_TOPIC, white_value_received)
|
||||||
restore_state(ATTR_WHITE_VALUE, self._optimistic_white_value)
|
restore_state(ATTR_WHITE_VALUE)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@log_messages(self.hass, self.entity_id)
|
@log_messages(self.hass, self.entity_id)
|
||||||
|
@ -420,7 +429,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
add_topic(CONF_XY_STATE_TOPIC, xy_received)
|
add_topic(CONF_XY_STATE_TOPIC, xy_received)
|
||||||
restore_state(ATTR_HS_COLOR, self._optimistic_xy)
|
restore_state(ATTR_HS_COLOR, ATTR_XY_COLOR)
|
||||||
|
|
||||||
self._sub_state = await subscription.async_subscribe_topics(
|
self._sub_state = await subscription.async_subscribe_topics(
|
||||||
self.hass, self._sub_state, topics
|
self.hass, self._sub_state, topics
|
||||||
|
@ -523,7 +532,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
|
|
||||||
return supported_features
|
return supported_features
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs): # noqa: C901
|
async def async_turn_on(self, **kwargs):
|
||||||
"""Turn the device on.
|
"""Turn the device on.
|
||||||
|
|
||||||
This method is a coroutine.
|
This method is a coroutine.
|
||||||
|
@ -541,6 +550,15 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
self._config[CONF_RETAIN],
|
self._config[CONF_RETAIN],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def set_optimistic(attribute, value, condition_attribute=None):
|
||||||
|
"""Optimistically update a state attribute."""
|
||||||
|
if condition_attribute is None:
|
||||||
|
condition_attribute = attribute
|
||||||
|
if not self._is_optimistic(condition_attribute):
|
||||||
|
return False
|
||||||
|
setattr(self, f"_{attribute}", value)
|
||||||
|
return True
|
||||||
|
|
||||||
if on_command_type == "first":
|
if on_command_type == "first":
|
||||||
publish(CONF_COMMAND_TOPIC, self._payload["on"])
|
publish(CONF_COMMAND_TOPIC, self._payload["on"])
|
||||||
should_update = True
|
should_update = True
|
||||||
|
@ -573,28 +591,18 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
rgb_color_str = f"{rgb[0]},{rgb[1]},{rgb[2]}"
|
rgb_color_str = f"{rgb[0]},{rgb[1]},{rgb[2]}"
|
||||||
|
|
||||||
publish(CONF_RGB_COMMAND_TOPIC, rgb_color_str)
|
publish(CONF_RGB_COMMAND_TOPIC, rgb_color_str)
|
||||||
|
should_update |= set_optimistic(ATTR_HS_COLOR, hs_color, ATTR_RGB_COLOR)
|
||||||
if self._optimistic_rgb:
|
|
||||||
self._hs_color = kwargs[ATTR_HS_COLOR]
|
|
||||||
should_update = True
|
|
||||||
|
|
||||||
if ATTR_HS_COLOR in kwargs and self._topic[CONF_HS_COMMAND_TOPIC] is not None:
|
if ATTR_HS_COLOR in kwargs and self._topic[CONF_HS_COMMAND_TOPIC] is not None:
|
||||||
|
|
||||||
hs_color = kwargs[ATTR_HS_COLOR]
|
hs_color = kwargs[ATTR_HS_COLOR]
|
||||||
publish(CONF_HS_COMMAND_TOPIC, f"{hs_color[0]},{hs_color[1]}")
|
publish(CONF_HS_COMMAND_TOPIC, f"{hs_color[0]},{hs_color[1]}")
|
||||||
|
should_update |= set_optimistic(ATTR_HS_COLOR, hs_color)
|
||||||
if self._optimistic_hs:
|
|
||||||
self._hs_color = kwargs[ATTR_HS_COLOR]
|
|
||||||
should_update = True
|
|
||||||
|
|
||||||
if ATTR_HS_COLOR in kwargs and self._topic[CONF_XY_COMMAND_TOPIC] is not None:
|
if ATTR_HS_COLOR in kwargs and self._topic[CONF_XY_COMMAND_TOPIC] is not None:
|
||||||
|
|
||||||
xy_color = color_util.color_hs_to_xy(*kwargs[ATTR_HS_COLOR])
|
xy_color = color_util.color_hs_to_xy(*kwargs[ATTR_HS_COLOR])
|
||||||
publish(CONF_XY_COMMAND_TOPIC, f"{xy_color[0]},{xy_color[1]}")
|
publish(CONF_XY_COMMAND_TOPIC, f"{xy_color[0]},{xy_color[1]}")
|
||||||
|
should_update |= set_optimistic(ATTR_HS_COLOR, hs_color, ATTR_XY_COLOR)
|
||||||
if self._optimistic_xy:
|
|
||||||
self._hs_color = kwargs[ATTR_HS_COLOR]
|
|
||||||
should_update = True
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
ATTR_BRIGHTNESS in kwargs
|
ATTR_BRIGHTNESS in kwargs
|
||||||
|
@ -608,10 +616,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
# Make sure the brightness is not rounded down to 0
|
# Make sure the brightness is not rounded down to 0
|
||||||
device_brightness = max(device_brightness, 1)
|
device_brightness = max(device_brightness, 1)
|
||||||
publish(CONF_BRIGHTNESS_COMMAND_TOPIC, device_brightness)
|
publish(CONF_BRIGHTNESS_COMMAND_TOPIC, device_brightness)
|
||||||
|
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
||||||
if self._optimistic_brightness:
|
|
||||||
self._brightness = kwargs[ATTR_BRIGHTNESS]
|
|
||||||
should_update = True
|
|
||||||
elif (
|
elif (
|
||||||
ATTR_BRIGHTNESS in kwargs
|
ATTR_BRIGHTNESS in kwargs
|
||||||
and ATTR_HS_COLOR not in kwargs
|
and ATTR_HS_COLOR not in kwargs
|
||||||
|
@ -628,10 +633,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
rgb_color_str = f"{rgb[0]},{rgb[1]},{rgb[2]}"
|
rgb_color_str = f"{rgb[0]},{rgb[1]},{rgb[2]}"
|
||||||
|
|
||||||
publish(CONF_RGB_COMMAND_TOPIC, rgb_color_str)
|
publish(CONF_RGB_COMMAND_TOPIC, rgb_color_str)
|
||||||
|
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
|
||||||
if self._optimistic_brightness:
|
|
||||||
self._brightness = kwargs[ATTR_BRIGHTNESS]
|
|
||||||
should_update = True
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
ATTR_COLOR_TEMP in kwargs
|
ATTR_COLOR_TEMP in kwargs
|
||||||
|
@ -644,19 +646,13 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
color_temp = tpl({"value": color_temp})
|
color_temp = tpl({"value": color_temp})
|
||||||
|
|
||||||
publish(CONF_COLOR_TEMP_COMMAND_TOPIC, color_temp)
|
publish(CONF_COLOR_TEMP_COMMAND_TOPIC, color_temp)
|
||||||
|
should_update |= set_optimistic(ATTR_COLOR_TEMP, kwargs[ATTR_COLOR_TEMP])
|
||||||
if self._optimistic_color_temp:
|
|
||||||
self._color_temp = kwargs[ATTR_COLOR_TEMP]
|
|
||||||
should_update = True
|
|
||||||
|
|
||||||
if ATTR_EFFECT in kwargs and self._topic[CONF_EFFECT_COMMAND_TOPIC] is not None:
|
if ATTR_EFFECT in kwargs and self._topic[CONF_EFFECT_COMMAND_TOPIC] is not None:
|
||||||
effect = kwargs[ATTR_EFFECT]
|
effect = kwargs[ATTR_EFFECT]
|
||||||
if effect in self._config.get(CONF_EFFECT_LIST):
|
if effect in self._config.get(CONF_EFFECT_LIST):
|
||||||
publish(CONF_EFFECT_COMMAND_TOPIC, effect)
|
publish(CONF_EFFECT_COMMAND_TOPIC, effect)
|
||||||
|
should_update |= set_optimistic(ATTR_EFFECT, effect)
|
||||||
if self._optimistic_effect:
|
|
||||||
self._effect = kwargs[ATTR_EFFECT]
|
|
||||||
should_update = True
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
ATTR_WHITE_VALUE in kwargs
|
ATTR_WHITE_VALUE in kwargs
|
||||||
|
@ -666,10 +662,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
|
||||||
white_scale = self._config[CONF_WHITE_VALUE_SCALE]
|
white_scale = self._config[CONF_WHITE_VALUE_SCALE]
|
||||||
device_white_value = min(round(percent_white * white_scale), white_scale)
|
device_white_value = min(round(percent_white * white_scale), white_scale)
|
||||||
publish(CONF_WHITE_VALUE_COMMAND_TOPIC, device_white_value)
|
publish(CONF_WHITE_VALUE_COMMAND_TOPIC, device_white_value)
|
||||||
|
should_update |= set_optimistic(ATTR_WHITE_VALUE, kwargs[ATTR_WHITE_VALUE])
|
||||||
if self._optimistic_white_value:
|
|
||||||
self._white_value = kwargs[ATTR_WHITE_VALUE]
|
|
||||||
should_update = True
|
|
||||||
|
|
||||||
if on_command_type == "last":
|
if on_command_type == "last":
|
||||||
publish(CONF_COMMAND_TOPIC, self._payload["on"])
|
publish(CONF_COMMAND_TOPIC, self._payload["on"])
|
||||||
|
|
Loading…
Add table
Reference in a new issue