đŸ”č Lovelace_gen - Add abilities to ui_lovelace.yaml

And another question

Can you pass variables into the style?

For example (and again this doesn’t work but is iot possible somehow?).

# lovelace_gen
type: custom:hui-markdown-card
style: |
  ha-card {
    font-size: {{ font_size | default('20px') }};
    font-family: Oswald;
    height: 30px;
    background: none;
    margin-top: -0.5em;
    margin-left: -10px;
    margin-bottom: 0.9em;
  }
content: {{ title }}

“Doesn’t work” is not very descriptive.
Please remember that by extension of the second law of thermodynamics, things can generally work in one way and not work in infinite ways.

Both your example should do something (assuming you actually define font_size somewhere too), but it won’t ever update dynamically when cycle_name changes, because lovelace_gen is only run when the lovelace config is rebuilt.

Ok, so yes I do define font_size but it seems to ignore it and apply the default.

      - !include
        - includes/titles.yaml
        - title: MORNING CYCLE SCHEDULE
        - font_size: 10px

Example1.

# lovelace_gen
type: custom:hui-markdown-card
style: |
  ha-card {
    font-size: {{ font_size | default('20px') }};
    font-family: Oswald;
    height: 30px;
    background: none;
    margin-top: -0.5em;
    margin-left: -10px;
    margin-bottom: 0.9em;
  }
content: {{ title }}

image

Example 2.

# lovelace_gen
type: custom:hui-markdown-card
style: |
  ha-card {
    font-size: {{ font_size | default('10px') }};
    font-family: Oswald;
    height: 30px;
    background: none;
    margin-top: -0.5em;
    margin-left: -10px;
    margin-bottom: 0.9em;
  }
content: {{ title }}

image

You’re passing three arguments to !include, but it only takes two - a file name and a dict of variables:

!include
  - includes/titles.yaml
  - title: MORNING CYCLE SCHEDULE
    font_size: 10px
1 Like

I’m doing something stupid but can’t for the life of me see what. I have the following code:

# lovelace_gen

{% set colors = ['cyan', 'magenta', 'yellow', 'black'] %}

in a file that’s included from ui_lovelace.yaml. I’m happily using lovelace_gen elsewhere in my config, so it’s installed correctly. I get the following error:

while scanning for the next token found character '%' that cannot start any token in "/config/views/adminView.yaml", line 4, column 2

can anyone see what I’m doing wrong?

It looks right to me. I’ve encountered that error before due to erroneous whitespace (accidentally hit [tab] first when trying to [alt]+[tab]).

1 Like

Thanks, you set me on the right track.

Although that was the first text in the file, there was a blank line above it. Now it’s the first line and working.

1 Like

Yes, you’re right, sorry.

So, I’m back looking at this and whilst this works:

title: Garden
cards:
  - type: horizontal-stack
    cards:
      #=== Cycle 1 Title
      - !include
        - includes/titles.yaml
        - title: MORNING CYCLE SCHEDULE

This gives an error

# lovelace_gen
title: Garden
cards:
  - type: horizontal-stack
    cards:
      #=== Cycle 1 Title
      - !include
        - includes/titles.yaml
        - title: {{ states('input_text.irrigation_cycle1_name') }}

image

image

Ah, yes.

Templates generally require quoting when they’re along on a line, because { } is a json (and thus yaml) object.

Try title: "{{ states('input_test.irrigation_cycle1_name') }}".

Yes, I already tried that but it gives the same error.

      #=== Cycle 1 Title
      - !include
        - includes/titles.yaml
        - title: "{{ states('input_text.irrigation_cycle1_name') }}"

image

I also tried

      #=== Cycle 1 Title
      - !include
        - includes/titles.yaml
        - title: >
            {{ states('input_text.irrigation_cycle1_name') }}

Did you check your hass log file?

Ahh
 no, but I have now

It seems to be objecting to the states


