@JimT’s solution is probably the simplest. I wanted to outline a few other approaches because this is one of those problems that has a lot of different potential solutions.
Hysteresis
This is a technique where one turns on the fan at a given set of readings and then wait for the readings to drop below a different reading to turn it back off (or vise versa). For example, turn on the heater when the temp first falls below 60 °F and turn it off only when it gets to 62 °F. when the temp is between 60 and 62, do nothing.
Thus any flapping behavior caused when the reading is jumping above and below the threshold quickly is smoothed out but it doesn’t require timers.
There exists an Hysteresis profile you could use to drive this, though it’s not hard to implement in a rule if that’s what you prefer.
This is a great choice when it’s the sensor readings instead of time that is most important.
UI Rule Conditions
This is how you would implement “doesn’t check to see if it needs to turn off for 20 minutes.” Though it could also be used for other approaches like to implement the hysteresis above. A rule’s condition extracts the common case where one has an if statement to check some states and only if that if is true does the rule do something.
This doesn’t seem like a big deal at first but in practice it opens up a whole lot of new ways to think about your rules. And by separating the condition from the actions both become simpler code and simpler is easier to understand and maintain in the long run.
So if we take Jim’s example, the UI rule would have a Script Condition (using Rules DSL here for consistency)
val temp = BigChief_SHT3XTemperature.state as Number
val emc = EMCCornDryingh.state as Number
emc > 14.5 && emc < 15 && temp > 0 && temp < 32
Then your script action would just be
ESP32Temp_TestSwich.sendCommand(ON)
or you wouldn’t even need to use a script at all since the UI has simple actions like this built in.
Another thing one could do is create a timer in the script action and then check for that in the script condition. But that requires the ability to store the timer outside of the scripts themselves and as far as I know JS Scripting is the only language that supports that in UI rules right now. But the condition could check for the existence of the Timer and not run the actions as long as it exists.
Rule Templates
There is a rule template on the marketplace that could be used here: Threshold Alert. This rule template will call another one of your rules when one or more of the members of a Group of Items exceeds a configured threshold, with some additional configuration to control how often it can call your rule and a do not disturb time range (which we don’t need here).
You would instantiate two instances of this rule, one for each of your sensors. Set the limit to “20m” so it won’t call your rule more than once every 20 minutes. Then in the rule that you write you’d just have a script action
var Number temp = BigChief_SHT3XTemperature.state as Number
var emc = EMCCornDrying.state
if (emc > 14.5 && emc < 15 && temp > 0 && temp <32) //check to see if the fan needs to turn on
ESP32Temp_TestSwitch.sendCommand(ON)//Turn fan on
This would be a more complicated way to implement this but is a good choice when you have, for example, a period of time throughout the day where you don’t want the rule to run regardless of the sensor readings.
You could also modify the rule generated by the template to make it handle both sensors in the same rule without too much trouble.
None of these are better solutions for these specific requirements, but I wanted to present the options for future readers who may have a similar problem but slightly different requirements.