Help with status update rule

Hi everyone i have been working on a status pannel for my setup its not going too plan what im trying too do is when a switch item changes to on it sends a text update to a string item

but some switch items are more important than others like test mode and it needs to be displayed if this is on no matter what else is on

some of my buttons work as expected and others not at all i have been trying to do this for days and input would be appretiated please ask if more info is needed

sample image of my setup

The Rule i have created so far

rule "System Status"
when
    Item Away_from_home changed or
    Item In_Bed changed or
    Item Kids_Holiday_Mode_SCHOOL_HOLIDAY changed or
    Item Weekend changed or
    Item Test_Mode changed or
    Item Movie_Mode_Enabled changed or
    Item Disable_Amp_Rule changed or
    Item Trigger_PowerOffLR changed or
    Item Trigger_Tylers_TV changed 
then
    if( Away_from_home.state == OFF && 
    In_Bed.state == OFF &&
    Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == OFF &&
    Weekend.state == OFF &&
    Test_Mode.state == OFF &&
    Movie_Mode_Enabled.state == OFF &&
    Disable_Amp_Rule.state == OFF &&
    Trigger_Tylers_TV.state == OFF &&
    Trigger_PowerOffLR.state == OFF ) {
            System_Status.sendCommand ("NORMAL") 
    }
    if( Test_Mode.state == ON && //ITEM CHANGED TO DISPLAY
    In_Bed.state == ON || // IF ANY OF THESE ARE ON SET TO ON AT THE SAME TIME DISPALY TO TEST MODE AS THESE ITEMS ARE LESS IMORTANT
    Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON ||
    Weekend.state == ON ||
    Away_from_home.state == ON ||
    Movie_Mode_Enabled.state == ON ||
    Disable_Amp_Rule.state == ON ||
    Trigger_Tylers_TV.state == ON ||
    Trigger_PowerOffLR.state == ON ) {
            System_Status.sendCommand ("TEST MODE") 
    }
    if( Away_from_home.state == ON  ) { // ITEM CHANGED TO DISPLAY
        if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON || Weekend.state == ON ) { //IF ANY OF THESE ARE ON SET TO ON AT THE SAME TIME DISPALY TO TEST MODE AS THESE ITEMS ARE LESS IMORTANT
            System_Status.sendCommand ("AWAY FROM HOME")                            //
        }                                                                           // SAME THEORY FOR ALL RULES BELOW
    }
    if( In_Bed.state == ON ) {
        if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON || Weekend.state == ON ) {
            System_Status.sendCommand ("BEDTIME")
        }
    }
    if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON && Weekend.state == ON) {
        System_Status.sendCommand ("SCHOOL HOLIDAY")
    }
    if( Weekend.state == ON ) {
        System_Status.sendCommand ("WEEKEND")
    }
    if( Movie_Mode_Enabled.state == ON ) {
        System_Status.sendCommand ("MOVIE MODE")
        if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON || Weekend.state == ON || Disable_Amp_Rule.state == ON ) {
            System_Status.sendCommand ("MOVIE MODE")
        }
    }
    if( Disable_Amp_Rule.state == ON ) {
        System_Status.sendCommand ("AMP RULE DISABLED")
        if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON || Weekend.state == ON  ) {
            System_Status.sendCommand ("AMP RULE DISABLED")
        }
    }
    if( Trigger_Tylers_TV.state == ON ) {
        System_Status.sendCommand ("KIDS SLEEP")
        if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON || Weekend.state == ON || Movie_Mode_Enabled.state == ON || Disable_Amp_Rule.state == ON ) {
            System_Status.sendCommand ("KIDS SLEEP")
        }
    }
    if( Trigger_PowerOffLR.state == ON ) {
        System_Status.sendCommand ("LR POWER OFF")
        if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON || Weekend.state == ON ) {
            System_Status.sendCommand ("LR POWER OFF")
        }
    }    
end

Thanks for any advice

eg:

Test mode ON shows as normal mode

Weekend ON Shows weekend like it should turning on moviemode shows moviemode like it should because its more important than weekend but once you enable disable amp rule it shows amp disbled when it should say movie mode as movie mode is more important

if( Test_Mode.state == ON && //ITEM CHANGED TO DISPLAY
    (In_Bed.state == ON || // IF ANY OF THESE ARE ON SET TO ON AT THE SAME TIME DISPALY TO TEST MODE AS THESE ITEMS ARE LESS IMORTANT
    Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON ||
    Weekend.state == ON ||
    Away_from_home.state == ON ||
    Movie_Mode_Enabled.state == ON ||
    Disable_Amp_Rule.state == ON ||
    Trigger_Tylers_TV.state == ON ||
    Trigger_PowerOffLR.state == ON )) {
            System_Status.sendCommand ("TEST MODE") 
    }

Put all the ORs in () as one boolean

But really you should look at this:

2 Likes

Thanks for the reply I have looked through the design patterns quite a few times now and before but this is the only approach to doing this that I can understand at the moment as my coding knowledge is very basic (although it’s improved drastically since I started this in Dec and didn’t know a single line of code)

I will edit the rule as you suggested without using the design pattern at the moment is that all y I u can see that’s wrong with it as you stated

I do edit all my rules as my knowledge advances one I understand more of the coding aspect I will be using the design patterns to cleanup and shorten my rules at a later date

I have got a huge list of things I still need to do alot of its beyond my ability atm

You seem to be on the right track!

For java operators precedence see:
https://introcs.cs.princeton.edu/java/11precedence/

In your case, the && in your condition was get evaluated first between the two members and then all the ||. So you need to put all the || between () to get evaluated as one boolean and then the && will be evaluated.

Keep your list but don’t bite more than you can chew. If you feel that you can’t tackle a particular project then you are probably right. Try to break it down it small parts and then tackle these one by one. Best way to learn is by doing it yourself.

Good luck, enjoy and break things. The best fun is fixing them!!

1 Like

I couldent agree more Openhab is extremely complicated, fun, rewarding project/hobby I have ever started its just helpful to have some input sometimes I can see me working on this for the rest of my life and I’m only 26 lol :wink:

I bet nearly everyone here has a list of things they want too add too openhab

I think I understand what you mean it was only comparing the values of the first two items I will try to fix that and post an update

I will be keeping the list i always reorder it into current next and future jobs I change them according to my skill level if I have learned something new that helps with a task I move it up the list complete it and mark it off

I fixed it for you in one of my previous posts. All you have to do is put all the || conditions in one ()

Isn’t that the same as:

if( Test_Mode.state == ON) {
System_Status.sendCommand ("TEST MODE")
}

Since you don’t care if any other Mode is On.

Yes but then it gets changed by anything else that changes while test mode is on

Eg If testmode was on and weekend changed too on it would now say weekend not testmode

The problem is stopping the text pannel from changing if an item changes when certain modes are on

@opus
Not quite, if they are all OFF (unlikely but you never know) then the if statement will return false. So the conditional check is probably not the right one

However, you are right. If Test_Mode is ON then @Sharpy it doesn’t matter what the other states are, doesn’t it?

Correct,I didn’t want to rewrite your whole rule.
You need to “leave” the rule after an If-statement went into the TRUE branch instead of doing all checks one after the other.
There are several ways to kill that cat, nested if Statements or select case Statements.

@opus
Sorry I didn’t thank you for replying I will add it here now thanks for the response

I’m not sure what you mean could you explain more or post me an example I do not know how to stop a rule from checking more or how to kill a cat lol

I don’t blame you for not wanting to rewrite my rule its long and I’m sick of doing it myself too this is like the 5th time already

What are nested if statements?
is that a if with a if inside I already do that in alot of my rules

What are statement clause cases?

How do you leave a rule?

To kill a cat is easy.
Writing rules for OH is more like skinning a cat!!

Ok, let’s simplify things one by one

