It is based on personal preferences, but this may help you to assess what works for you and develop your own style.
Various links to specific solutions/flows in this community,
You will see in past and present examples an evolution from simple flows to advanced flows and various styles.
A number of apps mentioned (eg. Advanced Triggers, Advanced Virtual Devices) are best used when you have some experience in flows.
Avoid starting flows at a specific time; other triggers are preferred.
Avoid dis/enabling flows in a flow
Avoid ALL cards for simplicity
Group triggers and central logic
Split flows into functional parts, connect them with for example āFlow is started withā cards, virtual triggers, advanced virtual device triggers or Advanced Triggers.
Use a logging app to trace flows (and use notifications for select events)
Use Note cards to document flows. Use a note color system.
Avoid constructing flows with app specific devices: Instead, try using zones and (advanced) virtual devices or Groups
Use zone timers where you can to avoid building your own timer
Use advanced flows. Limit the use of simple flows to cases where you may want to change the flow on your mobile app. Align cards in advanced flows consistently so you can read them back efficiently in the future.
As timer (that can be interrupted) use Chronograph, limit the use of built-in Delay timers
Variables: Use logical names for variables so you can trace back what they are used for.
An advanced virtual device can be used to store text/number/boolean variables that are related to each other. These device variables will not show in the logical variable list.
Did I mention to use zone cards where possible? (WHEN, AND, THEN). Great for motion, alarms, devices, etc.
Examples:
(use Chrome automatic translate to English for Dutch examples) (edited)
I agree on most of the points except for the first 3. For the first 2, I actually advise the opposite. I also apply point 5 to split larger flows into their triggers and their functional part. However, sometimes I just want to disable the flow based on conditions. I can also do that by creating a boolean variable and check it with the logic card inside the flow, but there are 2 issues with that. The first being, clean coding guidelines state that youāll want to create variables as locally as possible to avoid them being misused by other components and prevent unexpected side-effects. However, variables and tags in Homey are always global. Meaning, you cannot guarantee that the value is what you expect it to be. The disabled state of a flow on the other hand is very local to the flow and its meaning is absolutely explicit. It will never have an unexpected effect on any other flow.
The second problems with using variables and logic state is that it is effectively slower. Homey already has a system that will always check whether or not a flow is enabled before it runs it. Why would you let that always resolve to true only to then do another check inside to flow itself? Homey flows and cards are all nicely build on promises. If a homey flow canāt be started because itās disabled, the promise will be rejected early.
When it comes to point 3. This is ridiculous actually. If you do any type of advanced logic, you will come across situations where you want multiple conditions to be true before you continue. Sure you can check them all one by one. But like I said before, Homeyās cards are all just based Promises. The āAllā card is basically a wrapper around Promise.all. It will you to run all cards simultaneously and reject as early as possible. This will make your flows run way faster than if you were to check all conditions after each other.
I wholeheartedly disagree with any of this. I work as a software engineer. And in my company we even have a linting rule that prevent you from awaiting multiple promises in sequence if they are not dependent on each other. This is because it is just unnecessarily slow. The āAllā cards themselves donāt have any error handling indeed, but that is because you would already handle that in the cards you want to await. Hereās an example on how The all cards dramatically improve performance. In my example I took some fictional api calls that return in pretty decent response times. Iām not saying that all flow cards will be this slow, but with the principle that each flow card is basically an abstraction behind a promise, you simply donāt know how long it takes for a card to resolve. You can also see that I add error handling on each step where something could go wrong. The āAllā card really didnāt prevent me from anything i could do in sequence. It also didnāt massively increased the complexity of the flow. I just added the āAllā card and reconnected some wires. All it did was massively improved the speed of the entire flow. So if you really want your homey to perform fast, I really suggest you dive in to it a bit further.
This is not the use case I was describing. I know that you can pass variables from one flow/chain to another. But I sometimes also want to remember state for a longer time even after a flow/chain is finished. This can only be done in setting a global variable or tag. It would be very handy if Homey would let you declare variables and tags scoped to one advanced flow, but sadly thatās not the case right now. I know that there are flow cards that create and return so called local tags, but in reality these are just global tags that are deleted again after a few seconds.
I have found a nice way to work with disabled flows. Of course, the system doesnāt traces disabled advanced flow that have listener cards in them. I only disable/enable those subroutine flows that you identified in point 5. These flows are only triggered by other flows with the āStart [flow] with [tag}ā card. This card can be traced, as it will throw an error when the flow it wants to run is disabled. I also do not recommend disabling flows that has listener cards, but for subroutines it can be quite useful.
Here I have an example of how I combine the use of disabling/enabling of flows, and the All/Any cards effectively in my flows. In these flows I programmed my living room lights to autonomously dim depending on different times of the day and the measured luminance of my motion detector. During the day I want the luminance in my room to be around 200lx, while at night I want to dim to a more cozy atmosphere. I also configured two moods to override the autonomous dimming for watching movies or practicing yoga. When I activate one of these moods, the autonomous dimming flow is disabled. When I activate the Autonomous Dimming Mood, the flow is enabled again and then run at least on time. In my flows I already removed all error handling cards because these flows have been running very stable for over a year now. But the principle remains the same as the above, you can just add error handling on each and every step if you want.
Also, if your intent was to share some experience and things that worked for you, then I would also suggest to change the tone of the post a bit.
If the title of this article would be something like: āprinciples that I found worked for meā, then my response would have been different. But a title including words like ābest practiceāsā and sentences like āavoid thisā really suggests that people should adhere to these rules. Itās statements like that that are bound to cause a discussion.
New people on this forum that are also new to Homey, Home automation or to programming in general that read these posts will think that they should follow your principles that worked for you, thinking that they are best practices while in fact, thereās no real evidence to back up that claim.
ALL cards: youāve described a good use case where using ALL works well and fast and is justifiable to use.
However, thereās fast and thereās being CPU efficient. Your fastest result has simultaneous branches. If they are very CPU intensive you have to take into account that the CPU can take less care of other important events outside of this flow. Again, the CPU of the Homey pro is pretty good, but if you have many simultaneous flows, you need to take it into account.
My comments where for different use cases as shown in examples. And I focused on readability and ease of debugging in those cases.
Disabling/enabling flows: You showed a nice example where this works for you. Itās a tool that Homey offers, but Iāve already provided my view. And itās not that black or white either.
If there is such thing as a tone in posts, itās very hard to āreadā, and it also depends on your own state of mind at the time of reading.
I also donāt agree with all recommendations by Rrrr and you, but we always can discuss about it as fellow users?
Your ātoneā, to me, is also not the kindest, sorry.
Hmmmm I think you are getting a bit off track here, donāt you think?
Imho most people can think for themselves, and do realize it is a userās post with some info which might come in handy.
Forum posts are not āThe Only Truthā.
Iām missing a hint here:
According to Flow Checker I have : 8 flows and allready 85 (!) variables. I do a lot of math for energy usage and PVāsā¦
Is the an advice on how to keep track of all varables and where the ābelong toā or are used in ?
And sorry, I donāt think I can do with less variablesā¦
@JohanP Good point: I have added variables to the list in the OP.
There may be a way to use less variables if you can show us what they are used for.
Use a naming structure for the global variables according to their use (which most likely youāve already done).
One alternative is to set up an advanced virtual device with text/number/boolean variables.
You will then have in one view all the variables related to the logic you are implementing.
Like I said, I do a lot of math to calculate daily usage of power, how much the PVās produce, how much I deliver back to then Net, how the % of direct-use is etc. So I need to store the numbers of a dozen of counters, and the sum of them, the difference between these at the start of the day, and at the current moment, and the difference between themā¦
The flow is āin Dutchā not sure if you can understand, but this is my āStroom & Salderingā flow to fil in an Advanced Virtual device :
I might cut down on some of the varables, but this way the whole flow and whet Iām dooing is stiil āreadableā and understandable. I know I could do something with BLL, but it would take some of the calculations āout of sightāā¦
pls keep in mind Iām only working with Homey less then a month
Iām considering adding a ācodeā in front of the flow and variable to āconenctā them, like āaa_flownameā and āaa_variableā. next flow would be ābb_flowā and ābb_variableā. If i use a variable in both flows i could name it āab_variableāā¦
Please use the Google Translate icon in Chrome and your cards will show in English. Otherwise weāll need to take your post separate in a Dutch topic.
Well done, a very clear layout!
I see you are already using Advanced Virtual Devices, thatās great. However, you can also use the fields in AVDs to calculate, this will save you a lot of logic variables and logic calculation cards.
PBTH has a summarizer that automatically tracks power, gas, water. This will save you tracking these values over time. This will also allow you to cancel the āEvery 15 Minutesā card and the āWhen it is 00:00ā card who are both generating CPU demand on the dot, when potentially other flows do the same.
I see what you mean, we will live with the Dutch version then
I do not understand your comment fully, but of course, it is your choice.
Note that you can also store your intermediary results in AVD variables. It means replacing the logic calculation cards with AVD calculation cards.
This will not reduce the number of cards, but it will provide you with an much easier way to view the current values in device variables AND it reduces the number of logic variables for intermediate results and for final results.
Ok, only you as user can decide the balance between reducing cards and variables versus getting exactly what you want.
I cloud not create in 2, let alone one. Ok, maybe I could, but it would become a very hard to read and very long stringā¦
As far as CPU concerns, Iām not sure how āautomaticly tracking valuesā are less demanding on the CPU then once every 15 mins. The Homey must have poor performance if the calculations are that CPU intensive. Maybe if you have hundreds of flows runningā¦
I think the only way to make advanced calculations with true temporary constants while only making a few variables or tags public is by using homey script. You can use the ārun code and return number valueā card, or just create a separate script that sets a bunch of tags and just the ārun scriptā card.