First I’ll recommend Design Pattern: Time Of Day which will let you centralize this sort of logic in case you do this sort of thing for other lights or activities. I think it will let you get rid of the polling cron expression and only have to trigger your rule based off of events which simplifies things significantly.
I don’t know what you mean by “If I put the whole timing part of the rule in brackets”.
I’ll assume you are having problems with the if condition. Since your only special case is Sunday lets treat it separately.
First, a question which you can answer with a quick log statement. Is Sunday 7, or is it 6 or is it 0? Make sure you know which because it drastically changes your conditional.
Let’s assume it is 7 (it is, I just looked it up). If I write your expression a little simpler for Sunday it reads:
if(day == 7 && hour <=4 && hour >= 7)
So the above will only return true if it is Sunday and the hour is between 00 and 04 and the hour is between 07 and 24. Wait, the hour cannot both be less than 4 and greater than 7 at the same time! There is your first error. It should be:
if(day == 7 && (hour <=4 || hour >= 7))
A little better, maybe a lot better. Do you intend for the light to be on between midnight and 04:00, off from 4:00AM to 7:00AM, then on from 7:00AM to midnight on Sundays? That is what the above will do. Do you mean 7pm, i.e. 19:00?
if(day == 7 && (hour <=4 || hour >= 19))
That seems more reasonable.
Now let’s treat the other days. I see the some of the same problems and more.
The hour >=7 will match Sunday, so that is plain wrong to start. Normally you would just use > 7 in a case like this. However, there are no days of the week > 7 so this whole clause does nothing (once corrected).
Next, we are already testing for Sunday so we don’t need to test for the rest of the days so we can drop the <= 6 entirely.
So assuming you want the light to be on between midnight and 06:00 and between 23:00 and midnight on the rest of the days then your if concerning time and day of the week becomes:
if((day == 7 && (hour <=4 || hour >=19) || (hour >=7 || hour <=23))
Everything is evaluated from the inside to the outside (just like parens in math) so checking the hours on Sunday evaluates first, then the day == 7, then the hours for the rest of the week.
Finally, you only want to turn on the light if the light is below a certain luminance. As written in your original though, the light will only turn on at < 80 on Sunday (assuming that that part of the conditional was right) because the && gets evaluated before the ||. So you need to group all the time conditionals into its own set of parens.
if(((day == 7 && (hour <= 4 || hour >= 19) || (hour >= 7 || hour <= 23)) && Luminance_Garden_Terrace.state as Number < 80)
OK, well that is correct, but it sure is kinda hard to read. I would recommend breaking it up a bit along these lines (actually I would recommend moving this all into a Time of Day DP approach but for completeness):
var lightState = OFF
// Sunday from 00:00 to 04:00 or 19:00 to 00:00
if(day == 7 && (hour <= 4 || hour >= 19)) lightState = ON
// Not Sunday from 00:00 to 07:00 or 23:00 to 00:00
else if(hour >= 7 || hour <= 23) lightState = ON
// Too bright outside?
if(Luminance_Garden_Terrace.state as Number > 80) lightState = OFF
It really isn’t more lines than what you have but by breaking it up it is much easier to read and understand and you don’t have to mess with all of those parens.