Put all these items is a group:

    Item Away_from_home changed or
    Item In_Bed changed or
    Item Kids_Holiday_Mode_SCHOOL_HOLIDAY changed or
    Item Weekend changed or
    Item Test_Mode changed or
    Item Movie_Mode_Enabled changed or
    Item Disable_Amp_Rule changed or
    Item Trigger_PowerOffLR changed or
    Item Trigger_Tylers_TV changed 
Group:Switch:OR(ON,OFF) gStatus

First part of your rule becomes:

rule "System Status"   
when
    Member of gStatus changed
then
    if(gStatus.state == OFF) {
        System_Status.sendCommand ("NORMAL") 
        return;
    }

    if(Test_Mode.state == ON  {
        System_Status.sendCommand ("TEST MODE")
        return;
    }

    if( Away_from_home.state == ON  ) { // ITEM CHANGED TO DISPLAY
        if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON || Weekend.state == ON ) { //IF ANY OF THESE ARE ON SET TO ON AT THE SAME TIME DISPALY TO TEST MODE AS THESE ITEMS ARE LESS IMORTANT
            System_Status.sendCommand ("AWAY FROM HOME")                            //
        }                                                                           // SAME THEORY FOR ALL RULES BELOW
    }
...
1 Like

What exactly does that do end the rule at that point? Or move to the next if statement?

It ends the rule at that point. The ; is important!

1 Like

You didn’t put a return at the bottom of this was that by mistake

No, leave this as it is. We are going to simplify the rule bit by bit. I haven’t touched the special cases yet.

2 Likes

I suppose this needs to be at the top of the rule so it gets checked first and ends the rule before it gets to anything else then it wouldent matter what turned on while testmode was on because the return in the rule would end the rule before it got too check stuff like weekend and everything else

What would you do for the rest of the items in the rule write them how I wrote them in the first post?

I am working on the rest of your rule BUT

for example:

    if( Trigger_Tylers_TV.state == ON ) {
        System_Status.sendCommand ("KIDS SLEEP")
        if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON || Weekend.state == ON || Movie_Mode_Enabled.state == ON || Disable_Amp_Rule.state == ON ) {
            System_Status.sendCommand ("KIDS SLEEP")
        }
    }

What are you trying to achieve there?
You send the command first and then check something and send the same command anyway. Do you need that check?

It was just an attempt too make it work its supposed to be the same as all the others

Trigger tylers tv is more important than holiday mode, weekend…

if( Trigger_Tylers_TV.state == ON ) {
        if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON || Weekend.state == ON || Movie_Mode_Enabled.state == ON || Disable_Amp_Rule.state == ON ) {
            System_Status.sendCommand ("KIDS SLEEP")
        }
    }

rule "System Status"   
when
    Member of gStatus changed
then
    if(gStatus.state == OFF) {
        System_Status.sendCommand ("NORMAL") 
        return;
    }

    if(Test_Mode.state == ON  {
        System_Status.sendCommand ("TEST MODE")
        return;
    }

    var String statusCommand = ""
 
    if( Away_from_home.state == ON  ) {
        statusCommand = "AWAY FROM HOME"
    }

    if( In_Bed.state == ON ) {
        statusCommand = "BEDTIME"
    }

    if( Kids_Holiday_Mode_SCHOOL_HOLIDAY.state == ON && Weekend.state == ON) {
        statusCommand = "SCHOOL HOLIDAY"
    }

    if( Weekend.state == ON ) {
        statusCommand = "WEEKEND"
    }

    if( Movie_Mode_Enabled.state == ON ) {
        statusCommand = "MOVIE MODE"
        }
    }

    if( Disable_Amp_Rule.state == ON ) {
        statusCommand = "AMP RULE DISABLED"
        }
    }

    if( Trigger_Tylers_TV.state == ON ) {
        statusCommand = "KIDS SLEEP"
        }
    }

    if( Trigger_PowerOffLR.state == ON ) {
        statusCommand = "LR POWER OFF"
        }
    }
    System_Status.sendCommand(statusCommand)
end