Evaluate condition and set value variable between two dates

Hello, to realize a scenario which starts between May 15th and September 15th I carried out this rule based on the day of the year and a test on the current day.
It seems to me it works, on the other hand I would have liked to know other way of doing more … adapted if it has any, my knowledge being better day after day but far from being solid … thank you in advance: -)
The rule:


rule "Mode volet protection soleil"
when
	Time cron "0 * * * * ?"
  or 
	System started
then     
     val currDay = now.getDayOfYear
     if ((currDay >= 135 && currDay <= 258)) // du 15 Mai au 15 Septembre
      {       
        Mode_VoletProtectionSoleil.sendCommand("YES")
      }
      else 
      {
        Mode_VoletProtectionSoleil.sendCommand("NO")
      }
    logInfo("period","result vaux" + Mode_VoletProtectionSoleil.state)  
end

thanks

It seems pretty wasteful to run a rule like this every minute. Let’s gradually adjust this so it doesn’t spend so much time doing nothing.

First some assumptions:

  • persistence is configured and restoreOnStartup is configured on Mode_VoletProtectionSoleil
  • no other rule is depending on Mode_VoletProtectionSoleil being commanded ON and OFF every minute

OK, this really doesn’t need to run every minute. It can run once a day. So change the cron trigger to 0 2 0 * * ? and it will run once a day two minutes after midnight. Usually you want to avoid running something exactly at midnight because lots of other stuff is going on which might interfere.

That’s significantly better, but maybe we can do even better. If the above assumptions are true, we really only need to run this rule twice a year. And we can make it much simpler if we split it into two rules.

rule "Mode volet protection soleil YES"
when
    Time cron "0 2 0 15 5 ? *" // May 15th
then
   Mode_ColetProtectionSoleil.sendCommand("YES")
end

rule "Mode volet protection soleil NO"
when
    Time cron "0 2 0 15 9 ? *" // September 15th
then
   Mode_ColetProtectionSoleil.sendCommand("NO")
end

But what if persistence with restoreOnStartup is not possible. Note that String Items are not supported by rrd4j, the default for openHAB 3 so MapDB would need to be installed and configured.

In that case we can still get away with only running the rule twice a year and at system start. Keep the rule as originally written but change the triggers to

when
    Time cron "0 2 0 15 5 ? *" // May 15th
  or
    Time cron "0 2 0 15 9 ? *" // September 15th
  or
    System started
then

You’ve could have another option that is to (de)activate your rule depending upon the period of the year.
This is not possible with DSL rules but doable with GUI rules.

1 Like

I do that with my Christmas lights rules. That’s a good approach too. Also, the two rules I show above are simple enough that they can be created in the UI without needing any code as well.

FWIW to be clear this would translate to 2 additional UI rules:

triggers:
  - id: "1"
    configuration:
      cronExpression: 0 0 0 15 5 ? *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - id: "2"
    configuration:
      enable: "true"
      ruleUIDs:
        - other_rule_uid
    type: core.RuleEnablementAction

and

triggers:
  - id: "1"
    configuration:
      cronExpression: 0 0 0 15 9 ? *
    type: timer.GenericCronTrigger
conditions: []
actions:
  - id: "2"
    configuration:
      enable: "false"
      ruleUIDs:
        - other_rule_uid
    type: core.RuleEnablementAction

The rule(s) to activate/deactivate can be chosen in a picker in the UI.
I’m not sure whether you can deactivate DSL rules or not now that they are handled by the new rule engine :thinking:

Yes in fact the timecron was wrong I wrote the trigger wrong thinking it was midnight … sorry for this error, the idea of storing the “Mode_VoletProtectionSoleil” variable and triggering 2 times a year is great!
I can change the type to Number and be 0 or 1, that’s great it’s rational! Great ! thank you !

I don’t think we can get to the RuleManager in Rules DSL. But it might be possible. We can definitely call to another Rules DSL rule, I just don’t know if we can call another rule from Rules DSL. I think the main problem is scriptExtension is not injected in Rules DSL like it is in JavaScript and Python.

But if someone wants to try here’s some JavaScript that does it and even shows how you can pass data to the called rule. Obviously, most of this is handled for you when using the Helper Libraries.

// Run another rule
var FrameworkUtil = Java.type("org.osgi.framework.FrameworkUtil");
var _bundle = FrameworkUtil.getBundle(scriptExtension.class);
var bundle_context = _bundle.getBundleContext()
var classname = "org.openhab.core.automation.RuleManager"
var RuleManager_Ref = bundle_context.getServiceReference(classname);
var RuleManager = bundle_context.getService(RuleManager_Ref);
RuleManager.runNow("tocall");
var map = new java.util.HashMap();
map.put("test_data", "Passed data to called function!")
RuleManager.runNow("tocall", true, map); // second argument is whether to consider the conditions, third is a Map<String, Object> (way to pass data?)

Why not use a Switch or a Contact? If this Item can only have two states, use one of the binary/boolean Item types. The big difference is a Switch can receive commands and Contact can not.

Yes I meant if you disable a “non-managed” rule coming from a .rules file (with the “disable” action or manually in the UI), would it work and would they stay disabled if you restart OH?

But it appears so - disabled rules are kept in this JSON DB file automation_rules_disabled.json so a rule coming from a file will have a stable UID (as long as the files don’t change) and would be able to appear in that file and treated like any other.

Ah, in that case maybe. The unmanaged rule gets deleted when the text file is unloaded and then the rule gets created anew when the text file gets reloaded. It used to be the case (don’t know if it is still the case) that with Jython and JavaScript rules defined in text files the rule ID was randomly generated. And you could see that the rule ID was different every time OH restarted or the text file was reloaded.

Now in OH 3 the rule ID seems to be more fixed than that, at least with Rules DSL (I’ve not used text based rules in OH 3). However, if you change the order of the rules in the .rules file the rule IDs will change because the IDs are generated based on the order of the rules in the file. But as long as the rule IDs remain the same, a disabled rule will remain disabled on OH restart or text file reload because, as you found, that information is kept in a separate jsondb file.

I used to handle it in one of my sets of rules by having a rule run at startup and then determine which rules should be enabled/disabled and set them appropriately. But I could do that because these rules became enabled/disabled based on date and the state of an Item.