Getting an Item by Name

Hi,

I am looking for a way to get an Item and its value by its name.
Basicly a reverse postUpdate() funktion, e.g.

getItem( String item_name, org.openhab.core.items.GenericItem item)

which would return != 0 if the item doesn’t exist.
This would allow to address items dynamically by their names.

At the moment my only idea is to achieve this via the RestAPI
(eg sendHttpGetRequest to http://127.0.0.1:8080/rest/items/MyLight/state).
But this seems very inelegant and only a bad workaround.

Is there any other way how I can achieve this?

I’m not completely sure I understand what you’re after but you can get an items state in a rule using the

item_name.state
convention.

Eg.

if(item_name.state > 10) …

There are also persistence extensions that allow you to get the state, or average etc at some previous date (see the persistence wiki page for this) using a similar syntax.

Chris

Hi Chris,

I have a subset of items which are always named after the same schemata.
For every door (eg living_door) I have a DateTime Variable with the latest change (eg ts_living_door).
Since I know the naming convention I would like to address the items by their names and not by their object.
This would allow the creation of a lambda-function which could change lots of items by querying them by their name.
E.g.:
I pass the item door to the function. The functions appends ts_ in front of the item-name, gets the value and then modifies it.

val org.eclipse.xtext.xbase.lib.Functions$Function1 pseudocode= [
    org.openhab.core.items.GenericItem item|

    org.openhab.core.items.GenericItem itembyname
    getItem( "ts_" + item.name, itembyname)

    val dyn_val = itembyname.state as DecimalType
    //Now I can use the value which I got using the item name in the labda

    postUpdate( "ts_" + item.name, 1) //this already works
]

I hope you understand what I’m trying to do. Did the example make it more clear?

You can get a similar effect by putting the “related” items into Groups, and then using forEach over the members of that group.

I do that in a bunch of spots, and have different named-Groups attached to the various items. This avoids having to use Item naming conventions, and lets my Items be in multiple enumerations (for things like Goodnight, Away and Vacation scenes)

Could something similar be done here?

1 Like

Hi Chris,

there is no item registry or something you could ask, but you can achieve this by using a group like Mark suggested. You can then get the item by name with something like

<Group>.members.findFirst[name.equals(itemName)]

I also use this quite often.

1 Like

Thank you for your replies.
@guessed + @aruder77: since the values of the items do not correlate they are atm not in the same groups. This would mean I have to iterate over multiple groups (since every item is in a different group). If I wanted to change multiple items this would be the way to go.

I could create a group gAll where all my other groups belong to and then try the example of @aruder77.
But since I just want to change a single item, this might actually be a bit overkill and I worry that this will noticeably slow down the execution speed.

If you use workarounds like this quite often do you think I should open an issue for a function as I described above?
The functionality is already there (REST-API) but it seems the interface to the rules was forgotten … .

What do you have that’s invoking the proposed lambda?

If we better understand that we may be able to help restructure it to do it in another form. I definitely understand not wanting to enum all your Items, as that can be a long list :wink:

Hi,

I have some Philio 4-in-1 MultiSensors in my Flat. They have a door sensor, a movement sensor, a brightness sensor and a temperature sensor. Besides the values its-self, I generate a timestamp every time the door is opened and I count the amount of movement alarms ins the last 15mins and last hour. Additionally I count the times the door is opened/closed.
The sensors are in separate rooms and I use the values for switching and dimming of lights. I wanted to expand the data and keep 2 additional timestamps and additionally show the time since the last movement.
I have a strict naming-convention with pre- and suffixes which would make accessing items by name quite easy and elegant.

Why don’t you introduce an additional new group for all the items that are relevant for your function. Since an item can be part of multiple groups you don’t need to change your current group assignments. You could then use the method described earlier to get the item by name using the group.

Anyhow, I think opening an issue for a getItemByName API method is a good idea.

I have created an issue based on this thread: https://github.com/openhab/openhab/issues/3091
Let’s hope somebody has mercy and implements the corresponding action. :wink:
Please feel free to contribute. Until then, I’ll try the group-workaround.

@aruder77: I am still struggling how to access the item. Could you please provide a more detailed example of how you get the item? This would be really helpful. Thank you.

I use something like this to generically access my roller shutter auto modes. For every roller shutter I have, I also have an “auto mode” switch item which signals if the roller shutter is in automatic mode or not. If the roller shutter’s name is xx, the name of the autoMode switch is by convention xx_AutoMode.
My item definitions look like this:

Group           Modes  (All)

Rollershutter 	Shutter_FF_Bath             "Shutter [%d %%]"		(FF_Bath, Shutters, ShutterPosition)
Switch		Shutter_FF_Bath_AutoMode    "Shutter Auto Mode"		(FF_Bath, Shutters, Modes)

Rollershutter 	Shutter_FF_Sleep_Wide       "Shutter [%d %%]"		(FF_Sleep, Shutters, ShutterPosition)
Switch		Shutter_FF_Sleep_AutoMode   "Shutter Auto Mode"		(FF_Sleep, Shutters, Modes)

In my rules, I can then check for a given rollershutter-item ‘shutter’ if the auto-mode is on or off with something like

val autoModeItem = Modes.members.findFirst[name.equals(shutter.name + "_AutoMode")]
if (autoModeItem.state == OnOffType::ON) {
    ...
}

Thank you for your help.
I was struggeling with the correct item-type but this seems to work:

val org.eclipse.xtext.xbase.lib.Functions$Function1 CounterHandler = [
org.openhab.core.items.GenericItem countItem|

val String itemname= countItem.name

 //History
val DateTimeType ts     = gTimestamp.members.findFirst[ name.equals( "ts_" + itemname)].state as DateTimeType
val DateTimeType ts1    = gTimestamp.members.findFirst[ name.equals( "ts1_" + itemname)].state as DateTimeType
val DateTimeType ts2    = gTimestamp.members.findFirst[ name.equals( "ts2_" + itemname)].state as DateTimeType

postUpdate( "ts3_"    + itemname, ts2.toString())
postUpdate( "ts2_"    + itemname, ts1.toString())
postUpdate( "ts1_"    + itemname, ts.toString())
postUpdate( "ts_"     + itemname, now.toString())
]

This implements a small timestamp history (3 items).
The items are all named like the counter, but with the corresponding prefix.
So with one lambda which is called from 4 contacts I am accessing 20 items ( 1 counter + 4 timestamps).
If now I wouldn’t have to put them in a group, I’d be really happy (except for classes ;-))!

Simply because this shows up in searches I wanted to add a link to the “real” solution to the issue. There is a actually a way to get an item object from a name without adding the items to a group.

1 Like

I appreciate your effort!
I’ve since then switched to HABApp and getting items by name is quite easy there.