Presence Detection Problems

Hi Everyone!

I have a Raspberry Pi3 running openHab 2.2.0 build, and I have some problems in my Rules…
So I have installed iCloud binding for my devices which works fine. I want to use these data mainly to detect presence (home or not). I have found a really good and easy rule here
However I can’t get working this rule… Here are my files:
distancehome.rules

/***********************************************************************************
 
 Rule - Distance from home
	 
 This rule is triggered by an updated location item (Martin_Location). The location 
 item holds the coordinates to my iPhone and is updated by the Bridge/Thing in an 
 iCloud binding. The rule updates an item (Distance_From_Home) by calculating the 
 differene between two locations (a static HOME location and Martin_Location)
 *************************************************************************************
 
 Pre-requisites
 ***************************************************
 1. An .items file with the following content

Location Home_Location 
Number Distance_From_Home

2. A configured Bridge/Thing using the iCloud binding with a location item (in this case Martin_Location)
*****************************************************/

rule "Distance from home"

when
	Item KristofIPhone_Location changed
then


// ***************************************************************************
//  Set the location for HOME (tip - use google maps to find the coordinates).
// *************************************************************************** 

 // The Norwegian Royal Palace (Lat, Lon)... 
 Home_Location.state = new PointType(new DecimalType(47.527496), new DecimalType(19.112647))

// ******************************************************************************
// Calculate the distance from HOME (Home_Location) and iCloud (Martin_Location)
// ******************************************************************************

 Distance_From_Home.postUpdate(Home_Location.distanceFrom(KristofIPhone_Location))

// Optional logging to /var/log/openhab2/openhab2.log
 logInfo("Distance from home : ", Distance_From_Home.state.toString())
	
end

rule "Home Or Away"

when
	Item KristofIPhone_Location changed
then
	if((Distance_From_Home.state as NumberItem) < 100) {
		KristofiPhone_Home.sendCommand(ON)
	}
	else {
		KristofiPhone_Home.sendCommand(OFF)
	}
end

This works somehow, because I have a sitemap which shows some data, but I don’t know what is the unit of this data… it shows around 20 when I’m home, and if I’m away from home (more than 10 km) it shows around 70…

Also the other rule at the end, doesn’t seems to work… It doesn’t show either on or off anytime.

Here is the snippet of the sitemap file:

	Frame label="Phones status" {
		Default item=KristofIPhone_BatteryLevel label="Kristof iPhone Battery Level"
		Default item=KristofIPhone_BatteryStatus label="Kristof iPhone Battery Status" icon="iphone"
		Default item=KristofLocationString
		Default item=Distance_From_Home
		Switch item=KristofiPhone_Home mappings=[ON="Home", OFF="Away"]

Thanks for everyone’s help

If you look in here, you will see the comment that the distance is supposed to be in meters.
If that sounds wrong to you, you could post the 2 lat/longs used for a “false” calculation.

Thanks, I’ll try that rule!

Also if you could help me… I have 3 iDevices which I have to use this presence detection. How can I make a universal rule for these 3 devices, so that I don’t have to make 3 individual rules… which is the easiest way?

Something like:

Assuming all phones have associated items like
KristofiPhone_Location and KristofiPhone_Home

rule "Distances from home"
when
    Item KristofiPhone_Location changed or
    Item AdamiPhone_Location changed or
    Item EveiPhone_Location changed
then
   // specify your home location
   val PointType home_location  = new PointType(new DecimalType(51.0), new DecimalType(4.0))
   val PointType phone_location = triggeringItem.state as PointType
   val nameParts = triggeringItem.name.split("_")
   val triggeringiPhoneName= nameParts[0]+"_Home"
  val int distance = phone_location.distanceFrom(home_location).intValue()
  // specify your preferred radius (in meters)
  if ( distance < 200) {
     postUpdate(triggeringiPhoneName,ON)
     logInfo(nameParts[0], "is at home.")
 } else {
    postUpdate(triggeringiPhoneName,OFF)
    logInfo(nameParts[0], " is away.")
}
end

Not tested!!

Thanks, I’ll try that!

2018-03-28 18:05:10.311 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘iPhone Home’: The name ‘nameParts’ cannot be resolved to an item or type; line 10, column 29, length 12

I got this error, at this line:
val triggeringiPhoneName = nameParts[0] + “_Home”

As said. “Not tested”, I had to look in some old threads (found an answer from a guy named opus???)

Please change those two lines:

   val nameParts = triggeringItem.name.toString.split("_")
   val triggeringiPhoneName= nameParts.get(0)+"_Home"

No probs, thanks for your help! I’m a little bit new to this openHab and it’s language…

Thanks, I’ll try that!

I’m still more curious about the “false” calculated distance.

Now I got this error:

2018-03-28 19:16:02.766 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘iPhone Home’: An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(java.lang.String,java.lang.String) on instance: null

This is not my day!

Change this lines to:

postUpdate(triggeringiPhoneName,"ON")

postUpdate(triggeringiPhoneName,"OFF")

The ON and OFF needed to be Strings!

…and for the distance calculation I just tested it with thre values from to 55.0 / 5.0 to 56.0 /5.0 and got a value of 111319m. Converting that to Nautical miles give me 60,1074514, which is pretty close to the expected 60 Nm (Distance from 55N to 56N due is 1° or 60 Nm).
In short: Correct!

Yes, really thanks! It seems that this is working!

Thanks!

Dear Everyone!

This rule is working fine, but it has a minor problem. The phone sometimes loses precise location so it detects that the phone is not at home. (Accuracy ~1500m)
How can I use the location accuracy to include it in the distance?

What I would want is something like:

rule "iPhone Home"
when
	Item KristofIPhone_Location changed or
	Item EdinaIPhone_Location changed or
	Item ReKaIPhone_Location changed
then
	val PointType home_location = new PointType(new DecimalType(47.5274), new DecimalType(19.1126))
	val PointType phone_location = triggeringItem.state as PointType
	val nameParts = triggeringItem.name.toString.split("_")
	val triggeringiPhoneName = nameParts.get(0) + "_Home"
	val DecimalType locationAccuracy = nameParts.get(0) + "_LocationAccuracy"
	val int distance = phone_location.distanceFrom(home_location).intValue()
	if(distance < 150) {
		postUpdate(triggeringiPhoneName, "ON")
		logInfo(nameParts.get(0), "iPhone is at home.")
	} else {
		postUpdate(triggeringiPhoneName, "OFF")
		logInfo(nameParts.get(0),  "iPhone is away.")
	}
end 

So I want to use that LocationAccuracy (which is a Number type item) to include it somehow in detection. I thought of distance < 150 + LocationAccuracy or something like this, however it doesn’t seem to work