[APP][Pro] Device Capabilities - Enhance the capabilities of devices

How can I not save anything anymore? the save and close box remains gray? during maintenance. even when I make a new device.
It is on homey 2019
It is on a android tel. I can try on pc.

What’s the matter Arie ? I don’t recall what exactly was the problem.

My main usages/devices are zwave. And while the 2019 has about a 100% succes on commands, the 2023 does not. Some lights dont turn on/off, sometimes sensors are not updated. I have a lott of rx errors, while my 2019 hardlt had any.

The 2023 be faster, but its not (yet) completly reliable, while my hp2019 is.

Only issue is the 2019 is running out of memory.
The 2023 after migration has always the same out of memory issue, but once it works correctly, i want to upgrade the chip/memory.

But it needs to be used as reliable as the hp2019, which for, it isn’t yet.

1 Like

Yeah, so you will go for CM4 upgrade, like I did. I highly recommend it, they should equip or sell 4GB RAM version from scratch.

Anyway, sounds strange as recently, except of discussion about ZWAVE range, there was no complains here nor SLACK, at least not anything significant. A pity if you already migrated back but did not contacted support with diagnostic, it might help to un-cover some additional hidden issue, which might be not so common (or you did?). On the other side, if you run out of memory, in combination with high I/O (Athom is working on improving it), it might improve the situation - I will probably let you know to eventually test it again - in my case, with 66 apps, 283 devices (74 Zigbee, 18 ZWave) with 2GB RAM, it was crashing / overheating and overall, the experience was extremely poor. But with some own optimization under hood + replaced CM4 with 4GB, it’s working quite well.

I don’t like seeing you not developing :wink:

My conversion to HP2023 from 2019 gave me also z-wave issues, main part was that I had some unknown devices and one or 2 devices which where very chattie with errors. I repaired these devices and have healt some others which z-wave path was bit weird (4 or 5 hops) and from that moment on and 1 or 2 firmware upgrades later I have no issue with z-wave anymore (50 devices about I think)
Zigbee I needed to delete and pair again, repair did not work then (may 2023 I think I did the conversion)

Hi Arie,

Not a biggie, but I found a little bug

Yeah, i believe all optional dropdown lists are mandatory in the Mobile App, afaik this goes for all my apps.

1 Like

Ah I see, it looks like a limitation of the mobile flow editor then. I closed the ticket with “won’tfix”

Hi,
I’m trying to use following flow: The Flow Exchange(r) - Exchange Your Flows with Others! - #82 by Peter_Kawa
However, during running the Homey Playground API, i got the following error:

"root":{1 item
"error":string"Cannot read properties of undefined (reading 'split')"
}

I got this error with more templates, but not with all templates. Some are generated successfully.
Is this a known issue?

Code generated by DC:

