[SOLVED] Some Noobie Syntax Questions

Hi All,

I’ve been experimenting with openHAB 2.4 on Windows 10 for a while now, and am starting to have some success controlling things and running rules. I’m not a programmer so I’ve progressed very slowly mostly by hacking around examples from the forums to do what I want. Simple syntax mistakes frequently get me bogged down for ages though and there seems to be some inconsistency between lots of the examples online.
For instance should I use

myTimer.cancel

or

myTimer.cancel() 

or or doesn’t it matter?
How about

 if(Presence_Status_Away.state == ON){ 

or

if(Presence_Status_Away.state==ON){

My key confusion at the moment though is to do with testing the state of switch items. I have a bunch of items that I set on or off using the Alexa integration which works fine.

Switch Presence_Status_Home "Home" {alexa="Switchable"}
Switch Presence_Status_Out "Out" {alexa="Switchable"}
Switch Presence_Status_Away "Away" {alexa="Switchable"}
Switch Presence_Status_Bedtime "Bedtime" {alexa="Switchable"}

Home, Out, and Away each have a change rule when they’re turned on that turns the others off.

I then have some time triggered rules that try to do some stuff based on the state of the switches:

if(Presence_Status_Bedtime.state. == ON){
         logInfo("PAL", "Night Colour Triggered")	
	HallLight_Color.sendCommand("320,80,40")
}	
else {
	HallLight_Color.sendCommand("320,0,80")
	logInfo("PAL", "Day Colour Triggered")
}		}

This never triggers the night colour, however it will if I do it like this:

if(Presence_Status_Bedtime.state.toString == "ON"){
	logInfo("PAL", "Night Colour Triggered")	
	HallLight_Color.sendCommand("320,80,40")
}
else {
	HallLight_Color.sendCommand("320,0,80")
	logInfo("PAL", "Day Colour Triggered")
}

I thought the native state of a switch is ON or OFF so I don’t understand why I have to do a string comparison to make this work.

Similarly the Philips Hue light sensor supposedly reports a number for light level and illuminance so why doesn’t this work

if(HallLightSensor_Illuminance.state < 60) {
   do stuff
}

Sorry for a really long first post. but any help greatly appreciated.

Hi

I think I’m still in the same boat as you.

I certainly don’t think of myself as doing anything more than dipping my toe in.

But I think I can help a little.

This will probably work for you.

if ( Presence_Status_Away.state === ON ) {

A frequent trap in rules construction is overlooking that commands and states are two very different things, and are asynchronous.

Should you have a rule triggered say from received command , then the state of the Item may not (yet) be what you expect. Indeed, state may well change while your rule is being executed. It follows that doing more or less processing before looking at a state can affect the result in this case, simply because of the delay.

I’m just guessing, without seeing the full rule.

Empty parenthesis are optional in the old rule engine (rules DSL), but will be a good habit to have if you ever plan to move to the new rule engine and scripted automation.

This is the correct format for using a conditional statement to test if a SwitchItem state is ON in the rules DSL. Spaces are irrelevant in the rules DSL, but they improve readability.

The period after state is a typo.

Do you have you Items defined using UoM? If so, you will need to take this into account in your comparison.

if (HallLightSensor_Illuminance.state.intValue() < 60) {

Not at all! Welcome! If you aren’t using VS Code with the OH extension yet, it will help a lot!

The identity operator will not work here. Use it for when you are checking for null (which BTW is different than NULL).

1 Like

It doesn’t matter. In the Rules DSL syntax, if you have a function call that doesn’t take arguments (i.e. has ()) the () are optional.

The white space has no meaning to the language so use spaces in a way that makes it easier to read the code. I prefer the version with spaces.

That’s because you have a stray . after “state”.

This version is correct:

if(Presence_Status_Bedtime.state == ON)

Compared to what you have:

if(Presence_Status_Bedtime.state. == ON)

Numbers are a challenge in Rules DSL. Without going too deep into things, when doing math or comparisons, you need to tell the Rules DSL that the Item’s state is a Number.

if((HallLightSensor_Illuminance.state as Number) < 60) {

It becomes event more complicated if HallLightSensor_Illuminance is more than just a Number, e.g. Number:Illuminance. In that case for comparisons you need to tell what units you are using.

if(HallLightSensor_Illuminance.state < 60|lux){

That would not be an appropriate use of the ===, though I think it will work. Typically though you only want to use === or !== when you literally have null on either side. In all other cases you want to use == and !=.

See Trrying to turn a device off after a certain amount of time - #6 by rlkoshak for a post I made where I showed the difference with an example.

I think it is better to convert the constant to a UoM rather than converting the state in a comparison like this. That way the units are right there in your code, you have the option of mixing your units (e.g. the Item may be storing °C but you want to compare it with 60|°F). It isn’t always apparent what units an Item’s state is actually stored in and when you just call intValue you get the default units and you need to figure out what those units are and potentially do the math yourself to convert your constant to the right units, which defeats the purpose of UoM in the first place.

Finally, I’m not sure just calling intValue() will always work. Rules DSL has a lot of problems recognizing Number type States. You may need something along the lines of

if((HallLightSensor_Illuminance.state as QuantityType<Number>).intValue() < 60)
1 Like

Thanks for the replies everyone - a lot of things have been cleared up for me, and I think all my rules are working pretty much as expected now.