Control a heater with multiple sensors

Hi, I want to control a heater with multiple temperature sensors.

so I have a goal temperature to reach.
for turning off the heater I use <||> sign, because I have to be sure that in case of going up temperature in one section, the heater goes off.

for turning on, Im using <&&> sign to wait until all of the values are below goal temperature.

the problem raises when I get false values from sensors.
lower values don’t cause any problem. it will pass both of above rules but higher values cause the turning on section never happen.

rule "dryerprocess"

when
      Item t1 received update or
      Item t2 received update or
      Item t3 received update or
      Item t4 received update
then
	goaltemp.sendCommand(theArray1.get((tm.state as Number).intValue))

		if(dryer.state == ON)  {
    		if(dryer_pause.state == OFF) {
				  if(((t1.state as DecimalType) > (goaltemp.state as DecimalType)+3) || ((t2.state as DecimalType) > (goaltemp.state as DecimalType)+3) || ((t3.state as DecimalType) > (goaltemp.state as DecimalType)+3) || ((t4.state as DecimalType) > (goaltemp.state as DecimalType)+3)) {
       			 if(Heater.state != OFF) Heater.sendCommand(OFF)
  			  }

   		 	 if(((t1.state as DecimalType) < (goaltemp.state as DecimalType)+1) && ((t2.state as DecimalType) < (goaltemp.state as DecimalType)+1) && ((t3.state as DecimalType) < (goaltemp.state as DecimalType)+1) && ((t4.state as DecimalType) < (goaltemp.state as DecimalType)+1)) {
        	     if(Heater_Thermo.state != ON) Heater_Thermo.sendCommand(ON)
         }

   		  }
		}
end

So, I delete && part and use jus one sensor data and use Thread::sleep for 10 seconds to wait for other sensors to get lower than goal temperature but thread::sleep doesn’t work, so when one sensor is lower than goal temp and the others are upper, heater will turn on and off until all of them comes down …

rule "dryerprocess"

when
      Item t1 received update or
      Item t2 received update or
      Item t3 received update or
      Item t4 received update
then
	goaltemp.sendCommand(theArray1.get((tm.state as Number).intValue))

		if(dryer.state == ON)  {
    		if(dryer_pause.state == OFF) {
				  if(((t1.state as DecimalType) > (goaltemp.state as DecimalType)+3) || ((t2.state as DecimalType) > (goaltemp.state as DecimalType)+3) || ((t3.state as DecimalType) > (goaltemp.state as DecimalType)+3) || ((t4.state as DecimalType) > (goaltemp.state as DecimalType)+3)) {
       			 if(Heater.state != OFF) Heater.sendCommand(OFF)
  			  }

   		 	 if((t1.state as DecimalType) < (goaltemp.state as DecimalType)+1) {
              Thread::sleep
        	     if(Heater_Thermo.state != ON) Heater_Thermo.sendCommand(ON)
         }

   		  }
		}
end

I know this method is wrong even if thread::sleep worked.

any suggestion on solving the problem?
thanks.

You don’t a rules problem, you have a hardware problem…
What kind of sensors are you using?
Why to you get false values?
What kind of false values do you get?

1 Like

thanks. I want to use coding to cover the sensor failure temporarily to replace the sensor after that.
I use pt100 with sensor with nodemcu esp8266.
if pt100 amplifier has problem or something else… the value goes down to zero or between 0-30 C
or in some cases goes up like 1200 degrees

rule "dryerprocess"

when
      Item t1 received changed or
      Item t2 received changed or
      Item t3 received changed or
      Item t4 received changed
then
    val temp = triggeringItem.state as Number
    if (temp > 50) {
         triggeringItem.postUpdate(triggeringItem.previousState.toString)
    }
end
2 Likes

That’s tricky. While you can eliminate outliers with some simple math, how would you detect broken sensor that gives a normal looking value? Not rhetorical, I mean how YOU know it’s broken, so you can code similar method. One way might be to flag a fault if the value doesn’t change over some time period.

1 Like

This is a hard problem. As with all hard problems, you need to break it into multiple parts.

  1. As rossko57 indicates, you need to figure out how to know that a sensor is not working. Then write code/configuration to reliably detect this in your Rules. You will probably need to use a Proxy Item and a Rule. And of course how you do this depends greatly on the behavior the sensor exhibits when it is not working correctly. Does it stop reporting? Does it momentarily report an unreasonable value? What constitutes an unreasonable value? If it just stops reporting then you can use the Expire binding to set that Item to UNDEF if it doesn’t report for awhile. If it reports one odd value then comparing the current reading to the last reading might be sufficient. But you might need to use a bunch of complicate math and Markov chaining and the like to estimate where the temp reading should be based on past readings and if the actual is too far beyond the estimate then you reject it.
    To start, just write a Rule that logs out when it senses a bad sensor reading and double check that it is right.
rule "Filter out likely bad readings"
when
      Item t1 received changed or
      Item t2 received changed or
      Item t3 received changed or
      Item t4 received changed
then
    if(Math::abs(triggeringItem.state as Number - previousState as Number) < 50) 
        postUpdate(triggeringItem.name+"_Proxy", triggeringItem.state)
    else 
        logWarn("temp", triggeringItem.name + " returned an unreasonable sensor reading: curr = " + triggeringItem.state + " prev = " + previousState)
end

The above Rule triggers when any of the sensors changes. Only if the change between the current reading and the previous reading is less then 50 is the sensor reading forwarded on to the Proxy Item.

  1. Once you can reliably detect a bad sensor reading you need to figure out what is the correct way to handle it. Do you just ignore it? Do you estimate the value based on the other sensors (e.g. assume it’s the average of the other ones)? Do you shut everything down? etc.

  2. Finally, you need to implement the Rule that combines 1 and 2 as appropriate.

Honestly, having done this with my own heating to just handle the case where a sensor goes offline, it will be far far less work and far more reliable to fix the problem in hardware if that is an option.

1 Like