[SOLVED] Create a 'flexible' workweek

When I insert this, I’m having an error:

log/openhab.log:2018-10-16 18:44:00.002 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule ‘set workstate’: cannot invoke method public abstract org.eclipse.smarthome.core.types.State org.eclipse.smarthome.core.items.Item.getState() on null

I tried to play a bit wiht this formule, but seems I’m getting an error with the ‘*’?

if(now.getMinuteOfDay => "wwStartMinute" + "wwStartHour" * 60 && now.getMinuteOfDay < "wwEndMinute" + "wwEndHour" * 60)

Log:

2018-10-16 19:10:00.002 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule ‘set workstate’: Unknown variable or command ‘*’; line 22, column 52, length 16

Well, “wwStartMinute” is a String. How do you multiply a String?

Let’s do some logigng:

rule "set workstate"
when
    Time cron "0 0/5 * * * ?" // every day, every 5 minutes
then
    val acDay = now.getDayOfWeek.toString
    val day = wwDay.members.findFirst[d|d.name == "wwDay"+acDay].state as Number
    val sH = wwStartHour.members.findFirst[d|d.name == "wwStartHour"+acDay].state as Number
    val sM = wwStartMinute.members.findFirst[d|d.name == "wwStartMinute"+acDay].state as Number
    val eH = wwEndHour.members.findFirst[d|d.name == "wwEndHour"+acDay].state as Number
    val eM = wwEndMinute.members.findFirst[d|d.name == "wwEndMinute"+acDay].state as Number
    logInfo("work","day {} sH {} sM {} eH {} eM {}",day,sH,sM,eH,eM)
    if(day == ON) {
        if(now.getMinuteOfDay >= sM + sH *60 && now.getMinuteOfDay < eM + eH * 60) 
            Work.postUpdate(ON)
        else
            Work.postUpdate(OFF)
    }
end

Please be aware that I changed the method to .findFirst[].state

EDIT: changed typo and added type casting

Isn’t “wwStartMinute” a Number? :blush:

I simplified the setup a bit (to understand it better).
As I get it now, he times are nicely been picked up as numbers, but he can’t multiply it?

items:

Number wwStartHour                      "Start uur [%d]"
Number wwStartMinute                    "Start minuut [%d]"
Number wwEndHour                        "Eind uur [%d]"
Number wwEndMinute                      "Eind minuut [%d]"

Rule:

rule "set workstate"
when
    Time cron "0 0/5 * * * ?" // every day, every 5 minutes
then
        val sH = wwStartHour.state
        val sM = wwStartMinute.state
        val eH = wwEndHour.state
        val eM = wwEndMinute.state
        logInfo("work","sH {} sM {} eH {} eM {}",sH,sM,eH,eM)
        if(WorkWeek.state.toString == "WORK") {
             if (now.getMinuteOfDay => sM + sH * 60 && now.getMinuteOfDay < eM + eH * 60)
                    Work.postUpdate(ON)
                else
                    Work.postUpdate(OFF)
                }
end

Log:

