Remove option to use mireds for color temperature

This commit is contained in:
jbouwh 2025-04-13 12:37:28 +00:00
parent 10f86948fb
commit cbb9673091
4 changed files with 42 additions and 118 deletions

View File

@ -155,9 +155,7 @@ from .const import (
CONF_KEEPALIVE,
CONF_LAST_RESET_VALUE_TEMPLATE,
CONF_MAX_KELVIN,
CONF_MAX_MIREDS,
CONF_MIN_KELVIN,
CONF_MIN_MIREDS,
CONF_ON_COMMAND_TYPE,
CONF_OPTIONS,
CONF_PAYLOAD_AVAILABLE,
@ -236,9 +234,6 @@ ADDON_SETUP_TIMEOUT_ROUNDS = 5
CONF_CLIENT_KEY_PASSWORD = "client_key_password"
DEFAULT_MAX_MIREDS = 500
DEFAULT_MIN_MIREDS = 154
MQTT_TIMEOUT = 5
ADVANCED_OPTIONS = "advanced_options"
@ -386,15 +381,6 @@ KELVIN_SELECTOR = NumberSelector(
unit_of_measurement="K",
)
)
MIRED_SELECTOR = NumberSelector(
NumberSelectorConfig(
mode=NumberSelectorMode.BOX,
min=100,
max=1000,
step="any",
unit_of_measurement="mireds",
)
)
SCALE_SELECTOR = NumberSelector(
NumberSelectorConfig(
mode=NumberSelectorMode.BOX,
@ -477,7 +463,8 @@ class PlatformField:
required: bool
validator: Callable[..., Any]
error: str | None = None
default: str | int | vol.Undefined = vol.UNDEFINED
default: str | int | bool | vol.Undefined = vol.UNDEFINED
is_schema_default: bool = False
exclude_from_reconfig: bool = False
conditions: tuple[dict[str, Any], ...] | None = None
custom_filtering: bool = False
@ -506,17 +493,11 @@ def unit_of_measurement_selector(user_data: dict[str, Any | None]) -> Selector:
def validate_light_platform_config(user_data: dict[str, Any]) -> dict[str, str]:
"""Validate MQTT light configuration."""
errors: dict[str, Any] = {}
if user_data[CONF_COLOR_TEMP_KELVIN]:
if user_data.get(CONF_MIN_KELVIN, DEFAULT_MIN_KELVIN) >= user_data.get(
CONF_MAX_KELVIN, DEFAULT_MAX_KELVIN
):
errors[CONF_MAX_KELVIN] = "max_below_min_kelvin"
errors[CONF_MIN_KELVIN] = "max_below_min_kelvin"
elif user_data.get(CONF_MIN_MIREDS, DEFAULT_MIN_MIREDS) >= user_data.get(
CONF_MAX_MIREDS, DEFAULT_MAX_MIREDS
):
errors[CONF_MAX_MIREDS] = "max_below_min_mireds"
errors[CONF_MIN_MIREDS] = "max_below_min_mireds"
return errors
@ -580,11 +561,11 @@ PLATFORM_ENTITY_FIELDS = {
exclude_from_reconfig=True,
),
CONF_COLOR_TEMP_KELVIN: PlatformField(
selector=BOOLEAN_SELECTOR,
selector=Selector(),
required=True,
validator=bool,
default=True,
exclude_from_reconfig=True,
is_schema_default=True,
),
},
}
@ -1113,7 +1094,6 @@ PLATFORM_MQTT_FIELDS = {
required=False,
validator=cv.positive_int,
default=DEFAULT_MAX_KELVIN,
conditions=({CONF_COLOR_TEMP_KELVIN: True},),
section="advanced_settings",
),
CONF_MIN_KELVIN: PlatformField(
@ -1121,23 +1101,6 @@ PLATFORM_MQTT_FIELDS = {
required=False,
validator=cv.positive_int,
default=DEFAULT_MIN_KELVIN,
conditions=({CONF_COLOR_TEMP_KELVIN: True},),
section="advanced_settings",
),
CONF_MAX_MIREDS: PlatformField(
selector=MIRED_SELECTOR,
required=False,
validator=cv.positive_int,
default=DEFAULT_MAX_MIREDS,
conditions=({CONF_COLOR_TEMP_KELVIN: False},),
section="advanced_settings",
),
CONF_MIN_MIREDS: PlatformField(
selector=MIRED_SELECTOR,
required=False,
validator=cv.positive_int,
default=DEFAULT_MIN_MIREDS,
conditions=({CONF_COLOR_TEMP_KELVIN: False},),
section="advanced_settings",
),
CONF_FLASH_TIME_SHORT: PlatformField(
@ -1331,7 +1294,9 @@ def data_schema_from_fields(
component_data_with_user_input |= user_input
sections: dict[str | None, None] = {
field_details.section: None for field_details in data_schema_fields.values()
field_details.section: None
for field_details in data_schema_fields.values()
if not field_details.is_schema_default
}
data_schema: dict[Any, Any] = {}
all_data_element_options: set[Any] = set()
@ -1346,7 +1311,8 @@ def data_schema_from_fields(
if field_details.custom_filtering
else field_details.selector
for field_name, field_details in data_schema_fields.items()
if field_details.section == schema_section
if not field_details.is_schema_default
and field_details.section == schema_section
and (not field_details.exclude_from_reconfig or not reconfig)
and _check_conditions(field_details, component_data_with_user_input)
}
@ -1388,6 +1354,18 @@ def data_schema_from_fields(
return vol.Schema(data_schema)
@callback
def subentry_schema_default_data_from_fields(
data_schema_fields: dict[str, PlatformField],
) -> dict[str, Any]:
"""Generate custom data schema from platform fields or device data."""
return {
key: field.default
for key, field in data_schema_fields.items()
if field.is_schema_default
}
class FlowHandler(ConfigFlow, domain=DOMAIN):
"""Handle a config flow."""
@ -2204,6 +2182,16 @@ class MQTTSubentryFlowHandler(ConfigSubentryFlow):
last_step=False,
)
@callback
def _async_update_component_data_defaults(self) -> None:
"""Update component data defaults."""
for component_data in self._subentry_data["components"].values():
platform = component_data[CONF_PLATFORM]
subentry_default_data = subentry_schema_default_data_from_fields(
PLATFORM_ENTITY_FIELDS[platform]
)
component_data.update(subentry_default_data)
@callback
def _async_create_subentry(
self, user_input: dict[str, Any] | None = None
@ -2220,6 +2208,7 @@ class MQTTSubentryFlowHandler(ConfigSubentryFlow):
else:
full_entity_name = device_name
self._async_update_component_data_defaults()
return self.async_create_entry(
data=self._subentry_data,
title=self._subentry_data[CONF_DEVICE][CONF_NAME],
@ -2284,6 +2273,7 @@ class MQTTSubentryFlowHandler(ConfigSubentryFlow):
if len(self._subentry_data["components"]) > 1:
menu_options.append("delete_entity")
menu_options.extend(["device", "availability"])
self._async_update_component_data_defaults()
if self._subentry_data != self._get_reconfigure_subentry().data:
menu_options.append("save_changes")
return self.async_show_menu(

View File

@ -214,7 +214,6 @@
"description": "Please configure specific details for {platform} entity \"{entity}\":",
"data": {
"device_class": "Device class",
"color_temp_kelvin": "Color temperature in Kelvin",
"options": "Add option",
"schema": "Schema",
"state_class": "State class",
@ -223,7 +222,6 @@
},
"data_description": {
"device_class": "The Device class of the {platform} entity. [Learn more.]({url}#device_class)",
"color_temp_kelvin": "When set color mode updates will be published in Kelvin and processed state will be assumed in Kelvin. When not set the color temp values are converted to mireds instead.",
"options": "Options for allowed sensor state values. The sensors Device class must be set to Enumeration. The 'Options' setting cannot be used together with State class or Unit of measurement.",
"schema": "The schema to use. [Learn more.]({url}#comparison-of-light-mqtt-schemas)",
"state_class": "The [State class](https://developers.home-assistant.io/docs/core/entity/sensor/#available-state-classes) of the sensor. [Learn more.]({url}#state_class)",
@ -273,10 +271,10 @@
"blue_template": "[Template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract blue color from the state payload value. Expected result of the template is an integer from 0-255 range.",
"brightness_template": "[Template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract brightness from the state payload value. Expected result of the template is an integer from 0-255 range.",
"command_off_template": "The [template](https://www.home-assistant.io/docs/configuration/templating/#using-command-templates-with-mqtt) for \"off\" state changes. Available variables are: `state` and `transition`.",
"command_on_template": "The [template](https://www.home-assistant.io/docs/configuration/templating/#using-command-templates-with-mqtt) for \"on\" state changes. Available variables: `state`, `brightness`, `color_temp`, `red`, `green`, `blue`, `hue`, `sat`, `flash`, `transition` and `effect`. Values `red`, `green`, `blue` and `brightness` are provided as integers from range 0-255. Value of `hue` is provided as float from range 0-360. Value of `sat` is provided as float from range 0-100. Value of `color_temp` is provided as integer representing mired or Kelvin units if 'Color temperature in Kelvin' is true.",
"command_on_template": "The [template](https://www.home-assistant.io/docs/configuration/templating/#using-command-templates-with-mqtt) for \"on\" state changes. Available variables: `state`, `brightness`, `color_temp`, `red`, `green`, `blue`, `hue`, `sat`, `flash`, `transition` and `effect`. Values `red`, `green`, `blue` and `brightness` are provided as integers from range 0-255. Value of `hue` is provided as float from range 0-360. Value of `sat` is provided as float from range 0-100. Value of `color_temp` is provided as integer representing Kelvin units.",
"command_template": "A [template](https://www.home-assistant.io/docs/configuration/templating/#using-command-templates-with-mqtt) to render the payload to be published at the command topic.",
"command_topic": "The publishing topic that will be used to control the {platform} entity. [Learn more.]({url}#command_topic)",
"color_temp_template": "[Template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract color temperature from the state payload value. Expected result of the template is an integer. If the color tempemperature in Kelvin setting is true, the expected value is in Kelvin, else mireds are expected.",
"color_temp_template": "[Template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract color temperature in Kelvin from the state payload value. Expected result of the template is an integer.",
"green_template": "[Template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract green color from the state payload value. Expected result of the template is an integer from 0-255 range.",
"last_reset_value_template": "Defines a [template](https://www.home-assistant.io/docs/configuration/templating/#using-value-templates-with-mqtt) to extract the last reset. When Last reset template is set, the State class option must be Total. [Learn more.]({url}#last_reset_value_template)",
"force_update": "Sends update events even if the value hasnt changed. Useful if you want to have meaningful value graphs in history. [Learn more.]({url}#force_update)",
@ -300,18 +298,14 @@
"flash_time_long": "Flash time long",
"flash_time_short": "Flash time short",
"max_kelvin": "Max Kelvin",
"min_kelvin": "Min Kelvin",
"max_mireds": "Max mireds",
"min_mireds": "Min mireds"
"min_kelvin": "Min Kelvin"
},
"data_description": {
"expire_after": "If set, it defines the number of seconds after the sensors state expires, if its not updated. After expiry, the sensors state becomes unavailable. If not set, the sensor's state never expires. [Learn more.]({url}#expire_after)",
"flash_time_long": "The duration, in seconds, of a \"long\" flash.",
"flash_time_short": "The duration, in seconds, of a \"short\" flash.",
"max_kelvin": "The maximum color temperature in Kelvin.",
"min_kelvin": "The minimum color temperature in Kelvin.",
"max_mireds": "The maximum color temperature in mireds.",
"min_mireds": "The minimum color temperature in mireds."
"min_kelvin": "The minimum color temperature in Kelvin."
}
},
"light_brightness_settings": {
@ -482,7 +476,6 @@
"invalid_url": "Invalid URL",
"last_reset_not_with_state_class_total": "The last reset value template option should be used with state class 'Total' only",
"max_below_min_kelvin": "Max Kelvin value should be greater than min Kelvin value",
"max_below_min_mireds": "Max mireds value should be greater than min mireds value",
"options_not_allowed_with_state_class_or_uom": "The 'Options' setting is not allowed when state class or unit of measurement are used",
"options_device_class_enum": "The 'Options' setting must be used with the Enumeration device class. If you continue, the existing options will be reset",
"options_with_enum_device_class": "Configure options for the enumeration sensor",

View File

@ -155,22 +155,6 @@ MOCK_SUBENTRY_LIGHT_BASIC_KELVIN_COMPONENT = {
"entity_picture": "https://example.com/8131babc5e8d4f44b82e0761d39091a2",
},
}
MOCK_SUBENTRY_LIGHT_BASIC_MIREDS_COMPONENT = {
"8131babc5e8d4f44b82e0761d39091a2": {
"platform": "light",
"name": "Basic light",
"on_command_type": "last",
"optimistic": True,
"payload_off": "OFF",
"payload_on": "ON",
"command_topic": "test-topic",
"schema": "basic",
"state_topic": "test-topic",
"color_temp_kelvin": False,
"state_value_template": "{{ value_json.value }}",
"entity_picture": "https://example.com/8131babc5e8d4f44b82e0761d39091a2",
},
}
MOCK_SUBENTRY_NOTIFY_BAD_SCHEMA = {
"b10b531e15244425a74bb0abb1e9d2c6": {
"platform": "notify",
@ -214,10 +198,6 @@ MOCK_LIGHT_BASIC_KELVIN_SUBENTRY_DATA_SINGLE = {
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 0}},
"components": MOCK_SUBENTRY_LIGHT_BASIC_KELVIN_COMPONENT,
}
MOCK_LIGHT_BASIC_MIREDS_SUBENTRY_DATA_SINGLE = {
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 0}},
"components": MOCK_SUBENTRY_LIGHT_BASIC_MIREDS_COMPONENT,
}
MOCK_SENSOR_SUBENTRY_DATA_SINGLE = {
"device": MOCK_SUBENTRY_DEVICE_DATA | {"mqtt_settings": {"qos": 0}},
"components": MOCK_SUBENTRY_SENSOR_COMPONENT,

View File

@ -34,7 +34,6 @@ from homeassistant.helpers.service_info.hassio import HassioServiceInfo
from .common import (
MOCK_LIGHT_BASIC_KELVIN_SUBENTRY_DATA_SINGLE,
MOCK_LIGHT_BASIC_MIREDS_SUBENTRY_DATA_SINGLE,
MOCK_NOTIFY_SUBENTRY_DATA_MULTI,
MOCK_NOTIFY_SUBENTRY_DATA_NO_NAME,
MOCK_NOTIFY_SUBENTRY_DATA_SINGLE,
@ -2768,7 +2767,7 @@ async def test_migrate_of_incompatible_config_entry(
MOCK_LIGHT_BASIC_KELVIN_SUBENTRY_DATA_SINGLE,
{"name": "Milk notifier", "mqtt_settings": {"qos": 1}},
{"name": "Basic light"},
{"color_temp_kelvin": True},
{},
{},
{
"command_topic": "test-topic",
@ -2801,43 +2800,6 @@ async def test_migrate_of_incompatible_config_entry(
),
"Milk notifier Basic light",
),
(
MOCK_LIGHT_BASIC_MIREDS_SUBENTRY_DATA_SINGLE,
{"name": "Milk notifier", "mqtt_settings": {"qos": 1}},
{"name": "Basic light"},
{"color_temp_kelvin": False},
{},
{
"command_topic": "test-topic",
"state_topic": "test-topic",
"state_value_template": "{{ value_json.value }}",
"optimistic": True,
},
(
(
{"command_topic": "test-topic#invalid"},
{"command_topic": "invalid_publish_topic"},
),
(
{
"command_topic": "test-topic",
"state_topic": "test-topic#invalid",
},
{"state_topic": "invalid_subscribe_topic"},
),
(
{
"command_topic": "test-topic",
"advanced_settings": {"min_mireds": 200, "max_mireds": 190},
},
{
"max_mireds": "max_below_min_mireds",
"min_mireds": "max_below_min_mireds",
},
),
),
"Milk notifier Basic light",
),
],
ids=[
"notify_with_entity_name",
@ -2846,7 +2808,6 @@ async def test_migrate_of_incompatible_config_entry(
"sensor_total",
"switch",
"light_basic_kelvin",
"light_basic_mireds",
],
)
async def test_subentry_configflow(