iCloud binding with multiple phone rules optimization help!

rules
iphone
Tags: #<Tag:0x00007f51e493aac0> #<Tag:0x00007f51e493a2f0>

(shane kevin) #1

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…


(Danny mullen) #2

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


(shane kevin) #3

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


(Rich Koshak) #4

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.