DS18B20 sensor with an alarm threshold push notification - Rule problem

Good evening.

I have setup 2x DS18B20 sensors on GPIO pin 4 on my Rpi3 running Openhab2.

I followed instructions on this site : Kicking the tires on OpenHAB2: a RasPi 1-wire GPIO setup

It is working fine, I can persist the data correctly and I’m using this .items file :

String 	onewiretemp1Value 	"Freezer Fridge Temp [%s °C]"		<temperature>		{channel="exec:command:onewiretemp1:output"}
String 	onewiretemp2Value 	"Freezer Temp [%s °C]"				<temperature>		{channel="exec:command:onewiretemp2:output"}

I would like to compare the temperature values to a certain threshold inside a rule of this kind :

rule "Temp threshold check"
	when
		Item onewiretemp1Value changed
	then
		if(onewiretemp1Value > -20){
			AlarmPush.sendCommand(ON)
		}
		else {
			AlarmPush.sendCommand(OFF)
		}
end

rule "Send push notification when alarm is ON"

when
	Item AlarmPush changed from OFF to ON
then
	sendBroadcastNotification("Warning!")
end

Because the .items were created using a String, I get an error while using if(onewiretemp1Value > -20){ … because I can’t compare a String to a threshold numeric value.

If I change my items from String to Number, the items are not updated anymore (persist also stop working of course). The items stick to NULL.

What could I do to correctly use my rule or change my items to number?

Thank you for your precious help.

a quick look

Number onewiretemp1Value “Freezer Fridge Temp [%.1f °C]” {channel=“exec:command:onewiretemp1:output”}

rule “Temp threshold check”
when
Item onewiretemp1Value changed
then
var curTemper = onewiretemp1Value .state as DecimalType
if(curTemper > -20){
AlarmPush.sendCommand(ON)
}
else {
AlarmPush.sendCommand(OFF)
}
end

As far as I remember, there is an issue about exec not updating number items. https://github.com/openhab/openhab2-addons/issues/2149

As a workaround, I would suggest to use proxy items:

String strOnewireTemp1 {channel="exec:command:onewiretemp1:output"}
String strOnewireTemp2 {channel="exec:command:onewiretemp2:output"}
Number onewiretemp1Value "Freezer Fridge Temp [%.1f °C]" <temperature>
Number onewiretemp2Value "Freezer Temp [%.1f °C]"<temperature>

And of course a rule to update the items:

rule "update temp"
when
    Item strOnewireTemp1 changed or
    Item strOnewireTemp2 changed
then
    if(Double::parseDouble(strOnewireTemp1.state) != (onewiretemp1Value.state as Number))
        onewiretemp1Value.postUpdate(Double::parseDouble(strOnewireTemp1.state))
    if(Double::parseDouble(strOnewireTemp2.state) != (onewiretemp2Value.state as Number))
        onewiretemp2Value.postUpdate(Double::parseDouble(strOnewireTemp2.state))
    if((onewiretemp1Value as Number) > -20.0)  //force float by typing 20.0
        AlarmPush.sendCommand(ON)
    else if((onewiretemp1Value as Number) < -20.0)  //a little hysteresis
        AlarmPush.sendCommand(OFF)
end

Please be aware that you always have to use .state to get the state of an item. If you want the state treated as a number, you have to use type casting.

Of course, you could omit the proxy item, but you can take advance from an item of type number, e.g. you can set changing colors for label and/or value in dependence of the value.

1 Like

Thank you for your answer. We are on a good track…

I updated my items with your code.

Still have this error in the log : Rule ‘Update temp’: An error occurred during the script execution: Could not invoke method: java.lang.Double.parseDouble(java.lang.String) on instance: null

Actually, in Designer, I get a type mistmatch :

  • Cannot convert from State to String on strOnewireTemp1.state and strOnewireTemp2.state
  • Cannot cast from NumberItem to Number on onewiretemp1Value
rule "Update temp"
when
    Item strOnewireTemp1 changed or
    Item strOnewireTemp2 changed
then
    if(Double::parseDouble(strOnewireTemp1.state) != (onewiretemp1Value.state as Number))
        onewiretemp1Value.postUpdate(Double::parseDouble(strOnewireTemp1.state))
    if(Double::parseDouble(strOnewireTemp2.state) != (onewiretemp2Value.state as Number))
        onewiretemp2Value.postUpdate(Double::parseDouble(strOnewireTemp2.state))
    if((onewiretemp1Value as Number) > -20.0)  //force float by typing 20.0
        AlarmPush.sendCommand(ON)
    else if((onewiretemp1Value as Number) < -20.0)  //a little hysteresis
        AlarmPush.sendCommand(OFF)
end

Can you take a look?

Thank you very much for your help, very appreciated!

That’s strange… (well… the second type mismatch from designer is a copy&paste error, my bad…
Let’s try this:

rule "Update temp1"
when
    Item strOnewireTemp1 changed
then
    if(strOnewireTemp1.state.toString!="" && strOnewireTemp1.state.toString!="NULL")
        onewiretemp1Value.postUpdate(Double::parseDouble(strOnewireTemp1.state.toString))
    if((onewiretemp1Value.state as Number) > -20.0)  //force float by typing 20.0
        AlarmPush.sendCommand(ON)
    else if((onewiretemp1Value.state as Number) < -20.0)  //a little hysteresis
        AlarmPush.sendCommand(OFF)
end

rule "Update temp2"
when
    Item strOnewireTemp2 changed
then
    if(strOnewireTemp2.state.toString!="" && strOnewireTemp2.state.toString!="NULL")
        onewiretemp2Value.postUpdate(Double::parseDouble(strOnewireTemp2.state.toString))
end

I now ended up in two rules.
If there are strings that occur to strOnewireTempX (where X is 1 or 2) that are not numerical, you have to add them to the if-clause (maybe you can ensure that the exec will always return a valid number (and -999 for error or so, then you have to exclude this value through the if-clause).

1 Like

Little typo in your Update temp2 : changed strOnewireTemp1 to strOnewireTemp2

It now works perfectly!!! Thank you so much for helping the noob I am!

Keep up your good work! Have a good one!

Cool! Glad I could help. :slight_smile: