Need help selecting entities in grouped groups, in Python script

      [[[
        function flatten(entity_id, result=[], searched=[]) {
            var state = states[entity_id];
            if (state) {
                var entities = state.attributes.entity_id;
                if (entities) {
                    searched.push(entity_id);
                    entities.forEach(entity_id => {
                        if (!result.includes(entity_id) && !searched.includes(entity_id)
                            flatten(entity_id, result, searched);
                    }
                }
                else
                    result.push(entity_id);
            }
        }
        var light_ids = [];
        flatten(entity.entity_id, light_ids);

        var count = 0;
        light_ids.forEach(entity_id => {
            var state = states[entity_id];
            if (state && state.state === 'on')
                count++;
        }
        if (count == light_ids.length) return 'All ' + light_ids.length + ' lights on';
        if (count == 0) return 'No lights on';
        return 'Lights on: ' + count + ' of ' + light_ids.length;
      ]]]

hmmm. no matter what we try (and Iā€™e now copied indeed without readingā€¦):

Make sure all parenthesis have a matching closing parenthesis. I see the issue, can you find it? This is where having a good editor comes into play.

nopeā€¦ thought for a moment the else clause was positioned 1 level too far down, bu that didnt fix it.
Btw, Ive tried Atom and VSC too, but none of these make the bracketing better, not even the ā€˜bracket finderā€™.

      [[[
        function flatten(entity_id, result=[], searched=[]) {
            var state = states[entity_id];
            if (state) {
                var entities = state.attributes.entity_id;
                if (entities) {
                    searched.push(entity_id);
                    entities.forEach(entity_id => {
                        if (!result.includes(entity_id) && !searched.includes(entity_id)
                            flatten(entity_id, result, searched);
                        }
                    }
                else
                    result.push(entity_id);
                }
            }
        var light_ids = [];
        flatten(entity.entity_id, light_ids);

        var count = 0;
        light_ids.forEach(entity_id => {
            var state = states[entity_id];
            if (state && state.state === 'on')
                count++;
            }
        if (count == light_ids.length) return 'All ' + light_ids.length + ' lights on';
        if (count == 0) return 'No lights on';
        return 'Lights on: ' + count + ' of ' + light_ids.length;
      ]]]

simply donā€™t see it, sorry, complaining about:

button-card.js?v=3.4.0-2:1673 ButtonCardJSTemplateError: SyntaxError: Unexpected identifier in 'function flatten(entity_id, result=[], searched=[]) {
      var state = states[entity_id];
      i...'
    at new Function (<anonymous>)

So does your text editor highlight open and closing brackets? If you donā€™t have that ability, throw out what you have and download something that does. Like VSCode, Notepad++, iā€™m sure thereā€™s others.

yeahā€¦

vsc does highlight them, and no problems have been detected in the workspaceā€¦

Not curly brackets, parenthesisā€¦

Yep, added 3 of these too.

    label: >
      [[[
        function flatten(entity_id, result=[], searched=[]) {
            var state = states[entity_id];
            if (state) {
                var entities = state.attributes.entity_id;
                if (entities) {
                    searched.push(entity_id);
                    entities.forEach(entity_id) => {
                        if (!result.includes(entity_id) && !searched.includes(entity_id))
                            flatten(entity_id, result, searched);
                        }
                    }
                else
                    result.push(entity_id);
                }
            }
        var light_ids = [];
        flatten(entity.entity_id, light_ids);

        var count = 0;
        light_ids.forEach(entity_id) => {
            var state = states[entity_id];
            if (state && state.state === 'on')
                count++;
            }
        if (count == light_ids.length) return 'All ' + light_ids.length + ' lights on';
        if (count == 0) return 'No lights on';
        return 'Lights on: ' + count + ' of ' + light_ids.length;
      ]]]

btw, shouldnā€™t

if (state && state.state === 'on')
    count++;

be

if (state && state.state === 'on')
    {count++;}

thatā€™s a shorthand if statement.

So is it working or not after those changes?

noā€¦!
keeps throwing this:

probably because there was an incorrect closing parenthesis after entity_id here:

                if (entities) {
                    searched.push(entity_id);
                    entities.forEach(entity_id => {

but having trouble where to put it nowā€¦

Find where the closing curly bracket is for that line and add it after. Thatā€™s my mistake for leaving it out. I was missing 3 parenthesis in my original function.

The full foreach command isā€¦

somelist.forEach(x => { do stuff using x });

So, how would you find out where to put the closing parethesis? The semi-colon is optional. I usually add it.

EDIT: Also, remember that you have a second forEach belowā€¦

yes, that is what I have been doing for the past minutes:

would be

    label: >
      [[[
        function flatten(entity_id, result=[], searched=[]) {
          var state = states[entity_id];
          if (state) {
            var entities = state.attributes.entity_id;
            if (entities) {
              searched.push(entity_id);
              entities.forEach(entity_id => {
                if (! result.includes(entity_id) && ! searched.includes(entity_id))
                    flatten(entity_id, result, searched);
                });
              }
            else
              result.push(entity_id);
            }
          }
        var light_ids = [];
        flatten(entity.entity_id, light_ids);

        var count = 0;
        light_ids.forEach(entity_id => {
          var state = states[entity_id];
          if (state && state.state === 'on')
              count++;
          });
        if (count == light_ids.length) return 'All ' + light_ids.length + ' lights on';
        if (count == 0) return 'No lights on';
        return 'Lights on: ' + count + ' of ' + light_ids.length;
      ]]]

where the

was the finishing blowā€¦

hurray!

note that I have detached the ! 's in the line

             if (! result.includes(entity_id) && ! searched.includes(entity_id))

why doesnā€™t that make any difference? is JS so forgiving?
THANK YOU VM!

1 Like

@Mariusthvdb @petro @RomRider for several hours yesterday I followed through Mariuā€™s posts and the replies and was quickly educated on a bunch of things that I was struggling with so I wanted to say thanks. The posts were also at times funny asf with the way you guys banter back and forth.

With that being said I hit a wall today and wanted to see if one of you might be able to help. I didnā€™t think there was a way to get the name of the current View I was on within a Dashboard until your posts about how to use return window.location.pathname. I was trying to set up two buttons that when pressed will navigate one view either to the left or right depending on the button pressed. I used a script with conditions and sent a variable with the View I was on to it which then based on the view and button pressed would navigate one view to the left or right. It works fine but I tried putting the buttons inside of the sidebar-card and it caused a problem.

When I used the sidebar-card I stopped getting the View I was on and instead got the View that the browser was on when it was loaded or reloaded. I assume itā€™s because the sidebar-card is static and doesnā€™t change or refresh like the rest of the page does when changing views. Besides completely abandoning using the sidebar-card can any of you think of a way that I could do this and have the correct View returned.?

My only idea which I havenā€™t tried yet, is to somehow trigger a hidden button on each page and then have that button trigger return window.location.pathname so that the correct View is returned but I donā€™t know how or if that would even work.