That’s really strange…Mine comes in as “yes”, I change it, when I write the variable again it’s still “yes”…Maybe I need to contact support, then? The whole behavior is contra to everything I know from development, and I just created this little snippet to test it out.
Excuse me, but I don’t quite get it.
If I change “CV_Off” from No to Yes, then “CV_On” is automatically changed from Yes to No. And of course vice versa. And this doesn’t work for you?
Are there any other flows with these two variables?
Hmmm…that shouldn’t be an issue. I know I have flows setting these variables, but as far as I know there are no flows intercepting the change. I did try to change the variables (I had to reboot the Homey to access them, which was strange), and that seemed to work - so I’m not ruling anything out.
Do you know a way to see which flows uses variables, like you can look at a device and see which flows they are in?
Actually, you dont need to copy the TEF yourself.
After you press Create TEF, the TEF is automaticly placed in your clipboard, so you just need ctrl+v to paste it somewhere
Translation: TEF allready in clipboard.
I have a super HomeyScript for that:
// FindLogicsVarsInFlowsTEST.js
//
// Script to find Homey Logics Variables in Flows, and orphaned Variables (by RonnyW)
// Adjusted somewhat, when called from a flow, it returns the output in a Variable (PD)
//
// Enable all "log" entries to output results to console
//log("=============================================================");
//log("Flow Search for Logics Variables");
//log("=============================================================");
//log(" ");
const flows = await Homey.flow.getFlows();
const logicVars = await Homey.logic.getVariables();
let flowMatches;
let varUsed;
let position = [];
let results2Var; // To be able to build a string to output the results to
// a variable [OrphanedLogicsVars], for usage in flows
results2Var = ("** *** Flow Search for Logics Variables *** **\n\n");
for (var iLogicVar in logicVars){
// log("=============================================================");
// log(" ");
// log("Logics Variable: "+logicVars[iLogicVar].name);
results2Var = results2Var + "\n|| *VARIABLE*: ["+logicVars[iLogicVar].name + "]\n";
//log('ID: '+logicVars[iLogicVar].id);
//log("=============================================================");
let logicVar = logicVars[iLogicVar].name;
let logicVarId = logicVars[iLogicVar].id;
varUsed = false;
for (var iFlow in flows){
flowMatches = false;
position = [];
// Search for variable name in Triggers
if (flows[iFlow].trigger.uri == "homey:manager:logic"){
for (var iArgs in flows[iFlow].trigger.args){
if ( flows[iFlow].trigger.args[iArgs].name == logicVar
|| flows[iFlow].trigger.args[iArgs].id == logicVarId){
position.push("Trigger card (IF)");
flowMatches = true;
}
}
}
// Search for variable name in Condition cards
for(var iCond in flows[iFlow].conditions){
if ( flows[iFlow].conditions[iCond] &&
flows[iFlow].conditions[iCond].uri == "homey:manager:logic"){
//log(flows[iFlow].conditions[iCond].args);
for (var iArgs in flows[iFlow].conditions[iCond].args){
if ( flows[iFlow].conditions[iCond].args[iArgs].name == logicVar
|| flows[iFlow].conditions[iCond].args[iArgs].id == logicVarId ){
position.push("Condition (AND) - direct reference");
flowMatches = true;
}
}
}
for (var iArgs in flows[iFlow].conditions[iCond].args){
if ( flows[iFlow].conditions[iCond].args[iArgs] &&
JSON.stringify( flows[iFlow].conditions[iCond].args[iArgs] ).indexOf( logicVarId ) > 0 &&
JSON.stringify( flows[iFlow].conditions[iCond].args[iArgs] ).indexOf( "homey:manager:logic" ) > 0 ){
position.push("Condition (AND) - indirect reference (Tag)");
flowMatches = true;
}
}
}
// Search for variable name in Action cards
for(var iAct in flows[iFlow].actions){
if ( flows[iFlow].actions[iAct] &&
flows[iFlow].actions[iAct].uri == "homey:manager:logic"){
for (var iArgs in flows[iFlow].actions[iAct].args){
if ( flows[iFlow].actions[iAct].args[iArgs].name == logicVar
|| flows[iFlow].actions[iAct].args[iArgs].id == logicVarId ){
position.push("Action (THEN) - direct reference");
flowMatches = true;
}
}
}
for (var iArgs in flows[iFlow].actions[iAct].args){
if ( flows[iFlow].actions[iAct].args[iArgs] &&
JSON.stringify( flows[iFlow].actions[iAct].args[iArgs] ).indexOf( logicVarId ) > 0 &&
JSON.stringify( flows[iFlow].actions[iAct].args[iArgs] ).indexOf( "homey:manager:logic" ) > 0 ){
position.push("Action (THEN) - indirect reference (Tag)");
flowMatches = true;
}
}
}
// Results of Flows found:
if (flowMatches == true){
varUsed = true;
// log("-------------------------------------------------------------");
results2Var = results2Var + " - ";
// log(" Flow: "+flows[iFlow].name);
results2Var = results2Var + "**Flowname:** " + "(" + flows[iFlow].name + ") \n";
// // log(flows[iFlow].name);
// // results2Var = results2Var +flows[iFlow].name);
// log(" Position:");
results2Var = results2Var +" -Position: / \n";
for (iPos in position){
// log(" - "+position[iPos]);
results2Var = results2Var + " -" +position[iPos] + " / \n";
}
}
}
if (!varUsed){
// log(" ");
// log("* NOT FOUND in a flow *");
results2Var = results2Var +"*** NOT FOUND IN FLOWS *** \n\n";
// log(" ");
}
}
// Output (test to view the result data in 'results2Var')
console.log(results2Var)
// Output to a StringVariable [OrphanedLogicsVars]
await tag( "OrphanedLogicsVars", results2Var );
return(true);
Output snippet:
*VARIABLE*: [AB.StartChargingTime_Num]
- **Flowname:** (T1-2 Rem.ChargingTime)
-Position: /
-Action (THEN) - direct reference /
- **Flowname:** (T2-2 Departure.Time Change)
-Position: /
-Action (THEN) - direct reference /
- **Flowname:** (C2-3 StartCharging Time.Num2Normal)
-Position: /
-Trigger card (IF) /
-Condition (AND) - indirect reference (Tag) /
- **Flowname:** (C2-3 Start Laden Tijd.Num2Normal (Kopie))
-Position: /
-Trigger card (IF) /
-Condition (AND) - indirect reference (Tag) /
-Action (THEN) - indirect reference (Tag) /
-Action (THEN) - indirect reference (Tag) /
- **Flowname:** (T1-2 Rest.LaadtijdChange (Kopie))
-Position: /
-Action (THEN) - direct reference /
-Action (THEN) - indirect reference (Tag) /
-Action (THEN) - indirect reference (Tag) /
- **Flowname:** (T2-2 Vertrektijd.Gewijzigd (Kopie))
-Position: /
-Action (THEN) - direct reference /
-Action (THEN) - indirect reference (Tag) /
-Action (THEN) - indirect reference (Tag) /
|| *VARIABLE*: [Chronograph_ms_test]
- **Flowname:** (1-2 Chronograph Test)
-Position: /
-Action (THEN) - indirect reference (Tag) /
|| *VARIABLE*: [PrijsNu_Afgerond]
- **Flowname:** (De prijs wordt 1 vd laagste in de 2u. vóór 18u. PBTH)
-Position: /
-Action (THEN) - direct reference /
-Action (THEN) - indirect reference (Tag) /
- **Flowname:** (De gem. prijs komende 2u. wordt het laagst in de komende 8u. PBTH)
-Position: /
-Action (THEN) - direct reference /
-Action (THEN) - indirect reference (Tag) /
|| *VARIABLE*: [ABC.TimeNumeric2Time]
*** NOT FOUND IN FLOWS ***
Flow import worked, I adjusted it with added ms timestamps.
It seems to work well.
@Tiwas How did you test?
When I switched the start button I saved the flow every time. Then I ran the flow by rightclick on it’s name and hit ‘start’.
ON 2 - var AllOn: true (--- var AllOff: false) @ 04T15:51:13.950Z
ON 1 - var AllOn: true @ 04T15:51:13.828Z
ON 1 - var AllOn: false @ 04T15:51:02.367Z
OFF 2 - var AllOff: true (--- var AllOn: false) @ 04T15:51:02.354Z
OFF 1 var AllOff: true @ 04T15:51:02.255Z
OFF 1 var AllOff: false @ 04T15:50:52.300Z
ON 2 - var AllOn: true (--- var AllOff: false) @ 04T15:50:52.291Z
ON 1 - var AllOn: true @ 04T15:50:52.199Z
ON 1 - var AllOn: false @ 04T15:50:34.232Z
OFF 2 - var AllOff: true (--- var AllOn: false) @ 04T15:50:34.224Z
OFF 1 var AllOff: true @ 04T15:50:34.123Z
Flow:
[TEF:FLOWS:H4sIAAAAAAACA+1Y227bRhD9FYIIEBv1Onu/MCjQwqjbPjQGkrQvsSDs1SFKka5IpXZd/3uHFOVEitIyjZKnPOiyy+XMnDNnZ5a8y9/kxV0udIrCOomkJhJxEy3ShDjEhcIMR2eMVP26Oi9yW1Xzi2f5Sd7BwDVNFW2d35/kiXBpBY2Ic6kQ9yograJCOnphibAiYbll4/x818j9ML7LfbM4td1r+IZPvG39srzuNvf+1E+9WE/1d9i8eHWXl3AluOS4jAFFJzzi1AhkhEgoKeuJUYlBJOCyNzKfz39pQpluz5rFdbOqw292WVpXxRYWxLzolqt4kvvep7LROaUd8oZxxKMPyGHskHXBKc4iS5j0627yAp/kt3lBNPw24GQIvljY2l7FZVE1V6UH632kb0Zvc//a1lcxjER0y/IKlsKoBVB50lYFqgySlFCgNUXkjKNIMsMNkzpY6fLZwMDdg8n+fxnA2KScAht2Ed9m9b5n1HCtGOcU0WBhPQkRMskJ8pHKwPoP4VuImTwQ4qBt4M4xZAOBDBIN/zQTgFiFaHRkHNsPI56kwG3EoMEBMglUyuCBIiUhyd5FZD3WKIFwGCeWeyNGyITIMc//jTr+sbLVfKPvNWTf1KHsyqYfN12P2sqAicMe6SHPRBKkdVLISx4Nsxa0ax5Qzx+FZXPdNb/H+tF8v/O/J6W+hw0JNpTBZtEuWcQTqFwTD+n2xmISgnbO78KGHBwGdhISvBuQWaLAOTYQRiAKYeZVpABe8fRRsCflfygZUwgfYQs9OdsPGm9jt4Pe+hH6IHMdPIAH19Jo8M8UxJggZJcEI4ZGTmk8uMxPwFK1gqlkqzb2NExKwA4NE7I/mYagkmNEeuQD11Cvg0BaUgGEEO6FEhgreuj69j4LymGKDXQNoyAULinQyRNBSXgFQUA1chsxjBxIitdw2s4uuwc0sF9Y6vdSIhhx5RS0CCwRNpBa4Y2Hsp3PBvVRKyVozloLYDW1yBKWEBjAcI0FRfXokPLR42HE93n01PfKnshJBGzjEvwz4vpEgWxgSQqNnzKPBNOgD84Fchb0arXCAWPpsIsjLPXvtaJuujKV3vZRtyM8v4y2i/N3L+3dK5Ma1GavdPGmt3DxLCMZyoCY7PuquqiL7NWr/9suZrPsO7h9HVRRTDmaFEUL7b2+ms2GogtnimQjdHTPRYA9bjgIhScko+JcsySh7G3kwUZ9EH5IIne4oQfk5giht8ZS+pC1KVttNjvOtrie0i12uPZc2RShqAOpCfxECekJDDHBhSGCGUXIjmYZP7hmJ50udjV7fg6iPRSTWzxOOVzu8EhigHnhUJIUcq4kg70fDAqghkCSoTTEXc0yemgi91D0rnY/maRt9X7iVtgR75Qev1soppyOxmOJ2X8Wt9fXxf6HyDXxy1V91oT4PHarZd2+GLzvP6lNKVqb/PimV0P+5EnWlYsIh4PFdbYoq6pso89+fXl2WV/WcPHH2GWvV8BtFiD7WVmn5rKuYPLFbfszDLJvM/unLbtseNI9bW/bLi5Or2LXXzw6fpoNVn646ZYQa1Y13lZZs8z+WlWrwfFl3adymH8JQzA3Gj7t/f3Uez5tq9LHo/fnyzrEm4t09Dh7fPwNOX66ttWb3mPqI6wMIZ8Ncm8zOwZ9mT+P7arqLvOss1f9kuWQkLexw53j1CaEQSGTDo47CtmpbwdTyKQS8VUhX1ohU14krBXC8d6XGAcTyKRe/FUgX1ggk96trQXC9N73egcTyKQHjK8C+aICub+f3f8DyHjQUxwXAAA=]
I suddenly got the urge to hug you
Anyway - it showed what I believed to be true: those two variables are only in use in two places, they are set in scripts. No other events for handling them if they change.
One question, though - does the script look in advanced flows as well?
I saved it, then clicked the blue button to set one of the vars to ‘yes’. Right clicking it shouldn’t do anything other than that, should it?
Doesn’t look like it
Im adding Advanceds Flows now, i also need this script
@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
You’re a saint! Keep me updated
Would this be a good candidate for an app?
Allready adding it to DC/AVD/TFE
But way more advanced!
To search for devices, zones, whatever.
It’s probably too late, but…not to sound stupid, but…what’s " DC/AVD/TFE"?
- DC
[APP][Pro] Device Capabilities - Enhance the capabilities of devices - Apps - Homey Community Forum - AVD
[APP][Pro] Advanced Virtual Device (Device Capabilities App) with Unique Text Status Indicator - Apps - Homey Community Forum - TFE
The Flow Exchange(r) - Exchange Your Flows with Others! - Flows - Homey Community Forum - SYD
Share Your Device! - Advanced Virtual Devices from Device Capabilities - Apps - Homey Community Forum - TEF
The Exchanger File, used in Share Your Device and The Flow Exchange(r)
Thanks!
A lovely script is on it’s way, but during testing i found a bug in a app of mine, fixing that first
@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 , 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
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)
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.