(Solved) OH3 - Rule trigger but only if after sunset

Trying to create a rule in OH3 GUI for a motion sensor/light in the evening. Simply, if motion is detected and its after sunset, turn the light on. I have created a trigger using the motion detected item and action of turn the light on. I believe I should use a But only if condition to restrict this to after sunset only, but not sure how to achieve that. I have the astro binding up and running and have the sunset time exposed as an item, but it does not appear I can use a dynamic value in the condition i.e. if sunset time item is less than now - it looks like I can only use a static value i.e. sunset time item is less than this statis time.

Any thoughts/suggestions? Do I need to use a script for now?

No need for a script. Have a look over the Time of Day design pattern.

Basically, you need an unbound string item that you use to store the time of day (e.g. Day, Night), and then rules to change the state according to either time or astro updates. Then you can just use that item as your if condition.

You can get pretty complex with it. Personally, I just use a Day and Night, with the state changing at sunrise and sunset.

You’d need to use a Script Condition and write this as code. In Rules DSL it would be something like

now.isAfter((Sunset.state as DateTimeType).zonedDateTime)

That will return true if right now is after the time specified for Sunset. However, there is a problem because Sunset will be recalculated around midnight. So you also need to add in a check for sunrise.

now.isAfter((Sunset.state as DateTimeType).zonedDateTime) || now.isBefore((Sunrise.state as DateTimeType).zonedDateTime)

Notice that in a Script Condition it expects the last line to evaluate to a boolean (true or false) which is what the above will do.

Also notice how I use an or || condition. If you used and && the expression would always return false because Astro calculates sunrise and sunset for today. You’d never have a case where a time can be before sunrise today and after sunset today.

1 Like

Thank you both for your replies.

Sticking with your suggestion @rpwong, one of the items in the astro binding is the sun phase. Only issue is there are multiple phases to represent different stages of dusk and night - do you know if the But only if expressions are evaluated as OR or AND? If its OR, I can just add in each sun phase I want to include.

@rlkoshak thanks for the first snippet of DSL - if I were going down this route, how to write would have been my next question.

AND

Ah… can’t use the sun phase item then (unless I say it isn’t equal to all the pre-sunset states). I’ve gone with the DSL route - thank you @rlkoshak and @rpwong .

Rich is the expert here…I just like his design patterns. :wink:

I should have mentioned that I have multiple rules that reference my time of day item, which is why I prefer that approach. Also, I try to keep things as simple as possible so that my non-programmer brain can grasp them.

Pointing Stuart to the ToD Design Pattern was exactly correct. But while OH 3 is still new, I also like to actually answer the original question, even if it may or may not be the best overall approach. The more answers to stuff like “how do I use But only if…?” there are on the forum, hopefully the fewer questions we will need to answer about them later on. :wink:

@stuart475898, absolutely, if you have two or more rules that care about sunrise/sunset you should look at using the time of Day DP.

1 Like

I just use the but only if part of the rule section and say:

LocalSun_SunPhaseName != DAYLIGHT

That pretty much covers sunset to sunrise.

Screenshot from 2021-03-09 17-50-22

1 Like

Actually… that probably would do just as well. Not sure why I didn’t think of this??? Thanks @ubeaut

I use the sun phase, it is a alternative.
I guess this will depend on location.
Here (mid Norway) it will be after sunset, but there is no need for outdoor lightning mid summer.

I have light sensors as well so the lights only come on if the lux level is low.

I also use lux levels but I get them from the astro binding “diffuse radiation” value as I don’t have a light sensor yet. I use it in many rules including motion sensor lighting, christmas lighting (with 3 lighting levels defined for all on, only inside on and all off), exterior lighting auto-off triggers.

1 Like

I use the Phillips hue motion sensors as they have zigbee and have lux, motion and temperature sensors. I use zigbee2mqtt to talk to OH3.

Do you find it works well - that is, the lights generally come on when they need to? Could you give an example of where/how you use it? E.g. when radiation is below some value, toggle a virtual switch that OH uses to turn a light on when motion detected?

Sounds like an interesting way to solve the problem or light levels

Things
astro:sun:home @ "World" [ geolocation="##.####, ##.####, ###" ]

Items
Number:Intensity Diffuse_Radiation "Diffuse radiation [%.2f %unit%]" (Home, Sensors) { channel="astro:sun:home:radiation#diffuse" }

Rules

//------------------------------------------------------------------------------------------------
//--------------------------            Night light controll            --------------------------
//------------------------------------------------------------------------------------------------
rule "Night light controll"
when 
	Item Diffuse_Radiation changed or
	Item Someone_Home changed
then
	var DiffRad = Diffuse_Radiation.state as Number
	Diffuse_Radiation.persist

	if (DiffRad <= 40 && Someone_Home.state == ON) { 
		if (Cor_night_light.state != ON) Cor_night_light.sendCommand(ON) 
	} else { 
		if (Cor_night_light.state != OFF) Cor_night_light.sendCommand(OFF) 
	}
end


//------------------------------------------------------------------------------------------------
//--------------------------          Christmass tree controll          --------------------------
//------------------------------------------------------------------------------------------------
rule "Christmass tree controll"
when
	Item Diffuse_Radiation changed or
	Item Someone_Home changed or
	Time cron "0 0 8 1/1 * ? *" or
	Time cron "0 0 21 1/1 * ? *"
then
	var Number hours = now.getHourOfDay
	var DiffRad = Diffuse_Radiation.state as Number

	if (DiffRad <= 80 && Someone_Home.state == ON && hours >= 8 && hours < 21) {
		if (Sonoff_Powerstrip.state != ON) Sonoff_Powerstrip.sendCommand(ON)
	} else {
		if (Sonoff_Powerstrip.state != OFF) Sonoff_Powerstrip.sendCommand(OFF)
	}
end

Night light in the corridor turns on and stays on when it gets dark enough for that light to be of any help

Christmas Tree turns on if diffused light radiation is low enough for the tree lights to be visible but no earlier than 8 in the morning and turns off no later than 9 in the evening. In my case the number is rather high because the Christmas lights are bright and are still visible.

I also use a Someone_Home Item for presence detection and there is no reason for any of those lights to be ON while there’s nobody home.

Because the diffused radiation value is calculated based on geoposition, it increases and decreases without fluctuations so there is no need for any hysteresis. If I was using a real lux sensor, I would use if ((DiffRad + 5) <= 40) {...} else if ((DiffRad - 5) > 40) {...}.

I’m also interested in this. How accurate do you find the diffuse radiation over the course of the day and in varying weather conditions? For example, if there was a thunderstorm that suddenly darkened the sky and then cleared up, would the diffuse radiation keep up? It would be amazing if openHAB knew to turn the lights on when the sky suddenly darkened, then turn them off when it brightens up.

I’ve set up an item to monitor the changes over the course of a day, but I’m very curious about your experience with it.

@rpwong -

“if there was a thunderstorm that suddenly darkened the sky and then cleared up, would the diffuse radiation keep up? It would be amazing if openHAB knew to turn the lights on when the sky suddenly darkened, then turn them off when it brightens up.”

I believe that is only truly possible with an active sensor. Diffused Radiation is calculated based on the earths rotation by the Astro binding and not a measurement of current weather conditions and local light. I am also looking into options for doing exactly this - measure light levels and trigger rules based on the immediate conditions :slight_smile:

+1! :sunglasses:

For now though, using the Astro bindings Sun Phase channel and the Civil Dawn/Dusk state has been working just fine here!

1 Like

My active light sensors are great. It is dark and raining here in Australia today and the motion sensors are setting on the lights even though it is only 4pm.

1 Like

As d0t said, the astro binding calculates the light level only based on sun’s position and earth’s rotation. Cloud cover is not taken into account. I trialed my values based on how far from the windows is each light and how much scattered light gets there on an average day. Sometimes the lights go on when it’s too bright or go off when it’s too dark but in general it works OK. I do not have an active light sensor, so this is the only way I could figure out how to get as close to knowing the real lighting conditions as possible.

1 Like