[SOLVED] Create a variable inside of a conditional statement

Hi, I am trying to create a DP to define schedules, day activities, etc…For the purposes of keeping it simple, consider the following rule which takes the Season string (from the Astro Binding) and if the condition is true, then it assigns a value with a timestamp of 6:00am (of the current day):

rule "test" 
when
    Time cron "0 0/1 * 1/1 * ? *"
then
    var rule_name = "DayState"
    if( Season.state=="AUTUMN" ) { 
        logInfo(rule_name,"Logical Conditon Works!") 
    }
    val test_1 = new DateTime(now.withTimeAtStartOfDay.plusHours(6))
    logInfo(rule_name,"test_1 value is: " + test_1 )
end

As one will expect, it yields:

19:51:00.048 [INFO ] [lipse.smarthome.model.script.DayState] - Logical Conditon Works!                                                                                                           
19:51:00.050 [INFO ] [lipse.smarthome.model.script.DayState] - test_1 value is: 2018-11-25T06:00:00.000-06:00 

So far so good…but, if I add the value assignment inside the logical statement like this:

rule "test" 
when
    Time cron "0 0/1 * 1/1 * ? *"
then
    var rule_name = "DayState"
    if( Season.state=="AUTUMN" ) { 
        logInfo(rule_name,"Logical Conditon Works!") 
        val test_1 = new DateTime(now.withTimeAtStartOfDay.plusHours(6))
    }
    logInfo(rule_name,"test_1 value is: " + test_1 )
end

Then my problem starts… first, upon saving I get:

19:57:10.611 [INFO ] [del.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'test.rules', using it anyway:                                                     
    The value of the local variable test_1 is not used                                                                                                                                               
19:57:10.613 [INFO ] [del.core.internal.ModelRepositoryImpl] - Loading model 'test.rules'   

Then when the rules executes:

19:58:00.064 [INFO ] [lipse.smarthome.model.script.DayState] - Logical Conditon Works!                                                                                                           
19:58:00.065 [ERROR] [untime.internal.engine.ExecuteRuleJob] - Error during the execution of rule 'test': The name 'test_1' cannot be resolved to an item or type; line 10, column 45, length 6 

For the life of me I cannot understand why is not working… I am sure this has been discussed many times in other posts… have tried searching in the forums but have not been able to find a solution. Any help is much appreciated!

Thanks.

The scope of your variable test_1 is only inside the body of your if statement.

So, it’s complaining that you’re

  1. not using the variable test_1 within that scope, and
  2. referencing a variable test_1 that doesn’t exist outside of the body of the if statement.

This would work.

rule "test" 
when
    Time cron "0 0/1 * 1/1 * ? *"
then
    var rule_name = "DayState"
    if( Season.state=="AUTUMN" ) { 
        logInfo(rule_name,"Logical Conditon Works!") 
        val test_1 = new DateTime(now.withTimeAtStartOfDay.plusHours(6))
        logInfo(rule_name,"test_1 value is: " + test_1 )
    }
end

Thanks for the super lighting quick reply and help!, I now fully understand the issue and yes, bringing the loginfo into the IF statement does show the value the properly assigned… phew, this was driving me crazy!

So, expanding my simple example, if I wanted to see and use the values of test_1 outside the conditional statement, how can I accomplish that?

Ultimately, my goal is is assign a different time to “test_1” depending on the season so that I can further define my DayState rules. For example, during the Spring “test_1” will be 8:00am, during the Summer it will be 7:00am, during Attum will be 6:00am and during Winter will be 7:00am. Then from there I can automate things (say turn ON/OFF some lights, open shutters, etc…), I can easily do this with either CASE/SWITCH of a bunch of IF, but first I need the value of “test_1” to persist through the rule… any ideas?

Thanks!

You can do this.

rule "test" 
when
    Time cron "0 0/1 * 1/1 * ? *"
then
    var rule_name = "DayState"
    var DateTime test_1

    if( Season.state == "AUTUMN" ) { 
        logInfo(rule_name,"Logical Conditon Works!") 
        test_1 = new DateTime(now.withTimeAtStartOfDay.plusHours(6))
    }
    else {
        // You need to set test_1 to something here, otherwise 
        // your rule will throw an error on the logInfo statement 
        // when Season.state != "AUTUMN"
    }
    logInfo(rule_name,"test_1 value is: " + test_1 )
end

Or, even better

rule "Test Rule"
when 
    System started
then
    logInfo("test", "TEST: Running at startup")

    var rule_name = "DayState"
    var DateTime test_1

    switch Season.state {
        case "AUTUMN": 
            test_1 = new DateTime(now.withTimeAtStartOfDay.plusHours(6))
        case "SUMMER":
            test_1 = new DateTime(now.withTimeAtStartOfDay.plusHours(7))
        // Add case statements for FALL and WINTER
        default: {
            logInfo(rule_name, "Unknown season: {}", Season.state)
            test_1 = null
        }
    }
    if (test_1 !== null) {
        logInfo(rule_name,"test_1 value is: " + test_1 )
        // Do more stuff
    }

Great! this last one does exactly what I wanted… I could swear i tried using switch/case as one of my first options, but I see your syntax is a bit different (I used {} to contain the code for each case) any how, I will incorporate this into the ever growing DayState rule and define specific important times for each of the seasons. Hopefully I won’t hit any more major roadblocks :slight_smile: