Rule not giving the expected outcome

Hello All,

I’m trying to create a rule that allows me to use the value of my lux sensor to switch on lights at a certain brightness. Presently I have a load of “IF” statements, but it not only looks messy to me. It doesn’t really flow as I’d like it. So in my attempt to rewrite the rule, I’ve tried the approach below. This hasn’t worked and I’m sure those who know the rules language will be able to explain why that is.

No matter what value of Master_ST815_Lux, the output is always 1, unless of course the lux level is about the threshold of 250

So I’m looking for help and advise as to whether its possible to make this work with a few tweaks or I just need to stick with my existing rule.

rule "Update Light Level Status"
when
    Item Master_ST815_Lux changed
then
val Number vLux_Status = 0
switch Master_ST815_Lux.state {
    case Master_ST815_Lux.state < 250: vLux_Status = 1
    case Master_ST815_Lux.state < 225: vLux_Status = 2
    case Master_ST815_Lux.state < 200: vLux_Status = 3
    case Master_ST815_Lux.state < 175: vLux_Status = 4
    case Master_ST815_Lux.state < 150: vLux_Status = 5
    case Master_ST815_Lux.state < 100: vLux_Status = 6
}
logInfo(filename, "TESTING: Lux Status {}", vLux_Status)
end

What is logged when you device reports a change in lux and is it a QuantityType? If so, you will need to take that into account in your rule.

BTW, it looks like you could also use a Scale tranform for this.

The problen is the order of case statements, if the lux value is less then 250 the first case is true and no other case is checked. If you start with the lowest value it should work.

1 Like

The device reports a Number from 0 to 3000. I’ve taken a look at the link and not sure how I’d use that within my rule.

It would replace your rule, but Jürgen has your solution.

1 Like

I’ll give this a go and see what results I get. It’s dark here now so will have to wait until tomorrow to see.

Jurgen is absolutely correct
the case statement evaluates in the order it is written in the rule
here is another example. This rule sets an item to the time of day (a string which other rules use to make decisions) It runs on system start or every hour. (using a cron statement) Notice “Night” has two entries, one for midnight until 6AM, the other for 11PM until midnight. Without both if statements, in the correct order, night never triggered at 11PM

rule "SetTimeofDayMode"
when
    System started or
    Time cron "0 0 * ? * * *"
then
    if (now.getHourOfDay() >= 00 && now.getHourOfDay() < 06) {
        TimeOfDayMode.postUpdate("Night")
    }
    if (now.getHourOfDay() >= 06 && now.getHourOfDay() < 09) {
        TimeOfDayMode.postUpdate("Morning")
    }
    if (now.getHourOfDay() >= 09 && now.getHourOfDay() < 16) {
        TimeOfDayMode.postUpdate("Daytime")
    }
    if (now.getHourOfDay() >= 16 && now.getHourOfDay() < 23) {
        TimeOfDayMode.postUpdate("Evening")
    }
    if (now.getHourOfDay() >= 23 && now.getHourOfDay() < 24) {
        TimeOfDayMode.postUpdate("Night")
    }
end

WARNING
I’m pretty sure this will not work in OpenHAB3
I think

now.getHourOfDay()

would need to be changed to

now.getHour()

@Andrew_Rowe, since your if statements are mutually exclusive (only one can be true), you should use else if, so the rule stops running after the first true statement is found. It’s not that your rule won’t work, but it is not best practice to be wasteful of CPU cycles.

1 Like

@5iver, I didn’t realize you could use Scale transform in a profile. Makes a lot of sense for any case where one item directly informs another item’s state, but I suppose a rule is better if you might want to add conditional logic to determine if the rule should run (e.g. “only at night”).

1 Like