lovelace-auto-entities
lovelace-auto-entities copied to clipboard
add names config option for name transforms
Hi there! I've been finding this plugin super useful, and I was using templates to do some clever stuff like naming entities according to the room they're in etc.
It was working well, but I noticed that the cards using a template render async and take a second to load compared to other cards not using templates that render seemingly instantly.
This got me curious to investigate whether there was some way to transform the names of entities with this plugin without using templates.
It turns out it wasn't supported but wasn't that hard to add! I created forked version of this plugin for testing called auto-named-entities with a new names config option and it's working great to transform my entity names without needing a template.
I figured I'd submit this PR in case others might find this functionality useful.
Awesome (and needed IMHO) addition @jharris4 ! ā¤ļø
- I really like the example that remove the Area from names, mimicking the default HA Overview dashboard !
- BTW adding a 'regreplace' (or allowing regex both in match & replacement) would make it definitively gorgeous !
@thomasloven It really desserve to be merged (once successfully tested) ! š
I also would really appreciate this option to remove area from the names. Please add this feature @thomasloven. Thanks
@thomasloven Gentle reminder. We would love to get this "names" feature merged. š
Thank you š
I literally thought this was possible because you can template for the filter, but then shocked I couldn't for options.
@jharris4 Thanks for the patch, but it seems that there are now conflict with the main branch. Would you please fix it so that it can be merged by @thomasloven
@thomasloven Would you please consider adding this feature š to your/our beloved ovelace-auto-entities?
Although templating a ānameā option could be a useful feature for SOME use cases, I do not think this should be implemented. The ānameā option belongs to a very narrow set of cards/card elements like entity row in Entities card. The auto-entities card does not have options which are unique to some particular card(s), it merely creates a list of objects (dicts) which then can be passed into some card. So, the auto-entities card is abstract and universal, not a particular card- dependent. Adding a new option with a very limited application brings an inconsistency. Also, next time some users will start asking about adding more options like āicon_templateā, ācolor_templateā etc - which is a way to nowhere. The currently available ātemplateā options covers all needed functionality. With my respect to a developer who proposed this PR - suggest not to implement it.
With my respect to a developer who proposed this PR - suggest not to implement it.
I am leaning towards the same view.
Also, the experiemental eval_js could be used by users to do name translations.
Thinking about this more, a gloabl transform option that applies after sort may have merits. Inputs can be entity, group, area, label & state and their attributes, output can be any parameter being a string and or perhaps even an obejct. This would cover name transform but open up to be fully extensible. The current this.entity_id serach and replace should be just one option of a transform function. Also attribute tansform (PR #309) can be another option of a transform function.
Apart from name translation as per PR, a real basic case would be to to have output of markdown cards using text as content, wiich if plain formated then would be a nice output list, possibly formatted in markdown.
e.g. possible yaml, borrowing a [[ ]] replacement strategy from declutteriung card, abstracting from javascript templating which would be confusing as it won't run javascript, but javascript possible in replacements, basically doing an eval() on the whole parameter like the current eval_js option, possibly doing this recursively to output an object.
transform:
- output:
content: |
Entity [[entity.name.replace('foo','bar')]] in Group [[group.name.replace('baz', 'qux')]]
last turned [[entity.state]] at [[entity.attributes.last_changed]]
EDIT: Or just [[ ]] replacement of everything in options...
EDIT 2: Yes, running recursively over options: is most straighforward and allows the most extensibility. Covers off name transforms, the markdown example I gave and more.
Although templating a ānameā option could be a useful feature for SOME use cases, I do not think this should be implemented. The ānameā option belongs to a very narrow set of cards/card elements like entity row in Entities card. The auto-entities card does not have options which are unique to some particular card(s), it merely creates a list of objects (dicts) which then can be passed into some card. So, the auto-entities card is abstract and universal, not a particular card- dependent. Adding a new option with a very limited application brings an inconsistency. Also, next time some users will start asking about adding more options like āicon_templateā, ācolor_templateā etc - which is a way to nowhere. The currently available ātemplateā options covers all needed functionality. With my respect to a developer who proposed this PR - suggest not to implement it.
I use the "name" option almost everywhere in 20+ dashboards. That said, I can totally get that it might be a niche use case (despite the few comments with people chiming in saying they use it too).
I totally get the scope creep argument of "if we add this, then how can we say no to this other similar thing?" (ex: icon_template etc). To that point specifically, I would argue that the name of an entity is much more universal/foundational than icons or colors. To back up my point, take a look at the code for process_entity.ts, the name is very much foundational to the representation of the entity, it's the return value of the process_entity function...
More generally, I could see how some might expect that since this project is called auto-entities, then it should reasonably support customizing all the properties for the Entity Card. Personally I have no interest beyond the name property. :-)
If there was a general transform option that would easily let one do things like remove the area name from all entity names then I'd be totally on board with dropping the names option and using that instead.
I have done a review and left some general comments and specifically how you can update to match current master code, specifically post recent performance improvements.
Thanks for taking the time to do this! I had taking a stab at fixing the conflicts a few weeks ago but never had time to finish. It's been on my todo list, just hasn't gotten back to the top yet...
I've been using an old fork with this PR merged for ages, and I'd love to get this merged so I can ditch the fork!
I could probably find a little more time to work on it if there's consensus on a plan that would get the feature merged somehow!
@jharris4 first up, you are probably not fully aware of what eval_js: option does. This passes through the object, including entity and options as a string using JSON.stringify to evaluate as a function, which then allows for any javascript string templates ${} to be evaluated.
So the following works to replace DCD Browser light name with ACD Browser. I have icon: as option to make sure that is not touched, which is the case.
type: custom:auto-entities
card:
type: entities
filter:
include:
- options:
name: ${state.attributes.friendly_name.replace('DCD', 'ACD') }
icon: mdi:test-tube
eval_js: true
domain: light
exclude: []
Form looking at this just now, it is probably a bit limiting, but at the same time job is a lot done. My thoughts:
- stick with this as it is including
${}rather than anything else (earlier I suggested[[ ]]). I knoweval_jsis being used out in the wild - see what else needs to be added, probably group and label names, following the same convention already being used
- maybe think of a library of helpers that would be available, similar to what you had in your PR. So you would call helpers.someHelper(variable). button-card takes this approach.
- one helper would be
helpers.entity(entity_id)which gets you the entity config. My preference would be thatentitywould be that, but as it is currently name to change would be breaking Then probablyhelpers.group(entity_id)etc. for group, area, label, device configs. Another would behelpers.stateTranslate(state) - two minds about providing
hass. Too much to break. button-card is liberal and providesthisandhassso you could do some evil stuff if you wanted to.
See what you think. If you are willing then happy to review draft PR at any stage.
If anything; documenting eval_js is the way to go here, imo.
While eval is normally considered risky, it's not really any worse than installing random frontend resources anyway, and at least it has almost no maintenance overhead.
I've avoided adding name processing for several reasons, but mostly separation of concern. It's not what auto-entities is supposed to do, and having it do that too would be half-assed at best.
The best solution would be something like
type: custom:auto-entities
filter:
include:
...
options:
type: custom:name-fixer-entities-row
rules:
...whatever...
Two different things that are good at their own tasks - auto-entities for populating the entities list, name-fixer-entities-row for fixing the names of stuff.
But I don't know if name-fixer-entities-row exists, and I don't feel like making it.
For the same reason I don't really like the idea of including a helper library in auto-entities. It's not in scope.
Though if eval_js was used there's nothing stopping anyone from making a separate library of globaly declared helpers for things like this š¤
Ā
I regret I ever made [[ ]] templates. Adding yet another language was crazy, but those were crazy times...
I really like the idea of moving the logic to a separate name-fixer-entities-row lovelace card, much cleaner. Thanks for suggesting that! I think I'll try that approach instead of fixing the conflicts in this PR.
The name transform logic I added in this PR does make extensive use of the helpers provided by auto-entities (getEntities, getAreas etc in helpers.ts).
It wouldn't be that hard to just duplicate/borrow those helpers, but then I guess there'd be a duplicate cache unless I hackily also used window.autoEntities_cache.
I can't think of a clean solution for that, aside from moving auto-entities's helpers/cache to a separate sharable package somehow. Any thoughts/suggestions are welcome :-)
I got a probably crazy idea - what about adding a new option āoptions_templateā - which is a jinja to set options (like ānameā)?
The trouble with any option that uses Jinja is that it requires a server side request to render, introducing a delay.
This PR leveraged the caching of entities/devices/areas etc to perform transforms efficiently on the client side without a delay (after the initial cache population of course).
I'll dig into eval_js a little more when I have time, I want to see if I can wrangle it to do things like remove area name from entity names, in which case I won't need this PR anymore :-)
Finally got time to look at eval_js, and thanks to the example provided by @dcapslock I was able to successfully replace the use of names option with use of eval_js.
Old version:
{% for room in _global.rooms %}
- type: custom:auto-named-entities
show_empty: false
card:
type: entities
title: "{{ room }}"
show_header_toggle: false
filter:
include:
- area: "{{ room }}"
label: Temperature
options:
secondary_info: last-changed
names:
transforms:
- type: "replace"
match:
area: true
- type: "replace"
match:
text: Climate
trim: true
sort:
method: name
{% endfor %}
New version:
{% for room in _global.rooms %}
- type: custom:auto-entities
show_empty: false
card:
type: entities
title: "{{ room }}"
show_header_toggle: false
filter:
include:
- area: "{{ room }}"
label: Temperature
options:
eval_js: true
name: "${state.attributes.friendly_name.replace('Climate', '').replace(area, '').trim()}"
secondary_info: last-changed
sort:
method: name
{% endfor %}
Thanks everybody for all the help, I'm happy that existing features seem to make this PR redundant!
I'm going to close this PR now, but I would like to add a vote for documenting the eval_js feature for others who are looking to do similar things.