Building a string dependent of some conditions

Maybe someone can give me a hint with building a string. I think my programming skills are quite rudimentary, so the code is possibly quite bad programmed. :relaxed:
My intention with that piece of code is to build a string, which I can send to my Echo if I am reentering the house after a while. So i am calling the following script and know what has happend while not beeing at home.

var String string1=""
var String string2=""
var String string3=""
var String string4=""
var String erinnerung=""
var Number anz=0

if (WaschmaschineLeeren.state==ON){string1="Waschmaschine";anz=anz+1}
if (SpuehlmaschineLeeren.state==ON){string2="Spuehlmaschine";anz=anz+1}
if (TrocknerLeeren.state==ON){string3="Trockner";anz=anz+1}

if (BriefkastenLeeren.state==ON){string4="Post"}  

switch (anz) 
{
    case 1:
    {
        if(TrocknerLeeren.state==ON){
        erinnerung="Der Trockner kann ausgeleert werden"
        }
        if(SpuehlmaschineLeeren.state==ON||WaschmaschineLeeren.state==ON){
        erinnerung="Die"+string1+string2+"kann ausgeleert werden"
        }
    }
    case 2:
    {
        if(SpuehlmaschineLeeren.state==ON && WaschmaschineLeeren.state==ON){
        erinnerung="Die"+string1+" und die"+string2+"kann ausgeleert werden"
        }
        if(TrocknerLeeren.state==ON){
        erinnerung="Der Trockner und die"+string1+string2+"kann geleert werden"
        }
    }
    case 3:
    {
    erinnerung="Die"+string1+" und die"+string2+"und der"+string3+"kann ausgeleert werden"
    }
}
if (BriefkastenLeeren.state==ON&&anz>0){erinnerung=erinnerung+"Außerdem war die Post da"}
if (BriefkastenLeeren.state==ON&&anz==0){erinnerung=erinnerung+"Die Post war da"}


if(erinnerung!==""){Echo_Wohnzimmer_Text.sendCommand("Hallo"+erinnerung)}
else{Echo_Wohnzimmer_Text.sendCommand("Hi wie gehts")}

But it’s actually not working like I would expect. The string erinnerung is empty regardless an item like SpuehlmaschineLeeren is set to ON. So the script is always left with “Hallo” :roll_eyes:

You have to build a rule with a trigger https://www.openhab.org/docs/configuration/rules-dsl.html#defining-rules

I don’t know what yur error was but Xtend doesn’t accept ;
I tidied up so that your code is reading easier
Not the most efficient was to do what you want but it should work
I also note that you don’t use string4 further down in the code

var String string1 = ""
var String string2 = ""
var String string3 = ""
var String string4 = ""
var String erinnerung = ""
var Number anz = 0

if (WaschmaschineLeeren.state == ON) {
    string1 = "Waschmaschine"
    anz = anz + 1
}
if (SpuehlmaschineLeeren.state == ON) {
    string2="Spuehlmaschine"
    anz = anz + 1
}
if (TrocknerLeeren.state == ON) {
    string3="Trockner"
    anz = anz + 1
}

if (BriefkastenLeeren.state == ON) string4 = "Post"

switch (anz) {
    case 1 : {
        if (TrocknerLeeren.state==ON) {
            erinnerung = "Der Trockner kann ausgeleert werden"
        }
        if (SpuehlmaschineLeeren.state == ON || WaschmaschineLeeren.state == ON) {
            erinnerung = "Die" + string1 + string2 + "kann ausgeleert werden"
        }
    }
    case 2 : {
        if (SpuehlmaschineLeeren.state==ON && WaschmaschineLeeren.state==ON) {
            erinnerung = "Die" + string1+ " und die" + string2 + "kann ausgeleert werden"
        }
        if (TrocknerLeeren.state == ON) {
            erinnerung = "Der Trockner und die" + string1 + string2 + "kann geleert werden"
        }
    }
    case 3 : {
        erinnerung = "Die" + string1 + " und die" + string2 + "und der" + string3 + "kann ausgeleert werden"
    }
}

if (BriefkastenLeeren.state == ON && anz > 0 ) {
    erinnerung = erinnerung + "Außerdem war die Post da"
}
if (BriefkastenLeeren.state == ON && anz == 0){
    erinnerung = erinnerung + "Die Post war da"
}

if( erinnerung != "") {
    Echo_Wohnzimmer_Text.sendCommand("Hallo" + erinnerung)
} else {
    Echo_Wohnzimmer_Text.sendCommand("Hi wie gehts")
}

Actually it will. And in one case (return;) it is required. But I think it is ignored in all other cases. I think if (WaschmaschineLeeren.state==ON){string1="Waschmaschine";anz=anz+1} is valid. I don’t have easy access to VSCode to double check though so I could be wrong.

I knew about the return; special case
There are a few examples with ; in Xtend but they all seem to be one liners between {}
So I didn’t think that ; would be valid in this case.
I’ll check in an hour

Unless I’m missing a line, that is how OP is using them here as well.

No I mean {blah blah blah;}

@hr3 : This is a script. So this script is called by a rule. There will never be trigger in a script file. In my view it’s more like a function.

But isn’t there an actuall issue with using a Number variable in the Switch-Case construct? I just found a thread where you (@rlkoshak) wrote the following:

…switch statement does not work with primitives (i.e. int, long, short, float, double). …

Maybe I am completely wrong, but I changed all the cases to if and it works now.

By the way {string1=“Waschmaschine”;anz=anz+1} didn’t lead into a error in VSCode.

How would you programm an efficient solution for that kind of functionallity?

Number is not a primitive. It’s an Object and can be used in Switch statements as far as I know. You can always fake it and use the String:

switch(anz.toString) {
    case "1": ...

To be specific, unless you go out of your way to tell it to use a primitive, all numbers used in the Rules DSL will be of type BigDecimal which is itself of type Number.

It is a little hard to tell due to the language differences but it looks like you are constructing a String message based on the ON/OFF state of three Items.

I would, and have, handled this using a StringBuilder and building the message in such a way that it makes sense with the least amount of modifications. For example, here is the code I send to myself at 08:00 every morning to tell me what of my sensors/services are offline:

rule "Reminder at 08:00 and system start"
when
	Time cron "0 0 8 * * ? *" or
	System started
then
  val numNull = gSensorStatus.members.filter[ sensor | sensor.state == NULL ].size
  if( numNull > 0) logWarn("admin", "There are " + numNull + " sensors in an unknown state")

  val offline = gSensorStatus.members.filter[ sensor | sensor.state == OFF ]
  if(offline.size == 0) return;

  val message = new StringBuilder 
  message.append("The following sensors are known to be offline: ")
  offline.forEach[ sensor |
    var name = transform("MAP", "admin.map", sensor.name)
    if(name == "") name = sensor.name
    message.append(name)
    message.append(", ")
    gOfflineAlerted.members.filter[ a | a.name==sensor.name+"_Alerted" ].head.postUpdate(ON)
  ]
  message.delete(message.length-2, message.length) // delete the last ", "

  aInfo.sendCommand(message.toString)
end 
1 Like

Thanks very much. The Stringbuilder is a very nice thing, which I didn’t try before. There’s no need for all the string variables any more. I’ll try to use it in my scripts, so that I can reduce the lines of code.