button-card icon indicating copy to clipboard operation
button-card copied to clipboard

Getting entity state using a variable behaves differently to getting it using string

Open timothygee opened this issue 3 years ago • 4 comments

Checklist

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

Describe the bug A clear and concise description of what the bug is. If I define a variable as an entity id, then try to use that variable to get the state e.g. states[variables.entity_id].state it doesn't get the most recent state. If I change from a variable to a string e.g. states["switch.entity_id"].state it works fine.

I have a input_select that is set in an automation after the switch is turned on under certain conditions. When I use variables, the state of the input_select is the previous state When I use strings, the state of the input_select is correct

If I try to log out the state using console.log(), I can see that the code is run twice when I use a string but only once when I use a variable

Version of the card Version: 3.4.2

To Reproduce This is the configuration I used:


type: custom:button-card entity: switch.entity1 name: Entity variables: indicator_id: input_select.entity2 styles: card: - border-radius: 10% - padding: 0.6em - font-size: 1em - height: 6.45em grid: - grid-template-areas: '"i i a state" "n n n n"' - grid-template-columns: 1fr 1fr 1fr 1fr name: - font-weight: bold - font-size: 1em - align-self: middle - justify-self: start - text-align: left - white-space: normal icon: - width: 70% custom_fields: state: - display: | [[[ switch (states[variables.indicator_id].state) { // <-- this works: states["input_select.entity2"].state case "None": return "none"; default: return "inline-block"; } ]]] - width: 0.5em - height: 0.5em - margin-left: 50% - margin-top: '-100%' - border-radius: 50% - background-color: red - color: white - box-shadow: >- rgba(0, 0, 0, 0.12) 0px 2px 1px -1px, rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, rgba(0, 0, 0, 0.12) 0px 1px 3px 0px custom_fields: state: ''

Screenshots If applicable, add screenshots to help explain your problem.

Expected behavior A clear and concise description of what you expected to happen. It should behave the same whether I am using a variable or a string

Desktop (please complete the following information):

  • Firefox, chrome and edge

Smartphone (please complete the following information):

  • both iOS iPhone 8 and Android pixel 3

Additional context Add any other context about the problem here.

timothygee avatar Oct 02 '21 23:10 timothygee

I encountered the same issue.

jake404 avatar Nov 01 '21 15:11 jake404

Confirm the issue.

Here is an example of this strange 'heisenbug': зображення зображення

Code above is working. Field is correctly updated. However removing comment on line 398 breaks it! After server restart field content corresponds to previous state, not the current one! Browser refresh does not fix it too.

vpogorilyi avatar Nov 09 '21 21:11 vpogorilyi

Confirming the issue. For me, this is happening in entity_picture. My picture depends upon the state of an input_boolean.

If I simply store the name of the input_boolean in a variable before using the variable, it doesn't work (i.e. the entity_picture is not updated on state change)!

manisar2 avatar Feb 22 '22 23:02 manisar2

Anybody seeking a solution, see below.


Update 27-Feb-2022: The author has explained this behavior in the README.

By default, the card will update itself when the main entity in the configuration is updated. In any case, the card will parse your code and look for entities that it can match (it only matches states['ENTITY_ID']) so...

The solution is to use triggers_update, e.g.:

triggers_update:
  - switch.myswitch
  - light.mylight

Read below for old workaround

This is basically elaborating @vpogorilyi's comment above.

Have all the values of your variable mentioned somewhere in the template (in all the templates where this variable is used) - in the form of states['value']. Even a mention in the form of a comment makes it work!

So, e.g. if your variable called my_entitiy_id can have values:

  • switch.switch_1
  • switch.switch_2
  • switch.switch_3

Then, in all the templates where my_entitiy_id is used, have all these values mentioned in the form of comment (or in any other way):

// states['switch.switch_1']
// states['switch.switch_2']
// states['switch.switch_3']

This way, the component using this template will be monitored (and updated) on the state change of any of these entities, just like we would want.

It seems to me that shouldUpdate (or a similar function) in the code looks for entities literally present in a given template (within states[]), and updates the component using that template when the state of only any of those entities changes. Again, the entity name must be written out literally and within states[].

manisar2 avatar Feb 23 '22 06:02 manisar2