Hi,
I need to create a scheduled rule, that turn on a switch every monday at 1 AM, and keep it turned ON for 12 hours.
I found this solutions:
2 Scheduled Rules, one for turn ON and another one to turn OFF switch
Use a timer in a classic .rules files
I do not like first, because of 2 rule to accomplish same stuff, and I dont like the second, because I would like to remove the usage of .rules file, and I don’t know if a timer for 12 hours is safe to use.
Timers are available to you in UI scripts and Blockly.
In most cases, it’ll be fine, but it won’t survive a restart. I personally don’t use timers for anything more than a few minutes.
But it’s not the the same stuff. One rule turns it on at 1 AM, and the other turns it off at 1 PM. Those are two very simple and complementary rules, and any other solution would be more complicated by necessity. There’s no better solution.
There is always a balance between spreading stuff across multiple rules and consolidation into one rule. In this case I agree with @rpwong, having two ultra simple rules in the UI (don’t even need code) is fine (I do this myself in fact) and probably less complex and easier to implement, understand, and maintain in the long run than trying to merge them into one rule.
@rpwong has you covered here. Timers are not limited to .rules files. I’ll add that it’s safe to use a timer of any length, though anything longer than a few minutes probably needs logic to recreate it on an OH reboot.
But, you’ve got other options in addition to these two (all of which will be more complicated than the two ultra simple rules).
Trigger one rule at both times and toggle the light (could run into problems if the light and times get out of sync).
Trigger one rule at both times and turn it ON if it’s morning and OFF if it’s afternoon (you can use Astro for this I think if you don’t want to mess with date times, though date times are also an option)
Expire on the Light though on a reboot you’ll lose the Expire timer so this probably isn’t a real option.
Thank both for precious suggestion, I am moving to use 2 rules.
I have a question about Timer without a rule file. I have this code:
var Timer timer_luce_notte
//Accende la luce di cortesia quando tutte le luci sono spente
rule "Luce Notturna Cortesia ON"
when
Item CAMERA_MOTION_STATUS changed from OFF to ON or
Item BAGNO_MOTION changed from OFF to ON or
Item CUCINA_MOTION_STATUS changed from OFF to ON or
Item INGRESSO_MOTION changed from OFF to ON
then
var Number hourofday = now.getHour()
logInfo("LuceCortesia","INIT - ore "+hourofday)
if (INGRESSO_CORTESIA_ENABLE.state==ON){
logInfo("LuceCortesia","Gestione Luce Cortesia Abilitata")
if (grpTutteLeLuci.state==OFF){
logInfo("LuceCortesia","Tutte le luci OFF")
if ((XIAOMI_GW_LightSwitch.state==OFF) && ((hourofday >= 23) || (hourofday < 8))) {
logInfo("LuceCortesia","Luce Cotesia Spenta")
if (timer_luce_notte!==null) {
timer_luce_notte.cancel
timer_luce_notte = null
logInfo("LuceCortesia","set Timer Null")
}
XIAOMI_GW_LightSwitch.sendCommand(ON)
logInfo("LuceCortesia","Night Light ON durata secondi "+INGRESSO_CORTESIA_DURATA.state.toString)
timer_luce_notte = createTimer(now.plusMinutes((INGRESSO_CORTESIA_DURATA.state as DecimalType).intValue)) [| XIAOMI_GW_LightSwitch.sendCommand(OFF) ]
logInfo("LuceCortesia","Timer Avviato")
}
}
}
end
//Spegne luce cortesia se viene accesa una luce nel frattempo
rule "Luce Notturna Cortesia OFF"
when
Item grpTutteLeLuci changed from OFF to ON
then
if (XIAOMI_GW_LightSwitch.state == ON) {
XIAOMI_GW_LightSwitch.sendCommand(OFF)
timer_luce_notte.cancel
timer_luce_notte = null
}
end
I declare timer outside the rules, but in the .rules file, then with 1st rule I turn on a night light and start a timer. With second rule i turn off the night light and destroy timer.
It is possible to achieve this in rule from UI? Basically I would like to leave .rules file and move all to UI’s rules.
I don’t know if these have been added to Rules DSL yet but in OH 3.4 two caches were added to core. The first, privateCache lets you save values from one run to the next but it’s only available for that one Script Action/Condition. The sharedCache lets you store values to share between Script Actions/Conditions.
It’s implemented in Blockly, Nashorn JS, JS Scripting, jRuby and Groovy but I don’t think it’s available in Rules DSL yet.
Hi,
I can move to JS Scripting, if you have an example on how use timers and cache in JS, I will migrate my rules.
But from your point of view, it is better still use Rule DSL or move to JS or other languages?
Notice these examples are parts of the official docs. The JS Scripting docs are astonishingly complete and comprehensive, more-so than even the Rules DSL docs.
I do not recommend anyone who is just getting started to use Rules DSL. IMO, Blockly does a better job for supporting users who are new to programming (and it’s more capable than Rules DSL) and JS Scripting or jRuby does a better job of supporting users who are experienced programmers (or those who don’t want to use Blockly).
However, for those with a lot of legacy rules, I recommend sticking with what you know unless you want to change things. Then if you want to change (e.g. move to the UI), play around with all of the other languages and see which one fits you best and move any new work you do in that language.
You don’t have to drop Rules DSL. You don’t have to drop .rules files. But Blockly, JS Scripting, and jRuby in particular have way more continuous development and improvement going on, making them better and better with each new release. Rules DSL is pretty much static and in some ways behind, though that can be a good thing too.
For what it’s worth, I’ve left everything in .rules files, because it works. I’m now starting to break some of my bigger and more complex rules into smaller, individual rules that fulfill very specific purposes. This will make it easier to move them into the UI as:
Simple UI rules (e.g. turn on this thing at this time)
Rules that run DSL scripts (when Blockly isn’t enough).
Amusingly, the hardest part isn’t retyping the rules–it’s rewiring my brain to emphasize “many small rules” over “fewer big rules”. Once I’ve made that transition within my .rules files, I think it’ll be very easy to move them into the UI.
Note that there is nothing I’m aware of that you can do in Rules DSL that you cannot do in Blockly. However, there are many things you can do in Blockly that you cannot do in Rules DSL (e.g. modify Item metadata, run another rule, etc.).
Also be sure to check the marketplace periodically. Maybe you don’t need to reimplement it after all. Maybe you can replace a rule with a rule template. These will often offer more options and be better tested with better error checking than you would typically do yourself. They can be quite a time saver. Most of my rule templates are pretty generic and apply to many different use cases. For example, I use Open Reminder to:
alert me when my dad’s motion sensor hasn’t triggered in too long a time
alert me when one of the doors is left open too long
alert me when one of my sensors stops reporting
alert me when one of my services goes offline
That’s a lot of milage out of one rule template. But beyond just the alerting, each of these also support a do not disturb period (it’ll save the alert and publish it only at the end of the DND if the alerting state is still active) and it can be configured to repeat the alert periodically until it leaves the alerting state. That’s a lot of code and capability that basically comes for free to you. All you have to code is what to do when the alert occurs (i.e. it calls a rule you write so all you have to code is the “what to do”).
I’m currently rewriting all these for OH 4 and the latest changes in the JS Scripting libraries and greatly improving the error checking. My goal is to make these as bullet proof as possible so end users like the two of you don’t have to worry about them and can feel confident to just install and use them.
Absolutely. Getting into rule templates (and thus being able to support others who use them) is actually my main motivation for moving my rules into to the UI. Otherwise, I’d just leave everything the way it is.
If there’s an idea for one you want me to write or have help writing let me know. I just wrote one that lets you call it from another rule to change the time on an Expire metadata (e.g. maybe you want that light to stay on longer on weekends). I’m always looking for ideas like that to convert to a template.
Though if I implement it, it’ll be an OH 4.0+ template.
Though on OH 3.4 it might be located somewhere else. I thought I saw a PR go by where the cache was implemented but maybe I’m remembering incorrectly. There is so much changing it’s hard to keep up with it all and my memory isn’t what it used to be.
There is if you make one. I don’t know if all the Timer’s methods are exposed but there’s a hasTerminated, isRunning, and that sort of information that can be obtained from a Timer.
The code looks reasonable. Does it work?
You might need to test to see tmrTemocopertaMarco is null in the second rule.
Note, I don’t see an option for private or shared on the “store value” block so this might not be using the cache at all, meaning the second rule won’t ever see the stored timer. So your options are:
use a script block and interact with the cache by adding custom code