Help with JavaScript rule to compare luminance

Using OH 4.0.3 and openhab-js 4.5.1

Slowly porting rules from Jython and its progressed extremely smoothly until now. I’d like to compare a luminance value from a zwave item to a threshold value (currently 300 lx).

This is the rule:

rules.JSRule({
	name: "Master Bathroom Heat Lamp Is On",
	description: "Master Bathroom Heat Lamp Is On", tags: ["TEST1", "TEST2"],	id: "MasterBathroomHeatLampOn",
	triggers: [triggers.ItemStateChangeTrigger("Sensor2_luminance"), triggers.ItemCommandTrigger("Test_Switch_1")],
	execute: (event) => {
		console.info (utils.OPENHAB_JS_VERSION);
		console.log (`-------------------------------------------------------------------`);
		console.log (`RULE: Master Bathroom Heat Lamp Is On | Luminance state value is: [${items.getItem("Sensor2_luminance").state}]`);

		var reportedLuminance = items.Sensor2_luminance.quantityState;
		var thresholdLuminance = Quantity('300 lx');
		console.log (`RULE: Master Bathroom Heat Lamp Is On | Luminance value: [${reportedLuminance}] | threshold value: [${thresholdLuminance}].`);
		
		if (reportedLuminance < thresholdLuminance) {
			console.log (`RULE: Master Bathroom Heat Lamp Is On | Luminance value [${reportedLuminance}] is less than threshold: [${thresholdLuminance}]`);
		}
		else if (reportedLuminance >= thresholdLuminance) {
			console.log (`RULE: Master Bathroom Heat Lamp Is On | Luminance value [${reportedLuminance}] exceeds threshold: [${thresholdLuminance}]`);
			//
		}
	}
});

the output for some values is correctly calculated:

openhab:send Sensor2_luminance 20 lx

22:31:56.790 [INFO ] [hab.automation.script.file.xxxtest.js] - 4.5.1
22:31:56.793 [INFO ] [hab.automation.script.file.xxxtest.js] - -------------------------------------------------------------------
22:31:56.797 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance state value is: [20 lx]
22:31:56.800 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance value: [20 lx] | threshold value: [300 lx].
22:31:56.808 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance value [20 lx] is less than threshold: [300 lx]

however, where a luminanceValue starts with the first number of the threshold value, it seems to start giving the wrong calculation. For a threshold value of 300 the calculation tells me that 31 lx is greater than 300lx. If I change the threshold value to 400 anything less than 41 is ok, but from 41 onwards it tells me its higher):

openhab:send Sensor2_luminance 31 lx

22:34:26.527 [INFO ] [hab.automation.script.file.xxxtest.js] - 4.5.1
22:34:26.529 [INFO ] [hab.automation.script.file.xxxtest.js] - -------------------------------------------------------------------
22:34:26.530 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance state value is: [31 lx]
22:34:26.533 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance value: [31 lx] | threshold value: [300 lx].
22:34:26.536 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance value [31 lx] exceeds threshold: [300 lx]

The item definition is currently:
Number:Illuminance Sensor2_luminance "Luminance [%d]" (gBathroomSensor) { channel="zwave:device:24d480e0:node11:sensor_luminance", homekit="LightSensor, LightSensor.LightSensor"}
but i’ve tried with %unit% in the description and also { unit = "lx" } in the channel.

Using .numericState and comparing the threshold as a number (eg 300) avoids the problem, however I was hoping to work with the UoM as best practice (and also understand how it all works).

I thought that it might be because I’m sending updating the value manually however I let the item update naturally and got some wacky results:

23:08:39.764 [INFO ] [hab.automation.script.file.xxxtest.js] - 4.5.1
23:08:39.766 [INFO ] [hab.automation.script.file.xxxtest.js] - --------------------------------------------------------------------
23:08:39.768 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance state value is: [1708 lx]
23:08:39.770 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance value: [1708 lx] | threshold value: [300 lx].
23:08:39.773 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance value [1708 lx] is less than threshold: [300 lx]
23:09:40.157 [INFO ] [hab.automation.script.file.xxxtest.js] - 4.5.1
23:09:40.160 [INFO ] [hab.automation.script.file.xxxtest.js] - --------------------------------------------------------------------
23:09:40.163 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance state value is: [3 lx]
23:09:40.168 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance value: [3 lx] | threshold value: [300 lx].
23:09:40.172 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance value [3 lx] is less than threshold: [300 lx]
23:10:40.139 [INFO ] [hab.automation.script.file.xxxtest.js] - 4.5.1
23:10:40.141 [INFO ] [hab.automation.script.file.xxxtest.js] - --------------------------------------------------------------------
23:10:40.143 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance state value is: [4 lx]
23:10:40.146 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance value: [4 lx] | threshold value: [300 lx].
23:10:40.147 [INFO ] [hab.automation.script.file.xxxtest.js] - RULE: Master Bathroom Heat Lamp Is On | Luminance value [4 lx] exceeds threshold: [300 lx]

I’m sure its something simple I’m doing wrong but I just can’t work it out. Help is greatly appreciated.

EDIT: Just realised that the error occurs also with a single digit so if the luminanceValue is 4 and the thresholdValue is 300, then I also get “exceeds”.

The issue is based on numeric vs string comparison.

E.g. If 31lx &300lx are treated as a string, than it’s compared character by character.

First char:
3=3
Second char:
1>0, therefore 31lx > 300lx

You need either compare numeric state or you need to get the state as quantity and not as string.
There were some other post about similar issue in the past, maybe have a look for reference

1 Like

Hi Matthias

Thanks for your explanation. My reading of " Units of Measurement / Quantity Handling" at the link below led me to believe I was working with two quantity items but I have obviously misunderstood:

The updated rule below uses the methods .lessThan and .greaterThan and this now seems to be working. Maybe my use of the > < operators wasn’t correct :thinking:

		var reportedLuminance = items.getItem("Sensor2_luminance").quantityState;
		var thresholdLuminance = Quantity('300 lx');

		if (reportedLuminance.lessThan(thresholdLuminance)) {
			console.log (`RULE: Master Bathroom Heat Lamp Is On | Luminance value [${reportedLuminance}] is less than threshold: [${thresholdLuminance}]`);
		}
		else if (reportedLuminance.greaterThanOrEqual(thresholdLuminance)) {
			console.log (`RULE: Master Bathroom Heat Lamp Is On | Luminance value [${reportedLuminance}] exceeds threshold: [${thresholdLuminance}]`);
			//
		}

Thanks again for your help.

1 Like