Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions homeassistant/components/mqtt/light/schema_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
_optimistic: bool
_optimistic_brightness: bool
_optimistic_color_mode: bool
_optimistic_color_temp: bool
_optimistic_color_temp_kelvin: bool
_optimistic_effect: bool
_optimistic_hs_color: bool
_optimistic_rgb_color: bool
Expand Down Expand Up @@ -327,7 +327,7 @@ def _setup_from_config(self, config: ConfigType) -> None:
and topic[CONF_RGB_STATE_TOPIC] is None
)
)
self._optimistic_color_temp = (
self._optimistic_color_temp_kelvin = (
optimistic or topic[CONF_COLOR_TEMP_STATE_TOPIC] is None
)
self._optimistic_effect = optimistic or topic[CONF_EFFECT_STATE_TOPIC] is None
Expand Down Expand Up @@ -518,7 +518,9 @@ def _color_temp_received(self, msg: ReceiveMessage) -> None:

if self._optimistic_color_mode:
self._attr_color_mode = ColorMode.COLOR_TEMP
self._attr_color_temp = int(payload)
self._attr_color_temp_kelvin = color_util.color_temperature_mired_to_kelvin(
int(payload)
)

@callback
def _effect_received(self, msg: ReceiveMessage) -> None:
Expand Down Expand Up @@ -592,7 +594,7 @@ def _prepare_subscribe_topics(self) -> None: # noqa: C901
self.add_subscription(
CONF_COLOR_TEMP_STATE_TOPIC,
self._color_temp_received,
{"_attr_color_mode", "_attr_color_temp"},
{"_attr_color_mode", "_attr_color_temp_kelvin"},
)
self.add_subscription(
CONF_EFFECT_STATE_TOPIC, self._effect_received, {"_attr_effect"}
Expand Down Expand Up @@ -631,7 +633,7 @@ def restore_state(
restore_state(ATTR_RGBW_COLOR)
restore_state(ATTR_RGBWW_COLOR)
restore_state(ATTR_COLOR_MODE)
restore_state(ATTR_COLOR_TEMP)
restore_state(ATTR_COLOR_TEMP_KELVIN)
restore_state(ATTR_EFFECT)
restore_state(ATTR_HS_COLOR)
restore_state(ATTR_XY_COLOR)
Expand Down Expand Up @@ -803,14 +805,21 @@ def set_optimistic(
await publish(CONF_RGBWW_COMMAND_TOPIC, rgbww_s)
should_update |= set_optimistic(ATTR_BRIGHTNESS, kwargs[ATTR_BRIGHTNESS])
if (
ATTR_COLOR_TEMP in kwargs
ATTR_COLOR_TEMP_KELVIN in kwargs
and self._topic[CONF_COLOR_TEMP_COMMAND_TOPIC] is not None
):
ct_command_tpl = self._command_templates[CONF_COLOR_TEMP_COMMAND_TEMPLATE]
color_temp = ct_command_tpl(int(kwargs[ATTR_COLOR_TEMP]), None)
color_temp = ct_command_tpl(
color_util.color_temperature_kelvin_to_mired(
kwargs[ATTR_COLOR_TEMP_KELVIN]
),
None,
)
await publish(CONF_COLOR_TEMP_COMMAND_TOPIC, color_temp)
should_update |= set_optimistic(
ATTR_COLOR_TEMP, kwargs[ATTR_COLOR_TEMP], ColorMode.COLOR_TEMP
ATTR_COLOR_TEMP_KELVIN,
kwargs[ATTR_COLOR_TEMP_KELVIN],
ColorMode.COLOR_TEMP,
)

if (
Expand Down
42 changes: 30 additions & 12 deletions homeassistant/components/mqtt/light/schema_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_COLOR_MODE,
ATTR_COLOR_TEMP,
ATTR_COLOR_TEMP_KELVIN,
ATTR_EFFECT,
ATTR_FLASH,
ATTR_HS_COLOR,
Expand Down Expand Up @@ -273,8 +273,16 @@ def config_schema() -> VolSchemaType:

def _setup_from_config(self, config: ConfigType) -> None:
"""(Re)Setup the entity."""
self._attr_max_mireds = config.get(CONF_MAX_MIREDS, super().max_mireds)
self._attr_min_mireds = config.get(CONF_MIN_MIREDS, super().min_mireds)
self._attr_min_color_temp_kelvin = (
color_util.color_temperature_mired_to_kelvin(max_mireds)
if (max_mireds := config.get(CONF_MAX_MIREDS))
else super().min_color_temp_kelvin
)
self._attr_max_color_temp_kelvin = (
color_util.color_temperature_mired_to_kelvin(min_mireds)
if (min_mireds := config.get(CONF_MIN_MIREDS))
else super().max_color_temp_kelvin
)
self._attr_effect_list = config.get(CONF_EFFECT_LIST)

self._topic = {
Expand Down Expand Up @@ -370,7 +378,11 @@ def _update_color(self, values: dict[str, Any]) -> None:
return
try:
if color_mode == ColorMode.COLOR_TEMP:
self._attr_color_temp = int(values["color_temp"])
self._attr_color_temp_kelvin = (
color_util.color_temperature_mired_to_kelvin(
values["color_temp"]
)
)
self._attr_color_mode = ColorMode.COLOR_TEMP
elif color_mode == ColorMode.HS:
hue = float(values["color"]["h"])
Expand Down Expand Up @@ -469,9 +481,13 @@ def _state_received(self, msg: ReceiveMessage) -> None:
# Deprecated color handling
try:
if values["color_temp"] is None:
self._attr_color_temp = None
self._attr_color_temp_kelvin = None
else:
self._attr_color_temp = int(values["color_temp"]) # type: ignore[arg-type]
self._attr_color_temp_kelvin = (
color_util.color_temperature_mired_to_kelvin(
values["color_temp"] # type: ignore[arg-type]
)
)
except KeyError:
pass
except ValueError:
Expand All @@ -496,7 +512,7 @@ def _prepare_subscribe_topics(self) -> None:
self._state_received,
{
"_attr_brightness",
"_attr_color_temp",
"_attr_color_temp_kelvin",
"_attr_effect",
"_attr_hs_color",
"_attr_is_on",
Expand All @@ -522,8 +538,8 @@ async def _subscribe_topics(self) -> None:
self._attr_color_mode = last_attributes.get(
ATTR_COLOR_MODE, self.color_mode
)
self._attr_color_temp = last_attributes.get(
ATTR_COLOR_TEMP, self.color_temp
self._attr_color_temp_kelvin = last_attributes.get(
ATTR_COLOR_TEMP_KELVIN, self.color_temp_kelvin
)
self._attr_effect = last_attributes.get(ATTR_EFFECT, self.effect)
self._attr_hs_color = last_attributes.get(ATTR_HS_COLOR, self.hs_color)
Expand Down Expand Up @@ -690,12 +706,14 @@ async def async_turn_on(self, **kwargs: Any) -> None: # noqa: C901
self._attr_brightness = kwargs[ATTR_BRIGHTNESS]
should_update = True

if ATTR_COLOR_TEMP in kwargs:
message["color_temp"] = int(kwargs[ATTR_COLOR_TEMP])
if ATTR_COLOR_TEMP_KELVIN in kwargs:
message["color_temp"] = color_util.color_temperature_kelvin_to_mired(
kwargs[ATTR_COLOR_TEMP_KELVIN]
)

if self._optimistic:
self._attr_color_mode = ColorMode.COLOR_TEMP
self._attr_color_temp = kwargs[ATTR_COLOR_TEMP]
self._attr_color_temp_kelvin = kwargs[ATTR_COLOR_TEMP_KELVIN]
self._attr_hs_color = None
should_update = True

Expand Down
38 changes: 26 additions & 12 deletions homeassistant/components/mqtt/light/schema_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP,
ATTR_COLOR_TEMP_KELVIN,
ATTR_EFFECT,
ATTR_FLASH,
ATTR_HS_COLOR,
Expand Down Expand Up @@ -126,8 +126,16 @@ def config_schema() -> VolSchemaType:

def _setup_from_config(self, config: ConfigType) -> None:
"""(Re)Setup the entity."""
self._attr_max_mireds = config.get(CONF_MAX_MIREDS, super().max_mireds)
self._attr_min_mireds = config.get(CONF_MIN_MIREDS, super().min_mireds)
self._attr_min_color_temp_kelvin = (
color_util.color_temperature_mired_to_kelvin(max_mireds)
if (max_mireds := config.get(CONF_MAX_MIREDS))
else super().min_color_temp_kelvin
)
self._attr_max_color_temp_kelvin = (
color_util.color_temperature_mired_to_kelvin(min_mireds)
if (min_mireds := config.get(CONF_MIN_MIREDS))
else super().max_color_temp_kelvin
)
self._attr_effect_list = config.get(CONF_EFFECT_LIST)

self._topics = {
Expand Down Expand Up @@ -213,8 +221,10 @@ def _state_received(self, msg: ReceiveMessage) -> None:
color_temp = self._value_templates[CONF_COLOR_TEMP_TEMPLATE](
msg.payload
)
self._attr_color_temp = (
int(color_temp) if color_temp != "None" else None
self._attr_color_temp_kelvin = (
color_util.color_temperature_mired_to_kelvin(int(color_temp))
if color_temp != "None"
else None
)
except ValueError:
_LOGGER.warning("Invalid color temperature value received")
Expand Down Expand Up @@ -256,7 +266,7 @@ def _prepare_subscribe_topics(self) -> None:
{
"_attr_brightness",
"_attr_color_mode",
"_attr_color_temp",
"_attr_color_temp_kelvin",
"_attr_effect",
"_attr_hs_color",
"_attr_is_on",
Expand All @@ -275,8 +285,10 @@ async def _subscribe_topics(self) -> None:
if last_state.attributes.get(ATTR_HS_COLOR):
self._attr_hs_color = last_state.attributes.get(ATTR_HS_COLOR)
self._update_color_mode()
if last_state.attributes.get(ATTR_COLOR_TEMP):
self._attr_color_temp = last_state.attributes.get(ATTR_COLOR_TEMP)
if last_state.attributes.get(ATTR_COLOR_TEMP_KELVIN):
self._attr_color_temp_kelvin = last_state.attributes.get(
ATTR_COLOR_TEMP_KELVIN
)
if last_state.attributes.get(ATTR_EFFECT):
self._attr_effect = last_state.attributes.get(ATTR_EFFECT)

Expand All @@ -295,11 +307,13 @@ async def async_turn_on(self, **kwargs: Any) -> None:
if self._optimistic:
self._attr_brightness = kwargs[ATTR_BRIGHTNESS]

if ATTR_COLOR_TEMP in kwargs:
values["color_temp"] = int(kwargs[ATTR_COLOR_TEMP])
if ATTR_COLOR_TEMP_KELVIN in kwargs:
values["color_temp"] = color_util.color_temperature_kelvin_to_mired(
kwargs[ATTR_COLOR_TEMP_KELVIN]
)

if self._optimistic:
self._attr_color_temp = kwargs[ATTR_COLOR_TEMP]
self._attr_color_temp_kelvin = kwargs[ATTR_COLOR_TEMP_KELVIN]
self._attr_hs_color = None
self._update_color_mode()

Expand All @@ -325,7 +339,7 @@ async def async_turn_on(self, **kwargs: Any) -> None:
values["sat"] = hs_color[1]

if self._optimistic:
self._attr_color_temp = None
self._attr_color_temp_kelvin = None
self._attr_hs_color = kwargs[ATTR_HS_COLOR]
self._update_color_mode()

Expand Down
4 changes: 2 additions & 2 deletions tests/components/mqtt/test_light.py
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,7 @@ async def test_sending_mqtt_commands_and_optimistic(
"brightness": 95,
"hs_color": [100, 100],
"effect": "random",
"color_temp": 100,
"color_temp_kelvin": 100000,
"color_mode": "hs",
},
)
Expand All @@ -1021,7 +1021,7 @@ async def test_sending_mqtt_commands_and_optimistic(
assert state.attributes.get("brightness") == 95
assert state.attributes.get("hs_color") == (100, 100)
assert state.attributes.get("effect") == "random"
assert state.attributes.get("color_temp") is None
assert state.attributes.get("color_temp_kelvin") is None
assert state.attributes.get(light.ATTR_COLOR_MODE) == "hs"
assert state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) == color_modes
assert state.attributes.get(ATTR_ASSUMED_STATE)
Expand Down
6 changes: 3 additions & 3 deletions tests/components/mqtt/test_light_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ async def test_sending_mqtt_commands_and_optimistic(
"brightness": 95,
"hs_color": [100, 100],
"effect": "random",
"color_temp": 100,
"color_temp_kelvin": 10000,
Comment thread
jbouwh marked this conversation as resolved.
},
)
mock_restore_cache(hass, (fake_state,))
Expand All @@ -1065,7 +1065,7 @@ async def test_sending_mqtt_commands_and_optimistic(
assert state.attributes.get("brightness") == 95
assert state.attributes.get("hs_color") == (100, 100)
assert state.attributes.get("effect") == "random"
assert state.attributes.get("color_temp") is None # hs_color has priority
assert state.attributes.get("color_temp_kelvin") is None # hs_color has priority
color_modes = [light.ColorMode.COLOR_TEMP, light.ColorMode.HS]
assert state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) == color_modes
expected_features = (
Expand Down Expand Up @@ -1205,7 +1205,7 @@ async def test_sending_mqtt_commands_and_optimistic2(
"on",
{
"brightness": 95,
"color_temp": 100,
"color_temp_kelvin": 10000,
"color_mode": "rgb",
"effect": "random",
"hs_color": [100, 100],
Expand Down
4 changes: 2 additions & 2 deletions tests/components/mqtt/test_light_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ async def test_sending_mqtt_commands_and_optimistic(
"brightness": 95,
"hs_color": [100, 100],
"effect": "random",
"color_temp": 100,
"color_temp_kelvin": 10000,
Comment thread
jbouwh marked this conversation as resolved.
},
)
mock_restore_cache(hass, (fake_state,))
Expand All @@ -443,7 +443,7 @@ async def test_sending_mqtt_commands_and_optimistic(
assert state.state == STATE_ON
assert state.attributes.get("hs_color") == (100, 100)
assert state.attributes.get("effect") == "random"
assert state.attributes.get("color_temp") is None # hs_color has priority
assert state.attributes.get("color_temp_kelvin") is None # hs_color has priority
assert state.attributes.get(ATTR_ASSUMED_STATE)

await common.async_turn_off(hass, "light.test")
Expand Down