Removed
I recently posted my roller shutter flow here, but it did not get any reactions. I understand that the flow is very large and quite complex, and that the tags do not always show clearly identifiable values.
So I decided to break the elephant down into smaller pieces and did the same with my flow. I now use separate flows for different tasks.
I will present my flows here step by step, one part after the other. Feel free to ask for more information if anything is unclear or if you need more details.
Flow R110.1 Sun Data Collector:
This flow runs every 5 minutes and collects data points that are used by the other roller shutter flows.
The flow monitors these values over a period of 20 minutes. This is done with a Flow Gadgets card. In the other flows, I can then check whether a value has remained stable during that 20-minute period. This card can monitor multiple values at the same time, using the same observation period for all of them.
R110.2 Sun Protection Router
Column 1:
This flow is triggered whenever the sun azimuth changes, the sun protection switch changes, or the manual override switch is turned off.
Column 2:
This card checks whether we are between sunrise and sunset, whether the maximum temperature forecast is above 24°C, whether sun protection is switched on, and whether manual override is switched off.
This Flow Gadgets card accepts formulas in multiple expressions. The switches are virtual switches in my system.
If all these conditions are true, the blue path continues. Otherwise, the orange path runs.
Column 3:
The first line is a special case for my house, so you can ignore it. The cards on both paths, columns 3 and 4, release keys that are used later in the follow-up flows.
Columns 5 & 6:
These Flow Gadgets cards continue the flow elsewhere, in other flows. You can think of them as invisible lines between two cards.
R110.3 East Shading
This Advanced Flow controls the roller shutter for the east-facing window only.
It is started from another part of the automation by a Continue from here card. This makes it possible to keep the main logic on another canvas and continue here without drawing long lines across the Flow.
Column 1: Flow entry point
The Flow starts with a Continue from here card.
This is the receiving part of the Continue Flow card pair. The matching Continue elsewhere card can be placed on the same canvas or on another Advanced Flow canvas.
The same Continue key can also be used by other window-specific Flows, so several shading Flows can continue in parallel while each Flow only handles its own window.
Column 2: Sun position check
The Expressions match card checks whether the sun is in a relevant position for this window.
It evaluates three conditions:
- the sun azimuth is within the angle where sunlight can enter through the east-facing window
- the sun elevation is high enough to heat up the room
In Flow Gadgets expressions, the pipe character | means AND.
So this:
condition 1 | condition 2 | condition 3
means the same as, and can also be written like:
condition 1 AND condition 2 AND condition 3
Only when all conditions are true, the Flow continues to the shading decision.
Column 3: Luminance decision
This part decides whether the roller shutter should close for shading or open again.
The checks are cascaded:
- First, the Flow checks whether the observed luminance was high enough during the last 20 minutes.
The observed luminance value comes from theR110.1data collector Flow.
If this is true, the sun was strong enough for long enough, so the Flow continues to the close path. - If the luminance was not high enough, the Flow checks whether the luminance was low enough to ignore the sun.
If this is true, shading is no longer needed and the Flow continues to the open path. - If neither luminance condition is true, the Flow checks whether the sun azimuth is still before the relevant window angle.
In that case, the sun has not yet reached the window area, so the roller can also stay open.
Depending on these checks, the Flow continues on different paths.
Avoiding repeated roller commands
Each path uses a Return true once Flow Gadgets card before sending the roller command.
This is important because the Flow can be triggered many times, for example on every azimuth change. Without this protection, the same roller command could be sent again and again while the condition remains true.
The Return true once card lets the path continue the first time only. It then locks its own key and releases the keys of the other paths.
This means:
- the close path runs only once until another path has run
- the open path runs only once until another path has run
- each path can release the other paths again
This avoids repeated commands, reduces unnecessary network traffic, and keeps the Flow behavior predictable.
Roller positions
When shading is required, the roller shutter is set to 15% open.
When shading is not required anymore, the other paths use the same true-once logic and open the roller shutter to 100%.
Hereafter the flows for south R110.4 and west R110.5 , without explications as they use the same logic:
R110.6 Day / Night Fallback
This Flow is a fallback for the general day/night roller behavior.
It opens all rollers during the day and closes them fully after the evening limit.
Column 1: Flow entry point
The Flow starts with a Continue from here card.
This is the receiving part of the Continue Flow card pair. The matching Continue elsewhere card can be placed on the same canvas or on another Advanced Flow canvas.
Column 2: Day / night check
The Expressions match card checks whether the current time is between sunset and 23:00.
If the condition is true, the Flow follows the evening path.
If the condition is false, the Flow follows the day or night fallback path.
Column 3: Continue only on changes
Both paths pass through a Return true once card.
Each path locks its own key after it has run and releases the key of the other path. This makes sure that the same path does not continue again and again while the condition stays the same.
Only real changes are passed on.
Remember that several keys were released in Flow R110.2. This is important, because it resets these paths when a new cycle starts.
Column 4: Day fallback
This path opens all rollers.
It is used when the Flow is outside the sunset-to-23:00 window and the day path becomes active again.
Column 5: Night fallback
This path closes all rollers.
After 23:00, all rollers are set to night mode and close to 100%.
Note: This may happen a few minutes after 23:00, for example at 23:03, because the Flow is mainly triggered by azimuth changes and not by an exact time trigger. If you need the night fallback to run exactly at 23:00, add an At 23:00 trigger card in Flow R110.2.
To complete the example, here is the Flow for our bedroom.
This Flow uses a slightly different strategy, because here the most important factor is the open or closed state of the window. When the window is open and the outside air is cool enough, the roller should open wide to let fresh air in. If the window is closed, or if the outside air is too warm, the roller should close to reduce air exchange and protect the room from sun radiation.
The Flow mainly uses the same Flow Gadgets cards as the previous examples, so I will focus more on the logic than on every single card.
In the first part, the Flow checks whether the manual override is switched off.
It then checks two conditions:
- the bedroom window is open
- the minimum temperature from four outdoor sensors is below the selected value
The idea behind using the minimum temperature is that the coldest sensor is most likely in the shade and therefore represents the cooler outside air that can be used for ventilation.
If these conditions are true, the Flow then checks whether the temperature of the east sensor has stayed below the selected value for more than 20 minutes. This observed value comes from Flow `R110.1`. As this sensor is on the same side as the window it is exposed to the sun when it shines trough the window. A high temperature means the sun has actually enough energy to heat the room.
If this is also true, the Flow continues to the open path and opens the roller to let fresh air into the room.
If one of these checks is false, the Flow continues to the close path. In that case, the roller is closed to reduce air exchange and protect the room from sun radiation.
This is the flow that closes the roller shutters.
It checks the time and the state of the window. The idea is that I do not want the roller shutters to move in the morning before we are awake.
When we get up, we usually open the window, and we never sleep later than 9:00. So the condition is:
“Daytime and window open” OR “daytime and after 9:00”.
From this point on, the roller shutter position is set either to 15% in summer or to 35% in winter.
The 35% winter position is a “my wife” thing. ![]()
I think that this is another classic example of overthinking things trying to store derrived states and keeping them in sync.
I would try to go back to the start. In the end it comes back to these simple things:
- There are root states coming from devices and apps that pull info from the internet.
- There are Triggers that react on these root states
- Then you can then check some logic against these root states
- and based on this logic, you perform an action.
Do not try to store any other derived states calculated by logic cards. It will only make things more complicated.
What are the root states in these flows? I see Azimuth, luminance, temperature, contact alarm, and maybe time, and the position of your shutters. No other states need to be stored in a key. You can simply use cards like “When azimuth becomes higher than”, “When azimuth becomes lower than”, “When luminance becomes higher than”, “When Luminance becomes lower than”, “When Temperature becomes higher than”, and “When temperature becomes lower than”. You then just calculate what the position of the shutters should be based on any of these values and change the shutters accordingly.
Homey will not send commands to devices when the state of that device and the value you wish to change is the same. That is covered in the root drivers for all communication protocols. So you don’t need to worry about overloading the network by sending unnecessary commands.
Apps like Flow Gadgets look great at first sight, but they also offer features that might not always follow proper principles. expression matching is nice, but keeping and releasing keys is really overcomplicating things.
Keep it simple stupid.
Thanks for the feedback.
I agree with the basic principle that the root states should remain the source of truth. In this flow, they still are. The decisions are still based on azimuth, luminance, temperature, time, window state and shutter position.
But I do not fully agree with the conclusion that using Flow Gadgets automatically means overcomplicating things.
The reason I use Flow Gadgets here is exactly the opposite: to make an already complex automation more compact, more readable and easier to maintain.
Of course, I could rebuild parts of this with standard Homey cards, several ALL/ANY blocks, multiple helper flows and many more connections. But that would not make the logic simpler. It would only spread the same logic across more cards and more wires. I had versions of this automation before using these helper cards, and those flows quickly became much harder to read, maintain and modify.
The expression cards allow me to keep related conditions together in one readable place. Mathematical expressions also make it possible to use calculated or observed values directly, instead of creating several extra cards just to compare intermediate results. The Continue cards allow the flow to be structured into clear blocks, even on the same canvas, without turning the flow into a wiring mess.
The “true once until released” cards are also not meant to replace root states. They are used as latches / edge guards. They prevent the same shutter command from being sent again and again while the same condition remains true, and they release the opposite action when the state changes. That is useful for readability, but also for avoiding unnecessary commands. This matters even more with Thread/Matter devices, where I prefer not to create avoidable traffic.
So yes, a very simple version can absolutely be built with only root states and standard cards. For many users that may be enough. But this flow is not only about “if sun then close”. It also includes smoothing of luminance values, hysteresis between closing and opening, manual override, structured sections and logging for tuning the thresholds.
I would be very interested to see the same complete logic rebuilt with only standard Homey cards in a way that is actually easier to read and maintain. Maybe there is a simpler approach, but in my experience the complexity does not disappear — it just moves from expressions into a much larger number of cards and connections.
So I agree with “keep it simple” as a principle. I just think that, in this case, Flow Gadgets is what makes the flow simpler to build, understand and maintain.
Edit:
Did you notice that the observed states card also uses a calculated average from two sensors and the minimum value of two other sensors? Homey has no built-in trigger such as “Luminance is higher than X for X minutes” for calculated values like averages or minimums. This is another situation where Flow Gadgets can replace several cards and additional logic with a single card.
Like I said, this latch is already built into the homey drivers. You don’t need to worry about that. Homey will not send commands over zigbee, z-wave, bluetooth or any other built-in communication protocol when the value is the same as the current known state.
Also, when you use triggers like: “When azimuth becomes higher than”, “When azimuth becomes lower than”, “When luminance becomes higher than”, “When Luminance becomes lower than … for … minutes”, “When Temperature becomes higher than … for … minutes”, and “When temperature becomes lower than … for … minutes”, instead of timed triggers, and combine them with the correct logic, you will eventually further reduce the amount of commands you send.
Every 10 minutes means 144 times a day, while the other cards are being called only 6 to 8 times a day, depending a bit cloudiness and temperature shifts.
I agree that the expression match card could be a nicer way to combine multiple cards into one. But I personally prefer to only introduce libraries, or apps if it solves a problem that is otherwise very difficult to do. I would personally just use multiple native logic cards with an any card, but that’s just preference.
A universal same-value guard based on Homey’s known state could actually be counterproductive. The known state is only a cached state and may not always match the physical device.
For example, a Matter device shared through Multi-Admin may have been changed by another ecosystem, or a Shelly may have been changed through its physical input. If Homey missed or has not yet received that state update, suppressing the command would leave the device in the wrong state.
A driver may implement such an optimization when it knows that its state is reliable and current, but it cannot safely be assumed as universal behaviour. And it is still not equivalent to a latch, which prevents an entire logical flow branch from running again until it is released.
In my logs, I can clearly see that my shutter relays receive every command, even when the same target position—such as 100%—is sent ten times in a row. The roller does not move again because the relay itself handles the redundant command internally, but the command is still transmitted and logged. This directly contradicts the claim that Homey generally suppresses commands when the requested value matches its known state.
oh, that’s weird. I did some tests before with some devices, and saw no commands being send. Maybe some apps of some devices do this, but other don’t.
I would still much rather solve this by changing from a periodic trigger, to triggers where you actually can expect a change. If you then calculate what the change should be, the chances of sending duplicate commands is heavily reduced. Besides that, it also reduces the cpu and memory strain on the Homey itself. And it reduces complexity in your flows keeping it simple with less chances of bugs.
Like I said before, if you let the flow run every 10 minutes, the flow runs 144 times a day, even during the night, and even when conditions didn’t change. While if you use the other triggers, it only runs a few times a day when conditions have actually changed. This reduces strain on the cpu and on the network. And because you don’t need to store all those latches in persistent storage, you also reduce memory, storage, and cpu power there.
At this point, I can no longer see a constructive purpose in repeatedly presenting assumptions as facts, especially when several of those claims are demonstrably incorrect. It increasingly comes across as an attempt to discredit Flow Gadgets rather than a genuine effort to improve the Flow. You are, of course, free not to use the app.
More importantly, these claims are not based on Homey’s SDK3 developer documentation. Observing a particular behaviour with a few devices or apps does not establish a general Homey rule. Before presenting assumptions about command handling, CPU usage, memory usage or persistent storage as facts, they should be supported either by the official developer documentation or by reproducible measurements.
There is no universal Homey rule stating that duplicate commands are always suppressed. Each app developer can decide how commands are handled inside a driver. My own logs clearly show that my shutter relays receive every command, even when the same position is sent ten times. The relay itself decides not to move again. Other apps may suppress identical commands, but that does not make it universal Homey behaviour.
Relying blindly on a last known state would not necessarily be good driver design either. A device may have been changed externally, may have failed to report its state correctly, or may be shared through Matter Multi-Admin. A robust implementation must also consider silent failures where no error is returned but the command did not have the intended effect. Treating a cached state as unquestionable truth can therefore create incorrect behaviour rather than prevent it.
I also still do not see how your suggested solution would make this Flow simpler. For many devices, there simply is no trigger such as “when this value has remained above X for Y minutes”. Even where suitable triggers exist, every condition must be handled separately and connected to an ALL node. Since that node has no separate output for a failed result, the failed paths must additionally be routed through an ANY node.
For calculated values, the required standard cards do not exist at all. There is no standard trigger for the minimum of two sensors remaining above a threshold for a certain duration, nor for an average calculated from multiple sensors over time. I tried to build these Flows with standard cards before developing the corresponding Flow Gadgets features. Most cards in the app exist because I encountered an actual limitation, not because I wanted to make a simple Flow unnecessarily complicated. That’s not only true for this flow but for many others of my flows.
You have repeatedly stated that the same result would be easy to achieve with standard cards. So please rebuild the Flow using only standard cards and show it. It must reproduce the complete behaviour, including the calculated values, timing, both true and false paths, and suppression of unnecessary device commands. Saying that it should be simpler is easy. Providing a functionally equivalent Flow would turn that claim into something that can actually be evaluated.
Regarding CPU and memory usage, the attached developer measurements speak for themselves. Flow Gadgets remains at approximately 26 MB PSS, below Homey’s stated 30 MB recommendation, while most apps today use much more than 30 MB, while the CPU graph remains effectively flat at 0%. This includes the app’s in-memory states. These are measured figures, not assumptions.
You are also conflating three completely different things:
- running a Flow;
- accessing or updating a value in RAM;
- writing data to persistent storage.
Flow Gadgets stores its temporary values, observed values and latches in RAM. Running the Flow 144 times per day therefore does not produce 144 SSD writes. Reading or updating these in-memory states does not write them to Homey’s SSD.
Even as a deliberately absurd theoretical example, assume that every one of those 144 executions wrote an entire 1 MB to persistent storage. That would amount to only about 52.6 GB per year. Even a modest consumer SSD rated for around 150 TBW would need roughly 2,850 years to reach that figure at such a write rate. Even after assuming ten times that amount because of extreme write amplification, it would still take around 285 years.
A real Flow Gadgets state entry is vastly smaller than 1 MB, and, once again, these values are stored in RAM rather than written to the SSD. Raising SSD wear as a concern here is therefore not merely exaggerated; it is technically irrelevant to the actual implementation.
The same applies to the claimed CPU and memory strain. One lightweight evaluation every ten minutes is contradicted by the attached measurements, which show stable memory consumption and practically no CPU load. Claims about the app’s internal behaviour should be based on the SDK3 documentation, the actual source code, or measured results—not on assumptions about how it might work.
Edit: Here is what Flowchecker uses:











