Determine Object type in a Group (Dimmer or Switch)

I have an automation that toggles the state of a random light in a group. Some are switches and some are dimmers, so depending on type light (dimmer or switch) I would either send ON,OFF, or a number. Actually for the dimmers I just want 0 or 50, and not fully ON.
Currently to determine the type I have the following in my rules:

var randLightStateCurrent = Lights_Random.members.get(randLightIndex).state
if ((randLightStateCurrent == ON) || (randLightStateCurrent == OFF)) //this is a switch
var randLightStateNew = if (randLightStateCurrent == ON) OFF else ON
else //this is a dimmer
var randLightStateNew = if (randLightStateCurrent > 0) 0 else 50

I want to understand if there is a better way to determine the type of object rather than relying on the return values.

Thanks!

The easiest way would be to name you items dependind where it’s a switch or a dimmer, e.g.

Switch XXXXX_Switch
Dimmer XXXXX_Dimmer

And then, in the rule, you can see if the name contains Switch or Dimmer

if(randLightStateCurrent.name.contains("Switch")
............

AFAIR, this should work:

val String type_Of_Item=Lights_Random.members.get(randLightIndex).type
if(type_Of_Item=="Switch")
{
//do something for the switch type
}
else if (type_Of_Item=="Dimmer")
 {
//do something for the dimmer type
}

Thank you! That’s much cleaner.

Although the result is absolutely the one intended, your solution is doubtful in terms of efficiency!
Just my 2 cents!

I didn’t know about .type property.
I learned a new thing and that’s great!

As for efficiency, I’m sorry, but I have to disagree.
Of course, for the problem presented here - determining the type of item inside a rule - your solution is, by far, the most fitted.
From the efficiency point of view, on the long term, I find that properly naming the items would present some advantages.
After all, naming items like Livingroom_Light_Switch or Bedroom_Light_Dimmer makes it easier to use those items in rules, item files and even sitemaps…

But we are off-topic with this…
One more time, thanks for .type :smile:

1 Like

Is there a list of methods such as this one, the .type? This one is useful, but what else is available?

thanks

I agree a naming convention is definitely a must, but adding a duplicate definition string in the name of an object adds an unnecessary (inefficient) layer of description! Just my 2 cents!

From the “more than one way to skin a cat” department:

You can simplify this by using “instanceof”

if (triggeringItem instanceof DimmerType)
//do Dimmer things
else if (triggeringItem instanceof SwitchType)
//do Switchy things
4 Likes

yes, definitely could be!

Bartus has the correct solution. Or at least the most standard solution.

Another thing to keep in mind with naming Items: Design Pattern: Associated Items.

Using VSCode with the openHAB extension type in the name of an Item and wait half a second and a dialog will pop up with all the methods and data. But be aware, not everything you see in the list is intended to be called from the Rules DSL so it may or may not work.

Actually, it would be…

if (triggeringItem instanceof DimmerItem) {
    //do Dimmer things
}
else if (triggeringItem instanceof SwitchItem) {
    //do Switchy things
}

Just be careful using this with groups, as they will be neither, since they are GroupItems. Here is my lambda for setting light levels, where I use GenericItem.type and GroupItem.baseItem.type…

val Functions$Function4<Boolean, GenericItem, Integer, Integer, Boolean> actionLight = [
    active,
    lightItem,
    luxTrigger,
    lightLevel |

    //logDebug("Rules","Light: Test: starting lambda")
    if (active && lightLevel > 0 && Weather_SolarRadiation_Corrected.state <= luxTrigger) {
        if (lightItem.type == "Dimmer" || (lightItem.type == "Group" && (lightItem as GroupItem).baseItem.type == "Dimmer")) {
            if (lightItem.state != lightLevel && lightItem.state < 99) {
                lightItem.sendCommand(lightLevel)
                logDebug("Rules",">>>>>>> Light: ON [{}]",lightItem.name)
            }
        }
        else {//if (lightItem.type == "Switch" || (lightItem.type == "Group" && (lightItem as GroupItem).baseItem.type == "Switch")) {
            if (lightItem.state == OFF) {
                lightItem.sendCommand(ON)
                logDebug("Rules",">>>>>>> Light: ON [{}]",lightItem.name)
            }
        }
    }
    else {
        if (lightItem.type == "Dimmer" || (lightItem.type == "Group" && (lightItem as GroupItem).baseItem.type == "Dimmer")) {
            if (lightItem.state != 0) {
                lightItem.sendCommand(0)
                logDebug("Rules","<<<<<<<<<<<<<<<<<<<<< Light: OFF [{}]",lightItem.name)
            }
        }
        else {// if (lightItem.type == "Switch" || (lightItem.type == "Group" && (lightItem as GroupItem).baseItem.type == "Switch")) {
            if (lightItem.state == ON) {
                lightItem.sendCommand(OFF)
                logDebug("Rules","<<<<<<<<<<<<<<<<<<<<< Light: OFF [{}]",lightItem.name)
            }
        }
    }
    true
]

I just realized the check for switches is unnecessary, since the items going through this lambda are all lights, so I commented it out!

This Worked for me

LampenPassiv.allMembers.forEach [Lampe|
      logWarn("Debug","StartLoop " + Lampe.type.toString)
      if  (Lampe.type.toString == "Dimmer" ) {logWarn("Debug","IS Dimmer %s")}
      else if (Lampe.type.toString == "Switch"){logWarn("Debug","IS Switch")}
1 Like