Rule example: Engine heater based on temperature

Hi.
Thought I’d share a simple rule I made for turning my engine heater on at the right time before departure. It’s done according to recommendations from Calix (Swedish manufacturer of engine heaters).

Reasoning:

  • I want to leave home at 06:45 every week day
  • If the temperature is -10 degrees or lower the engine heater should be active for two hours, ie from 04:45
  • If the temperature is between -10 and 10 degrees the engine heater should be active for one hour minus the temperature times six (which gives a straight curve from zero to two hours)
  • If the temperature is above 10 degrees the heater isn’t needed at all
  • Turn the heater off 07:30 (by then I should already be at work)

Rule follows. Comments are welcome :slight_smile:

rule "Turn on engineheater"
when
        Time cron "0 45 4 ? * MON-FRI"
then
        if(Utetemperatur.state <= -10) {
                Motorvarmare_Switch.sendCommand(ON)
        } else if(Utetemperatur.state <= 10) {
                var int minutes = 60 - (Utetemperatur.state as DecimalType).intValue * 6
                var departure = new DateTime(now.getYear(), now.getMonthOfYear(), now.getDayOfMonth(), 6, 45, 0)
                engineTimer = createTimer(departure.minusMinutes(minutes)) [|
                        Motorvarmare_Switch.sendCommand(ON)
                ]
        }
end

rule "Turn off engineheater"
when
        Time cron "0 30 7 ? * MON-FRI"
then
        Motorvarmare_Switch.sendCommand(OFF)
end

edit: Forgot to mention: I’m in Sweden. So temperatures are in degrees Celsius, utetemperatur is outdoors temperature and motorvärmare is engine heater. In case you didn’t guess that already :wink:

2 Likes

Nice rule! I could see an expansion of the rule where it keeps checking say every five minutes, and if the temperature drops below the curve to turn on the engine heater. This would replace the Timer and make the rule a little more responsive to changing temps in the morning.

It may be a complication beyond reasonable but it is fun to solve those sorts of problems. :slight_smile:

I don’t know where you are but here dawn is around 07:00 and the lowest temp tends to be around 06:00 unless a front moves through (I’ve seen 60 degree drops in an hour before.

Oh. Well, that certainly would change things. I’m in Sweden. Don’t think I’ve ever seen temperature changes of more than 5-10 degrees between 04:00 and 06:00 (without actually having checked in the database), so changes in temperature doesn’t really make that much of a difference. Either it’s cold in the morning or it’s not :wink:

I should say that is 60 degrees F, so more like 16 degrees C. It should be obvious I’m not living on the planet Mercury. :smiley:

I do live at 7000 ft above sea level in the mountains and the weather can change quite drastically in very little time. Keeps us on our toes. Just this morning I left my house in near blizzard conditions and it was sunny by the time I got to work.

Doh. Fahrenheit. That’s weird stuff. It just hit me now though that I never mentioned in my post that I was actually talking Celsius. Added that information now :slight_smile:

My simple sample of temperature rule…

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

	rule "temperature"
	when
        	Item temp changed
	then
		if(temp.state >= 25) {
		Fan.sendCommand(ON)
		}
	else if(temp.state < 25) { 
		Fan.sendCommand(OFF)
		}
end

And my PIR sensor rule:

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

var Timer timer = null

rule "Lamp"
when
        Item presence changed from CLOSED to OPEN
then
        Lamp.sendCommand(ON)
	sendMail("myemail@emailserver.com", "Front Door.", "You have guests on front door!", "http://mycamip/snapshot.jpg?user=admin&pwd=")
	sendTelegramPhoto("bot1", "http://mycamip/snapshot.jpg?user=admin&pwd=", null)
end

rule "Lamp OFF"
when
        Item presence changed from OPEN to CLOSED
then
	timer = createTimer(now.plusSeconds(6)) [|	
        	Lamp.sendCommand(OFF)
		timer - null
	]
end

Attaching to this topic because it appears to be the most relevant… :slight_smile:
I get the concept of rules… I have a few based on time for turning on light, etc,
However, these rules seem to defy simple logic sometimes… and maybe due to my ignorance… so I apologize for that.
I have a temp sensor in the greenhouse (item=greenhousetemp) Been working and sending data for months)
I have a ZWave Wallplug (item=wallplug2) Also controllable via basic UI and/or iphone and android openhab app with no issue.
The wife wants the greenhouse heater (wallplug2) to turn on when equal or less than 40 and turn off at equal or greater than 45. (Winter tomatoes stuff)
Here is my rule, but does not work (my values are different right now for testing)
Log shows this:
2018-10-10 15:16:55.027 [vent.ItemStateChangedEvent] - greenhousetemp changed from 47.0 to 47.2
No coinciding event to show: Wallplug2 changed from OFF to ON
Here is the rule… where is my logic failing?

