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

Entity without an attribute is not rendered if it is not the first entity in card #92

Open
tolga-orhon opened this issue Sep 8, 2024 · 0 comments

Comments

@tolga-orhon
Copy link

tolga-orhon commented Sep 8, 2024

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

  1. 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
  1. Add a cart with both entities, using the entity with no attribute first:
type: custom:flex-horseshoe-card
entities:
  - entity: sensor.sensor_with_no_value_attribute
  - entity: sensor.sensor_with_value_attribute
    attribute: value
show:
  horseshoe_style: fixed
layout:
  states:
    - id: 0
      entity_index: 0
      xpos: 50
      ypos: 45
      styles:
        - font-size: 3.5em;
    - id: 1
      entity_index: 1
      xpos: 50
      ypos: 70
      styles:
        - font-size: 1.5em;
horseshoe_scale:
  min: 7
  max: 35
color_stops:
  '0': '#1B0F52'
  1. Observe that this works as expected:
    image

  2. Change the order of entities in card definition:

type: custom:flex-horseshoe-card
entities:
  - entity: sensor.sensor_with_value_attribute
    attribute: value
  - entity: sensor.sensor_with_no_value_attribute
show:
  horseshoe_style: fixed
layout:
  states:
    - id: 0
      entity_index: 0
      xpos: 50
      ypos: 45
      styles:
        - font-size: 3.5em;
    - id: 1
      entity_index: 1
      xpos: 50
      ypos: 70
      styles:
        - font-size: 1.5em;
horseshoe_scale:
  min: 7
  max: 35
color_stops:
  '0': '#1B0F52'
  1. Observe that the second entity is not rendered:
    image

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++;
      }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant