Delay in variable?

Doesn’t look like it :wink:

Im adding Advanceds Flows now, i also need this script :wink:

1 Like

@Peter_Kawa , @RonnyW and @Tiwas

Please note: This script does include droptokens at all! And Variables are used in droptokens a lott! like, every condition card!
(And droptokens are not a sub-object/part-of the args.)
Meaning: This script does not(!) tell you all flows that use a variable, mostly the Logic (condition) cards themself!

I am alltering the script because i need the same for DC/AVD/TFE, so ill fix it, just wait :wink:

You’re a saint! Keep me updated :slight_smile:

Would this be a good candidate for an app?

Allready adding it to DC/AVD/TFE :wink:
But way more advanced!
To search for devices, zones, whatever.

1 Like

It’s probably too late, but…not to sound stupid, but…what’s " DC/AVD/TFE"?

2 Likes

Thanks!

A lovely script is on it’s way, but during testing i found a bug in a app of mine, fixing that first :wink:

@Peter_Kawa , @RonnyW and @Tiwas

Here is a/the new script. I am not completly done, and the return is not exactly like it was with the other script.
Still improving it, but i throught i would share it, so you could look at it and perhaps if you have questions or are missing something, let me know.
@RonnyW since you created an original script, i thought you might like this one.

Total time to search for all variables within all Flows and Advanced flows, also within droptokens and dropdownlists/selects from other apps: 1.4 seconds. Thats how its done!

(In real-live, i rewrite scripts (and SQLs) for beter performance :wink: , so i always love to make it faster )

You can also search for Devices allready(!), but i don’t have the filter up there yet, so you would probably get all flows you have :slight_smile:

But it will show you for all devices in wich flows they are!

It also searches “smart” in arguments, so it will also find references directly by other apps.
My DC Get Insights from Log for [device] flowcards also show up when searching for references!

Variables

Devices

The script

// Search for objects in flows and advanced flows.
// Created by Arie J. Godschalk
// Script to find objects

//Define defaults
const _now = Date.now();
let _last = _now;
const time = (str)=> {
  log(str.padEnd(30, " ") + ' - Duration: ' + (Date.now()-_last)+ ', Total: ' + (Date.now()-_now));
  _last = Date.now();
 };
 

return await FindObject('variables');
//return await FindObject('devices');


