Calibrating thermometers in openHAB

Hi community!

For my heating-control, I need a lot of temperature-sensors. I found the “PHILIPS HUE Motionsensors” which are supportet by the OpenHab-HUE-Binding and also have a temerature-sensor build in. I need one of this sensors per room to manage the temperature per room. But the accuracy of this sensors is very, very bad.

Problem Statement
I want to got the Philips HUE Motionsensors working as temperature sensors with sufficient accuracy for heating control.

The measured values of the sensors differs up to +/- 3°.The difference of the value is not constant. It depends on the current temperature. So, a simple solution via the openhab-offset-profile wont fix the problem. But fortunately the values are consistent by the same temperature. So it seems that the hardware sensor works fine, just calibration is missing.

Concept
I’ve got that sensors working with a linear correction with two calibration-points. Its coded with a minimal effort for every single sensor. That allowes to use many of them without getting lost in tonns of code.

Items
Two items are needed for every sensor. The first Item is the Item with the hardware-binding. The “raw”-value-item. Don’t use this Item for controling or displaying.

Number:Temperature <SENSORNAME>_Temp_RAW "RAW Temp <SENSORNAME> [%.2f %unit%]" <temperature> { channel="hue:0302:1:motionsensor3Temp:temperature" }

The second Item is a proxy-item, with the corrected value. Use this Item for displaying and controling:

Number:Temperature <SENSORNAME>_Temp "Temp <SENSORNAME> [%.1f %unit%]" <temperature>

Rules
I put this correction in an lambda, which does the math of the linear correction

val Functions$Function6<GenericItem, GenericItem, Float, Float, Float, Float, Boolean> calculate = [ 
	GenericItem source_item,
	GenericItem target_item,
	Float mess1,
	Float echt1,
	Float mess2,
	Float echt2
	 |
					
	if (source_item.state == UNDEF) {
		postUpdate(target_item, UNDEF)
	} else {				
		val Float currMess = (source_item.state as Number).floatValue
			
		val Float  abweichung1 = echt1 - mess1;
		val Float  abweichung2 = echt2 - mess2;
			
		val Float  abweichungDiff = abweichung2 - abweichung1;
		val Float  tempDiff = mess2 - mess1;
		val Float  currTempDiff = currMess - mess1;
		val Float  steigung = abweichungDiff / tempDiff;
					
		val Float  currAbweichung = abweichung1 + steigung * currTempDiff;
			
		val Float  res = currMess + currAbweichung;
		sendCommand(target_item, res)
	}				
] 	

To use this Lambda, I create a rule for every sensor. In this rule, the callibration-points are defined:

rule "[SENSORNAME]_Temp calibration"
when 
	Item [SENSORNAME]_Temp_RAW changed 
then
	calculate.apply([SENSORNAME]_Temp_RAW, [SENSORNAME]_Temp, 16.4, 18.6, 17.8, 20.1)
end

This rule just call the lamba with the raw-sensor, the proxy-item, and the calibration-data. The calibration-data are put in this order:

  1. sensor-measurement at the lower calibration-point
  2. real temperature at the lower calibration-point
  3. sensor-measurement at the upper calibration-point
  4. real temperature at the upper calibration-point

The calibration-process
I put all the sensors to an environment with an constant temperature at the lower end of my mearure-range. Round about 17°C - in my basement. I wait several minutes until the sensors all gives me a constant value. Also I measured the correct temperature of this environment with an reliable thermometer. I wrote down the real temperature and all the values from the sensors. So I have the first, lower calibration-points for my sensors.

Next, I put all the sensors to an high-temerature-environment (about 22°C) and got the second calibration-point.

Disadvantages

  1. This correction just work in the calibrated temperature-range. Outsite this range, it MAY works, but can be very incorrect.
  2. I dont know, if the characteristic of this sensor is really linear. So may the linear correction is not very accurate in the middle of the range.

So this linear correction only works in the calibrated range and only if this range is as small as posible. For me, in this 5°-range, it works with an accuracy of +/-0.1° - Exact enough for an heating control.

Conclusion
I’m not very happy this this solution. Its feels a little hacky to me. I’m sad about philips to not do a factory-site calibration of this sensor. But whis this sollution, I can use this sensors for heating-control. After that, the sensors are working fine!

Happy Coding,
Igor

heating_sensor_calibration.rules.txt (5.1 KB)

1 Like

Nice write-up! I’d suggest changing the title to “Calibrating thermometers in openHAB”, as I think it will apply to more than just the Philips HUE device you have. I know that my Zooz 4-in1 sensor could benefit from something like this, but same as you I’m not convinced that its inaccuracy is linear.

Thank you. Ive changed the title.

Good look with your sensors. If a linear correction is not enough, my solution can be extended to use more calibration-points or any other math…

Dou you have done some measuring with your sensors?

Have a nice weekend!
Igor

I have an old digital thermometer that sits next to my Zooz sensor, and I don’t remember them ever displaying the same temperature or humidity. I compared them both with a meat thermometer and none of them say the same thing, but they’re all close enough that I haven’t worried too much about it.

I might make a point of recording the readings to see if a pattern emerges.