async function run() { let exchangerFile={"zonesToReplace":[{"name":"[000] Test","replacements":[{"id":"8a6928ea-26b2-4922-9ead-d20ee6695dd3","name":"Badkamer","$$hashKey":"object:371"},{"id":"855113f1-f488-4223-b675-2f01270f573e","name":"Begane grond","$$hashKey":"object:372"},{"id":"381a3e64-6b61-4d6b-bf8e-5a2f0d30a5e1","name":"Buiten","$$hashKey":"object:373"},{"id":"b840a982-a3a7-4513-9d96-902d81128f5c","name":"Eerste verdieping","$$hashKey":"object:374"},{"id":"478cfd92-6475-4214-80d9-27125e39863a","name":"Gang","$$hashKey":"object:375"},{"id":"37782dac-6d40-40a2-a0a4-17a0dd05003a","name":"Kelder","$$hashKey":"object:376"},{"id":"2ab5a003-0120-4c01-80f2-a237dcf4ba14","name":"Keuken","$$hashKey":"object:377"},{"id":"ddc3cdaa-8172-4c4a-97c9-22d8ec462972","name":"Slaapkamer","$$hashKey":"object:378"},{"id":"1815c884-af06-4d53-a2c1-6f4c77e9eb4e","name":"Studeerkamer","$$hashKey":"object:379"},{"id":"9919ee1e-ffbc-480b-bc4b-77fb047e9e68","name":"Thuis","$$hashKey":"object:380"},{"id":"5204dc44-8e9c-49e7-aed8-9d5c93330126","name":"Tuin","$$hashKey":"object:381"},{"id":"9eb2975d-49ea-4033-8db0-105a3e982117","name":"Woonkamer","$$hashKey":"object:382"},{"id":"6a48add5-7349-4ff3-84b9-812e2d706e50","name":"Zolder","$$hashKey":"object:383"}],"id":"9fc79e23-76b0-4ee6-80c5-a033b66b277d","$$hashKey":"object:358","replaceWithId":"8a6928ea-26b2-4922-9ead-d20ee6695dd3","replaceWith":{"id":"8a6928ea-26b2-4922-9ead-d20ee6695dd3","name":"Badkamer","$$hashKey":"object:371"},"searchFor":"homey:zone:9fc79e23-76b0-4ee6-80c5-a033b66b277d","searchReplaceWith":"homey:zone:8a6928ea-26b2-4922-9ead-d20ee6695dd3"}],"devicesToReplace":[{"name":"Lamp Hal","class":"light","replacements":[],"actions":["on","off"],"conditions":["on"],"id":"9f6e935e-8514-44fd-8748-89995c7edbe0","tags":[],"$$hashKey":"object:361"},{"name":"Button","class":"other","replacements":[],"triggers":["trigger_virtualdevice_button"],"id":"ca581209-de4b-40a8-b27c-74a22628c0f9","tags":[],"$$hashKey":"object:362"}],"variablesToReplace":[{"name":"Button ON","type":"boolean","replacements":[{"id":-1,"name":"-- Create --","newName":"Button ON","$$hashKey":"object:397"},{"id":"663f834b-3ebc-4307-95ee-d78ced675315","name":"Kelder Aan","$$hashKey":"object:398"}],"replaceWith":{"id":"663f834b-3ebc-4307-95ee-d78ced675315","name":"Kelder Aan","$$hashKey":"object:398"},"replaceWithId":"663f834b-3ebc-4307-95ee-d78ced675315","id":"7cecb623-c641-404b-8606-2e91a173d1d4","$$hashKey":"object:366","searchFor":"homey:manager:logic|7cecb623-c641-404b-8606-2e91a173d1d4","searchReplaceWith":"homey:manager:logic|663f834b-3ebc-4307-95ee-d78ced675315"}],"tokensToReplace":[{"name":"Chronograph","types":[[{"name":"TimerX","replacements":[{"id":-1,"name":"-- Create --","newName":"TimerX","$$hashKey":"object:407"}],"replaceWith":{"id":-1,"name":"-- Create --","newName":"Timer5"},"replaceWithId":-1,"$$hashKey":"object:405","searchFor":"homey:app:nl.fellownet.chronograph|TimerX","searchReplaceWith":"homey:app:nl.fellownet.chronograph|Timer5"}]],"id":"nl.fellownet.chronograph","tokens":[],"args":[],"$$hashKey":"object:369"}],"advancedflows":[{"id":"2ac8ca1b-27d7-49e9-ac74-23bfa8c73b4c","name":"Zone activated Device with Button OnOff","cards":{"c7fc4c21-cad0-423c-9d04-afb245b9b04d":{"x":1040,"y":380,"ownerUri":"homey:app:nl.fellownet.chronograph","id":"homey:app:nl.fellownet.chronograph:timer_pause","type":"action","args":{"name":"Timer5"}},"665241e4-b96c-43c5-8fe8-1b743cd6fc16":{"x":1040,"y":300,"ownerUri":"homey:device:9f6e935e-8514-44fd-8748-89995c7edbe0","id":"homey:device:9f6e935e-8514-44fd-8748-89995c7edbe0:on","type":"action"},"0aee7f90-c3f4-43fb-a9bb-850fcb75054e":{"x":40,"y":780,"ownerUri":"homey:zone:8a6928ea-26b2-4922-9ead-d20ee6695dd3","id":"homey:zone:8a6928ea-26b2-4922-9ead-d20ee6695dd3:inactive","type":"trigger","outputSuccess":["a8364eed-e2a1-4736-891d-d12045073ebb"]},"9b2c9c12-0d50-44cc-8608-49d8134fee48":{"x":40,"y":1060,"ownerUri":"homey:app:nl.fellownet.chronograph","id":"homey:app:nl.fellownet.chronograph:timer_finished","type":"trigger","outputSuccess":["e80bb293-e370-4b49-8ce2-ba05c93b8a0a"],"args":{"name":"Timer5"}},"476a8fe9-255a-4beb-beb8-a920bde3188a":{"x":40,"y":280,"ownerUri":"homey:zone:8a6928ea-26b2-4922-9ead-d20ee6695dd3","id":"homey:zone:8a6928ea-26b2-4922-9ead-d20ee6695dd3:active","type":"trigger","outputSuccess":["4c390726-4bdc-4216-869d-0d3a169239b6"]},"43edeae5-8e5d-459f-ad1d-5c94e7e07d13":{"x":1040,"y":1060,"ownerUri":"homey:device:9f6e935e-8514-44fd-8748-89995c7edbe0","id":"homey:device:9f6e935e-8514-44fd-8748-89995c7edbe0:off","type":"action"},"9d2b8019-1cad-4ef4-8103-5eaadc3ba163":{"x":640,"y":300,"ownerUri":"homey:device:9f6e935e-8514-44fd-8748-89995c7edbe0","id":"homey:device:9f6e935e-8514-44fd-8748-89995c7edbe0:on","type":"condition","outputTrue":["665241e4-b96c-43c5-8fe8-1b743cd6fc16"],"inverted":true},"e80bb293-e370-4b49-8ce2-ba05c93b8a0a":{"x":640,"y":1060,"ownerUri":"homey:device:9f6e935e-8514-44fd-8748-89995c7edbe0","id":"homey:device:9f6e935e-8514-44fd-8748-89995c7edbe0:on","type":"condition","outputTrue":["43edeae5-8e5d-459f-ad1d-5c94e7e07d13"],"inverted":false},"e84d9679-4a2d-4472-967b-7967d69fd798":{"x":1040,"y":760,"ownerUri":"homey:app:nl.fellownet.chronograph","id":"homey:app:nl.fellownet.chronograph:timer_start_v2","type":"action","args":{"name":"Timer5","time":"3","unit":"minutes"}},"4c390726-4bdc-4216-869d-0d3a169239b6":{"x":460,"y":400,"type":"any","outputSuccess":["c7fc4c21-cad0-423c-9d04-afb245b9b04d","9d2b8019-1cad-4ef4-8103-5eaadc3ba163"]},"88f60bd8-9431-4e2a-8c40-bafb5c5e7e10":{"x":40,"y":460,"ownerUri":"homey:device:ca581209-de4b-40a8-b27c-74a22628c0f9","id":"homey:device:ca581209-de4b-40a8-b27c-74a22628c0f9:trigger_virtualdevice_button","type":"trigger","outputSuccess":["4c390726-4bdc-4216-869d-0d3a169239b6","d7c4cc1f-c732-418a-83b6-b3e1f2f551c0"],"args":{"field":{"id":"button1","name":"Button","description":"Button 1"},"mode":"set"}},"76db780c-49b5-4fe4-9ec5-18e9abc58cd2":{"value":"When","color":"yellow","x":40,"y":0,"width":null,"height":null,"type":"note"},"903f46a0-0fa3-41b5-8b76-e9e9503bad16":{"value":"And","color":"yellow","x":520,"y":0,"width":null,"height":null,"type":"note"},"df8b9e8f-caee-4217-9aad-d1733da6bb2a":{"value":"Then","color":"yellow","x":1040,"y":0,"width":null,"height":null,"type":"note"},"9b873d04-dd9e-4042-8fb1-563fae86d04c":{"value":"Motion sensor(s) and Garage Door Contact(s)","color":"green","x":40,"y":180,"width":null,"height":null,"type":"note"},"cba9bd35-244c-4b9e-8e26-03e596883276":{"value":"Push button","color":"green","x":40,"y":400,"width":null,"height":null,"type":"note"},"50e514ab-ea0a-4ca5-a27f-853cb146b4cd":{"value":"Motion sensor(s) & Garage Door Contact(s)","color":"green","x":40,"y":700,"width":null,"height":null,"type":"note"},"c8a0daf8-2daf-42b3-9ada-65fbe56879db":{"value":"Light OFF flows","color":"red","x":0,"y":620,"width":null,"height":null,"type":"note"},"f8c5abe0-df1b-43d6-86ea-584ac1e14612":{"value":"Light ON flows","color":"red","x":0,"y":100,"width":null,"height":null,"type":"note"},"d7c4cc1f-c732-418a-83b6-b3e1f2f551c0":{"x":1040,"y":460,"ownerUri":"homey:manager:logic","id":"homey:manager:logic:variable_set_boolean","type":"action","args":{"variable":{"id":"663f834b-3ebc-4307-95ee-d78ced675315","name":"Kelder Aan"},"value":true}},"143c150a-ca94-46b2-b0da-ab3e9188c3c5":{"x":440,"y":940,"ownerUri":"homey:manager:logic","id":"homey:manager:logic:equal_boolean","type":"condition","outputTrue":["a29fa991-411f-4f79-a7ba-e9c068850dcc","e80bb293-e370-4b49-8ce2-ba05c93b8a0a"],"outputFalse":[],"droptoken":"homey:manager:logic|663f834b-3ebc-4307-95ee-d78ced675315"},"87eb55e9-6f86-4f44-88cf-cd93c48977ee":{"x":40,"y":940,"ownerUri":"homey:device:ca581209-de4b-40a8-b27c-74a22628c0f9","id":"homey:device:ca581209-de4b-40a8-b27c-74a22628c0f9:trigger_virtualdevice_button","type":"trigger","outputSuccess":["143c150a-ca94-46b2-b0da-ab3e9188c3c5"],"args":{"field":{"id":"button1","name":"Button","description":"Button 1"},"mode":"set"}},"ff4492d2-1b1f-4f20-9d68-9094bfe34dd3":{"value":"Push Button","color":"green","x":40,"y":880,"width":null,"height":null,"type":"note"},"a29fa991-411f-4f79-a7ba-e9c068850dcc":{"x":1040,"y":940,"ownerUri":"homey:manager:logic","id":"homey:manager:logic:variable_set_boolean","type":"action","args":{"variable":{"id":"663f834b-3ebc-4307-95ee-d78ced675315","name":"Kelder Aan"},"value":false}},"a8364eed-e2a1-4736-891d-d12045073ebb":{"x":640,"y":780,"ownerUri":"homey:manager:logic","id":"homey:manager:logic:equal_boolean","type":"condition","outputTrue":["e84d9679-4a2d-4472-967b-7967d69fd798"],"outputFalse":[],"inverted":true,"droptoken":"homey:manager:logic|663f834b-3ebc-4307-95ee-d78ced675315"}},"$$hashKey":"object:355","cardlength":25}],"flowsToReplace":[],"usersToReplace":[]};
                for(let i=0;i<exchangerFile.advancedflows.length;i++) {
                    let oldId = exchangerFile.advancedflows[i].id;
                    exchangerFile.advancedflows[i] = await Homey.flow.createAdvancedFlow({advancedflow:exchangerFile.advancedflows[i]});
                    if(exchangerFile.flowsToReplace && exchangerFile.flowsToReplace[oldId]) {
                        _.each(exchangerFile.flowsToReplace[oldId].types, type=> {
                            if(type.replaceWithId===oldId) type.replaceWith = {id:exchangerFile.advancedflows[i].id, name:exchangerFile.advancedflows[i].name};
                        });
                    }
                }
                for (let i = 0; i < exchangerFile.variablesToReplace.length; i++) {
                    const variable = exchangerFile.variablesToReplace[i];
                    if(variable.replaceWithId===-1) {
                        let val = variable.type=='string' ? '' : variable.type=='boolean' ? false : variable.type=='number' ? 0 : undefined;

                        variable.replaceWith = await Homey.logic.createVariable({ variable: {name:variable.replaceWith.id===-1?variable.replaceWith.newName : variable.replaceWith.name, type:variable.type, value:val} });
                        variable.searchFor = "homey:manager:logic|"+variable.id;
                        variable.searchReplaceWith = "homey:manager:logic|" + variable.replaceWith.id;
                    }  else exchangerFile.variablesToReplace[i] = null;
                }

                for(let afIndex=0;afIndex<exchangerFile.advancedflows.length;afIndex++) {
                    let update = false;
                    for (const cardKey in exchangerFile.advancedflows[afIndex].cards) {
                        if (Object.hasOwnProperty.call(exchangerFile.advancedflows[afIndex].cards, cardKey)) {
                            const card = exchangerFile.advancedflows[afIndex].cards[cardKey];
                            const c=card;
                            if(card && card.id && card.id.startsWith('homey:manager:flow:') && card.args && card.args.flow) {                            
                                for(let i=0;i<exchangerFile.flowsToReplace.length;i++) {
                                    for(let j=0;j<exchangerFile.flowsToReplace[i].types.length;j++) {                                
                                        if(card.id === ('programmatic_trigger' + (exchangerFile.flowsToReplace[i].types[j].id===''?'': '_' + exchangerFile.flowsToReplace[i].types[j].id + '_tag' )) && card.args.flow.id===exchangerFile.flowsToReplace[i].id && exchangerFile.flowsToReplace[i].types[j].replaceWith) {
                                            card.args.flow.id = exchangerFile.flowsToReplace[i].types[j].replaceWith.id;
                                            card.args.flow.name = exchangerFile.flowsToReplace[i].types[j].replaceWith.name;
                                            update = true;
                                        }
                                    }
                                    
                                }
                            }

                            if(c.args) for (const argKey in c.args) {
                                if (Object.hasOwnProperty.call(c.args, argKey)) {
                                    //const c.args[argKey] = c.args[argKey];
                                    switch (typeof(c.args[argKey])) {
                                        case "string":      
                                            _.each(exchangerFile.variablesToReplace, (variable)=>{
                                                if(!variable) return;
                                                if(variable.searchFor) {
                                                    if(c.args[argKey] === variable.searchFor) 
                                                    { c.args[argKey] = variable.searchReplaceWith; update = true; }
                                                    else if(c.args[argKey].indexOf("[[" + variable.searchFor + "]]")>-1) 
                                                    { c.args[argKey] = c.args[argKey].replaceAll("[[" + variable.searchFor + "]]", "[[" +variable.searchReplaceWith + "]]");  update = true; }
                                                } 
                                            });
                                            break;
                                        case "object":      
                                            if(c.args[argKey].id && c.id && c.id.startsWith('homey:manager:logic:')) _.each(exchangerFile.variablesToReplace, (variable)=>{ 
                                                if(!variable) return;
                                                if(variable.searchFor && c.args[argKey].id==variable.id && variable.replaceWith) {                                                
                                                    c.args[argKey].id = variable.replaceWith.id; c.args[argKey].name = variable.replaceWith.name;
                                                    update = true;
                                                }  
                                            });                                        
                                            break;
                                    }
                                }
                            }
                            if(c.droptoken) _.each(exchangerFile.variablesToReplace, (variable)=>{ 
                                if(!variable) return;
                                if(variable.searchFor && c.droptoken==variable.searchFor && variable.replaceWith) {                                                
                                    c.droptoken = variable.searchReplaceWith;
                                    update = true;
                                }  
                            }); 
                        }

                        if(update) {
                            exchangerFile.advancedflows[afIndex] = await Homey.flow.updateAdvancedFlow({id: exchangerFile.advancedflows[afIndex].id, advancedflow:
                                {cards: exchangerFile.advancedflows[afIndex].cards}
                            });
                        }
                    }
                }
            };
            run();
            