[INFO ] [.eclipse.smarthome.model.script.work] - sH 5 sM 15 eH 19 eM 30
[ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule ‘set workstate’: Unknown variable or command ‘*’; line 23, column 41, length 7

        val sH = wwStartHour.state as Number
        val sM = wwStartMinute.state as Number
        val eH = wwEndHour.state as Number
        val eM = wwEndMinute.state as Number

Tried that one also. But had suddenly ‘worse’ errors. So came back from it. :wink:
Specially because I was under the impression that the numbers came back properly (seen the log output (info)).

018-10-17 09:39:00.002 [INFO ] [.eclipse.smarthome.model.script.work] - sH 5 sM 15 eH 19 eM 30
2018-10-17 09:39:00.003 [ERROR] [ntime.internal.engine.ExecuteRuleJob] - Error during the execution of rule ‘set workstate’: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.ObjectExtensions.operator_doubleArrow(T,org.eclipse.xtext.xbase.lib.Procedures$Procedure1) on instance: null

>= not =>

1 Like

Did the trick. Pfff, just this small detail… :crazy_face:

To summarize, the whole idea works now with following things. I need to overthink the extra start times. It can be useful for different hours on different days. Of different timings per day (morning, afternoon…).

But for now:

  • I can input days through the sitemap
  • I can input start and end time through the sitemap
  • I can use WorkWeek (ON/OFF) and WorkTime (ON/OFF) in rules

workweek.items

//Werktijden
String WerkWeek         "Werkweek"
Group wwDay
Switch wwDay1           "Maandag"                    <calendar>        (wwDay)
Switch wwDay2           "Dinsdag"                    <calendar>        (wwDay)
Switch wwDay3           "Woensdag"                   <calendar>        (wwDay)
Switch wwDay4           "Donderdag"                  <calendar>        (wwDay)
Switch wwDay5           "Vrijdag"                    <calendar>        (wwDay)
Switch wwDay6           "Zaterdag"                   <calendar>        (wwDay)
Switch wwDay7           "Zondag"                     <calendar>        (wwDay)
Switch wwDayFlag        "Status [%d]"                <calendar>
String WorkState        "Status [%s]"                <calendar>
String WorkWeek         "Status [%s]"                <calendar>
Number wwStartHour      "Start uur [%d]"             <time>
Number wwStartMinute    "Start minuut [%d]"          <time>
Number wwEndHour        "Eind uur [%d]"              <time>
Number wwEndMinute      "Eind minuut [%d]"           <time>
Switch WorkTime         "Werktijden status [%s]"     <time>

sitemap (workweek part)

Group item=werkweek {
	Frame label="Werkdagen"  {         
		Switch item=wwDay1                   
        Switch item=wwDay2                  
		Switch item=wwDay3                  
		Switch item=wwDay4                   
		Switch item=wwDay5                   
		Switch item=wwDay6                  
		Switch item=wwDay7                
		}
	Frame label="Werktijden"  {       
		Setpoint item=wwStartHour minValue=0 maxValue=23 step=1
		Setpoint item=wwStartMinute minValue=0 maxValue=55 step=5
		Setpoint item=wwEndHour minValue=0 maxValue=23 step=1
		Setpoint item=wwEndMinute minValue=0 maxValue=55 step=5
		}                      
	Frame label="Status" {                         
		Text item=WorkWeek                 
		Text item=WorkTime                 
		}
	}                    

workweek.rules

rule "Calculate workweek"
when
	Member of wwDay changed or                                         
    Time cron "0 5 0 ? * *" 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(WorkWeek.state.toString != newState) WorkWeek.sendCommand(newState)
end

rule "set workstate"
when                                                             
    Time cron "0 0/5 * * * ?" // every day, every 5 minutes
then
	val sH = wwStartHour.state as Number                       
    val sM = wwStartMinute.state as Number
    val eH = wwEndHour.state as Number
	val eM = wwEndMinute.state as Number                             
	if(WorkWeek.state.toString == "WORK") {
		if (now.getMinuteOfDay >= sM + sH * 60 && now.getMinuteOfDay < eM + eH * 60)
			WorkTime.postUpdate(ON)
		else
			WorkTime.postUpdate(OFF)
		}
end

Thanks to everybody for their patience and help!!!

1 Like

Please be aware that this Time cron

Time cron "0 5 * ? * *"

is: *:05:00 (i.e. every hour five minutes after the hour)

openHAB is using quartz cron, which - other than GNU/Linux cron - includes seconds.

1 Like

Ah, indeed. Isn’t necessary to do this every hour.
It should be enough to do this once a day, fe after midnight.
So this one should be better:

    Time cron "0 5 0 ? * *" or

Nice pickup! Things I love about you guys. You always double check our things. Even when we say that it’s correct. I corrected it in my previous post.

I keep this in the toolbar menu, just for cron https://www.freeformatter.com/cron-expression-generator-quartz.html.:wink:

1 Like