Order selectors alphabetically in helper (#149269)

This commit is contained in:
Artur Pragacz 2025-07-22 23:06:51 +02:00 committed by GitHub
parent 993b0bbdd7
commit dde73c05cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -575,49 +575,6 @@ class ConstantSelector(Selector[ConstantSelectorConfig]):
return self.config["value"] return self.config["value"]
class QrErrorCorrectionLevel(StrEnum):
"""Possible error correction levels for QR code selector."""
LOW = "low"
MEDIUM = "medium"
QUARTILE = "quartile"
HIGH = "high"
class QrCodeSelectorConfig(BaseSelectorConfig, total=False):
"""Class to represent a QR code selector config."""
data: str
scale: int
error_correction_level: QrErrorCorrectionLevel
@SELECTORS.register("qr_code")
class QrCodeSelector(Selector[QrCodeSelectorConfig]):
"""QR code selector."""
selector_type = "qr_code"
CONFIG_SCHEMA = BASE_SELECTOR_CONFIG_SCHEMA.extend(
{
vol.Required("data"): str,
vol.Optional("scale"): int,
vol.Optional("error_correction_level"): vol.All(
vol.Coerce(QrErrorCorrectionLevel), lambda val: val.value
),
}
)
def __init__(self, config: QrCodeSelectorConfig) -> None:
"""Instantiate a selector."""
super().__init__(config)
def __call__(self, data: Any) -> Any:
"""Validate the passed selection."""
vol.Schema(vol.Any(str, None))(data)
return self.config["data"]
class ConversationAgentSelectorConfig(BaseSelectorConfig, total=False): class ConversationAgentSelectorConfig(BaseSelectorConfig, total=False):
"""Class to represent a conversation agent selector config.""" """Class to represent a conversation agent selector config."""
@ -872,6 +829,39 @@ class EntitySelector(Selector[EntitySelectorConfig]):
return cast(list, vol.Schema([validate])(data)) # Output is a list return cast(list, vol.Schema([validate])(data)) # Output is a list
class FileSelectorConfig(BaseSelectorConfig):
"""Class to represent a file selector config."""
accept: str # required
@SELECTORS.register("file")
class FileSelector(Selector[FileSelectorConfig]):
"""Selector of a file."""
selector_type = "file"
CONFIG_SCHEMA = BASE_SELECTOR_CONFIG_SCHEMA.extend(
{
# https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept
vol.Required("accept"): str,
}
)
def __init__(self, config: FileSelectorConfig) -> None:
"""Instantiate a selector."""
super().__init__(config)
def __call__(self, data: Any) -> str:
"""Validate the passed selection."""
if not isinstance(data, str):
raise vol.Invalid("Value should be a string")
UUID(data)
return data
class FloorSelectorConfig(BaseSelectorConfig, total=False): class FloorSelectorConfig(BaseSelectorConfig, total=False):
"""Class to represent an floor selector config.""" """Class to represent an floor selector config."""
@ -1213,6 +1203,49 @@ class ObjectSelector(Selector[ObjectSelectorConfig]):
return data return data
class QrErrorCorrectionLevel(StrEnum):
"""Possible error correction levels for QR code selector."""
LOW = "low"
MEDIUM = "medium"
QUARTILE = "quartile"
HIGH = "high"
class QrCodeSelectorConfig(BaseSelectorConfig, total=False):
"""Class to represent a QR code selector config."""
data: str
scale: int
error_correction_level: QrErrorCorrectionLevel
@SELECTORS.register("qr_code")
class QrCodeSelector(Selector[QrCodeSelectorConfig]):
"""QR code selector."""
selector_type = "qr_code"
CONFIG_SCHEMA = BASE_SELECTOR_CONFIG_SCHEMA.extend(
{
vol.Required("data"): str,
vol.Optional("scale"): int,
vol.Optional("error_correction_level"): vol.All(
vol.Coerce(QrErrorCorrectionLevel), lambda val: val.value
),
}
)
def __init__(self, config: QrCodeSelectorConfig) -> None:
"""Instantiate a selector."""
super().__init__(config)
def __call__(self, data: Any) -> Any:
"""Validate the passed selection."""
vol.Schema(vol.Any(str, None))(data)
return self.config["data"]
select_option = vol.All( select_option = vol.All(
dict, dict,
vol.Schema( vol.Schema(
@ -1295,6 +1328,41 @@ class SelectSelector(Selector[SelectSelectorConfig]):
return [parent_schema(vol.Schema(str)(val)) for val in data] return [parent_schema(vol.Schema(str)(val)) for val in data]
class StateSelectorConfig(BaseSelectorConfig, total=False):
"""Class to represent an state selector config."""
entity_id: str
hide_states: list[str]
@SELECTORS.register("state")
class StateSelector(Selector[StateSelectorConfig]):
"""Selector for an entity state."""
selector_type = "state"
CONFIG_SCHEMA = BASE_SELECTOR_CONFIG_SCHEMA.extend(
{
vol.Optional("entity_id"): cv.entity_id,
vol.Optional("hide_states"): [str],
# The attribute to filter on, is currently deliberately not
# configurable/exposed. We are considering separating state
# selectors into two types: one for state and one for attribute.
# Limiting the public use, prevents breaking changes in the future.
# vol.Optional("attribute"): str,
}
)
def __init__(self, config: StateSelectorConfig) -> None:
"""Instantiate a selector."""
super().__init__(config)
def __call__(self, data: Any) -> str:
"""Validate the passed selection."""
state: str = vol.Schema(str)(data)
return state
class StatisticSelectorConfig(BaseSelectorConfig, total=False): class StatisticSelectorConfig(BaseSelectorConfig, total=False):
"""Class to represent a statistic selector config.""" """Class to represent a statistic selector config."""
@ -1335,41 +1403,6 @@ class TargetSelectorConfig(BaseSelectorConfig, total=False):
device: DeviceFilterSelectorConfig | list[DeviceFilterSelectorConfig] device: DeviceFilterSelectorConfig | list[DeviceFilterSelectorConfig]
class StateSelectorConfig(BaseSelectorConfig, total=False):
"""Class to represent an state selector config."""
entity_id: str
hide_states: list[str]
@SELECTORS.register("state")
class StateSelector(Selector[StateSelectorConfig]):
"""Selector for an entity state."""
selector_type = "state"
CONFIG_SCHEMA = BASE_SELECTOR_CONFIG_SCHEMA.extend(
{
vol.Optional("entity_id"): cv.entity_id,
vol.Optional("hide_states"): [str],
# The attribute to filter on, is currently deliberately not
# configurable/exposed. We are considering separating state
# selectors into two types: one for state and one for attribute.
# Limiting the public use, prevents breaking changes in the future.
# vol.Optional("attribute"): str,
}
)
def __init__(self, config: StateSelectorConfig) -> None:
"""Instantiate a selector."""
super().__init__(config)
def __call__(self, data: Any) -> str:
"""Validate the passed selection."""
state: str = vol.Schema(str)(data)
return state
@SELECTORS.register("target") @SELECTORS.register("target")
class TargetSelector(Selector[TargetSelectorConfig]): class TargetSelector(Selector[TargetSelectorConfig]):
"""Selector of a target value (area ID, device ID, entity ID etc). """Selector of a target value (area ID, device ID, entity ID etc).
@ -1559,39 +1592,6 @@ class TriggerSelector(Selector[TriggerSelectorConfig]):
return vol.Schema(cv.TRIGGER_SCHEMA)(data) return vol.Schema(cv.TRIGGER_SCHEMA)(data)
class FileSelectorConfig(BaseSelectorConfig):
"""Class to represent a file selector config."""
accept: str # required
@SELECTORS.register("file")
class FileSelector(Selector[FileSelectorConfig]):
"""Selector of a file."""
selector_type = "file"
CONFIG_SCHEMA = BASE_SELECTOR_CONFIG_SCHEMA.extend(
{
# https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept
vol.Required("accept"): str,
}
)
def __init__(self, config: FileSelectorConfig) -> None:
"""Instantiate a selector."""
super().__init__(config)
def __call__(self, data: Any) -> str:
"""Validate the passed selection."""
if not isinstance(data, str):
raise vol.Invalid("Value should be a string")
UUID(data)
return data
dumper.add_representer( dumper.add_representer(
Selector, Selector,
lambda dumper, value: dumper.represent_odict( lambda dumper, value: dumper.represent_odict(