Problem with rules and timer, Task: turn off relay after device finished work (< x Watt) and cooled down (after 5 minutes)

I have a 3D Printer running with a TP-Link Switch (HS110) to turn off the printer after the printer finished his jop. I tried a rule and it works but I have two mistakes:

how do i get rid of this two errors:

  • Validation issues found in configuration model ‘drucker.rules’, using it anyway:
  • An error occurred during the script execution: Couldn’t invoke ‘assignValueTo’ for feature JvmVoid

Is there a better way to acomplish this Task?

  • I don’t like the fact that i had to define a thing for this rule, to prevent it executed again and again
  • I don’t like that i had to initialize this thing so that it is not undefined

Log:

2018-11-04 16:38:26.168 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'drucker.rules', using it anyway:
2018-11-04 16:38:26.178 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'drucker.rules'
2018-11-04 16:38:44.159 [vent.ItemStateChangedEvent] - Drucker_Switch changed from OFF to ON
2018-11-04 16:39:14.304 [vent.ItemStateChangedEvent] - Drucker_Power changed from 0.0 to 5.689
2018-11-04 16:39:44.471 [vent.ItemStateChangedEvent] - Drucker_Power changed from 5.689 to 0.0
2018-11-04 16:39:44.966 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'drucker': An error occurred during the script execution: Couldn't invoke 'assignValueTo' for feature JvmVoid:  (eProxyURI: drucker.rules#|::0.2.0.2.0.4.1.0.0.1.0.2::0::/1)
2018-11-04 16:39:49.964 [ome.event.ItemCommandEvent] - Item 'Drucker_Switch' received command OFF
2018-11-04 16:39:49.984 [vent.ItemStateChangedEvent] - Drucker_Switch changed from ON to OFF

device Rule:

import org.openhab.model.script.actions.Timer

rule "drucker"

when

Item Drucker_Power received update 

then

var float power = (Drucker_Power.state as Number).floatValue
var prntr = (printerStart.state as Number).intValue
var isOn  = 0

// Power over 150 Watts (4 Watts for testing with LED-Lamp (5 Watt)
if (power > 4.0 && prntr == 0 )
{
	sendPushoverMessage(pushoverBuilder("Drucker start"))
	//entry for while-loop
	isOn = 1
	//prevents this if-statement to be executed again
	printerStart.sendCommand(1)
}

//intention was the rule should not be executed again until rule finished, does not work that way
while (isOn == 1)
{
	//Device finishes work, Power drops to 0.5 Watts, but does not turn off alone
	if ((Drucker_Power.state as Number).floatValue < 1)
	{
		sendPushoverMessage(pushoverBuilder("Drucker fertig"))
		
		//Device later needs to cool down 5 Minutes before turn off (5 seconds for Test)
		Timer myTimer = createTimer(now.plusSeconds(5), [|
			Drucker_Switch.sendCommand(OFF)
			//rest for first if-statement
			printerStart.sendCommand(0)
			//exit for while-loop
			isOn = 0
		])
	}
}
end

startup Rule:

rule "System Start"
when
    System started
then
    printerStart.sendCommand(0)
end

items:

Number printerStart "Drucker Start"

Try adding var Timer myTimer with your other var above and use only myTimer in the rule.

It’s recommended to use uppercase for items

Number PrinterStart

Try that:

var Timer myTimer = null
var isOn = 0

rule "drucker"
when
    Item Drucker_Power received update 
then
    var power = Drucker_Power.state as Number
    var prntr = printerStart.state as Number
    
// Power over 150 Watts (4 Watts for testing with LED-Lamp (5 Watt)
 if (power > 4 && prntr == 0 && isOn == 0) {
	sendPushoverMessage(pushoverBuilder("Drucker start"))
	//entry for while-loop
	isOn = 1 //sets the printer on flag
	//prevents this if-statement to be executed again
	printerStart.sendCommand(1)
    return; //exit the rule
}

//intention was the rule should not be executed again until rule finished, does not work that way
if (isOn == 1) {
	//Device finishes work, Power drops to 0.5 Watts, but does not turn off alone
	if (power < 1) {
		sendPushoverMessage(pushoverBuilder("Drucker fertig"))
		
		//Device later needs to cool down 5 Minutes before turn off (5 seconds for Test)
        if (myTimer === null) {
		    myTimer = createTimer(now.plusSeconds(5), [|
			    Drucker_Switch.sendCommand(OFF)
			    //rest for first if-statement
			    printerStart.sendCommand(0)
			    //exit for while-loop
			    isOn = 0 // resets the printer on flag
                myTimer = null
		    ])
        }
	}
}
end
1 Like

H102 and Vincent I think I have it. But to summarize:

Remove the import statement. You don’t need it and in OH 2 you should not include anything from org.openhab. And even if you did still need this import, that isn’t where Timer is defined anymore.

As H102 points out, you are missing the val.

See Vincent’s version because that while loop is a really bad idea.

I don’t really understand what you are saying here. Are you saying you don’t like that you have to create a Rule? Well what you are looking for is a behavior and behaviors are defined in Rules.