Skip to content
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

wrong entity in javascript template #389

Closed
2 tasks done
ktownsend-personal opened this issue Oct 27, 2020 · 7 comments
Closed
2 tasks done

wrong entity in javascript template #389

ktownsend-personal opened this issue Oct 27, 2020 · 7 comments
Labels
wontfix This will not be worked on

Comments

@ktownsend-personal
Copy link

Checklist

  • I updated the card to the latest version available
  • I cleared the cache of my browser

Describe the bug
A button-card nested inside another button-card using custom_fields is not getting the correct entity variable in javascript templates. It is receiving the parent card's entity.

Version of the card
Version: 3.3.6

To Reproduce
This is the configuration I used:

type: 'custom:button-card'
entity: switch.office_neon
show_name: false
show_icon: false
styles:
  grid:
    - display: contents
custom_fields:
  child:
    card:
      type: 'custom:button-card'
      entity: sensor.aqualink_run_mode
      name: '[[[ return entity.entity_id ]]]'

Screenshots
The yaml above gives this result. The icon is from the correct local entity, but the name is from the parent card's entity.
image

Expected behavior
The javascript should receive the entity for the local card. It may be ok to inherit entity from the parent card if the local card does not define an entity, but only if not defined. If an entity is defined on the local card but does not exist then the javascript should get undefined.

@ktownsend-personal ktownsend-personal added the bug Something isn't working label Oct 27, 2020
@RomRider
Copy link
Collaborator

RomRider commented Oct 27, 2020

Hi, I understand your use case, but that's not possible.
The only way to make this work is to use a template for the embedded card (with the javascript in the template, not in the main card)

@RomRider RomRider added wontfix This will not be worked on and removed bug Something isn't working labels Oct 27, 2020
@ktownsend-personal
Copy link
Author

That's an unexpected limitation. Would a template have the same problem if it had both the parent and the child button-card in the template? What about 3 nesting levels in the template?

I'm curious what specifically causes the technical challenge. I haven't had a chance to review your code to see what it's doing, but I'm a developer by trade and quite familiar with javascript and DOM so I should be able to understand the tech details if you have time to explain.

A related issue I found after creating this issue is that the triggers_update don't seem to be able to use javascript for the array values. I have a case where I use variables for 2 entities that are related to the main entity for a composite button and I wanted to automatically set up the triggered_updates for them in the template because they aren't auto-detected in the javascript (I assume because they are variable names in the javascript). I can create a separate issue for this if there is a chance it can be implemented.

I also discovered variables don't seem to automatically pass down to nested templates, nor can a variable use javascript to refer to another variable in the same list. Is that feasible to do?

@RomRider
Copy link
Collaborator

RomRider commented Oct 27, 2020

That's an unexpected limitation. Would a template have the same problem if it had both the parent and the child button-card in the template? What about 3 nesting levels in the template?

You can nest templates inside templates.
The reason why this is happening is that the JS templates are based on the main card config. The reason it is based on the main card config is that nested cards can be anything, and most of them don't support javascript so it is a convenient way to allow some JS templating for them too.
It works with nested button-card but if you want the JS templates for the nested button-card to be based on the nested one, you have to put that in a template. It's a fair trade off. Tomorrow you're (or someone else) going to ask me can I have a part of this nested card's JS template based on the main card, and this part of the nested card's config based on the nested one... and then we have a problem.

A related issue I found after creating this issue is that the triggers_update don't seem to be able to use javascript for the array values.

The reason triggers_update was introduced is because the card was updating on every change in every entity of HA and it could become quite slow.
So supporting templates in triggers_update would again introduce the overhead of running some JS code for every update which is not something I want to do. I was only thinking about allowing to use variables inside the triggers_update and only once on initialisation of the card. It means the value will only get evaluated once and replaced by the result. But it's confusing.

I also discovered variables don't seem to automatically pass down to nested templates, nor can a variable use javascript to refer to another variable in the same list. Is that feasible to do?

If you have an idea of how to implement variables dependencies in YAML, I'm all ears ;) (except by running them in the alphabetical order, which is the only solution that I found to be not too bad)

@ktownsend-personal
Copy link
Author

Thanks, I appreciate the details.

I have a thought on the entity localization. This is just a brainstorming concept and not based on any review of your implementation or any knowledge of lovelace because I haven't dug into any of that yet (I will eventually...too many projects LOL). I don't know how much of the yaml merging you have control over, but what I'm picturing is during the merge each button card gets a fresh entity that is defined for that card, with a parent reference to the entity instance of the button card containing it. That allows for each card to have its own entity reference and still be able to access upstream entities if needed. In the case of no local entity, either the closest upstream entity can be given or a null. Depends what is better behavior.

Regarding triggers_update, my scenario would be supported with a one-time evaluation. I can see what you mean about the overhead of trying to support re-evaluation on every state change, while also being more intuitive behavior. I would lean toward one-time evaluation and mentioning that limitation in the documentation.

Variables passing down to child button cards would probably just be handled while merging everything. Essentially the top card initiates the dictionary, and then as each button card is found it is given a clone of the parent button card's dictionary and any local variables of the same name override what was in the cloned instance.

Do variables support re-evaluation on state change? I can imagine that walking the hierarchy to do re-evaluation would have some significant overhead. No idea if you're already doing something like this, but it occurs to me that a map can be built up while running through the first merge & evaluation to simplify re-evaluation. Perhaps a dictionary of triggers (one entry per entity trigger), and each trigger having an array of wrapper objects. One wrapper for each javascript encountered, with references to the local entity instance, the local variables instance and a DOM reference of where to stick the result.

I really should spend some time looking at your implementation before I get too crazy with ideas so I can understand the challenges. This is my new favorite element for Lovelace because it has the power to create some really nice composite elements. I've already created a bunch, and the templates really help reduce repetition. My templates are getting out of control though...I wish there was a better way to organize them as files instead of at the top of my raw dashboard config. I have multiple dashboards, so I still have to replicate all my templates by hand. Last night I just clobbered some recently added changes that I hadn't yet copied to the other dashboards because I was experimenting in a different dashboard that didn't have the changes. I saw passing mention of !include in your documentation, but I couldn't do it with the UI managed yaml and I wasn't able to find any good references on !include for dashboards. Lovelace is in serious need of a re-use strategy, especially between multiple dashboards.

Thanks again for the details on my questions.

@kongo09
Copy link

kongo09 commented Jan 16, 2021

I've run across the same challenge. This is indeed unexpected behaviour and should be documented explicitly. It leads to the effect that you cannot copy a working button-card from somewhere else into a custom_field, which feels strange. I also could not get it to work with a template.

@RomRider
Copy link
Collaborator

It's not unexpected 😊 however it's not explained in the documentation, I agree.

The template way works so maybe you did something wrong. Please share the config if you want.

@RomRider
Copy link
Collaborator

This is fixed in 4.0.0. You can stop template evaluation on a per custom_field basis. I'm closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

3 participants