diff --git a/homeassistant/helpers/selector.py b/homeassistant/helpers/selector.py index 52e48724639..8f2d9bf4938 100644 --- a/homeassistant/helpers/selector.py +++ b/homeassistant/helpers/selector.py @@ -565,6 +565,49 @@ class ConstantSelector(Selector[ConstantSelectorConfig]): 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(TypedDict, 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 = vol.Schema( + { + 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 = None) -> 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(TypedDict, total=False): """Class to represent a conversation agent selector config.""" diff --git a/tests/helpers/test_selector.py b/tests/helpers/test_selector.py index 633673cac98..00942b396e8 100644 --- a/tests/helpers/test_selector.py +++ b/tests/helpers/test_selector.py @@ -1112,3 +1112,32 @@ def test_condition_selector_schema( def test_trigger_selector_schema(schema, valid_selections, invalid_selections) -> None: """Test trigger sequence selector.""" _test_selector("trigger", schema, valid_selections, invalid_selections) + + +@pytest.mark.parametrize( + ("schema", "valid_selections", "invalid_selections"), + ( + ( + {"data": "test", "scale": 5}, + ("test",), + (False, 0, []), + ), + ( + {"data": "test"}, + ("test",), + (True, 1, []), + ), + ( + { + "data": "test", + "scale": 5, + "error_correction_level": selector.QrErrorCorrectionLevel.HIGH, + }, + ("test",), + (True, 1, []), + ), + ), +) +def test_qr_code_selector_schema(schema, valid_selections, invalid_selections) -> None: + """Test QR code selector.""" + _test_selector("qr_code", schema, valid_selections, invalid_selections)