I’m looking for a way to allow a user (via BasicUI/Android app) to enter a start time when a specific item should start.
BasicUI doesn’t really have a date/time picker, so I was considering the Selection element type for this. One element type would allow the selection of hours (24 values), and the other minutes, with a 5 minute interval (5,10,15,… => 12 values).
It’s not ideal, but I don’t know a better way.
Now the hard part. I know how to switch an item via a rule using a time cron job. But that doesn’t seem to allow variables.
I’ve made some alterations. I thought it would maybe interesting for other people as well. It is based on “Alarm clock 2”. I use it to turn on the sauna at a preset time. Key changes are:
I included a (negative) offset, because the sauna needs to heat up during 30 minutes;
The delayed start is triggered with an on/off switch;
No rescheduling is done;
Slight changes to the sitemap;
The rule:
// ***************************
// Global variables
// ***************************
var Timer sauna_schedule_timer
var java.util.concurrent.locks.ReentrantLock sauna_lock = new java.util.concurrent.locks.ReentrantLock()
// ***************************
// Turn on sauna at a given time
// ***************************
rule "Turn on sauna at a given time - part 1"
when
Item Virtual_Sauna_PlannedStart_AanUit changed from OFF to ON
then
// If the UI to change the Alarm time is clicked several times the code below
// is subject to race conditions. Therefore we make sure that all events
// are processed one after the other.
sauna_lock.lock()
try {
var String msg = ""
// Copy the Alarm-Time from the UI to local variables
var hour = Virtual_Sauna_Startuur.state as DecimalType
var minute = Virtual_Sauna_Startminuut.state as DecimalType
// Combine the hour and minutes to one string to be displayed in the
// user interface
if (hour < 10) { msg = "0" }
msg = msg + Virtual_Sauna_Startuur.state.format("%d") + ":"
if (minute < 10) { msg = msg + "0" }
msg = msg + Virtual_Sauna_Startminuut.state.format("%d")
postUpdate(Virtual_Sauna_PlannedStart,msg)
// calculate the alarm time [min]
var int sauna_start
sauna_start = (Virtual_Sauna_Startuur.state as DecimalType).intValue * 60 +
(Virtual_Sauna_Startminuut.state as DecimalType).intValue
sauna_start = sauna_start.intValue
// calculate current time [min]
var int current_time
current_time = now.getMinuteOfDay
current_time = current_time.intValue
// calculate the difference between the requested alarm time and
// current time (again in minutes)
var int delta_time
delta_time = (sauna_start - current_time)
delta_time = delta_time.intValue
// add one day (1440 minutes) if alarm time for today already passed
if (current_time > sauna_start) { delta_time = delta_time + 1440 }
// The sauna takes 30 minutes to heat up. So we need to start a bit sooner.
delta_time = delta_time - 30
// The sauna takes 30 minutes to heat up. So if the delta time is too short, we don't do anything.
if (delta_time < 0) {
postUpdate(Virtual_Sauna_PlannedStart_AanUit, OFF)
logInfo ("Sauna", "Sauna Timer - Timer was disabled, because the delta was too small. The delta was: " + delta_time)
}
// check if there is already an alarm timer; cancel it if present
if (sauna_schedule_timer !== null) {
sauna_schedule_timer.cancel
sauna_schedule_timer = null
}
// create a new timer using the calculated delta [min]
if (delta_time > 0) {
logInfo ("Sauna", "Sauna Timer - The timer is activated. The sauna will heat up in " + delta_time + " minutes" )
sauna_schedule_timer = createTimer(now.plusMinutes(delta_time)) [|
sendCommand(KNX_ZO_Sauna_SaunaOven_4_4_3, ON)
logInfo ("Sauna", "Sauna Timer - The sauna starts to heat up")
logInfo ("Sauna", "Sauna Timer - The set time was " + Virtual_Sauna_PlannedStart.state.toString)
logInfo ("Sauna", "Sauna Timer - The time was set at " + Virtual_Sauna_PlannedStart_AanUit.lastUpdate.toDateTime.toString("yyyy-MM-dd HH:mm:ss"))
// The planned start will be switched off.
postUpdate(Virtual_Sauna_PlannedStart_AanUit, OFF)
]
}
} finally {
// release the lock - we are ready to process the next event
sauna_lock.unlock()
}
end
rule "Turn on sauna at a given time - part 2"
when
Item Virtual_Sauna_PlannedStart_AanUit changed from ON to OFF
then
postUpdate(Virtual_Sauna_PlannedStart, "disabled")
Thread::sleep(1000)
if(sauna_schedule_timer!==null) {
sauna_schedule_timer.cancel
sauna_schedule_timer = null
}
end