[Solved] iCloud Presence Turn on outside light


(Chase Mixon) #1

Ok I wrote a rule to turn on outside light when sunset occurred. then I was like I can make this better, what if the light turned on when I was like on the road I lived on, and I thought I had figured out how to do that. but I’ve run into a snag, hoping you guys can help… here’s the rules for those two things, I have two issues, one is it doesn’t turn on in time, I may have fixed that, but the main thing is it keeps turning on… I turn it off 5 minutes later it’s back on… UGH!
I think I need another variable so I can tell OH2 that I’m already home, I just can’t wrap my brain around how to do that…
Thanks for your help

1st rule

var boolean sunset = false
rule "Sunset rule"
when
        Channel 'astro:sun:local:set#event' triggered START
then
        sunset = true
        if (Chase_iPhone_Home=="ON" || Tracy_iPhone_Home=="ON" || Cale_iPhone_Home=="ON")
        {
        sendCommand(PorchLight, ON)
        sendCommand(LED_Power,ON)
        Light_Color.sendCommand("1,0,100") // White
        }
end


2nd rule

rule "Chase_iPhone Home"
when
    Item Chase_iPhone_Location changed
then
        // specify your home location 1.000 lat 2000 long
// Didn't want any of you guys seeing where I actually live :slight_smile: 
        val PointType home_location  = new PointType(new DecimalType(1.0000), new DecimalType(2.000))
        val PointType phone_location = Chase_iPhone_Location.state as PointType
        val int distance = phone_location.distanceFrom(home_location).intValue()
        // specify your preferred radius (in meters)
        if ( distance < 1000)
        {
                Chase_iPhone_Home.postUpdate(ON)
                logInfo("iPhone Home", "Chase's iPhone is at home.")
                if (sunset == true)
                {
                        sendCommand(PorchLight, ON)
                        sendCommand(LED_Power,ON)
                        Light_Color.sendCommand("1,0,100") // White
                }
        }
        else
        {
                Chase_iPhone_Home.postUpdate(OFF)
                logInfo("iPhone Home", "Chase's iPhone is away.")
        }
end

(Kurt S) #2

Hi,

you’re probably querrying your distance from Home, using the iCloud Binding for every 5min.
As a result in “2nd rule” Then your Item
Chase_iPhone_Home is getting updated, which results in PorchLight and LED_Power Items being turned on each 5min. So congrats: Your rule works, as expected :wink:

The way I have implemented it, is to create a dummy item switch (Presence) which gets turned on when the phones are within a distance.

Then, you could do something like

rule "Lights on"
when Item Presence changed from OFF to ON
then
sendCommand(PorchLight, ON)
sendCommand(LED_Power,ON)
Light_Color.sendCommand(“1,0,100”) // White
end

this way, your lights only get turned on once, when the Switch “Presence” gets turned on.

Kurt


(Christoph) #3

First off all, please use code fences.

The delay is caused by the binding. You can force the refresh to get the actual location.

There are two ways to prevent the rule turning the light on again. I suggest, 5 minutes is the refresh time of the iCloud binding. So your second rule also turns on the light every 5 minutes. So you can either split the rule in two or change your existing rule a little bit:

rule “Chase_iPhone Home”
when
Item Chase_iPhone_Location changed
then
// specify your home location 1.000 lat 2000 long
// Didn’t want any of you guys seeing where I actually live :slight_smile:
val PointType home_location = new PointType(new DecimalType(1.0000), new DecimalType(2.000))
val PointType phone_location = Chase_iPhone_Location.state as PointType
val int distance = phone_location.distanceFrom(home_location).intValue()
// specify your preferred radius (in meters)
if ( distance < 1000) {
     if(Chase_iPhone_Home != ON){
         Chase_iPhone_Home.postUpdate(ON)
         logInfo(“iPhone Home”, “Chase’s iPhone is at home.”)
         if (sunset == true){
            sendCommand(PorchLight, ON)
            sendCommand(LED_Power,ON)
            Light_Color.sendCommand(“1,0,100”) // White
         }
    }
}
else
{
Chase_iPhone_Home.postUpdate(OFF)
logInfo(“iPhone Home”, “Chase’s iPhone is away.”)
}
end

