thomasloven / hass-lovelace_gen

🔹 Improve the lovelace yaml parser for Home Assistant
MIT License
209 stars 22 forks source link

Templating stops working when lovelace_gen is used! #44

Open Aleborg opened 1 year ago

Aleborg commented 1 year ago

When using lovelace_gen in a yaml file the all templating stops working. states, state_attr etc HA, HACS, lovelace_gen, auto-entities etc is all up2date with the latest versions.

Working:

type: custom:auto-entities
card:
  type: entities
filter:
  template: |
    {% for light in states.light %}
      {% if light.state == "on" %}
        {{ light.entity_id}},
      {% endif %}
    {% endfor %}

Not working:

# lovelace_gen

type: custom:auto-entities
card:
  type: entities
filter:
  template: |
    {% for light in states.light %}
      {% if light.state == "on" %}
        {{ light.entity_id}},
      {% endif %}
    {% endfor %}

Error:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 27, in _handle_async_response
    await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/lovelace/websocket.py", line 38, in send_with_error_handling
    result = await func(hass, connection, msg, config)
  File "/usr/src/homeassistant/homeassistant/components/lovelace/websocket.py", line 86, in websocket_lovelace_config
    return await config.async_load(msg["force"])
  File "/usr/src/homeassistant/homeassistant/components/lovelace/dashboard.py", line 186, in async_load
    is_updated, config = await self.hass.async_add_executor_job(
  File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/lovelace/dashboard.py", line 205, in _load_config
    config = load_yaml(self.path, Secrets(Path(self.hass.config.config_dir)))
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 155, in load_yaml
    return parse_yaml(conf_file, secrets)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 168, in parse_yaml
    return _parse_yaml(SafeLoader, content, secrets)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 198, in _parse_yaml
    yaml.load(content, Loader=lambda stream: loader(stream, secrets))
  File "/usr/local/lib/python3.10/site-packages/yaml/__init__.py", line 81, in load
    return loader.get_single_data()
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 51, in get_single_data
    return self.construct_document(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 55, in construct_document
    data = self.construct_object(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 325, in _ordered_dict
    nodes = loader.construct_pairs(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 155, in construct_pairs
    value = self.construct_object(value_node, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 246, in _include_yaml
    return _add_reference(load_yaml(fname, loader.secrets), loader, node)
  File "/config/custom_components/lovelace_gen/__init__.py", line 37, in load_yaml
    return loader.yaml.load(config_file, Loader=lambda stream: loader.SafeLineLoader(stream, secrets)) or OrderedDict()
  File "/usr/local/lib/python3.10/site-packages/yaml/__init__.py", line 81, in load
    return loader.get_single_data()
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 51, in get_single_data
    return self.construct_document(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 55, in construct_document
    data = self.construct_object(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 356, in _construct_seq
    (obj,) = loader.construct_yaml_seq(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 408, in construct_yaml_seq
    data.extend(self.construct_sequence(node))
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 129, in construct_sequence
    return [self.construct_object(child, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 129, in <listcomp>
    return [self.construct_object(child, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/config/custom_components/lovelace_gen/__init__.py", line 54, in _include_yaml
    return loader._add_reference(load_yaml(fname, ldr.secrets, args=args), ldr, node)
  File "/config/custom_components/lovelace_gen/__init__.py", line 37, in load_yaml
    return loader.yaml.load(config_file, Loader=lambda stream: loader.SafeLineLoader(stream, secrets)) or OrderedDict()
  File "/usr/local/lib/python3.10/site-packages/yaml/__init__.py", line 81, in load
    return loader.get_single_data()
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 51, in get_single_data
    return self.construct_document(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 55, in construct_document
    data = self.construct_object(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 325, in _ordered_dict
    nodes = loader.construct_pairs(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 155, in construct_pairs
    value = self.construct_object(value_node, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 356, in _construct_seq
    (obj,) = loader.construct_yaml_seq(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 408, in construct_yaml_seq
    data.extend(self.construct_sequence(node))
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 129, in construct_sequence
    return [self.construct_object(child, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 129, in <listcomp>
    return [self.construct_object(child, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/config/custom_components/lovelace_gen/__init__.py", line 54, in _include_yaml
    return loader._add_reference(load_yaml(fname, ldr.secrets, args=args), ldr, node)
  File "/config/custom_components/lovelace_gen/__init__.py", line 34, in load_yaml
    return loader.yaml.load(stream, Loader=lambda _stream: loader.SafeLineLoader(_stream, secrets)) or OrderedDict()
  File "/usr/local/lib/python3.10/site-packages/yaml/__init__.py", line 81, in load
    return loader.get_single_data()
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 51, in get_single_data
    return self.construct_document(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 55, in construct_document
    data = self.construct_object(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 325, in _ordered_dict
    nodes = loader.construct_pairs(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 155, in construct_pairs
    value = self.construct_object(value_node, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 356, in _construct_seq
    (obj,) = loader.construct_yaml_seq(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 408, in construct_yaml_seq
    data.extend(self.construct_sequence(node))
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 129, in construct_sequence
    return [self.construct_object(child, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 129, in <listcomp>
    return [self.construct_object(child, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/config/custom_components/lovelace_gen/__init__.py", line 54, in _include_yaml
    return loader._add_reference(load_yaml(fname, ldr.secrets, args=args), ldr, node)
  File "/config/custom_components/lovelace_gen/__init__.py", line 34, in load_yaml
    return loader.yaml.load(stream, Loader=lambda _stream: loader.SafeLineLoader(_stream, secrets)) or OrderedDict()
  File "/usr/local/lib/python3.10/site-packages/yaml/__init__.py", line 81, in load
    return loader.get_single_data()
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 51, in get_single_data
    return self.construct_document(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 55, in construct_document
    data = self.construct_object(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 325, in _ordered_dict
    nodes = loader.construct_pairs(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 155, in construct_pairs
    value = self.construct_object(value_node, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 356, in _construct_seq
    (obj,) = loader.construct_yaml_seq(node)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 408, in construct_yaml_seq
    data.extend(self.construct_sequence(node))
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 129, in construct_sequence
    return [self.construct_object(child, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 129, in <listcomp>
    return [self.construct_object(child, deep=deep)
  File "/usr/local/lib/python3.10/site-packages/yaml/constructor.py", line 100, in construct_object
    data = constructor(self, node)
  File "/config/custom_components/lovelace_gen/__init__.py", line 54, in _include_yaml
    return loader._add_reference(load_yaml(fname, ldr.secrets, args=args), ldr, node)
  File "/config/custom_components/lovelace_gen/__init__.py", line 32, in load_yaml
    stream = io.StringIO(jinja.get_template(fname).render({**args, "_global": llgen_config}))
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "/config/includes/lovelace/tablet/templates/pages/media/test.yaml", line 8, in top-level template code
    {% for light in states.light %}
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 485, in getattr
    return getattr(obj, attribute)
jinja2.exceptions.UndefinedError: 'states' is undefined
mcholcha commented 1 year ago

I have exactly the same problem. This line crashes the whole dashboard:

{% set names = state_attr('input_select.radio_names', 'options') %}

A little bigger example:

# lovelace_gen
{% set names = state_attr('input_select.radio_names', 'options') %}
title: My test view
cards:
  - type: custom:mushroom-title-card
    title: >
      {{ names }}
mcholcha commented 1 year ago

Ehh, now I just read that we can't use state or attributes. Pity, I thought I had solved the problem of a globally accessible key/value list :(

@Aleborg in your case you need to wrap the templating code by {% raw %}

d2kagw commented 1 year ago

I'm curious @mcholcha, where did you read about not being able to use states or attributes?