5858from homeassistant .util .async_ import run_callback_threadsafe
5959from homeassistant .util .hass_dict import HassKey
6060from homeassistant .util .yaml import load_yaml_dict
61- from homeassistant .util .yaml .loader import JSON_TYPE
6261
6362from . import config_validation as cv , entity_registry as er
63+ from .automation import get_absolute_description_key , get_relative_description_key
6464from .integration_platform import async_process_integration_platforms
6565from .template import Template , render_complex
6666from .trace import (
@@ -132,7 +132,7 @@ def starts_with_dot(key: str) -> str:
132132_CONDITIONS_SCHEMA = vol .Schema (
133133 {
134134 vol .Remove (vol .All (str , starts_with_dot )): object ,
135- cv .slug : vol .Any (None , _CONDITION_SCHEMA ),
135+ cv .underscore_slug : vol .Any (None , _CONDITION_SCHEMA ),
136136 }
137137)
138138
@@ -171,6 +171,9 @@ async def _register_condition_platform(
171171
172172 if hasattr (platform , "async_get_conditions" ):
173173 for condition_key in await platform .async_get_conditions (hass ):
174+ condition_key = get_absolute_description_key (
175+ integration_domain , condition_key
176+ )
174177 hass .data [CONDITIONS ][condition_key ] = integration_domain
175178 new_conditions .add (condition_key )
176179 else :
@@ -288,22 +291,21 @@ def wrapper(hass: HomeAssistant, variables: TemplateVarsType = None) -> bool | N
288291
289292
290293async def _async_get_condition_platform (
291- hass : HomeAssistant , config : ConfigType
292- ) -> ConditionProtocol | None :
293- condition_key : str = config [CONF_CONDITION ]
294- platform_and_sub_type = condition_key .partition ("." )
294+ hass : HomeAssistant , condition_key : str
295+ ) -> tuple [str , ConditionProtocol | None ]:
296+ platform_and_sub_type = condition_key .split ("." )
295297 platform : str | None = platform_and_sub_type [0 ]
296298 platform = _PLATFORM_ALIASES .get (platform , platform )
297299 if platform is None :
298- return None
300+ return "" , None
299301 try :
300302 integration = await async_get_integration (hass , platform )
301303 except IntegrationNotFound :
302304 raise HomeAssistantError (
303- f'Invalid condition "{ condition_key } " specified { config } '
305+ f'Invalid condition "{ condition_key } " specified'
304306 ) from None
305307 try :
306- return await integration .async_get_platform ("condition" )
308+ return platform , await integration .async_get_platform ("condition" )
307309 except ImportError :
308310 raise HomeAssistantError (
309311 f"Integration '{ platform } ' does not provide condition support"
@@ -339,17 +341,20 @@ def disabled_condition(
339341
340342 return disabled_condition
341343
342- condition : str = config [CONF_CONDITION ]
344+ condition_key : str = config [CONF_CONDITION ]
343345 factory : Any = None
344- platform = await _async_get_condition_platform (hass , config )
346+ platform_domain , platform = await _async_get_condition_platform (hass , condition_key )
345347
346348 if platform is not None :
347349 condition_descriptors = await platform .async_get_conditions (hass )
348- condition_instance = condition_descriptors [condition ](hass , config )
350+ relative_condition_key = get_relative_description_key (
351+ platform_domain , condition_key
352+ )
353+ condition_instance = condition_descriptors [relative_condition_key ](hass , config )
349354 return await condition_instance .async_get_checker ()
350355
351356 for fmt in (ASYNC_FROM_CONFIG_FORMAT , FROM_CONFIG_FORMAT ):
352- factory = getattr (sys .modules [__name__ ], fmt .format (condition ), None )
357+ factory = getattr (sys .modules [__name__ ], fmt .format (condition_key ), None )
353358
354359 if factory :
355360 break
@@ -960,25 +965,33 @@ async def async_validate_condition_config(
960965 hass : HomeAssistant , config : ConfigType
961966) -> ConfigType :
962967 """Validate config."""
963- condition : str = config [CONF_CONDITION ]
964- if condition in ("and" , "not" , "or" ):
968+ condition_key : str = config [CONF_CONDITION ]
969+
970+ if condition_key in ("and" , "not" , "or" ):
965971 conditions = []
966972 for sub_cond in config ["conditions" ]:
967973 sub_cond = await async_validate_condition_config (hass , sub_cond )
968974 conditions .append (sub_cond )
969975 config ["conditions" ] = conditions
970976 return config
971977
972- platform = await _async_get_condition_platform (hass , config )
978+ platform_domain , platform = await _async_get_condition_platform (hass , condition_key )
979+
973980 if platform is not None :
974981 condition_descriptors = await platform .async_get_conditions (hass )
975- if not (condition_class := condition_descriptors .get (condition )):
976- raise vol .Invalid (f"Invalid condition '{ condition } ' specified" )
982+ relative_condition_key = get_relative_description_key (
983+ platform_domain , condition_key
984+ )
985+ if not (condition_class := condition_descriptors .get (relative_condition_key )):
986+ raise vol .Invalid (f"Invalid condition '{ condition_key } ' specified" )
977987 return await condition_class .async_validate_config (hass , config )
978- if platform is None and condition in ("numeric_state" , "state" ):
988+
989+ if platform is None and condition_key in ("numeric_state" , "state" ):
979990 validator = cast (
980991 Callable [[HomeAssistant , ConfigType ], ConfigType ],
981- getattr (sys .modules [__name__ ], VALIDATE_CONFIG_FORMAT .format (condition )),
992+ getattr (
993+ sys .modules [__name__ ], VALIDATE_CONFIG_FORMAT .format (condition_key )
994+ ),
982995 )
983996 return validator (hass , config )
984997
@@ -1088,11 +1101,11 @@ def async_extract_devices(config: ConfigType | Template) -> set[str]:
10881101 return referenced
10891102
10901103
1091- def _load_conditions_file (hass : HomeAssistant , integration : Integration ) -> JSON_TYPE :
1104+ def _load_conditions_file (integration : Integration ) -> dict [ str , Any ] :
10921105 """Load conditions file for an integration."""
10931106 try :
10941107 return cast (
1095- JSON_TYPE ,
1108+ dict [ str , Any ] ,
10961109 _CONDITIONS_SCHEMA (
10971110 load_yaml_dict (str (integration .file_path / "conditions.yaml" ))
10981111 ),
@@ -1112,11 +1125,14 @@ def _load_conditions_file(hass: HomeAssistant, integration: Integration) -> JSON
11121125
11131126
11141127def _load_conditions_files (
1115- hass : HomeAssistant , integrations : Iterable [Integration ]
1116- ) -> dict [str , JSON_TYPE ]:
1128+ integrations : Iterable [Integration ],
1129+ ) -> dict [str , dict [ str , Any ] ]:
11171130 """Load condition files for multiple integrations."""
11181131 return {
1119- integration .domain : _load_conditions_file (hass , integration )
1132+ integration .domain : {
1133+ get_absolute_description_key (integration .domain , key ): value
1134+ for key , value in _load_conditions_file (integration ).items ()
1135+ }
11201136 for integration in integrations
11211137 }
11221138
@@ -1137,7 +1153,7 @@ async def async_get_all_descriptions(
11371153 return descriptions_cache
11381154
11391155 # Files we loaded for missing descriptions
1140- new_conditions_descriptions : dict [str , JSON_TYPE ] = {}
1156+ new_conditions_descriptions : dict [str , dict [ str , Any ] ] = {}
11411157 # We try to avoid making a copy in the event the cache is good,
11421158 # but now we must make a copy in case new conditions get added
11431159 # while we are loading the missing ones so we do not
@@ -1166,7 +1182,7 @@ async def async_get_all_descriptions(
11661182
11671183 if integrations :
11681184 new_conditions_descriptions = await hass .async_add_executor_job (
1169- _load_conditions_files , hass , integrations
1185+ _load_conditions_files , integrations
11701186 )
11711187
11721188 # Make a copy of the old cache and add missing descriptions to it
@@ -1175,7 +1191,7 @@ async def async_get_all_descriptions(
11751191 domain = conditions [missing_condition ]
11761192
11771193 if (
1178- yaml_description := new_conditions_descriptions .get (domain , {}).get ( # type: ignore[union-attr]
1194+ yaml_description := new_conditions_descriptions .get (domain , {}).get (
11791195 missing_condition
11801196 )
11811197 ) is None :
0 commit comments