[SOLVED] Variables not registered when placed inside if/else

Hey guys, I’m struggling with getting a rule to work. The issue pertains to the ‘heating_time’ value, which is not being picked up below the ‘if/else’ part. The ‘logError’ part is executed just fine. If I place heating_time outside if/else, the script works as well…

My script:

rule "setpoint changed"
	when
		Item thermostat_setpoint changed
	then
		var setpoint 			= thermostat_setpoint.state as Number
		var current_temp		= tempsensor_01_temperature.state as Number
		var delta_temp 		= setpoint - current_temp
		var current_time		= now.millis as Number
		var time_on			= thermostat_time_on.state as Number
		var time_off			= thermostat_time_off.state as Number

		var delta_time_off		= ( current_time - (time_off) ) / 1000 / 60

		if(delta_time_off > 30){
			logError("TEST", "greater than 30")
			var heating_time = delta_temp / 0.086
		}else{
			logError("TEST", "smaller than 30")
			var heating_time = delta_temp / 0.129
		}

		if(setpoint >= current_temp){
			if(thermostat_state.state == OFF){
				thermostat_state.sendCommand(ON)
				thermostat_heating_time.sendCommand(heating_time)
				thermostat_time_on.sendCommand(current_time)
				thermostat_time_off.postUpdate(delta_time_off)
				thermostat_timer.sendCommand(ON)
			}else{
				thermostat_heating_time.sendCommand(heating_time)
				thermostat_timer.sendCommand(ON)
			}
		}else{
			thermostat_state.sendCommand(OFF)
			thermostat_heating_time.sendCommand(0)
			thermostat_time_on.sendCommand(0)
			thermostat_time_off.sendCommand(current_time)
			thermostat_timer.sendCommand(OFF)
		}

end

The ‘ERROR’

Blockquote
2020-01-04 14:02:45.121 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model ‘thermostaat.rules’, using it anyway:
The value of the local variable time_on is not used
The value of the local variable heating_time is not used
The value of the local variable heating_time is not used

Proof that stuff inside the if/else are being executed;

Blockquote
==> /var/log/openhab2/openhab.log <==
2020-01-04 14:03:09.607 [ERROR] [.eclipse.smarthome.model.script.TEST] - greater than 30

That looks to be a variable scoping issue.
I think most people define their variables globally first so they are available where needed.

If I’m not mistaken a variable declared within an if-clause (or better within “{…}”) do not exist outside the clause.
Declare the variable at the beginning and just assign new values for it in the if-clauses.

3 Likes

As Bruce mentions, this is a scoping issue. heating_time does not exist outside of the if or else statements. Declare a reference variable first (build the box/memory address) and then assign it (store something in the box/memory address) in the if or else statements.

    var heating_time
    if (delta_time_off > 30) {
        heating_time = delta_temp / 0.086
    } else {
        heating_time = delta_temp / 0.129
    }

https://www.eclipse.org/xtend/documentation/203_xtend_expressions.html#variable-declaration

1 Like

As @Bruce_Osborne, @opus and @5iver said, you have a scope issue. But I would say, perhaps also a DSL parser/runtime mismatch issue. The declaration of heating_time in the if or else scope is only considered valid within that block of code (between {}) by the rule parser. It is declared but not referenced.
However, somehow the DSL ‘runtime’ keeps that variable around because it looks like you can still reference it later with thermostat_heating_time.sendCommand(heating_time). Or is there another error in the logs?

This is just to tell you that you declared a variable at the beginning of the rule that is not used elsewhere in the rule.

You have two options:

  1. Ignore the log messages.
  2. Move the variables to the outerscope (preferred, as already mentioned).

Do that then. Declaring a variable should be done within the scope of the use of that variable.

1 Like

So a scoping issue it is; I’ve moved the variable and the script now works. Thanks everyone!