Time schedule

Simple question but Im not sure on the best option here.

Ideally a time schedule with a simple GUI where you can set times or use a slider per day is what I expect on an automation system but after a quick google it seems this isn’t so simple on openhab? or am I missing something obvious here?

How do I go about setting my on/off times for different things on my system?

Thanks

You could take a look at using
https://docs.openhab.org/configuration/rules-dsl.html#time-based-triggers

It is not that difficult once you get a hang of it. A rule to fire every weekday at 14:00 could look as simple as

rule "Light ON"
when 
	//Every weekday at 14:00 hours
	Time cron "0 0 14 ? * MON-FRI *"
then
	// update item to switch on light here
end
3 Likes

Yeah I saw the whole cron job thing but that seems so backwards for what should be an automation system with a decent GUI.

I was considering just writing my own python program and then regularly sending out the current status of the different schedules. That way anything connected to MQTT will also be able to pick it up.

Which actually leads me to another question, is there a simple library for schedules? the ones ive seen all look quite OTT and not actually too dissimilar to cron

1 Like

Or set up a full blown configurable timer in openhab:

RULES FILE:


var Timer timer1 = null
var java.util.concurrent.locks.ReentrantLock lock1 = new java.util.concurrent.locks.ReentrantLock()

rule "Initialization"
 when 
   System started
 then
    // postUpdate(WekkerTijdUren,  	6)
    // postUpdate(WekkerTijdMinuten,	00)
    // postUpdate(WekkerMaandag,     	ON)
    // postUpdate(WekkerDinsdag,   	ON)
    // postUpdate(WekkerWoensdag,  	ON)
    // postUpdate(WekkerDonderdag, 	ON)
    //  postUpdate(WekkerVrijdag,   	ON)
    // postUpdate(WekkerZaterdag,  	OFF)
    // postUpdate(WekkerZondag,    	OFF)
 end

rule "Wektijd"
when
    Item WekkerTijdUren changed or 
    Item WekkerTijdMinuten changed
then

  lock1.lock()
  try {
    var String msg = ""


    var uren = WekkerTijdUren.state as DecimalType
    var minuten = WekkerTijdMinuten.state as DecimalType


    if (uren < 10) { msg = "0" } 
    msg = msg + WekkerTijdUren.state.format("%d") + ":"

    if (minuten < 10) { msg = msg + "0" }
    msg = msg + WekkerTijdMinuten.state.format("%d")
    postUpdate(WekkerTijdTekst,msg)


    var int wektijd1
    wektijd1 = (WekkerTijdUren.state as DecimalType).intValue * 60 + 
                (WekkerTijdMinuten.state as DecimalType).intValue
    wektijd1 = wektijd1.intValue


    var int nu1
    nu1 = now.getMinuteOfDay
    nu1 = nu1.intValue


    var int delta1
    delta1 = (wektijd1 - nu1)
    delta1 = delta1.intValue

    if (nu1 > wektijd1) { delta1 = delta1 + 1440 }

    if (timer1 != null) {
       timer1.cancel
       timer1 = null
    }


    timer1 = createTimer(now.plusMinutes(delta1)) [|

        var Number day = now.getDayOfWeek
        if (((day == 1) && (WekkerMaandag.state == ON))     ||
            ((day == 2) && (WekkerDinsdag.state == ON))   ||
            ((day == 3) && (WekkerWoensdag.state == ON))   ||
            ((day == 4) && (WekkerDonderdag.state == ON)) ||
            ((day == 5) && (WekkerVrijdag.state == ON))    ||
            ((day == 6) && (WekkerZaterdag.state == ON))    ||
            ((day == 7) && (WekkerZondag.state == ON))) {
 
			logInfo('Alarm Clock', 'Alarm Clock wake up time triggered')
			RuleWektijdTS.postUpdate( new DateTimeType() )
			sendCommand(SqueezeWakeUp, ON)
           }

           timer1.reschedule(now.plusHours(24))


        ]
  } finally  {

     lock1.unlock()
  }
end

ITEMS FILE:

