Need help selecting entities in grouped groups, in Python script

Yep, it can be!

You don’t need this line

or this line

Also, your {} are not set properly, this is what I meant about formatting.

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);
                }
            }
        }
    }
}

Then using it…

var light_ids = [];
flatten(entity.entity_id, light_ids);

light_ids.forEach(entity_id => {
    var state = states[entity_id].state;
    ... extra crap here...
}
      [[[
        function flatten(entity_id, result= [], searched= [])
        {
          var state = states[entity_id];

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

       var i;
       var count = 0;

      light_ids.forEach(entity_id => {
          var state = states[entity_id].state;

         for (i = 0; i < light_ids.length; i++) {
           var state = states[entities[i]].state;
           if (state == 'on') {count += 1;}
           }
       }
       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;

        ]]]

still returning the same error about

arrow function parameter list in 'function flatten(entity_id, result= [], searched= [])
  {
    var state = states[entity_id];

    ...'

think the connection between the function and the other ‘crap’ in the code isnt as it should be…

what editor do you use? Your spacing is all whacky and it makes it hard to read.

Aslo, it seems you aren’t reading the code, you’re just pasting previous stuff where ... other crap... went

BBEdit

might the forum software, looking ok here (though it probably in yaml mode not JS?

nope, not true, please don’t think so bad of me all the time and have some faith.
It’s not that this is my livelyhood is it.
Given the fact this hasn’t been posted before on the forum at all, I’d like to focus on getting the result, not on being a bad student. Why would I?

so, back to progress:

       var light_ids = [];
       flatten(entity.entity_id, light_ids);

       var count = 0;

       light_ids.forEach(entity_id => {
          var state = states[entity_id].state;
          if (state == 'on') {count += 1;}
           }

       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;

same result…seems the flatten function doesnt de-duplicate yet, given the fact light_ids.length is still counting all (double listed) groups. The error must be in the function above, the Malformed arrow function parameter list.

wait, this is so stupid, I had another counting button there, showing as expected. But hiding the fact this new test button wasn’t showing at all… sorry for that

so, we’re stuck at the error (which is for this button) and preventing anything else from happening…

I missed an else statement in flatten, but you fixed using flatten.

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);
        }
    }
}

And, because you like tightening things up…

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);
    }
}

back to my previous comment

Your brackets should line up and they don’t, also your lines don’t match up throughout.

      [[[
        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.