Rule: Sunrise & motion sensor in order to open rollershutter

I would like to trigger a rule that opens my rollershutters when three requirements are fulfilled:

  1. It should be later than ‘sunrise’ but earlier than 08.30am.
  2. A motion sensor needs to receive an update.
  3. The rollershutters are still closed.

I installed the Astro binding and defined two items as well as the motion sensor (which receives updates via MQTT) as well as rollershutters (not shown).

myItems.items

DateTime Sunrise_Time  "Sunrise[%1$tH:%1$tM]"   { channel="astro:sun:local:rise#start" }
DateTime Sunset_Time   "Sunset [%1$tH:%1$tM]"   { channel="astro:sun:local:set#start" }
String eg_flur_multiSensor "Motion sensor [%s]" {mqtt="<[mosquitto:eg/flur/multisensor:state:default]"}

I am struggling with my rule, especially with the “when”-part.

myRules.rules

rule "Open rollershutter"

when
    Channel "astro:sun:local:(what comes here?)" triggered START and
    Time is earlier than 08.30am (something like Time cron "0 30 8 ? * * *)"and
    Item rollershutter_state == 'closed' and
    Item eg_flur_multiSensor received update
then
    gEG_rollershutter.members.forEach[i|i.sendCommand(0)] (This command is already working)
end

Also, once the rule has been triggered, a variable (e.g. rollershutter_state) should be set to ‘open’ in order to prevent the rule to be triggered every time the motion sensor receives an update while it is stil earlier than 08.30am.

I don’t have a complete solution to offer to but a few pointers.
Rule triggers are always “or”, never “and”. They’re triggers and would need to fire at exactly the same time for and to happen and they never will do that.
So, you want to build your rule so that e.g. the motion sensor is you trigger “the when part”. In the “then” part you want to check the different conditions “if sunrise has happened & not past 8:30 & blinds are closed”.

Mikael

@mikaelgu hot the nail on the head.

The when clause is where you define what EVENTS trigger the rule.

You need to use if clauses in the rule to check for the multiple conditions.

I’ll also point you to the Time of Day Design Pattern which might be able to help you figure out the time part of your conditions in a reusable manner.

I’ve just posted my shading automation setup, maybe it’s of use to you.

@mikaelgu
@rlkoshak
Guys, after re-reading the rules documentation, it began to dawn on me that I need to fundamentally change my understanding regarding rule triggers. You just confirmed it :slight_smile:

So, here’s how I (hopefully) solved my problem:

  1. I defined two switches called ‘dayTime’ and ‘nightTime’. It is probably a simplified version of @rlkoshak’s Time of Day Design Pattern.
  2. I defined a GroupItem switch that comprises all my rollershutter. It will be used for checking whether the command to open the rollershutters will be fired at all. That is, if the GroupSwitch’s state is ‘ON’, i.e. the rollershutters are already open, the command won’t be executed.
  3. A simple CRON job will open the rollershutters at 08.30am if they are still closed (and eventually set the GroupItem’ state to ‘ON’).

myItems.items:

// Astro
DateTime Sunrise_Time  "Sonnenaufgang [%1$tH:%1$tM]" <sun>  { channel="astro:sun:local:civilDawn#start" }
DateTime Sunset_Time   "Sonnenuntergang [%1$tH:%1$tM]" <moon> { channel="astro:sun:local:nauticDusk#start" }

// rollershutter
Group:Switch:OR(ON, OFF) gEG_rollershutter_switch "Rolläden Erdgeschoss [(%d)]" <blinds>

Switch eg_wz_rollade1 "Wohnzimmerrollade 1 [%d%%]"   (gEG_rollershutter_switch) ...
Switch eg_wz_rollade2 "Wohnzimmerrollade 2 [%d%%]"   (gEG_rollershutter_switch) ...
Switch eg_wz_rollade3 "Wohnzimmerrollade 3 [%d%%]"   (gEG_rollershutter_switch) ...
Switch eg_wz_rollade4 "Wohnzimmerrollade 4 [%d%%]"   (gEG_rollershutter_switch) ...
Switch eg_kueche_rollade "Kuechenrollade [%d%%]"     (gEG_rollershutter_switch) ...
Switch eg_bad_rollade1 "Badezimmerrollade 1 [%d%%]"  (gEG_rollershutter_switch) ...
Switch eg_bad_rollade2 "Badezimmerrollade 2 [%d%%]"  (gEG_rollershutter_switch) ...

// multi-sensors
String eg_flur_multiSensor "Bewegungsmelder [%s]" <light> ... (Alternates between the two states "alarm" and "clear")

myRules.rules:

// Astro
rule "Set day time"

when
    Channel 'astro:sun:local:civilDawn#event' triggered START
then
    nightTime.sendCommand(OFF)
    dayTime.sendCommand(ON)
end

rule "Set night time"

when
    Channel 'astro:sun:local:nauticDusk#event' triggered START
then
    nightTime.sendCommand(ON)
    dayTime.sendCommand(OFF)
end

// Rollershutter
rule "Open rollershutter ground floor via motion sensor"

when
    Item eg_flur_multiSensor changed from "clear" to "alarm"
then
    if ( (dayTime.state == ON) && (gEG_rollershutter_switch.state == OFF) )
        gEG_rollershutter_switch.sendCommand(ON)
end



rule "Open rollershutter ground floor at specific time"

when
    Time cron "0 30 8 ? * * *"
then   
    if (gEG_rollershutter_switch.state == OFF)
        gEG_rollershutter_switch.sendCommand(ON)
end

Do you see any possibilities for code improvements?

I still find it a bit strange how OpenHAB rules are designed. In my view, all the potential triggers should go into the ‘when’ part and the ‘AND’ operator should be available, maybe something like this:

when (or better if)
    (dayTime.state == ON) &&
    ((gEG_rollershutter_switch.state == OFF) &&
    (Item eg_flur_multiSensor changed from "clear" to "alarm")
then
    gEG_rollershutter_switch.sendCommand(ON)
end

But I am pretty sure the OH designers implemented rules the way they did it on purpose. Maybe someone can enlighten me why they did it in this particular way, i.e. specifing event-based triggers, time-based triggers, and system-based triggers and omitting the ‘AND’ operator?

Rules are triggered by events, not states. No two events are going to occur at exactly the same point in time so it makes no sense to have an AND in the when clause. These events include an Item receiving a command or an update, changing it’s state, a specific time is reached, a channel trigger event occurs, etc. But all of these are an event and events do not have a duration. Consequently events don’t ever occur at the same time.

The new experimental rules engine has a separate clause added where you can check for states but that this new clause only supports AND, not OR.