thomasloven / hass-lovelace_gen

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

Home Assistant tries to render the lovelace UI before lovelace_gen is loaded. Other custom components may fail, too. #23

Open lmamakos opened 3 years ago

lmamakos commented 3 years ago

If you're using jinja2 templates in your lovelace_gen enhanced pages, funny business can ensue upon restarting Home Assistant because the front end tries to render the pages without lovelace_gen having been loaded. If you're using jinja2 templates, the ugly syntax can really piss off the YAML parser.

Best case, you get broken pages until you refresh the page after lovelace_gen is in effect.

A worse case is that HACS is broken. Yeah, really! I opened this issue on what I noticed. It seems that while HACS starts up, it calls system_health_info() which returns a long horrible traceback and a yaml.parser.ParserError exception that is not caught. HACS only catches some other specific exception..

Here's an excerpt of one of my YAML files that was choked on with the stock YAML loader:

# lovelace_gen  {% import '/config/lovelace/jinja-macros.j2' as ll %}

[....]

      # column 2
      - type: grid
        columns: 1
        square: false
        title: Outside Environmental
        cards:
          - type: custom:weather-card
            entity: weather.dark_sky
            icons: /local/wx-icons/static/
            name: WX
            mode: daily

          - type: grid
            columns: 3
            square: true
            cards:
              - {{ ll.tempSensor('sensor.ow_outside_h_temp', 'Outside') }}
              - {{ ll.tempSensor('sensor.wx_outdoor_temp', 'WX Station') }}
              - {{ ll.tempSensor('sensor.wx_outdoor_humidity', 'Humidity') }}
              - type: custom:button-card
                name: Main Thermostat
                entity: climate.thermostat001
                units: "°F"
                label: >
                  [[[
                    return states['climate.thermostat001'].attributes.current_temperature + " °F"; 
                  ]]]
                show_label: true
                show_units: true
                show_name: true
                show_state: false
                show_icon: false

I think the root cause here is that I'm not aware of a dependency capability that requires one custom component to be loaded before the next is started. If you're lucky, the ordering mostly works out for you. If you're not lucky, it seems to break more often.

I do not know where the right place for ultimate resolution is; in the mean time, I've manually patched my HACS custom component so things are back to normal. I wanted to raise the issue mostly for awareness so that others might not have to go chase ghosts that timing dependent..

wklink commented 3 years ago

HACS 1.9.0 failed occasionally on a restart, but HACS 1.10.0 now fails to load on every restart.

lmamakos commented 3 years ago

@wklink - I made a one-line change to the HACS extension (which is shown in the linked ticket), and it seems to work around the restart problem for me. I also did the upgrade to 2021.1.2 and it still seems to be working. I don't know what appetite HACS has to make a change in the same fashion.

Here's the change in HACS:

--- /tmp/hacs/operational/setup.py  2020-12-14 19:18:48.000000000 -0500
+++ hacs/operational/setup.py   2021-01-11 23:24:59.573888355 -0500
@@ -125,7 +125,7 @@

     try:
         lovelace_info = await system_health_info(hacs.hass)
-    except TypeError:
+    except:
         # If this happens, the users YAML is not valid, we assume YAML mode
         lovelace_info = {"mode": "yaml"}
     hacs.log.debug(f"Configuration type: {hacs.configuration.config_type}")

which just treat any/all exceptions from that call to system_health_info() the same way. That's probably too broad a change, but "works for me."

nnhhuu commented 3 years ago

@wklink - I made a one-line change to the HACS extension (which is shown in the linked ticket), and it seems to work around the restart problem for me. I also did the upgrade to 2021.1.2 and it still seems to be working. I don't know what appetite HACS has to make a change in the same fashion.

Here's the change in HACS:

--- /tmp/hacs/operational/setup.py    2020-12-14 19:18:48.000000000 -0500
+++ hacs/operational/setup.py 2021-01-11 23:24:59.573888355 -0500
@@ -125,7 +125,7 @@

     try:
         lovelace_info = await system_health_info(hacs.hass)
-    except TypeError:
+    except:
         # If this happens, the users YAML is not valid, we assume YAML mode
         lovelace_info = {"mode": "yaml"}
     hacs.log.debug(f"Configuration type: {hacs.configuration.config_type}")

which just treat any/all exceptions from that call to system_health_info() the same way. That's probably too broad a change, but "works for me."

thank you @lmamakos

this works for me too... i'm in 2021.1.5, does anybody knows if this will be corrected in a future version.

lmamakos commented 3 years ago

It looks like a fix was committed in the last day to HACS. I suppose I'll see how effective next time I do an upgrade. That issue was https://github.com/hacs/integration/issues/1808 and links to the change that was made when the issue was closed.

hanerd commented 3 years ago

Is it possible this is what I'm running into here?

HACs won't load because a card where I'm specifying an !include with a variable is undefined.

https://pastebin.com/murehRek

lmamakos commented 3 years ago

It doesn't look like source is defined within that "speaker" macro?