diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index 7d63fb4a7b4..b9ff5704246 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -431,6 +431,19 @@ def icon(value: Any) -> str: raise vol.Invalid('Icons should be specified in the form "prefix:name"') +_COLOR_HEX = re.compile(r"^#[0-9A-F]{6}$", re.IGNORECASE) + + +def color_hex(value: Any) -> str: + """Validate a hex color code.""" + str_value = str(value) + + if not _COLOR_HEX.match(str_value): + raise vol.Invalid("Color should be in the format #RRGGBB") + + return str_value + + _TIME_PERIOD_DICT_KEYS = ("days", "hours", "minutes", "seconds", "milliseconds") time_period_dict = vol.All( diff --git a/tests/helpers/test_config_validation.py b/tests/helpers/test_config_validation.py index f997e3a6c10..c16d7b1ec51 100644 --- a/tests/helpers/test_config_validation.py +++ b/tests/helpers/test_config_validation.py @@ -1647,3 +1647,27 @@ def test_domain() -> None: assert cv.domain_key("hue1") == "hue1" assert cv.domain_key("hue 1") == "hue" assert cv.domain_key("hue 1") == "hue" + + +def test_color_hex() -> None: + """Test color validation in hex format.""" + assert cv.color_hex("#123456") == "#123456" + assert cv.color_hex("#FFaaFF") == "#FFaaFF" + assert cv.color_hex("#FFFFFF") == "#FFFFFF" + assert cv.color_hex("#000000") == "#000000" + + msg = r"Color should be in the format #RRGGBB" + with pytest.raises(vol.Invalid, match=msg): + cv.color_hex("#777") + + with pytest.raises(vol.Invalid, match=msg): + cv.color_hex("FFFFF") + + with pytest.raises(vol.Invalid, match=msg): + cv.color_hex("FFFFFF") + + with pytest.raises(vol.Invalid, match=msg): + cv.color_hex("#FFFFFFF") + + with pytest.raises(vol.Invalid, match=msg): + cv.color_hex(123456)