Google Services TTS in Advanced Flow

Holy mo!! It works!!!

How did those speakers get disabled in the chromecast app? Sooo weird… enebled them and now ur flow works also!

1 Like

But… when i change the var: google zegt
While it is still playing, it stops and speak out the second text.

So… it does not yet what it should

Pfff, finally.

So straign indeed, because after i imported your flow, everything worked so perfectly from the start…

Disable your old flow! :wink:

Hahaha it is :slight_smile:

It does break the running tts… with my simple solution it didn’t :stuck_out_tongue: hahaha

But i do like yours better… should the no be yes again then?

Edit, no that’s not it

No i have just tried it, and the wait to finish doesn’t matter (and shouldn’t).

But you knew that already :stuck_out_tongue:

Im not sure why it wouldn’t execute sequential.
And i need a moment for a bug.

Please use the next Device Capability App Then Card:

Set it to Variables and type in Google Zegt

Then post the result?

Uhmmm… the result is: {}

But this card will collect all my flows where that variable is entered? That will be a lot!!!
I don’t think my homey is strong enough to find them… it is mega slow…

Pfff, i have build it fast! Havent had a 60 seconds timeout yet! :slight_smile:

And, it searches al flows, no matter if the variable is in it or not. So the search for any variable should be about the same as any.

Lol… but i just change the context of “google zegt” in logic tab in the homey app… first i past a long text to have time to enter a second one. And that breaks the TTS

I dont get why there are no flows showing. Be right back.

Hhaha frustrating hu? Haha… well, thanks for the time you spend.

Would you disable my flow and then update the Google zegt vatiable?
What happens?

Execute this in HomeyScript:

/// -- The Find Objects in Flows Script --
/// Search for objects in flows and advanced flows.
/// Created by Arie J. Godschalk
/// Creation date: 2022-10-05
/// Script to find objects (Variables, Devices, Zones, Apps)  within Flows and AFs.

/// Define defaults
const _now =;
let _last = _now;
const time = (str)=> {
  log(str.padEnd(50, " ") + ' - Duration: ' + ( ', Total: ' + (;
  _last =;
//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('variables', 'Google zegt');

async function FindObject(type, toFind) {

  let preType;
  let objectsToFind;
  if(toFind) {
    if(!_.isArray(toFind)) toFind = [toFind];
    for(let i=0;i<toFind.length;i++) {
      if(typeof(toFind[i])=='string') {
        if(type!=='apps' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/gm.test(toFind[i])) toFind[i] = {id:toFind[i]};
        else  toFind[i] = {name:toFind[i]};
      if(toFind[i].name && toFind[i].name.endsWith('*')) {
        toFind[i].startsWith = true;
        toFind[i].name = toFind[i].name.substring(0,toFind[i].name.length-1);
  //return toFind;
  time('ObjectToFind Collect - Start');
  switch(type.toLowerCase()) {
    case 'variables':
      preType = 'homey:manager:logic|';
      objectsToFind = await Homey.logic.getVariables();
    case 'devices':
      preType = 'homey:device:';
      objectsToFind = await Homey.devices.getDevices();
    case 'zones':
      preType = 'homey:zone:';
      objectsToFind = await Homey.zones.getZones();
    case 'apps':
      preType = 'homey:app:';
      objectsToFind = await Homey.apps.getApps();
  time('ObjectToFind Collect - Finish');

  time('ObjectToFind Filter - Start');

if(toFind) objectsToFind = _.pickBy(objectsToFind, o=> !!_.find(toFind, find=>
    (! || && 
    (! || (find.startsWith ? :;
  time('ObjectToFind Filter - Finish');
  //let type = 'Variables'
  time('Get Flows - Start');
  let flows = await Homey.flow.getFlows();
  time('Get Flows - Finish');

  //flows = _.filter(flows, f=>'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[]) objectsFound[] = {,, flows:{}}
    if(!objectsFound[].flows[]) objectsFound[].flows[] = {,, enabled:flow.enabled};
    if(!objectsFound[].flows[][cardType+'s']) {
      objectsFound[].flows[][cardType+'s'] = true;//{found:true};

  time('Remap Flows - Start');
  flows =,f=>{let rFlow = {,
    for(let i=0;i<cardTypes.length;i++) {
      let cardType = cardTypes[i];
      if(f[cardType+'s']) rFlow[cardType+'s'] =[cardType+'s'], x=>{
        var r= {
          args:_.filter(x.args, arg=> arg && 
          (typeof(arg)==='string' && arg.indexOf('[['+preType)>-1) ||
        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 =,f=>{let rFlow = {,
    for(let i=0;i<cardTypes.length;i++) {
      let cardType = cardTypes[i];
      rFlow[cardType+'s'] =, c=>c.type===cardType), x=>{
        var r= {
          args:_.filter(x.args, arg=> arg && 
          (typeof(arg)==='string' && arg.indexOf('[['+preType)>-1) ||
        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];
            for(let iCards=0;iCards<flow[cardType+'s'].length;iCards++) {
              let card = flow[cardType+'s'][iCards];
              if(containsId(card.droptoken,, 1)) addToFound(flow, cardType, obj);
              if(containsId(card.ownerUri,, 1)) addToFound(flow, cardType, obj);

              if(card.args) _.each(card.args, arg=> {
                switch (typeof(arg)) {
                  case 'string':
                  if(containsId(arg,, 2)) addToFound(flow, cardType, obj);
                  case 'object':
                    for(let o in arg) {
                      if(containsId(arg[o], addToFound(flow, cardType, obj);
  time('Search Objects - Finish');

  return objectsFound;

Nothing happens

I have now a quick result, but with a lot of private informatie… 1 thing is for sure, i wont post that on here hahaha, sorry!

BTW… 80 or 90% are disabled flows coz i allready have those converted to advanced flows.

No, i can imagen.

Now enable my flow again and try again?

And send me a printscreen of how the flow is now please?
Just to be sure.

Que??? The whole flow is f###ed up now…. Well… it returned to the old state, now i have to edit it again :frowning: