Switch an item on time (entered in BasicUI)

Hi,

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.

Can anyone point me in the right direction?

Take a look at https://github.com/openhab/openhab1-addons/wiki/AlarmClock

Thanks! That is exactly what I needed!

The AlarmClock example was really helpfull.

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

The sitemap:

			Text label="Delayed start [%s]" item=Virtual_Sauna_PlannedStart icon="clock" visibility=[KNX_ZO_Sauna_OperatingMessage_4_4_0==CLOSED] {
				Frame label="Time" {
					Setpoint item=Virtual_Sauna_Startuur minValue=0 maxValue=23 step=1						label="Start uur"			visibility=[Virtual_Sauna_PlannedStart_AanUit==OFF]
					Setpoint item=Virtual_Sauna_Startminuut minValue=0 maxValue=55 step=5					label="Start minuut"		visibility=[Virtual_Sauna_PlannedStart_AanUit==OFF]
					Text item=Virtual_Sauna_PlannedStart													label="Planned start: "	visibility=[Virtual_Sauna_PlannedStart_AanUit==ON]
					Switch item=Virtual_Sauna_PlannedStart_AanUit											label="Enable delayed start"
				}
			}
2 Likes