Switch  WekkerMaandag	"Maandag"	<switch>  (gWekkerWeekdagen) 
Switch  WekkerDinsdag	"Dinsdag"   <switch>  (gWekkerWeekdagen) 
Switch  WekkerWoensdag	"Woensdag"  <switch>  (gWekkerWeekdagen) 
Switch  WekkerDonderdag	"Donderdag" <switch>  (gWekkerWeekdagen) 
Switch  WekkerVrijdag	"Vrijdag"   <switch>  (gWekkerWeekdagen) 
Switch  WekkerZaterdag	"Zaterdag"  <switch>  (gWekkerWeekdagen) 
Switch  WekkerZondag	"Zondag"    <switch>  (gWekkerWeekdagen) 

String WekkerTijdTekst "%s"

Number WekkerTijdUren 		"Uren 		[%d]" <clock> (gWekkerTijd)
Number WekkerTijdMinuten 	"Minuten 	[%d]" <clock> (gWekkerTijd)



SITEMAP FILE:

	Text label="Wekker [%s]" item=WekkerTijdTekst icon="time" {
            Frame label="Tijd" {
                Setpoint item=WekkerTijdUren minValue=0 maxValue=23 step=1
                Setpoint item=WekkerTijdMinuten minValue=0 maxValue=55 step=5
            }
            Frame label="Weekdagen" {
                Switch item=WekkerMaandag
                Switch item=WekkerDinsdag
                Switch item=WekkerWoensdag
                Switch item=WekkerDonderdag
                Switch item=WekkerVrijdag
                Switch item=WekkerZaterdag
                Switch item=WekkerZondag
            }

The final result:

2 Likes

That looks so much more complicated than anything else Ive seen lol.

Also makes me think doing that, I might as well carry on with my idea of making a python program to do it and distribute it on MQTT periodically.

set it up once to your likings, rince and repeat… :slight_smile:
It’s not complicated… not more complicated than having an external python script triggering stuff over MQTT…

So you have all that set up for starting a timer, or to post a ‘start’ signal and then post a ‘stop’ signal some time later? So for multiple schedules, you repeat this for as many as you need?

Exactly… using this code i:

  • Configure the start time
  • configure the start days (of the week in my case, but you could change this into e.g. a date)

At the end of the rules file i fire specific commands.
I have this script running multiple times for multiple things ( e.g. start music in the house every morning at 06:15). Pre-heat coffee machine at 06:30 etc

I believe its in German so Im trying to decipher it, you set you start time, then it runs for a preset period of time.

What if I want to send a start at 6.30, and a stop at 10.30. The problem here is the timer function, there is no timer in a schedule.

This bit of code though it pretty useful and definitely has a good purpose but its not the function of a schedule. I might give it a try though ,if I can get my head around the language :slightly_smiling_face:

It’s Dutch… ;-0

Wekker = Alarm Clock
Wektijd = Alarm Time
Maandag = Monday
Dinsdag = Tuesday
Woensdag = Wednesday
Donderdag = Thursday
Vrijdag = Friday
Zaterdag = Saturday
Zondag = Sunday

Uren = hours
Minuten = Minutes

Weekdagen = Weekdays
Tijd = Time

1 Like

and as a reply to you question… If i understand your use case correctly you want to start and stop a specific action at a specific time.

You could keep that as simple as using the rule as mentioned by MartinKo twice… once to start and once to stop.

Or use the alarm clock rule twice … to start and to stop whatever it is you would like to do.

@snoekieboe Thank you for sharing this simple and beatuful solution.
I tried to copy on my openhabian, but I got this error:
“org.eclipse.smarthome.model.script.engine.ScriptExecutionException: The name ‘RuleWektijdTS’ cannot be resolved to an item or type;”
I modified the line in (puted in front //):
//RuleWektijdTS.postUpdate( new DateTimeType() )
and now it’s working, but (because I’m not a progarammer) this is corrert, or better, what mean thi line?
Thank you

Not a problem… RuleWektijdTS is only used as an item to check when a my rules have fired for the last time… Commenting out this line does not impact anything else.

br

Roel

1 Like

Inspired by @snoekieboe I made my own timer like this:

ITEMS file:

// ************************************************** Timers ****************************************************

Group                   gTimer                                          "Timers"                <time> (Home)

Group                   gTimerMorning                                   "Morning Alarm"         <time> (gTimer)                 [ "Timer" ]

Switch                  TimerMorningEnabled                             "Enabled"               <switch> (gTimerMorning)
Switch                  TimerMorningWeekdayEnabled                      "Enabled"               <switch> (gTimerMorning)
String                  TimerMorningWeekdayText                         "[%s]"                  <time> (gTimerMorning)
Number                  TimerMorningWeekdayHour                         "Hour [%d]"             <time> (gTimerMorning)
Number                  TimerMorningWeekdayMinute                       "Minutes [%d]"          <time> (gTimerMorning)
Switch                  TimerMorningWeekendEnabled                      "Enabled"               <switch> (gTimerMorning)
String                  TimerMorningWeekendText                         "[%s]"                  <time> (gTimerMorning)
Number                  TimerMorningWeekendHour                         "Hour [%d]"             <time> (gTimerMorning)
Number                  TimerMorningWeekendMinute                       "Minutes [%d]"          <time> (gTimerMorning)

Switch                  TimerMorningCoffee                              "Coffee Machine"                <brew> (gTimerMorning)
Switch                  TimerMorningWakeUpLights                        "Bedroom lights"                <light> (gTimerMorning)
Switch                  TimerMorningShuttersBedroom                     "Bedroom shutters"              <rollershutter> (gTimerMorning)
Switch                  TimerMorningShuttersAll                         "All shutters"                  <rollershutter> (gTimerMorning)
Switch                  TimerMorningTV                                  "Turn ON TV"                    <television> (gTimerMorning)

SITEMAP

Group item=gTimerMorning {
    Frame label="Schedule" {
        Switch item=TimerMorningEnabled
        Text label="" icon=""

        Switch item=TimerMorningWeekdayEnabled label="Workind days"
        Text label="" icon=""
        Setpoint item=TimerMorningWeekdayHour minValue=0 maxValue=23 step=1
        Setpoint item=TimerMorningWeekdayMinute minValue=0 maxValue=59 step=1

        Switch item=TimerMorningWeekendEnabled label="Weekend days"
        Text label="" icon=""
        Setpoint item=TimerMorningWeekendHour minValue=0 maxValue=23 step=1
        Setpoint item=TimerMorningWeekendMinute minValue=0 maxValue=59 step=1
    }

    Frame label="Actions" {
        Default item=TimerMorningCoffee
        Default item=TimerMorningWakeUpLights
        Default item=TimerMorningShuttersBedroom
        Default item=TimerMorningShuttersAll
        Default item=TimerMorningTV
    }
}

RULES:
var Timer timerMorning = null
var Timer timerSwitchOffCoffeeStation = null
var java.util.concurrent.locks.ReentrantLock lockMorning = new java.util.concurrent.locks.ReentrantLock()
var java.util.concurrent.locks.ReentrantLock lockSwitchOffCoffeeStation = new java.util.concurrent.locks.ReentrantLock()

rule "TimersInitialization"
 when 
   System started
 then
    postUpdate(TimerMorningWeekdayHour,         9)
    postUpdate(TimerMorningWeekdayMinute,       0)
    postUpdate(TimerMorningWeekendHour,         10)
    postUpdate(TimerMorningWeekendMinute,       0)
    postUpdate(TimerMorningEnabled,             OFF)

    postUpdate(TimerSwitchOffCoffeeStationMinute,               0)
    postUpdate(TimerSwitchOffCoffeeStationHour,                 19)
    postUpdate(TimerSwitchOffCoffeeStationEnabled,              ON)

 end



rule "TimerMorning"
when
    Item TimerMorningWeekdayHour changed or 
    Item TimerMorningWeekdayMinute changed or 
    Item TimerMorningWeekendHour changed or 
    Item TimerMorningWeekendMinute changed or
    System started
then


val org.eclipse.xtext.xbase.lib.Functions$Function0<Integer> getNextExecutionInMinutes = [ |

    var String msg = ""
    var hourWD = TimerMorningWeekdayHour.state as DecimalType
    var minuteWD = TimerMorningWeekdayMinute.state as DecimalType

    if (hourWD < 10) { msg = "0" } 
    msg = msg + TimerMorningWeekdayHour.state.format("%d") + ":"

    if (minuteWD < 10) { msg = msg + "0" }
    msg = msg + TimerMorningWeekdayMinute.state.format("%d")
    postUpdate(TimerMorningWeekdayText,msg)

    msg = ""
    var hourWE = TimerMorningWeekendHour.state as DecimalType
    var minuteWE = TimerMorningWeekendMinute.state as DecimalType

    if (hourWE < 10) { msg = "0" } 
    msg = msg + TimerMorningWeekendHour.state.format("%d") + ":"

    if (minuteWE < 10) { msg = msg + "0" }
    msg = msg + TimerMorningWeekendMinute.state.format("%d")
    postUpdate(TimerMorningWeekendText,msg)

    var int minuteTimeWD
    var int minuteTimeWE

    minuteTimeWD = (TimerMorningWeekdayHour.state as DecimalType).intValue * 60 + 
                (TimerMorningWeekdayMinute.state as DecimalType).intValue

    minuteTimeWE = (TimerMorningWeekendHour.state as DecimalType).intValue * 60 + 
                (TimerMorningWeekendMinute.state as DecimalType).intValue

    var int nowMinute
    nowMinute = now.getMinuteOfDay

    var int delta1
    delta1 = (minuteTimeWD - nowMinute)
    delta1 = delta1

    var int delta2
    delta2 = (minuteTimeWE - nowMinute)
    delta2 = delta2


    if (nowMinute >= minuteTimeWD) { delta1 = delta1 + 1440 }
    if (nowMinute >= minuteTimeWE) { delta2 = delta2 + 1440 }

    var int deltaFinal = 0

    if (delta1 < delta2) { 
        deltaFinal = delta1
    } else { 
        deltaFinal = delta2
    }


    return deltaFinal
]

  lockMorning.lock()

  try {

    if (timerMorning !== null) {
      logInfo('TimerMorning', "Cancelling old timer");
      timerMorning.cancel
      timerMorning = null
    }

    var int deltaFinal = 0
        deltaFinal = getNextExecutionInMinutes.apply()


    logInfo('TimerMorning', "Setting up timer delta to " + deltaFinal.toString() + "minutes from now");

    timerMorning = createTimer(now.plusMinutes(deltaFinal), [|

        var Number day = now.getDayOfWeek

        if (
            TimerMorningEnabled.state == ON &&
            (
              ((day < 6) && (TimerMorningWeekdayEnabled.state == ON)) ||
              ((day >= 6) && (TimerMorningWeekendEnabled.state == ON))
            )
        ) {
 
          logInfo('TimerMorning', 'Alarm Clock wake up time triggered')

          // perform actions          
          if(TimerMorningCoffee.state == ON) { 
            logInfo('TimerMorning', 'Turning on coffee station')
            CoffeeStation_Plug.sendCommand(ON) 
          }

          if(TimerMorningWakeUpLights.state == ON) { 
            logInfo('TimerMorning', 'Turning on lights')
            AT_Bedroom_Light.sendCommand(ON) 
            AT_Bedroom_LightStrip_Color.sendCommand(ON) 
          }

          if(TimerMorningShuttersAll.state == ON) { 
            logInfo('TimerMorning', 'Rolling up all shutters')
            gShutter.members.forEach[ i | i.sendCommand(0) ]
          } else {
            if(TimerMorningShuttersBedroom.state == ON) {
              logInfo('TimerMorning', 'Rolling up bedroom shutters')
              AT_Bedroom_Shutter1.sendCommand('UP')
              AT_Bedroom_Shutter2.sendCommand('UP')
            }
          }
        }

        if(TimerMorningTV.state == ON) {
          LGWallpaperTV_Power.sendCommand(ON)
          LGWallpaperTV_Mute.sendCommand(ON)
          Thread::sleep(5000)
          LGWallpaperTV_Application.sendCommand("com.webos.app.livetv")
          LGWallpaperTV_Volume.sendCommand(10)
          Thread::sleep(2000)
          LGWallpaperTV_Channel.sendCommand("3_7_5_0_112_1204_1")
        }

        var deltaNext = getNextExecutionInMinutes.apply();

        if(deltaNext == 0)
                deltaNext = 1440

        logInfo('TimerMorning', "Rescheduling timer to " + deltaNext.toString() + "minutes from now");

        timerMorning.reschedule(now.plusMinutes(deltaNext))

    ])
  } finally  {
     lockMorning.unlock()
  }
end

RESULT

4 Likes