@The_Cowman Which version of Homey and which version of DC do you use?

Homey: 10.0.5
DC: V2.14.9

1 Like

I guess the Homey model is relevant as well. The TEF was made with a Pro 2019

I have the Homey Pro (Early 2019).

Hi @Arie_J_Godschalk and @The_Cowman ,

I just imported the same TEF, and I encountered the same error as Cowman when running the generated code in the web API playground.

Homey2019 v10.0.5
DC v2.14.9
DC v2.15.4 test: Same error occurred

Screenshot from 2024-01-29 19-45-45

Screenshots of .js files mentioned: clickme

Screenshot from 2024-01-29 20-02-09

Screenshot from 2024-01-29 19-50-52

Screenshot from 2024-01-29 19-52-16


1 Like

Can someone please enlighten me if there is a posibility to make an automation using Device Capabilities that can work like this : WHEN motion alarm is OFF → AND → motion alarm is off for more than X minutes → DO → this
I am interested in the “more than x minutes” part but I want to make it a little bit more simple than with timers.

Yes, but you will only need the one WHEN card:
image

When [device].[tunredon/onoff] is [Equal to] [false] for [10] [minutes], execute ones after each change.

When you configure a flowcard like the one above, it indeed is the same as using timers.

Here is what you want:
image

When motion sensor device.motionalarm is Equal to false for 10 minutes, execute ones after each change.
This card will trigger after 10 minutes when a motionalarm is turned off and stays off for 10 minutes.

  • If within the 10 minutes it is turned on and off again, the timer “resets”.
  • If it is triggered after 10 minutes, it will only trigger ones.
    Until the motion is turned on again, and off again for 10 minutes, then it will trigger ones again.
