I want following rule to run only on certain days, not the whole week.
rule "Outside ON at sunrise"
when
Channel "astro:sun:local:set#event" triggered START
then
logInfo("ELEC", "buitenverlichting aan")
sendCommand( VERL_Parking, ON)
end
I was thinking of creating somewhere (sitemap based) a frame where we can select “working days” and “hours”. And link this to a dummy switch (fe TIME_WORKWEEK, TIME_WORKSTART & TIME_WORKEND). Not sure how to link it with the dates? A kind of cron after every midnight to update this?
A good idea to go this way?
I was thinking of getting an end result as below.
The end time is another question mark. but let’s start easy;
rule "Outside ON at sunrise"
when
Channel astro:sun:local:set#event triggered START
then
if (TIME_WORKWEEK == ON) {
logInfo("ELEC", "buitenverlichting aan")
sendCommand( VERL_Parking, ON)
}
end
rule "Outside OFF at end of workday"
when
TIME_WORKEND is passed // (???)
then
if (TIME_WORKWEEK == ON) {
logInfo("ELEC", "buitenverlichting uit")
sendCommand( VERL_Parking, OFF)
}
end
ps I’m a bit afraid that I’ll need to reinsert this every time that the server (service) restarts. This is something I still need to figure out, how to ‘remember certain status’.
The question is: how do you get the information if the actual day is a workday and when the workday ends?
Are there any rules (not openHAB rules…) to calculate this information? Or is this information completely irregular?
One option would be to use a calendar and use the calendar binding to read the information daily.
I started out with the gcal. Works great. But couldn’t get the sunset time working with that.
As I tried to describe in my orignal post, I was thinking to create some ‘switches’ that defines the week, and start/end times. This way, we can set this by the sitemap:
work_day_monday (ON or OFF)
work_day_tuesday (ON or OFF)
work_day_wednesday (ON or OFF)
work_day_thursday (ON or OFF)
work_day_friday (ON or OFF)
work_day_saturdday (ON or OFF)
work_day_sunday (ON or OFF)
work_time_start (1>24 : 1>60)
work_time_stop (1>24 : 1>60)
And then, with a cron rule update every day the status.
when
Time cron "0 5 0 ? * MON *"
then
if work_day_monday.state == ON {
sendCommand( TIME_WORKWEEK, ON)
else {
sendCommand( TIME_WORKWEEK, OFF)
}
when
Time cron "0 5 0 ? * TUE *"
then
if work_day_tuesday.state == ON {
sendCommand( TIME_WORKWEEK, ON)
else {
sendCommand( TIME_WORKWEEK, OFF)
}
...
For the time, I don’t have any clue yet. For this, i must investigate some time in the date/time formats.
Not sure what you think about this? Good, bad, one way to do it…
Just to give you some idea’s, this is what I use as a rule for time of day.
rule "Calculate time of day state"
when
Time cron "0 * * ? * *" // runs every minuet
then
val String curr_time = now.toString("HH:mm")
val String night_start = "00:00"
var String morning_start = "06:00"
val String day_start = (Sun_Dawn_Start.state as DateTimeType).format("%1$tH:%1$tM")
val String evening_start = (Sun_Dusk_End.state as DateTimeType).format("%1$tH:%1$tM")
val String midnight_time = "24:00"
var new_val = "UNKNOWN"
if (day_start < morning_start) {
morning_start = day_start
}
switch true {
case night_start <= curr_time && curr_time < morning_start: new_val = "NIGHT"
case morning_start <= curr_time && curr_time < day_start: new_val = "MORNING"
case day_start <= curr_time && curr_time < evening_start: new_val = "DAY"
case evening_start <= curr_time && curr_time < midnight_time: new_val = "EVENING"
}
if (Time_Of_Day.state.toString != new_val) {
logInfo("Time_Of_Day", "Current time of day is now " + new_val)
Time_Of_Day.sendCommand(new_val)
}
end
I don’t think its possible to change a rules value via input from the sitemap. You will need several rules and use a proxy switch with an if statement that determines if the rule get fired.
Another idea for time of day in a rule is use something like this
This a litte old, but I think perhaps looking at the AlarmClock example may help? It says OH1 but it just rules and items, so should work with OH2 as well.
Well, you can do it this way, but as you can see, will have to setup (minimal) 7 Items for weekday (if Sunday is possible part of workweek) plus two items for start and stop hour plus two items for start and stop minute. Simply use Number Items with minimum, maximum and step (I’m pretty sure you would not need precise Minute but maybe 5 minute steps or maybe quarters may suffice.) If you want flexible data, you will have to add 5 Items per weekday (ON/OFF, Start/End-hour/minute)
In question of the rule, you only would need one rule if you set the names of the Items carefully, e.g.
Group wwDay
Switch wwDay1 "Monday" (wwDay)
Switch wwDay2 "Tuesday" (wwDay)
Switch wwDay3 "Wednesday" (wwDay)
Switch wwDay4 "Thursday" (wwDay)
Switch wwDay5 "Friday" (wwDay)
Switch wwDay6 "Saturday" (wwDay)
Switch wwDay7 "Sunday" (wwDay)
Group wwStartHour
Number wwStartHour1 "Start hour Monday" (wwStartHour)
...
Group wwStartMinute
Number wwStartMinute1 "Start minute Monday" (wwStartMinute)
...
Group wwEndHour
Number wwendHour1 "End hour Monday" (wwStopHour)
...
Group wwEndMinute
Number wwEndMinute1 "End minute Monday" (wwStopMinute)
...
Switch Work "Work"
rule "set workstate"
when
Time cron "0 0/5 * * * ?" // every day, every 5 minutes
then
val acDay = now.getDayOfWeek.toString
val day = wwDay.members.filter[d|d.name == "wwDay"+acDay].head.state
val sH = wwStartHour.members.filter[d|d.name == "wwStartHour"+acDay].head.state
val sM = wwStartMinute.members.filter[d|d.name == "wwStartMinute"+acDay].head.state
val eH = wwEndHour.members.filter[d|d.name == "wwEndHour"+acDay].head.state
val eM = wwEndMinute.members.filter[d|d.name == "wwEndMinute"+acDay].head.state
if(day == ON) {
if(now.getMinuteOfDay => sM + sH *60 && now.getMinuteOfDay < eM + eH * 60)
Work.postUpdate(ON)
else
Work.postUpdate(OFF)
}
end
Probably the easiest is to put seven Switching on your sitemap, one for each day. When ON that sets that day as a work week.
Then apply the Time of Day DP (It’s not just for times of day) along the following lines (note, I recommend using a String Item instead of a Switch so you can add in other special day types like holidays or travel or the like):
name the workday Items using “WorkDay0” for Sunday and “WorkDay1” for Monday and so on
put the WorkDay Items into the WorkDays Group
rule "Calculate work day"
when
Member of WorkDays changed or
Time cron "0 5 * ? * *" or
System started
then
val workDayFlag = WorkDays.members.findFirst[ d | d.name = "WorkDay"+now.getDayOfWeek ]
val newState = if(workDayFlag.state == ON) "WORK" else "OFF"
if(WorkSate.state.toString != newState) WorkState.sendCommand(newState)
end
You can easily add in time start and time stop to the above Rule.
rule "Calculate work day"
when
Member of wwDay changed or
Time cron "0 5 * ? * *" or
System started
then
val wwDayFlag = wwDay.members.findFirst[ d | d.name = "wwDay"+now.getDayOfWeek ]
val newState = if(wwDayFlag.state == ON) "WORK" else "OFF"
if(WorkSate.state.toString != newState) WorkState.sendCommand(newState)
end
Error
But when I change a Day, I’m getting following error in the log files:
2018-10-16 12:39:36.310 [ome.event.ItemCommandEvent] - Item ‘wwDay1’ received command OFF
2018-10-16 12:39:36.312 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Calculate work day’: Couldn’t invoke ‘assignValueTo’ for feature JvmVoid: (eProxyURI: werkweek.rules#|::0.2.0.2.0.0.2.7.0.1.0.0::0::/2)
2018-10-16 12:39:36.313 [vent.ItemStateChangedEvent] - wwDay1 changed from ON to OFF
rule "Calculate work day"
when
Member of wwDay changed or
Time cron "0 5 * ? * *" or
System started
then
val wwDayFlag = wwDay.members.findFirst[ d | d.name = "wwDay"+now.getDayOfWeek.toString ]
val newState = if(wwDayFlag.state == ON) "WORK" else "OFF"
if(WorkState.state.toString != newState) WorkState.sendCommand(newState)
end
Log:
2018-10-16 14:29:15.228 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Calculate work day’: Couldn’t invoke ‘assignValueTo’ for feature JvmVoid: (eProxyURI: werkweek.rules#|::0.2.0.2.0.0.2.7.0.1.0.0::0::/2)
if(WorkState.state.toString != newState) {
WorkState.sendCommand(newState)
}
You may need the brackets like above.
rule "Calculate work day"
when
Member of wwDay changed or
Time cron "0 5 * ? * *" or
System started
then
val wwDayFlag = wwDay.members.findFirst[ d | d.name = "wwDay"+now.getDayOfWeek.toString ]
val newState = if(wwDayFlag.state == ON) "WORK" else "OFF"
if(WorkState.state.toString != newState) {
WorkState.sendCommand(newState)
}
end