async function FindObject(type) {

  let preType;
  let objectsToFind;
  
  time('ObjectToFind - Start');
  switch(type.toLowerCase()) {
    case 'variables':
      preType = 'homey:manager:logic|';
      objectsToFind = await Homey.logic.getVariables();
      break;
    case 'devices':
      preType = 'homey:device:';
      objectsToFind = await Homey.devices.getDevices();
      break;
  }
  time('ObjectToFind - Finish');

  let idsToFind = _.map(objectsToFind, x=>x.id);
  //let type = 'Variables'
  
  time('Get Flows - Start');
  let flows = await Homey.flow.getFlows();
  time('Get Flows - Finish');

  //flows = _.filter(flows, f=>f.name==='FIND VARIABLES');
  time('Get Advanced Flows - Start');
  let afs = await Homey.flow.getAdvancedFlows();
  time('Get Advanced Flows - Finish');

  let cardTypes = ['trigger', 'condition', 'action'];


  let objectsFound = {};

  let containsId = (str, id, preFixed)=> typeof(str)==='string' ? (str.indexOf(preFixed? (preFixed===2?'[[':'')+preType+id : id)>-1) : null;
  let containsIds = (str, preFixed)=> containsId(str, objectsToFind, preFixed);

  let addToFound = (flow, cardType, obj) => {
    if(!objectsFound[obj.id]) objectsFound[obj.id] = {id:obj.id, name:obj.name, flows:{}}
    if(!objectsFound[obj.id].flows[flow.id]) objectsFound[obj.id].flows[flow.id] = {id:flow.id, name:flow.name, enabled:flow.enabled};
    if(!objectsFound[obj.id].flows[flow.id][cardType+'s']) {
      objectsFound[obj.id].flows[flow.id][cardType+'s'] = true;//{found:true};
    }
  };


  time('Remap Flows - Start');
  flows = _.map(flows,f=>{let rFlow = {
    id:f.id,
    name:f.name
    };
    for(let i=0;i<cardTypes.length;i++) {
      let cardType = cardTypes[i];
      if(f[cardType+'s']) rFlow[cardType+'s'] = _.map(f[cardType+'s'], x=>{
        var r= {args:_.filter(x.args, arg=> arg && 
        (
          (typeof(arg)==='string' && arg.indexOf('[['+preType)>-1) ||
          (typeof(arg)==='object')
        )
        )};
        if(!Object.keys(r.args).length) delete r.args;
        if(x.droptoken && x.droptoken.indexOf(preType)>-1) r.droptoken = x.droptoken;
        return r;
      });
    }
    return rFlow;
  });
  time('Remap Flows - Finish');


  time('Remap Advanced Flows - Start');
  afs = _.map(afs,f=>{let rFlow = {
    id:f.id,
    name:f.name
    };
    for(let i=0;i<cardTypes.length;i++) {
      let cardType = cardTypes[i];
      //if(f[cardType+'s']) 
      rFlow[cardType+'s'] = _.map(_.filter(f.cards, c=>c.type===cardType), x=>{
        var r= {args:_.filter(x.args, arg=> arg && 
        (
          (typeof(arg)==='string' && arg.indexOf('[['+preType)>-1) ||
          (typeof(arg)==='object')
        )
        )};
        if(!Object.keys(r.args).length) delete r.args;
        if(x.droptoken && x.droptoken.indexOf(preType)>-1) r.droptoken = x.droptoken;
        return r;
      });
    }
    return rFlow;
  });

  time('Remap Advanced Flows - Finish');

  time('Combining Flows and Advanced Flows - Start');
  flows = _.union(flows, afs);
  time('Combining Flows and Advanced Flows - Finish');




  time('Search Objects - Start');
  for(let objID in objectsToFind) {
    let obj = objectsToFind[objID];
    for (let iFlow=0;iFlow<flows.length;iFlow++) {
      let flow = flows[iFlow];
      for(let iCardType=0;iCardType<cardTypes.length;iCardType++) {
          let cardType = cardTypes[iCardType];
          if(flow[cardType+'s']) 
            for(let iCards=0;iCards<flow[cardType+'s'].length;iCards++) {
              let card = flow[cardType+'s'][iCards];
              if(containsId(card.droptoken, obj.id, 1)) addToFound(flow, cardType, obj);
              if(card.args) _.each(card.args, arg=> {
                switch (typeof(arg)) {
                  case 'string':
                  if(containsId(arg, obj.id, 2)) addToFound(flow, cardType, obj);
                    break;
                  case 'object':
                    for(let o in arg) {
                      if(containsId(arg[o], obj.id)) addToFound(flow, cardType, obj);
                    }               
                    break;
                }
              });
            }
          
      }
    }
  }
  time('Search Objects - Finish');

  return objectsFound;
};

P.s. adding zones and other stuff and a pre filter, so you can give id’s for what you are searching for (for a single device for instance)

3 Likes

Okay, i have updated the script a lott: A (Homey) Script to find Any Items (Devices, ZOnes, Apps, Variables) in any flow - Flows - Homey Community Forum

You can search for


//return await FindObject('variables');
//return await FindObject('devices');
//return await FindObject('zones');
//return await FindObject('apps');

//return await FindObject('variables', 'test');
//return await FindObject('variables', 'c31ecacc-26fe-448e-ab00-d109618c8382');
//return await FindObject('devices', [{id:'f6ef2b6f-e3f2-4ecf-a205-4f919a7a6d3f'}, {name:'Test AVD'}, {name:'Light SwitCH'} ]);
//return await FindObject('zones', 'Hal*'); //Use astrix at the end means it tries to find the start of the name
return await FindObject('apps', 'Device Cap*');

See the topic, ill continue the script itself there.

1 Like

Right click on the flowname on the left, start the flow from there.
When you click the blue button, just a simulation gets started

The script was one of the reasons to create the Flow Checker app :wink:

If you want to loop through Arrays or Collections, see my new JSON Loop action Card:
[APP][Pro] JSON Handler and Manipulator - Apps - Homey Community Forum

Hi Arie, nice to see how a simple script is envolving. Started with a simple nested loop to find all possible places of variables.
Im not a JS pro, so it’s good that someone with more skill is making it better :smiley:

1 Like

I don’t like droptokens in a device definition. There I can’t set an example value (if perhaps a token from another card is needed). I often use default string args with description and example even if only a token should be used. :innocent:

Yeah, i dont use it too. But the logic conditioncard do, so uts good that it searches for it.

And this script is actually more a rewrite of how i wanted to do it to be used in the DC app. So when it was requested, it feelt luke the right time to code the script.

1 Like