1 Like

Additionally, when you use zone activity, it’s a built in feature. But very restricted compared to Arie’s example. It comes with only a selection of fixed delays to choose from, and it’s up to 60 minutes (@ Pro 201x)

1 Like

Is there also a way with THEN card?


I would like when I come home and connect to wifi to check if theres is presence in the last amount of minutes in the house and execute only if theres is no presence.
I am trying to make this so that I do not accidentally open the door when I am home and connect disconnect from wifi.
Also geofence is not an option because I live in a flat.

Something like this but with motion. Right now check if I was on wifi or not 10 minutes ago if I don’t mistake.

The zone cards no matter what I have on or off they still come back with a FALSE

I’m sorry, I don’t understand what you want to check.
I’ll try to make it more clear for myself, pls correct me if I’m wrong.

Your case:

Translated to:
When…
I re-connect to the wifi
And…
there was no activity for x minutes in the house
Or…
no one was connected to the wifi for x minutes
Then…
start something

How do you detect ‘no activity’? With motion/contact sensors?
Or do you mean by presence, other household members connect to the wifi?
Because the latter doesn’t activate zones.

.

I’ve read the sentence several times, but I don´t understand what you are saying, and what you’re trying to achieve.
Can you describe it in other words? Are you trying to prevent alarm triggers?
.

A zone only gets active by a motion- or contact sensor
https://support.homey.app/hc/en-us/articles/360026209853-Using-Zone-Activity