-
-
Notifications
You must be signed in to change notification settings - Fork 37.8k
Support templating MQTT triggers #45614
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
aa3eb1f
f8388b3
2160b0c
106cd75
2fdcf6a
9cf182b
22506d4
1ac04a3
eeac975
0256c00
baa72ce
d185abc
be5908d
5c7a50e
df7598b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -279,6 +279,7 @@ class Template: | |
| "is_static", | ||
| "_compiled_code", | ||
| "_compiled", | ||
| "_limited", | ||
| ) | ||
|
|
||
| def __init__(self, template, hass=None): | ||
|
|
@@ -291,10 +292,11 @@ def __init__(self, template, hass=None): | |
| self._compiled: Optional[Template] = None | ||
| self.hass = hass | ||
| self.is_static = not is_template_string(template) | ||
| self._limited = None | ||
|
|
||
| @property | ||
| def _env(self) -> "TemplateEnvironment": | ||
| if self.hass is None: | ||
| if self.hass is None or self._limited: | ||
| return _NO_HASS_ENV | ||
| ret: Optional[TemplateEnvironment] = self.hass.data.get(_ENVIRONMENT) | ||
| if ret is None: | ||
|
|
@@ -315,6 +317,7 @@ def render( | |
| self, | ||
| variables: TemplateVarsType = None, | ||
| parse_result: bool = True, | ||
| limited: bool = False, | ||
| **kwargs: Any, | ||
| ) -> Any: | ||
| """Render given template.""" | ||
|
|
@@ -325,14 +328,15 @@ def render( | |
|
|
||
| return run_callback_threadsafe( | ||
| self.hass.loop, | ||
| partial(self.async_render, variables, parse_result, **kwargs), | ||
| partial(self.async_render, variables, parse_result, limited, **kwargs), | ||
| ).result() | ||
|
|
||
| @callback | ||
| def async_render( | ||
| self, | ||
| variables: TemplateVarsType = None, | ||
| parse_result: bool = True, | ||
| limited: bool = False, | ||
|
balloob marked this conversation as resolved.
|
||
| **kwargs: Any, | ||
| ) -> Any: | ||
| """Render given template. | ||
|
|
@@ -344,7 +348,7 @@ def async_render( | |
| return self.template | ||
| return self._parse_result(self.template) | ||
|
|
||
| compiled = self._compiled or self._ensure_compiled() | ||
| compiled = self._compiled or self._ensure_compiled(limited) | ||
|
|
||
| if variables is not None: | ||
| kwargs.update(variables) | ||
|
|
@@ -519,12 +523,16 @@ def async_render_with_possible_json_value( | |
| ) | ||
| return value if error_value is _SENTINEL else error_value | ||
|
|
||
| def _ensure_compiled(self) -> "Template": | ||
| def _ensure_compiled(self, limited: bool = False) -> "Template": | ||
| """Bind a template to a specific hass instance.""" | ||
| self.ensure_valid() | ||
|
|
||
| assert self.hass is not None, "hass variable not set on template" | ||
| assert ( | ||
| self._limited is None or self._limited == limited | ||
| ), "can't change between limited and non limited template" | ||
|
|
||
| self._limited = limited | ||
| env = self._env | ||
|
|
||
| self._compiled = cast( | ||
|
|
@@ -1352,6 +1360,32 @@ def __init__(self, hass): | |
| self.globals["strptime"] = strptime | ||
| self.globals["urlencode"] = urlencode | ||
| if hass is None: | ||
|
|
||
| def unsupported(name): | ||
| def warn_unsupported(*args, **kwargs): | ||
| _LOGGER.warning( | ||
| "Use of '%s' is not supported in limited templates", name | ||
| ) | ||
| return "" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should it raise?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure, maybe better to raise to entirely block the template from rendering?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's better to break it and not have it attach the trigger.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because triggers are a pain to debug.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed to raise, it gets really noisy though:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should catch
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, fixed in eeac975 |
||
|
|
||
| return warn_unsupported | ||
|
|
||
| hass_globals = [ | ||
| "closest", | ||
| "distance", | ||
| "expand", | ||
| "is_state", | ||
| "is_state_attr", | ||
| "state_attr", | ||
| "states", | ||
| "utcnow", | ||
| "now", | ||
| ] | ||
| hass_filters = ["closest", "expand"] | ||
| for g in hass_globals: | ||
| self.globals[g] = unsupported(g) | ||
| for f in hass_filters: | ||
| self.filters[f] = unsupported(f) | ||
| return | ||
|
|
||
| # We mark these as a context functions to ensure they get | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.