Create rule with input from a sensor, then add or subtract from that value?

Ok so yesterday I was working on some code to control a heater, I did get it to work almost the way I’d like it to. But I’d like it to offset the turn on point to one or two degrees below the set point, and turn off one or two degrees above the set point.

this is the rule I currently have:

rule "Maintain Heat"
when
	Item temperature1 received update
	or Item TSsetpoint received update
	or Item TstatEnable received update
then
	if (TstatEnable.state == ON){
		if (temperature1.state <= TSsetpoint.state){
			if (Heat.state == OFF){
			sendCommand(Heat,ON)
			}
		}
		else if (temperature1.state >= TSsetpoint.state){
			sendCommand(Heat,OFF)
			}
	}
end

What I’d like to do is like this, but it doesn’t seem to work (I commented the two lines I’m talking about)

rule "Maintain Heat"
when
	Item temperature1 received update
	or Item TSsetpoint received update
	or Item TstatEnable received update
then
	if (TstatEnable.state == ON){
		if (temperature1.state <= TSsetpoint.state-1){  // Here's the problem "ADDED -1 HERE"
			if (Heat.state == OFF){
			sendCommand(Heat,ON)
			}
		}
		else if (temperature1.state >= TSsetpoint.state+1){ // Here's the problem "ADDED +1 HERE"
			sendCommand(Heat,OFF)
			}
	}
end

Anyone know how to do this?

It is always most helpful to post the errors you see in the logs.

Without the actual error I would guess you need to cast the states to DecimalType.

if((temperature1.state as DecimalType) <= (TSsetpoint.state as DecimalPoint) - 1)

sorry the error I was getting getting:
Error during the execution of rule ‘Maintain Heat’: The name ’ - ’ cannot be resolved to an item or type.

I made the changes you suggested but now i get this error:
2016-12-15 16:04:01.502 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Maintain Heat’: Cannot cast org.openhab.core.library.types.DecimalType to void

Are you sure that you have an Item named Heat?

Are you using Desginer?

What happens when you use the sendCommand method instead of the action, which you should do anyway.

Heat.sendCommand(ON)

Are you certain temperature1 and TSsetpoint have a state and are not Undefined?

yes I am sure the item is called Heat, ans yes I verified that TSsetpoint does indeed have a state, (currently 74), I just tried changing sendCommand(Heat,ON) to Heat.sendCommand(ON) I’m still getting this error:

Error during the execution of rule ‘Maintain Heat’: Cannot cast org.openhab.core.library.types.DecimalType to void

yes i am using designer 1.8.0

oh and yes temperature1 does have a value, it updates every 2 minutes

And temperature1? Does it have a state?

What happens when you break it down?

val temp1 = temperautre1.state as DecimalType
logInfo("test", "Temperature 1 = " + temp1)
val setPoint = TSsetpoint.state as DecimalType
logInfo("test", "Setpoint = " + setPoint)
logInfo("test", "Heat = " + Heat.state)

// Any casting errors should occur above this
if(TStatEnable.state == ON) {
    if(temp1 < setPoint-1){
        if(Heat.state != ON) Heat.sendCommand(ON)
    }
    else if(temp1 >= setPoint+1){
        if(Heat.state != OFF) Heat.sendCommand(OFF)
    }
}

For the avoidance of doubt (Strings? Numbers?) may we see your Item definitions?

OK, just copied and pasted your code, I had to change the first line (item was misspelled), but I’m still getting this error:
Error during the execution of rule ‘Maintain Heat’: Cannot cast org.openhab.core.library.types.DecimalType to void

With no other log statements before that? These details matter. We are flying blind here.

Post your Item definitions? They are Numbers right (per @rossko57’s question)?

this is what I’ve got back from the logs between this and the last try:
2016-12-15 16:28:41.505 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Maintain Heat’: Cannot cast org.openhab.core.library.types.DecimalType to void
2016-12-15 16:28:52.909 [INFO ] [runtime.busevents ] - PCD2 state updated to OFF
2016-12-15 16:28:55.909 [INFO ] [runtime.busevents ] - PCD1 state updated to OFF
2016-12-15 16:29:22.161 [INFO ] [.o.b.i.InsteonPLMActiveBinding] - devices: 6 configured, 6 polling, msgs received: 10
2016-12-15 16:29:24.434 [INFO ] [.o.b.i.i.device.MessageHandler] - DimmerRequestReplyHandler: set device 27.2A.C7 to level 100
2016-12-15 16:29:27.052 [INFO ] [c.internal.ModelRepositoryImpl] - Refreshing model 'Tstat.rules’
2016-12-15 16:29:33.122 [INFO ] [runtime.busevents ] - TstatEnable received command OFF
2016-12-15 16:29:33.522 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Maintain Heat’: Cannot cast org.openhab.core.library.types.DecimalType to void
2016-12-15 16:29:37.364 [INFO ] [runtime.busevents ] - lightLevel state updated to 1.00
2016-12-15 16:29:37.468 [INFO ] [runtime.busevents ] - temperature1 state updated to 69.98
2016-12-15 16:29:37.474 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Maintain Heat’: Cannot cast org.openhab.core.library.types.DecimalType to void