or two rules

rule “Chase_iPhone Home”
when
Item Chase_iPhone_Location changed
then
// specify your home location 1.000 lat 2000 long
// Didn’t want any of you guys seeing where I actually live :slight_smile:
val PointType home_location = new PointType(new DecimalType(1.0000), new DecimalType(2.000))
val PointType phone_location = Chase_iPhone_Location.state as PointType
val int distance = phone_location.distanceFrom(home_location).intValue()
// specify your preferred radius (in meters)
if ( distance < 1000){
    Chase_iPhone_Home.postUpdate(ON)
} else {
Chase_iPhone_Home.postUpdate(OFF)
logInfo(“iPhone Home”, “Chase’s iPhone is away.”)
}
end
rule “Chase_iPhone Home Lights on”
when
Item Chase_iPhone_Home changed to ON
then
if (sunset == true){
    sendCommand(PorchLight, ON)
    sendCommand(LED_Power,ON)
    Light_Color.sendCommand(“1,0,100”) // White
}
end

(Chase Mixon) #4

Thanks! I like this idea.


(Chase Mixon) #5

Thanks for the code fences, I had no idea, I always thought the website did that automatically… my bad… :blush: I did go back and put them in now. And thank you for all the detail, I’m still very new to OH2.


(Chase Mixon) #6

ok maybe I need a little more help, so what I did was, I already had a dummy switch ( Chase_iPhone_Home) is the switch, in the code
I change the previous to this.

var boolean sunset = false
rule "Sunset rule"
when
        Channel 'astro:sun:local:set#event' triggered START
then
        sunset = true
end

and put this in there…
but this is all Jacked up! can you pass along a little more wisdom? yes I know it’s commented out, that was to get rid of the error messages in my rules file.

rule "Chase_iPhone Home"
when
    Item Chase_iPhone_Location changed
then
        val PointType home_location  = new PointType(new DecimalType(1.0000), new DecimalType(-2.0000))
        val PointType phone_location = Chase_iPhone_Location.state as PointType
        val int distance = phone_location.distanceFrom(home_location).intValue()
        // specify your preferred radius (in meters)
        if ( distance < 1000)
        {
                Chase_iPhone_Home.postUpdate(ON)
                logInfo("iPhone Home", "Chase's iPhone is at home.")
        }
        else
        {
                Chase_iPhone_Home.postUpdate(OFF)
                logInfo("iPhone Home", "Chase's iPhone is away.")
        }
end

//rule "Turn On lights"
//when
//      Item Chase_iPhone_Home change from OFF to ON or
//      Item Tracy_iPhone_Home change from OFF to ON or
//      Item Cale_iPhone_Home change from OFF to ON
//then
//        {
//        sendCommand(PorchLight, ON)
//        sendCommand(LED_Power,ON)
//        Light_Color.sendCommand("1,0,100") // White
//       }
//end


(Christoph) #7

In your last rule there is missing

    if (sunset == true)

before the brackets (if you still want to turn lights on only after sunset, else remove the{})

I overlooked it first: it has to be changed and not change

Besides that it is a good idea to make a Switch item for your sunset instead of using a var.


(Chase Mixon) #8

Thanks SO MUCH! I made those changes, and I’ll see how it goes tonight! I will not call myself a programmer, cause I’m not, but I do write scripts to do a lot of admin stuff, why is having a dummy switch better than a variable? that seems weird to me?


(Christoph) #9

To understand the advantages have a look at this example: Design Pattern: Time Of Day

A big advantage having an item is also that you can persist it, restore it on startup and it holds the state even when you rewrite and reload your rule after sunset.


(Rich Koshak) #10

In addition to persistence and restore on startup, there are a lot of IMHO even more compelling reasons to use an Item instead of a variable for something like time of day.

Variables can only be used in that one rules file. Items can be access from anywhere. You will likely have lots of rules across many files that will want to know the time of day.

Variables cannot be displayed on a sitemap or Habpanel. Items can. This can be useful information for users of your home automation.

Variables cannot be queried for through the REST API. Items can. External services may care about timer off day too (e.g. Tasker on Android phones).

Variables cannot be used to trigger rules. Items can. You may want to do things when the time of day transitions to a new time period.

