Use String variable in if statement to change Item state

  • Platform information:
    • OS: Raspbian GNU/Linux 10 buster on Pi 3
  • openHAB version: 2.5.12

Hey Guys! Im kind of a newbie in OpenHAB, but i was wondering if someone here could answer my “short” question.:

First off here is the code, which is written into my .rules File:

var Number DebugCounter
val String CurrentBulbVar = "NULL"


rule "Bulbs Control"
when
    Item BulbCounterID changed
then
    if (BulbCounterID.state == 1) { CurrentBulbVar = "Bedroom_Light.sendCommand" }
    else if (BulbCounterID.state == 2) { CurrentBulbVar = "LivingRoom_Light.sendCommand" }
    else if (BulbCounterID.state == 3) { CurrentBulbVar = "HueAmbianceLamp1Brightness.sendCommand" }
    else if (BulbCounterID.state == 4) { CurrentBulbVar = "HueAmbianceLamp2Brightness.sendCommand" }
    else if (BulbCounterID.state == 5) { CurrentBulbVar = "HueAmbianceLamp3Brightness.sendCommand" }

    logWarn("DebugCurrentBulb", "Current Bulb Var has changed to " + CurrentBulbVar)
end

rule "Control Bulbs"
when
    Item BulbConfirmerID changed
then
    if (BulbConfirmerID.state == ON) { CurrentBulbVar (ON) }
    else if (BulbConfirmerID.state == OFF) { CurrentBulbVar (OFF) }
end

here are the .items files:
(Virtual Items)

Group     BulbStatusGrp      "BulbStatusGrp"

Number    BulbCounterID      "BulbCounter"      (BulnStatusGrp)
Switch    BulbConfirmerID    "BulbConfirmer"    (BulnStatusGrp)
Switch    DummySwitchID      "DummySwitch"      (BulbStatusGrp)
Switch    DummySwitch2ID     "DummySwitch2"     (BulbStatusGrp)

(Tradfri Hardware)

Group                       Home                                "Home"                       <house>

Group                       Bedroom                             "Schlafzimmer"               <bedroom>    (Home)
Group                       LivingRoom                          "Wohnzimmer"                 <sofa>       (Home)

Switch                      Bedroom_Light                       "Licht"                      <light>      (Bedroom, gLight)       {channel="tradfri:0220:gw4491603032fb:65537:brightness"}
Dimmer                      Bedroom_Light_Brightness            "Schlafzimmer Helligkeit"    <light>      (Bedroom, gLight)       {channel="tradfri:0220:gw4491603032fb:65537:brightness"}
Dimmer                      Bedroom_Light_ColorTemp             "Schlafzimmer Farb Temp"     <sun>        (Bedroom, gLight)       {channel="tradfri:0220:gw4491603032fb:65537:color_temperature"}
Number                      Bedroom_RemoteCtrl_BatteryStatus    "Batterie Status"            <battery>    (Bedroom)               {channel="tradfri:0830:gw4491603032fb:65539:battery_level"}
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
Switch                      LivingRoom_Light                    "Licht"                      <light>      (LivingRoom, gLight)    {channel="tradfri:0220:gw4491603032fb:65541:brightness"}
Dimmer                      LivingRoom_Light_Brightness         "Wohnzimmer Helligkeit"      <light>      (LivingRoom, gLight)    {channel="tradfri:0220:gw4491603032fb:65541:brightness"}
Dimmer                      LivingRoom_Light_ColorTemp          "Wohnzimmer Farb Temp"       <sun>        (LivingRoom, gLight)    {channel="tradfri:0220:gw4491603032fb:65541:color_temperature"}

/*Dummy Switch for rules*/
Switch                      AlleLichter                         "Alle Lichter"

So what Im trying to achieve is the switching between 5 different bulbs, therefore I have made the Virtual Items, “BulbCounterID” for example is used to define which Bulb should be controlled, at the moment I have set up the Switches in Basic UI:


I can switch between the Bulbs with the two arrows (up and down). You can ignore the “Dim Up” and “Dim Down” switches for now. My Problem is, that I would like to enable the currently selected Bulb with the “Bulb Confirmer” Switch. More precise: I want to know why the command:

if (BulbConfirmerID.state == ON) { CurrentBulbVar (ON) }

doesn’t work. Everything works if I just put the Item ID and .sendCommand instead of “CurrentBulbVar”, but if I do that I lose the ability to switch between the bulbs and control them, does anyone have an Idea?

This isn’t DSL syntax. What is CurrentBulbVar, it’s a string type variable right? It’s just a string, you cannot execute it.

What’s your objective here, to access an Item when you have its name in a string variable?

There might be shortcuts to what you are about, by carefulchoice of Item names

1 Like

Yeah I would like to just put the ID of the current Item into the string variable, which I planned to insert into the command, if the BulbCounterID Item would’ve been 1 for example the string would be “Bedroom_Light.sendCommand”. I thought I could just put the variable inside my if statement and instead of the Variable name it would execute the command like this:

Bedroom_Light.sendCommand (ON)

Okay, from the first link you should be able to get hold of an Item by its string name, then do what you like with it.

1 Like

okay Thanks very much,I’ll try it!

This might most easily be accomplished with a switch statement. A switch statement will let you choose between multiple different values of an expression (in this case your BulbCounterID.state). This should let you reduce this down to one simple rule. You don’t even need the CurrentBulbVar global or the Bulbs Control rule. Something like this:

rule "Control Bulbs"
when
    Item BulbConfirmerID changed
then
    switch BulbCounterID.state
        {
        case 1: { Bedroom_Light.sendCommand(BulbConfirmerID.state) }
        case 2: { LivingRoom_Light.sendCommand(BulbConfirmerID.state) }
        etc...
        }
end
1 Like

Hey! Thanks for the Idea!
Unfortunately that doesn’t work, I’ve tried with your code (except for the “etc…” obviuosly), that didn’t work either :frowning:

rule "Control Bulbs"
when
    Item BulbConfirmerID changed or Item BulbCounterID changed
then
    switch BulbCounterID.state
        {
        case 1: { Bedroom_Light.sendCommand(BulbConfirmerID.state) }
        case 2: { LivingRoom_Light.sendCommand(BulbConfirmerID.state) }
        case 3: { HueAmbianceLamp1Brightness.sendCommand(BulbConfirmerID.state) }
        case 4: { HueAmbianceLamp2Brightness.sendCommand(BulbConfirmerID.state) }
        case 5: { HueAmbianceLamp3Brightness.sendCommand(BulbConfirmerID.state) }
        }
end

If I take a look at the openhab log I get the following error when I try to turn on the “BulbConfirmerID” Switch:


05:48:23.728 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule 'Control Bulbs': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(org.eclipse.smarthome.core.items.Item,java.lang.String) on instance: null

May I have to import something?

You cannot always command Items with state objects.
You can get over that by commanding with string, and let the framework parse it into whatever type it needs.

val x = someItem.state.toString

other item.sendCommand(x)
1 Like

Sorry, typing quickly this morning. I forgot to stringify the item states. The error tells you that the sendCommand function expects a val of string type and item.state gives you a state type. Add .toString() to the end of each BulbConfirmerID.stateBulbConfirmerID.state.toString().

1 Like

Unfortunately

And

Don’t work, there are no error messages anymore, but the Bulbs still don’t receive a command. If you are wondering if the Bulbs are even online and controlable: yes they are, I can switch them on and off in PaperUI and BasicUI.

Show us the full rule now please. Don’t to-string your switch-case.

1 Like

Here you go:

var Number DebugCounter
var Number Helligkeit1
var Number Helligkeit2
var Number Helligkeit3
var Number Helligkeit4
var Number Helligkeit5
//var String CurrentBulbVar = "NULL"

rule "DebugLog"
when
    Item BulbCounterID changed
then
    DebugCounter = BulbCounterID.state.toString
    logWarn("DebugCounter", "BulbCounter changed to " + DebugCounter)
end



/*----------Dim Bulbs----------*/
/* You can ignore this Part
rule "DimBulbsUp"
when
    Item DummySwitchID changed to ON or Item DimmschalterDimmerSwitch changed to 2001.0
then
    Bedroom_Light_Brightness.sendCommand(5)
    Helligkeit1 = Bedroom_Light_Brightness.state as Number
    while (Helligkeit1 < 100 && DummySwitchID.state == ON) {
    Helligkeit1 = Helligkeit1 + 5
    Bedroom_Light_Brightness.sendCommand(Helligkeit1)
    Thread::sleep(700)
    if (Helligkeit1 < 5) { DummySwitchID.sendCommand(OFF) }
    }

end

rule "DimBulbsDown"
when
    Item DummySwitch2ID changed to ON
then
    Helligkeit1 = Bedroom_Light_Brightness.state as Number
    while (Helligkeit1 > 5 && DummySwitch2ID.state == ON) {
    Helligkeit1 = Helligkeit1 - 5
    Bedroom_Light_Brightness.sendCommand(Helligkeit1)
    Thread::sleep(700)
    }
end
/*----------Dim Bulbs----------*/


/*TEST AREA*/

rule "Event Trigger Debug"
when
   Channel "hue:0820:2ceacbcb:dimmer_switch_event" triggered
then
    logWarn("DimmerTest", "Dimmer switch event was triggered ", dimmer_switch_event.state.toString)
end

rule "Control Bulbs"
when
    Item BulbConfirmerID changed or Item BulbCounterID changed
then
    switch BulbCounterID.state.toString()
        {
        case 1: { Bedroom_Light.sendCommand(BulbConfirmerID.state.toString()) }
        case 2: { LivingRoom_Light.sendCommand(BulbConfirmerID.state.toString()) }
        case 3: { HueAmbianceLamp1Brightness.sendCommand(BulbConfirmerID.state.toString()) }
        case 4: { HueAmbianceLamp2Brightness.sendCommand(BulbConfirmerID.state.toString()) }
        case 5: { HueAmbianceLamp3Brightness.sendCommand(BulbConfirmerID.state.toString()) }
        }
end

Because for some mysterious reason you chose to change the switch statement which was working to a string as well, you must now change your case statements to strings as well or they won’t match.

1 Like

Okay Thank you very much, it’s working now after I removed “.ToString()” from:

I’ve tried this before, but it didn’t work, I don’t know what I’ve done, but it wasn’t right :sweat_smile: :joy:

Thank you for the help @rossko57 @JustinG, I really appreciate it <3