Working with maths

Hi,
My current efforts are around integrating Sonoff Temperature and Humidity sensors.
Depending on where I place them room or even areas of a room the level of accuracy changes when measured against a more accurately calibrated wireless tag.

I am trying to do some maths so I can compare measured Temp once an adjusted weight has been applied to an Adjusted Temp value.

I am looking to do a similar thing for humidity too but in this case its a range ( max, min) rather than a single target).

I am struggling with this as I do not seem to have a grasp of how to perform maths on items defined as Numbers, or val.

Here is a rough idea of what I am trying to accomplish on Rule form.

rule "livingroom-temp"
when
Item LR_Temp received update
then
	postUpdate(LR_Min_Temp, ((LR_Tgt_Temp.state as DecimalType) - 2))
	logInfo("temp.rules", "Living Room Temperature: Measured : " + LR_Temp.state + " Target : " + LR_Tgt_Temp.state + " Minimum: " + LR_Min_Temp.state)
	if (LR_Temp.state > LR_Tgt_Temp.state)
		{
		logDebug("temp.rules", "Livingroom is considered Over temperature, (HOT)") 
		}
	else if (LR_Temp.state < LR_Min_Temp.state ) 
		{
		logDebug("temp.rules", "Livingroom is considered Under temperature, (Cold)") 
		}
	else 
		{
		logDebug("temp.rules", "Livingroom is considered Normal temperature, (Normal)")
		}
end

How do I adjust say for an inaccuracy of 1.6 degrees?

Thanks

Paul

Are you getting errors in the logs for this rule and if so what are they?

Are you getting errors parsing the rule and if so what are they?

Are you getting the wrong log statements when the rule executes or is the rule not executing?

I notice four potential problems. I want to emphasize the word “potential” because without further info I can’t say for sure.

  1. It is almost always better, particularly when dealing with Number Items, to use the postUpdate on the Item rather than the postUpdate Action as you are using. The problem is the Action can only take two Strings and then it has to parse that String into whatever the state the Item needs. But sometimes the Rules engine is not able to figure out how to convert what gets passed to it into a String. The method, on the other hand, can take all sorts of different types of arguments and is much better able to figure out how to convert them into what the Item needs. So one potential problem is that the Rules engine doesn’t know how to convert the result of subtracting 2 from the LR_Tgt_Temp.state into a String.

  2. Number is a special case that can cause problems even when using the methods instead of Actions. The problem is that the state of a Number is a DecimalType and DecimalTyp is a Number. Unfortunately, the postUpdate method has a verion for both types which can result in an “Ambiguous method call” error because it can’t figure out which version of the method you need. Therefore I always recommend casting the state from a Number Item to a Number rather than DecimalType when you plan on doing math.

    LR_Min_Temp.postUpdate(LR_Tgt_Temp.state as Number - 2)

  3. You may need to cast the states of LR_Temp, LR_Tgt_Temp, and LR_Min_Temp to Number in your if statements for the comparisons to work.

  4. When you postUpdate or sendCommand (note, all of the above applies to sendCommand as well) it can take a little bit (dozens to hundreds of milliseconds) for the new state to get to the event bus and reach the Item. It is possible that your postUpdate to LR_Min_Temp is not yet done being processed and applied when you get to the conditional a few lines further down. I recommend assigning the adjusted temp as a local variable and use the local variable in your comparison instead. Another alternative would be to add a sleep.

    val adjustedMin = LR_Tgt_Temp.state as Number - 1.6
    logInfo(...
    if(LR_Temp.state as Number > LR_Tgt_Temp.state as Number) {
        ...
    }
    else if(LR_Temp.state as Number < LR_Min_Temp.state as Number) {
        ...
    }
    else {
        ...
    }

Other approaches are possible as well depending on the binding used to populate your Item. If it supports a transform, you can apply the adjustment in a JS transform so the temp gets adjusted before it ever gets to the Item in the first place.