diff --git a/homeassistant/helpers/config_validation.py b/homeassistant/helpers/config_validation.py index bbe4e05fd34..78c63049e5f 100644 --- a/homeassistant/helpers/config_validation.py +++ b/homeassistant/helpers/config_validation.py @@ -1045,9 +1045,33 @@ def expand_condition_shorthand(value: Any | None) -> Any: # Schemas -def empty_config_schema(domain: str) -> vol.Schema: - """Return a config schema which accepts no configuration parameters.""" - return vol.Schema({vol.Optional(domain): vol.Schema({})}, extra=vol.ALLOW_EXTRA) +def empty_config_schema(domain: str) -> Callable[[dict], dict]: + """Return a config schema which logs if there are configuration parameters.""" + + module = inspect.getmodule(inspect.stack(context=0)[2].frame) + if module is not None: + module_name = module.__name__ + else: + # If Python is unable to access the sources files, the call stack frame + # will be missing information, so let's guard. + # https://github.com/home-assistant/core/issues/24982 + module_name = __name__ + logger_func = logging.getLogger(module_name).error + + def validator(config: dict) -> dict: + if domain in config and config[domain]: + logger_func( + ( + "The %s integration does not support any configuration parameters, " + "got %s. Please remove the configuration parameters from your " + "configuration." + ), + domain, + config[domain], + ) + return config + + return validator PLATFORM_SCHEMA = vol.Schema( diff --git a/tests/helpers/test_config_validation.py b/tests/helpers/test_config_validation.py index f1f644a36a7..df8e989d672 100644 --- a/tests/helpers/test_config_validation.py +++ b/tests/helpers/test_config_validation.py @@ -1468,3 +1468,25 @@ def test_positive_time_period_template() -> None: schema("{{ 'invalid' }}") schema({"{{ 'invalid' }}": 5}) schema({"minutes": "{{ 'invalid' }}"}) + + +def test_empty_schema(caplog: pytest.LogCaptureFixture) -> None: + """Test if the current module cannot be inspected.""" + expected_message = ( + "The test_domain integration does not support any configuration parameters" + ) + + cv.empty_config_schema("test_domain")({}) + assert expected_message not in caplog.text + + cv.empty_config_schema("test_domain")({"test_domain": {}}) + assert expected_message not in caplog.text + + cv.empty_config_schema("test_domain")({"test_domain": {"foo": "bar"}}) + assert expected_message in caplog.text + + +def test_empty_schema_cant_find_module() -> None: + """Test if the current module cannot be inspected.""" + with patch("inspect.getmodule", return_value=None): + cv.empty_config_schema("test_domain")({"test_domain": {"foo": "bar"}})