[SOLVED] Rules based on specific temperature change

Hi Guys,

Sorry if I’m posting a repeated question, but I couldn’t find (yet) a related situation.

I have 3 temperature, humidity and pressure sensors. I’d like a simple rule, when temperature rises above 27 degrees, to send a notification

rule "Kitchen Temperature above 27 °C"
when
    Item KitchenTempHumAndPressSensorTemperature changed
then
    var TempK = KitchenTempHumAndPressSensorTemperature.state as Number
    if( TempK >= 27 ) {
        sendHttpGetRequest("http://xxxxxxx")
    }
end

The problem is the rule is not triggered at 27 or more but on every change. What am I missing? I tried with “var” and also just item state:

rule "Kitchen Temperature above 27 °C"
when
    Item KitchenTempHumAndPressSensorTemperature changed
then
    if( KitchenTempHumAndPressSensorTemperature.state as Number >= 27 ) {
        sendHttpGetRequest("http://xxxxxxx")
    }
end

Result the same.

Thank you and sorry if I opened a duplicate topic.
Br,
Mario

Does your Item have units i.e. a Number:Temperature type?

Add logging for unexpected values

var TempK = KitchenTempHumAndPressSensorTemperature.state as Number
logInfo("test", "Value " + TempK.toString)

Is your Item defined for UoM? I’m a bit rusty using the DSL, but you could try…

 if( KitchenTempHumAndPressSensorTemperature.state >= 27 | °C ) {

or…

 if( (KitchenTempHumAndPressSensorTemperature.state as QuantityType<Number>).intValue >= 27 ) {
1 Like

That did the trick. Thanks!

Just a quick comment I would like to add:

Please note that the code will be run every time there is a change and the temperature is still equal to or above 27 °C. So every temperature rise or drop that remains >= 27 °C will generate another notification. If this is not your desired behavior it may make sense to introduce a boolean variable to keep track of the notification:

var boolean Notification27CAlreadySent = false

Set it to true after the first notfication and avoid further notifications by checking the variable. Finally reset it to false when the temperature drops below 27 °C again.

Make the reset to false at a lower temp e.g. 26 C and you have hysteresis to reduce dithering.

1 Like

Does this makes sense? :slight_smile:

rule "Living Room Temperature above 27 °C"
when
    Item LivingRoomTempHumAndPressSensorTemperature changed
then
    var TempLR = LivingRoomTempHumAndPressSensorTemperature.state as Number
    var boolean TempNotif = false
    if( TempLR >= 27 | °C && TempNotif == false) {
        sendHttpGetRequest("http://xxxxxxxxx/&text=Living%20Room%20Temperature%20above%2027")
        logInfo("senzortest", "vrednost " + TempLR.toString)
        TempNotif = true
    }
    else if( TempLR < 27 | °C && TempNotif == true ) {
        TempNotif = false
    }
end

Nearly. Your TempNotif variable is declared fresh every time the rule runs, and discarded when the rule exits.

Moving the var declaration outside of any rule, and putting it in the file before any rules, makes it into a durable “global variable”

So I guess like that:

//Variables
var boolean TempNotif = false

//Notifications
rule "xxx"
when
...
...

Will test.

Can confirm that this is working. So my next question is: :slight_smile:

Instead of notification “Temperature is above 27” id like “Temperature is [exact value]”. For notification I’m using HTTP GET method. Text is URL Encoded.

I tried something following this ([SOLVED] HttpGet rule with variables) but not ok.

Logs show:
Rule ‘Living Room Temperature above 27 °C’: Illegal character in query at index 139: http://xxxxxxx/…&text=Living%20Room%20Temperature%2027.09 °C

The problems is clearly second part as it is not encoded. Well I just added “+ TempLR.toString” to my request. Guess need something other. :slight_smile:

Thank you,

Because you’ve now set up your rule to report just once as the temperature threshold is crossed, I doubt such a message is very useful? It’s always going to report just a bit over 27.

Anyways, the problem is clear, the degree symbol is not allowed in url. You need to url encode it.
Probably the easiest way is string replace the symbol character with the url encoding.

Makes sense

Hello everyone, Looked around and this was the closest topic to an issue I am trying to resolve.
simple electric heater in powder room to switch on and off according to outside temperature.
Though new to code-Currently finding a new interest and hope to learn and someday contribute.
Very simple rule
Though I had to miss something, as events log reports temperature properly,Though does not log or change value of the heater.
VS Code shows no errors

rule “Powder Room Heat”
when
Item CurrentTemperature received update
then
if ((CurrentTemperature.state <= 65) && (Powder_Heater.state == OFF))
{
sendCommand(Powder_Heater,ON)
logInfo(“Heater On”,“Turned on Powderoom heater”)
}
if((CurrentTemperature.state >= 65) && (Powder_Heater.state == ON))
{
sendCommand(Powder_Heater,OFF)
logInfo(“Heater Off”,“Turned off Powderoom heater”)
}
end

Does anyone see what I missed?

Openhab 2.5.12 raspberry pi 4
open weather API
Aeotec Nano Switch on heater

What is that state? What I’m driving at is that your Item is perhaps a Number:Temperature type, with units.

Thank you for a quick reaction and pointing me in the right direction,
As I have been Trying to learn Python-which caused me to start my openHAB project,
Prior to posting I had CurrentTemperature= Number
Though that obviously did not work.
After reading your suggestion,I tried about 6 different variables in the documentation without success.
Here is where I am and think am close.Thoughts?

Screen Shot 2021-03-10 at 4.18.26 PM

Please post code in code fences, rather than screenshots. It’s easier to highlight extracts and offer suggestions for everyone.

when
    Item CurrentTemperature received update

Okay, that’s an Item.

   val CurrentTemperature = CurrentTemperature as Number

First, don’t make new variables with the same name as your Items. It confuses me, and probably confuses the rules parser too.

Second, you can’t get an Item as a Number variable. An Item is a complex object, with many properties like name, label, type, etc. It’s usually the state property you’d be interested in.
But you don’t even need state as a Number. You just want to compare, so compare it with another Quantity with units.

So let’s have a try -

...
when
    Item CurrentTemperature received update
then
    if ( (CurrentTemperature.state < 65|°F) && (Powder_Heater.state == OFF) ) {
...etc

Note that Powder_Heater is another Item, where you’d want to be looking at the state.

Thank you very much Rossko57. The rule is now running perfectly
It will trigger according to the state of temperature and heater as to not overload the relay with every time the temperature changes
One interesting fact is,You will notice an adjustment to the send command syntax to the heater.The rule was not functioning correctly until I reread the rule syntax documentation and adjusted accordingly.
Your guidance is much appreciated! Great forum!

when
	Item CurrentTemperature received update
then
	if  ((CurrentTemperature.state < 65|°F) && (Powder_Heater.state == OFF))
	{
        Powder_Heater.sendCommand(ON)
            logInfo("Heater On","Turned on Powderoom heater")
    }
    if  ((CurrentTemperature.state > 65|°F) && (Powder_Heater.state == ON))
    {
        Powder_Heater.sendCommand(OFF)
            logInfo("Heater Off","Turned off Powderoom heater")
    }
end```
1 Like