Flexible Horseshoe card for Home Assistant Lovelace UI. A card with a flexible layout, a horseshoe-like donut graph, multiple entities or attributes, graphics and animations!
278
stars
43
forks
source link
Entity without an attribute is not rendered if it is not the first entity in card #92
Summary
When an entity without an attribute is used in the card as the first entity, it is rendered normally. If an entity without an attribute is used in the card as not a first entity and if the first entity is using an attribute, then the entity is not rendered on the card.
Steps to reproduce
Create two template sensors, one with an attribute and one without
- sensor:
- name: "Sensor with no value attribute"
state: 30
- sensor:
- name: "Sensor with value attribute"
state: 20
attributes:
value: 20
Add a cart with both entities, using the entity with no attribute first:
Reason for the bug
In file flex-horseshoe-card.js the following code block exists in the definition of 'hass' method:
// Update state strings and check for changes.
// Only if changed, continue and force render
var value;
var index = 0;
var attrSet = false;
var newStateStr;
for (value of this.config.entities) {
this.entities[index] = hass.states[this.config.entities[index].entity];
// Get attribute state if specified and available
if (this.config.entities[index].attribute) {
if (this.entities[index].attributes[this.config.entities[index].attribute]) {
newStateStr = this._buildState(this.entities[index].attributes[this.config.entities[index].attribute], this.config.entities[index]);
if (newStateStr != this.attributesStr[index]) {
this.attributesStr[index] = newStateStr;
entityHasChanged = true;
}
attrSet = true;
}
}
if (!attrSet) {
newStateStr = this._buildState(this.entities[index].state, this.config.entities[index]);
if (newStateStr != this.entitiesStr[index]) {
this.entitiesStr[index] = newStateStr;
entityHasChanged = true;
}
}
index++;
}
In this code block, the default value for the variable attrSet is set as false outside of the for loop. If the first entity in the index has an attribute, then the value of attrSet variable is set to true in the first condition check. As variable is in the same scope, on the next iteration of the for loop, value of attrSet variable still evaluates to true thus bypasses the second conditional block, which supposed to render an entity without an attribute.
This also explains, why an entity without an attribute works if it is the first entity, as the value of attrSet variable evaluates to false in the first iteration.
Proposed Solution
Set the value of attrSet variable to false inside of the loop, before the conditional blocks.
// Update state strings and check for changes.
// Only if changed, continue and force render
var value;
var index = 0;
var attrSet = false;
var newStateStr;
for (value of this.config.entities) {
attrSet = false;
this.entities[index] = hass.states[this.config.entities[index].entity];
// Get attribute state if specified and available
if (this.config.entities[index].attribute) {
if (this.entities[index].attributes[this.config.entities[index].attribute]) {
newStateStr = this._buildState(this.entities[index].attributes[this.config.entities[index].attribute], this.config.entities[index]);
if (newStateStr != this.attributesStr[index]) {
this.attributesStr[index] = newStateStr;
entityHasChanged = true;
}
attrSet = true;
}
}
if (!attrSet) {
newStateStr = this._buildState(this.entities[index].state, this.config.entities[index]);
if (newStateStr != this.entitiesStr[index]) {
this.entitiesStr[index] = newStateStr;
entityHasChanged = true;
}
}
index++;
}
Summary When an entity without an attribute is used in the card as the first entity, it is rendered normally. If an entity without an attribute is used in the card as not a first entity and if the first entity is using an attribute, then the entity is not rendered on the card.
Steps to reproduce
Add a cart with both entities, using the entity with no attribute first:
Observe that this works as expected:
Change the order of entities in card definition:
Observe that the second entity is not rendered:
Reason for the bug In file
flex-horseshoe-card.js
the following code block exists in the definition of 'hass' method:In this code block, the default value for the variable
attrSet
is set asfalse
outside of the for loop. If the first entity in the index has an attribute, then the value ofattrSet
variable is set totrue
in the first condition check. As variable is in the same scope, on the next iteration of the for loop, value ofattrSet
variable still evaluates totrue
thus bypasses the second conditional block, which supposed to render an entity without an attribute.This also explains, why an entity without an attribute works if it is the first entity, as the value of
attrSet
variable evaluates tofalse
in the first iteration.Proposed Solution Set the value of
attrSet
variable tofalse
inside of the loop, before the conditional blocks.