Error handling message: Unknown error
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py", line 20, in _handle_async_response
    await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/lovelace/__init__.py", line 187, in send_with_error_handling
    result = await func(hass, connection, msg)
  File "/usr/src/homeassistant/homeassistant/components/lovelace/__init__.py", line 212, in websocket_lovelace_config
    return await hass.data[DOMAIN].async_load(msg["force"])
  File "/usr/src/homeassistant/homeassistant/components/lovelace/__init__.py", line 145, in async_load
    self._load_config, force
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/lovelace/__init__.py", line 164, in _load_config
    config = load_yaml(fname)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 62, in load_yaml
    return yaml.load(conf_file, Loader=SafeLineLoader) or OrderedDict()
  File "/usr/local/lib/python3.7/site-packages/yaml/__init__.py", line 114, in load
    return loader.get_single_data()
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 43, in get_single_data
    return self.construct_document(node)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 47, in construct_document
    data = self.construct_object(node)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 92, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 196, in _ordered_dict
    nodes = loader.construct_pairs(node)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 147, in construct_pairs
    value = self.construct_object(value_node, deep=deep)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 92, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 227, in _construct_seq
    (obj,) = loader.construct_yaml_seq(node)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 399, in construct_yaml_seq
    data.extend(self.construct_sequence(node))
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 122, in construct_sequence
    for child in node.value]
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 122, in <listcomp>
    for child in node.value]
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 92, 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, args), ldr, node)
  File "/config/custom_components/lovelace_gen/__init__.py", line 37, in load_yaml
    return loader.yaml.load(config_file, Loader=loader.SafeLineLoader) or OrderedDict()
  File "/usr/local/lib/python3.7/site-packages/yaml/__init__.py", line 114, in load
    return loader.get_single_data()
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 43, in get_single_data
    return self.construct_document(node)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 47, in construct_document
    data = self.construct_object(node)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 92, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 196, in _ordered_dict
    nodes = loader.construct_pairs(node)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 147, in construct_pairs
    value = self.construct_object(value_node, deep=deep)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 92, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 227, in _construct_seq
    (obj,) = loader.construct_yaml_seq(node)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 399, in construct_yaml_seq
    data.extend(self.construct_sequence(node))
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 122, in construct_sequence
    for child in node.value]
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 122, in <listcomp>
    for child in node.value]
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 92, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 196, in _ordered_dict
    nodes = loader.construct_pairs(node)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 147, in construct_pairs
    value = self.construct_object(value_node, deep=deep)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 92, in construct_object
    data = constructor(self, node)
  File "/usr/src/homeassistant/homeassistant/util/yaml/loader.py", line 227, in _construct_seq
    (obj,) = loader.construct_yaml_seq(node)
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 399, in construct_yaml_seq
    data.extend(self.construct_sequence(node))
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 122, in construct_sequence
    for child in node.value]
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 122, in <listcomp>
    for child in node.value]
  File "/usr/local/lib/python3.7/site-packages/yaml/constructor.py", line 92, 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, 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.7/site-packages/jinja2/asyncsupport.py", line 76, in render
    return original_render(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "/config/lovelace/includes/irrigation/zone_duration_line.yaml", line 27, in top-level template code
    name: "{{ states('input_text.irrigation_zone1_name') }}"
jinja2.exceptions.UndefinedError: 'states' is undefined

Oh my! How did I miss that for so long?

Lovelace_gen regenerates your static lovelace configuration when you ask it to rebuild. It cannot be used to update the design dynamically when you change a value.
As such, you can’t use states, because that just wouldn’t make sense.

Yes, ok.
But I was hoping to use it to apply user created friendly names to entities.

e.g. The underlying entity names are
input_number.zone1_duration, input_number.zone2_duration... etc

I have corresponding input_text values which I was hoping to use as the name: so allowing the UI to show a user created name.

Is there any way to do this if I don’t need them to dynamically update?

EDIT: The title example I have been using in this post was just a simple example to prove the concept (or not!)

Hi thomas,
I started using lovelace_gen, and I think it’s great!

I have one problem with the default functionality: I cannot make it work


I’ve tried to setup both string and int variable with the default instruction, but it just won’t work.
Do you have any suggestion?
Any of these below worked

icon: {{ icon|default(’“mdi:lightbulb”’) }}
icon: {{ icon|default(‘mdi:lightbulb’) }}
vertical_size: {{ vertical_size|default(‘1’) }}

Hi all,

I’m using the !file as described in the documentation. It works well and it got rid of all cache related issues since I’ve been using it. However, there seem to be a side effect: errors pop in chrome’s console.

image
(1 error for each !file statement. Since I use this for everthing in my lovelace resources, I get 30 errors at each reload).

It’s a bit annoying because it makes debugging errors less noticable.
-> For those who use the !file command, are you facing the same issue ? Have you foudn a way to get rid of this ?

I’m slowly rolling out fixes for that as I update my cards. It’s annoying indeed, but can be safely ignored.

Thanks for your answer, that is not a big deal compared to what your plugins offer. Cheers :slight_smile: !

@thomasloven Hi Thomas, I came across your add-on and I’m now doing a big overhaul of my Lovelace files. This works pretty great so far, thanks a lot for making this!

Question: is there any possibility to define macros for using in multiple views, to have some sort of global templates? I tried defining macros in the ui-lovelace.yaml, but that didn’t work out (I couldn’t use the macros in the views). It seems that the !include statement does not pass variables from the parent file.

I read in the Jinja manual that you should use the import statement to use externally defined macros in the local scope. `my attempts resulted in the following error:

  File "/srv/homeassistant/lib/python3.7/site-packages/jinja2/loaders.py", line 199, in get_source
    raise TemplateNotFound(template)
jinja2.exceptions.TemplateNotFound: my_templating_file.yaml

Any thoughts on this?

Unfortunately that’s not quite possible. Allowing macros in that way requires keeping track of the jinja context in a way that would require too much changing of the Home Assistant functionality to guarantee stable operation. Believe me, I’ve tried.

The best solution I can offer is to include a file with arguments: https://github.com/thomasloven/hass-lovelace_gen#passing-arguments-to-included-files