rule “greenhousetemperature”
when
Item greenhousetemp changed
then
if (greenhousetemp.state <= 48.0) {
wallplug2.sendCommand(ON)
}
if (greenhousetemp.state > >= 49.0) {
wallplug2.sendCommand(OFF)
}
end
PS I hate asking for help with such stupid, simple stuff :frowning:
Do I need an import of something??
Thanks
Todd

I must add that this temperature value is gathered from MQTT on another R-Pi that the sensors reside on. I wouldn’t think that matters, though :slight_smile:

A bit of a hijack :wink:

Fix the syntax and the rule should work. You’ve got an extra >
Add some debug logWarn to see if it enters the rule.

Probably would have been more appropriate to start a new thread.

In the future, when posting code How to use code fences.

I strongly recommend using VSCode to edit .rules files. See https://www.openhab.org/docs/configuration/editors.html#openhab-vs-code-extension. It will point out syntax errors. Failing that, always watch openhab.log when making changes to a .rules file. It will tell you if you have a syntax error.

As Crispin says, you have an extra > in your second if statement which is probably causing OH to reject the whole .rules file as syntactically incorrect.

VScode would have underlined that line in red as soon as you typed it.

Thanks,
I Recently installed Visual Studio Code, installed the OpenHab extension but AM TRYING TO FIGURE OUT HOW TO CONNECT TO THE OPENHABIANPI share on my network… not seeing it.
I don’t think the extra > is the issue… that is just a recent typo while adding the <= value

I’ll look this up too: How to use code fences.
Thanks Rich.
Todd

One more interesting thing… I always keep my “Tail” opened so I can see if the new edit I make causes an issue.
This rule reports NOTHING when ever I make a change to it… like it is going un-noticed!

Which log file are you tailing? events.log only shows Items change and command events (some Thing events too). To see errors and a log of what OH is doing you need to tail openhab.log. When you edit the .rules file and save you should at least be seeing “Loading model ‘rulesfilename.rules’” in openhab.log. If there are syntax errors you will see the error after that line and it will tell you what and where (row and column).

Be sure to copy and paste code is it is exactly as it appears in your posts. We can’t know whether a stray character is in the original or not.

Add a logInfo as the first line of the Rule to verify whether the Rule is executing. I would guess you have a syntax error here or elsewhere in the same .rules file. But if not this will show whether the rule is executing or not.

Is the Item named “wallplug2” or “Wallplug2”? Case does matter.

Here is what I watch:
tail -F /var/log/openhab2/openhab.log /var/log/openhab2/events.log
Here is the Rule again
(greenhouseheater.rule)

logInfo
rule "greenhouseheater"
when 
	Item greenhousetemp changed
then
	if (greenhousetemp.state <= 45.5) {
		wallplug2.sendCommand(ON)
	} 
	if (greenhousetemp.state >= 49.0) {
		wallplug2.sendCommand(OFF)
	} 
end

Let me know what you think, Rich! :slight_smile:THanks
Todd

To verify that my item is working, I switched it on then off again…
Here is the log for that:

2018-10-10 17:17:29.214 [vent.ItemStateChangedEvent] - Wallplug2 changed from OFF to ON

2018-10-10 17:17:32.222 [ome.event.ItemCommandEvent] - Item ‘Wallplug2’ received command OFF

2018-10-10 17:17:32.246 [vent.ItemStateChangedEvent] - Wallplug2 changed from ON to OFF

:sunglasses:

DOH… maybe it IS a “W” thing
Let me change that :frowning:

Well, bummer!
Still no go.

Maybe I’ll make another rule based on some other kind of event to assure that the Wallplug2 will take a command…
No fun! :slight_smile:

Yep. Woke up this morning with 11 mails in my mailbox about this thread. Thought someone finally realized the brilliance :smile: Actually I started using my engine heater again last week, starting to get cold in Sweden now.

I don’t know if it’s a copy-paste error, but the first row in the rule (“logInfo”) doesn’t seem to belong there. I think what you need to do though is to put a couple of logInfo() calls in the script to see where it actually executes and not. See https://www.openhab.org/docs/configuration/rules-dsl.html#scripts. And then just tail openhab.log.

@toddwevans

Try that:

rule "greenhouseheater"
when 
    Item greenhousetemp changed
then
    if (greenousetemperature.state == NULL) return; // If no temp do nothing

    // Calculate states
    val temperature = greenhousetemperature.state as Number
    var wallPlugState
    if (wallplug2.state == NULL) {
        wallplug2.sendCommand(OFF) // Initialise wallplug2 to OFF just in case
        wallPlugState = OFF
    } else { 
        wallPlugState = wallplug2.state
    }

    if (temperature <= 45.5) {
       wallPlugState = ON
    } 
    if (temperature >= 49.0) {
        wallPlugState = OFF
    }

    // Do the command
    wallplug2.sendCommand(wallPlugState)
end

Trying to understand… Wouldn’t this mean that wallPlugState is only declared if wallplug2.state isn’t null? Shouldn’t the declaration of the variable be before the if? Also I guess wallplug.state should really be wallplug2.state.

1 Like