iCloud binding with multiple phone rules optimization help!

Hi all, I have icloud installed, with 3 phones in my house, here is the items:

Group:Switch:OR(ON,OFF) iCloud_Group <iphone>

//iPhone6 Plus
String   IPhone6P_BatteryStatus             "6P [%s %%]"        <battery>    (iCloud_Group)       {channel="icloud:device:id1:b2b472ce:batteryStatus"}
Number   IPhone6P_BatteryLevel              "6P [%.0f]"         <battery>    (iCloud_Group)       {channel="icloud:device:id1:b2b472ce:batteryLevel"}
DateTime IPhone6P_LocationLastUpdate        "6P [%1$tH:%1$tM]"  <iphone>     (iCloud_Group)       {channel="icloud:device:id1:b2b472ce:locationLastUpdate"}
Location IPhone6P_Location                  "6P [%s]"             <iphone>       (iCloud_Group)       {channel="icloud:device:id1:b2b472ce:location"}
Switch   IPhone6P_Refresh                   "6P"              <iphone>       (iCloud_Group)       {channel="icloud:device:id1:b2b472ce:location", autoupdate="false"}
Switch   IPhone6P_Home                      "6P"              <iphone>       (iCloud_Group)

//iPhone 6S
String   IPhone6S_BatteryStatus             "6S [%s %%]"        <battery>    (iCloud_Group)       {channel="icloud:device:id1:67f17221:batteryStatus"}
Number   IPhone6S_BatteryLevel              "6S [%.0f]"         <battery>    (iCloud_Group)       {channel="icloud:device:id1:67f17221:batteryLevel"}
DateTime IPhone6S_LocationLastUpdate        "6S [%1$tH:%1$tM]"  <iphone>     (iCloud_Group)       {channel="icloud:device:id1:67f17221:locationLastUpdate"}
Location IPhone6S_Location                  "6S [%s]"             <iphone>       (iCloud_Group)       {channel="icloud:device:id1:67f17221:location"}
Switch   IPhone6S_Refresh                   "6S"              <iphone>       (iCloud_Group)       {channel="icloud:device:id1:67f17221:location", autoupdate="false"}
Switch   IPhone6S_Home                      "6S"              <iphone>       (iCloud_Group)

and the rules to define the distance from home:

rule "allPhone_Rules"
when
    Item IPhone6P_Location changed or
    Item IPhone6S_Location changed
then
    // specify your home location
    val PointType home_location  = new PointType(new DecimalType(xx.05135920063), new DecimalType(xx.6613793811))
    val PointType phone1_location = IPhone6P_Location.state as PointType
    val PointType phone2_location = IPhone6S_Location.state as PointType
    val int distance1 = phone1_location.distanceFrom(home_location).intValue()
    val int distance2 = phone2_location.distanceFrom(home_location).intValue()
    // specify your preferred radius (in meters)
    if ( distance1 < 200 || distance2 < 200) {
        iCloud_Group.postUpdate(ON)
        logInfo("allPhone", "home!")
    } 
    else if ( distance1 >= 200 && distance2 < 200) {
        iCloud_Group.postUpdate(ON)
        logInfo("allPhone", "home!")
    }
    else if ( distance2 >= 200 && distance1 < 200) {
        iCloud_Group.postUpdate(ON)
        logInfo("allPhone", "home!")
    }
    else {
        iCloud_Group.postUpdate(OFF)
        logInfo("allPhone", "away!")
    }
end

The rule looks… very stupid :frowning: , althrough it kind of work… I only test with 2 phones, and I need to add 3 more phones and 2 watches, ipads, so the rules will get many “else if” I think? pretty stupid but I have no idea of how to optimize them…:cry:
What I want is,

  1. If any of the phone’s distance < 200, make the group switch to ON, only if all 3 phones >=200(means no one near home), then change the group switch to OFF.
  2. Be able to add more phones without changing the rule files(which I don’t know how to).
  3. Be able to add different icloud account.

So sorry for the noob questions, could you guys please help me optimize the rules? Thanks…

Not sure exact term but search for rules using groups and foreach loop.

I know examples are on forum, just don’t remember exact threads.

Something like Group items & forEach loops

Thanks man,
I also found this link, hope can help someone

1 Like

Look at Design Pattern: Working with Groups in Rules.

There might be some useful info in Generic Presence Detection.

But one thing you will run into I suspect is that in order to write good Rules that don’t require changing them to add new phones, you will need to get a bit of understanding for Rules.

At a high level, put all the location Items in a Group:Location Group.
Trigger the Rule with Member of PhoneLocations changed
Use a map/reduce to get the phone distance that is furthest from home. Then update and log as approraite.

val PointType home_location = new PointType(new DecimalType(xx.05135920063), new DecimalType(xx.6613793811))

rule "allPhone_Rules"
when
    Member of PhoneLocations changed
then
    val furthest = PhoneLocations.members.map[ state as PointType].reduce[max=0, phone |
        distance = phone.distanceFrom(home_location)
        if(distance > max) max = distance
    ] 
    if(furthest < 200) {
        iCloud_Group.postUpdate(ON)
        logInfo("allPhone", "home!")
    }
    else {
        iCloud_Grouop.postUpdate(OFF)
        logInfo("allPhone", "away!")
    }    
end

I’m not 100% certain I have the syntax right on the map/reduce but it should be pretty close.