here are my item definitions:
Number temperature1 “Room Temperature [%.1f °F]” (Jory) {mqtt="<[myBroker:STATUS/TF1:state:JS(trim.js)]"}

Switch Heat “Heater” (Jory){insteonplm=“2F.83.A2:F00.00.02#switch”}
Number TSsetpoint “Heating Set Point” (Jory)
Switch TstatEnable “Tstat enable” (Jory)

OK, lets try to give it a little extra hint about Item types. We can also add some logging to know what the rule things temperature1.state is.

logInfo("test", "temperature1.state = " + temperature1.state.toString)
val Number temp1 = temperature1.state as Number
logInfo("test", "Temperature 1 = " + temp1)
val Number setPoint = TSsetpoint.state as Number
logInfo("test", "Setpoint = " + setPoint)
...

DecimalType is a Number so the above should work OK.

Thank you, This seems to be working now I get this back from the logs:

2016-12-15 16:50:22.367 [INFO ] [c.internal.ModelRepositoryImpl] - Refreshing model 'Tstat.rules’
2016-12-15 16:50:30.959 [INFO ] [runtime.busevents ] - TstatEnable received command OFF
2016-12-15 16:50:31.428 [INFO ] [org.openhab.model.script.test ] - temperature1.state = 68.90
2016-12-15 16:50:31.625 [INFO ] [org.openhab.model.script.test ] - Temperature 1 = 68.90
2016-12-15 16:50:31.812 [INFO ] [org.openhab.model.script.test ] - Setpoint = 74
2016-12-15 16:50:33.259 [INFO ] [runtime.busevents ] - TstatEnable received command ON
2016-12-15 16:50:33.278 [INFO ] [org.openhab.model.script.test ] - temperature1.state = 68.90
2016-12-15 16:50:33.286 [INFO ] [org.openhab.model.script.test ] - Temperature 1 = 68.90
2016-12-15 16:50:33.294 [INFO ] [org.openhab.model.script.test ] - Setpoint = 74
2016-12-15 16:50:33.796 [INFO ] [.o.b.i.InsteonPLMActiveBinding] - Item: Heat got command ON
2016-12-15 16:50:33.807 [INFO ] [.o.b.i.i.device.CommandHandler] - LightOnOffCommandHandler: sent msg to switch 2F.83.A2 to on
2016-12-15 16:50:33.810 [INFO ] [.o.b.i.i.device.CommandHandler] - Sending message to 2F.83.A2
2016-12-15 16:50:33.813 [INFO ] [runtime.busevents ] - Heat received command ON
2016-12-15 16:50:34.162 [INFO ] [.o.b.i.i.device.MessageHandler] - SwitchRequestReplyHandler: set device 2F.83.A2 to ON
2016-12-15 16:50:34.166 [INFO ] [runtime.busevents ] - Heat state updated to ON
2016-12-15 16:50:58.293 [INFO ] [.o.b.i.i.device.MessageHandler] - DimmerRequestReplyHandler: set device 27.2A.DC to level 100
2016-12-15 16:51:13.949 [INFO ] [runtime.busevents ] - PCD2 state updated to OFF
2016-12-15 16:51:16.949 [INFO ] [runtime.busevents ] - PCD1 state updated to OFF

Can you please explain to me what was wrong, I’d really like to understand

So would I…

It should have worked before now.

I’ve been on OH 2 for quite some time so perhaps there was some issue back in 1.8 that I’ve forgotten that makes working with DecimalType harder.

For now, all I can say is before using the state from a Number Item, cast it to a Number (not DecimalType).

Now that it works, you could probably go back to doing it inline

if((temperature1.state as Number) <= (TSsetpoint.state as Number) - 1)

Though maybe it’s best to let sleeping dogs lie.

I’ll definitely be tweaking it a bit, but it’s nice to have a baseline where everything works, thanks so much for your help though I really appreciate it.

I really like that you changed this if(Heat.state == OFF) to if(Heat.state != OFF).
I thought about that a minute and realized that the device might not always report OFF or may be uninitialized, thanks for that bit. so at least I took away something, even if I don’t understand why my code wasn’t working. so thanks again.

I often throw in stuff like that when I rewrite others code on this forum. You are the first to notice, or at least the first to mention it. :blush: