How to model location of an item?

Hi all,
i try to figure out how to best assign Rooms to Items. In cases the items stay in the same room i can just use nested groups to model Openhab2 Rooms.

Do you have an idea how to model items which are changing their room? e.g. Wearables like Smart Watch, Phone, Remote or other battery devices (assuming there is a binding for that).

My first idea is to programatically change the group the item is in. But it looks like casting ist not parsed bei xtext and also i assume i will run into problems when the config gets reloaded.

rule "Change Group"
when
    Item changeGroup received command
then
    if(changeGroup.getGroupNames().get(0).toString() == "first") {
        ((ActiveItem)changeGroup).removeGroupName("first")
        ((ActiveItem)changeGroup).addGroupName("second")
    }
    logDebug("voice", "Group is now" + changeGroup.getGroupNames().get(0).toString())
end

Second idea is to use tags, but here it’s the same problem like with groups.

Third idea would be to group the item with a second StringItem which represents the room group. But this looks like a workaround for me.

To dynamically add or remove an Item from a Group I think you need to do it from the Group, not the Item. So you would use first.removeMember(changeGroup) and second.addMember(changeGroup) instead.

I have never done this and have no idea whether it will work but that seems like way to do it.

Alternatively, I’m pretty sure you can do this through the REST API using one of the HTTP actions.

As an aside, how are you determining which rooms a device has moved to?

I tried your solution, but it doesn’t seem to work either. In some samples i saw people using GroupName?.members.xyz to access members, but i found no documentation to this syntax.

Regarding your question my Basic idea is qurrently to use one or more NFC Tags which identify one Room. An Android App sends a HTTP Request to OpenHAB when it receives the signal. Also i have a VoiceCommand to tell where i am(In case I’m in a Room where no NFC tag is reachable e.g. garden).

Just a tip… if you are looking for assistance it is a good idea to show at least a snippet of the code you tried and what the specified results were.

You’re right, i was in a hurry. I will post a snippet of the code when i
get home. :slight_smile:


http://www.eclipse.org/xtend/documentation/203_xtend_expressions.html (see Range Operators for forEach, filter, etc and see Short Circuit Boolean Operators for ?)

Then you may have to either change the Item’s Group using the OH REST API calls or model this behavior some other way, for example a separate Item. This might help with that.

Ah, OK. Too bad. I had my hopes up that you had something a little less interactive in mind.

1 Like

Okay i had another look on my code and it works, but you have to keep attention to what are you logging.

This is my sample code:

rule "Test Dynamic Grouping"
when
    Item smartWatch_room received command
then    
    if(gfirst.getMembers().contains(smartWatch)) {
        gfirst.removeMember(smartWatch)
        smartWatch.removeGroupName("gfirst")
    } else {
        gfirst.addMember(smartWatch)
        smartWatch.addGroupName("gfirst")
    }
    logDebug("voice", "smartWatch groups" + smartWatch.getGroupNames)
    logDebug("voice", "gfirst members" + gfirst.getMembers)
end

First the type of the function differs. On the parent you can call group.addMember(Item) and on the member you can call item.addGroupName(String)

Also a call to group.addMember doesn’t add a group name to the member item. Looks like a bug to me because this causes inconsistency in the item relationships. Is there an argument against just calling genericItem.addGroupName(baseItem.getName()); in GroupItem.java Line 160

Awesome i missed this part to fully understand the rule syntax.

My focus is currently on building a conversational context-aware Voice Interface. The NFC tags are an easy and cheap way to get room-context. Other options would be gps-like trianglulation, sensor-based approaches or signal fingerprinting. This paper has a good overview of the techniques in chapter 4.

My big problem with the NFC and other room location based (reelyActive for Bluetooth, FIND for wifi, etc.) techniques is it requires the occupants to carry something with them at all times while in the house for accurate location. This won’t work with guests, small children, and I probably couldn’t convince my wife to do so either.

My problem with voice based is I do not find forcing the users to verbally announce or perform some action every time they enter a room to be very user-friendly.

My home automation philosophy is pretty strict and defined and thus far I’ve found no automation scenario that fits into my family’s lifestyle that would warrant the compromises necessary to make room by room tracking worth while.

I found this post but for me getGroupNames is not working

Group:Number:SUM        gSwitchesAnzahl   "Test-Switches [(%d)]"
Switch          swSwitch01      "Switch01 [%s]"                     (gSwitchesAnzahl)
Switch          swSwitch02      "Switch02 [%s]"                     (gSwitchesAnzahl)
Switch          swSwitch03      "Switch03 [%s]"                     (gSwitchesAnzahl)
Switch          swSwitch04      "Switch04 [%s]"                     (gSwitchesAnzahl)

My code

gSwitchesAnzahl.addMember(swSwitch04)
logInfo("gSwitches", "swSwitch04.getGroupNames=[{}]",swSwitch04.getGroupNames())

2018-01-09 11:25:04.563 [INFO ] [pse.smarthome.model.script.gSwitches] - swSwitch04.getGroupNames=[[gSwitchesAnzahl]]

gSwitchesAnzahl.removeMember(swSwitch04)
logInfo("gSwitches", "swSwitch04.getGroupNames=[{}]",swSwitch04.getGroupNames())

2018-01-09 11:25:10.065 [INFO ] [pse.smarthome.model.script.gSwitches] - swSwitch04.getGroupNames=[[gSwitchesAnzahl]]

Am I doing something wrong? After removeMember the group membership should.

If I iterate the group gSwitchesAnzahl by

	gSwitchesAnzahl.members.forEach[item |
		logInfo("Logger","gSwitchesAnzahl Itemname: "+item.name + ": "+ item.state.toString)
	]

I can see, that the item is not included anymore. Looks like getGroupNames does not work correct.

What you experience is what i mentiond earlier:

if you add items programatically via the Group, the item does not know that it is assigned to a new group. If you add groups progamatically via the item, the group doesn’t know that it has a new member. So what you could try is:

parentGroup.addMember(item) 
item.addGroupName(parentGroup.getName()) //notice the parameter is a string and you can call this method only on a GenericItem

I just fixed the code for myself by altering the behavior of the GroupItem, but as more ppl running into this i think it’s a good idea to raise a issue for this.

1 Like

I meant to open an issue for this… thank you for moving to get this behavior corrected! When group memberships are modified through rules, getGroupNames does not properly reflect the change, but group.members.contains(item) does, so can be used as a workaround.