By using an Item you only need one rule to calculate timer off day in one place and should you choose to modify how you calculate the time of day (e.g. use a different Astro trigger) you only have to change it on one place. With a variable you have to change it in each rules file that cares about that time if day.


(Chase Mixon) #11

I’m starting to think I’m an idiot… I can’t even get this code to work…

where am I going wrong?

rule "Init"
when
        System started
then
        sunset = false
end

rule "Sunset rule"
when
        Channel 'astro:sun:local:set#event' triggered START
then
        sunset = true
end

rule "Turn On lights"
when
        Item Chase_iPhone_Home changed from OFF to ON or
        Item Tracy_iPhone_Home changed from OFF to ON or
        Item Cale_iPhone_Home changed from OFF to ON
then
        if (sunset == true)
        {
        sendCommand(PorchLight, ON)
        sendCommand(LED_Power,ON)
        Light_Color.sendCommand("1,0,100") // White
        }
end
rule "Chase_iPhone Home"
when
    Item Chase_iPhone_Location changed
then
        val PointType home_location  = new PointType(new DecimalType(1.0000000), new DecimalType(-2.000000))
        val PointType phone_location = Chase_iPhone_Location.state as PointType
        val int distance = phone_location.distanceFrom(home_location).intValue()
        // specify your preferred radius (in meters)
        if ( distance < 1000)
        {
                Chase_iPhone_Home.postUpdate(ON)
                logInfo("iPhone Home", "Chase's iPhone is at home.")
        }
        else
        {
                Chase_iPhone_Home.postUpdate(OFF)
                logInfo("iPhone Home", "Chase's iPhone is away.")
        }
end



(Christoph) #12

You forgot to declare your var sunset at the top of the file.


(Chase Mixon) #13

I put it in the items file as a switch…


(Christoph) #14

then the correct syntax would be (assuming sunset is your Switch item)

rule "Sunset rule"
when
        Channel 'astro:sun:local:set#event' triggered START
then
        sunset.postUpdate(ON)
end

and

rule "Turn On lights"
when
        Item Chase_iPhone_Home changed from OFF to ON or
        Item Tracy_iPhone_Home changed from OFF to ON or
        Item Cale_iPhone_Home changed from OFF to ON
then
        if (sunset.state == ON)
        {
        sendCommand(PorchLight, ON)
        sendCommand(LED_Power,ON)
        Light_Color.sendCommand("1,0,100") // White
        }
end

(Chase Mixon) #15

oh! that make total sense now… Thanks Syn!


(Chase Mixon) #16

Just want to throw this out here for anyone who looks at this in the future, I’m still playing with the distance part, currently I’m up to 5000 (in Meters) and it still not seeing me home in time to turn the light on in time. :frowning:
I’m guessing that because the icloud binding only updates every 5 minutes, I’ll need it to be like somewhere about 10 minutes away to make sure it turns on before I arrive… trying 15000 meters tomorrow.

rule "Chase_iPhone Home"
when
    Item Chase_iPhone_Location changed
then
        val PointType home_location  = new PointType(new DecimalType(1.0000), new DecimalType(-2.0000))
        val PointType phone_location = Chase_iPhone_Location.state as PointType
        val int distance = phone_location.distanceFrom(home_location).intValue()
        // specify your preferred radius (in meters)
        if ( distance < 1000)
        {
                Chase_iPhone_Home.postUpdate(ON)
                logInfo("iPhone Home", "Chase's iPhone is at home.")
        }
        else
        {
                Chase_iPhone_Home.postUpdate(OFF)
                logInfo("iPhone Home", "Chase's iPhone is away.")
        }
end

(Christoph) #17

Or you combine multiple events to get a better presence detection, e.g. (because it uses the force refresh command of the iCloud binding) https://community.openhab.org/t/icloud-device-data-integration-in-openhab/32329/298?u=syn
Browse the forum, there are tons of examples and suggestions how to do that.


(Chase Mixon) #18

One last note, none of my rules that had switches were working and I could not figure out for the life of me why… so just in case someone else comes across this… you have to have switches with .state on the end of them like this

Incorrect at least on my openhab box

if (sunset == ON)

Correct

if (sunset.state == ON)