I would like to be able to turn on a light when I arrive. There are example apps that do this but these only look for presence. So it will turn back on if switched off when polling occurs.
I want to develop an app that will only look for the presence to change from “not present” to “present” and turn on a single time?
Suggestions?
Thanks,
Scott
You are describing a “state machine”.
Luckily, SmartApps persistently store any values you wish in the state.* attributes of each App.
I can pseudo code this if you like, later, but give it some thought in the meantime.
@tgauchat Thanks for the help. I know this is a very simple app. But I don’t know how to write the code to see the state change from not present to present. Then once it determines the state change only runs once? Is that what he unsubscribe () would do?
I want to write an app that will turn on a couple of lights when I arrive after dark (I’ll do this with a mode change instead of sunset/sunrise).
Thanks,
Scott
OK…I figured it out based on the Presence Change Push app:
/**
* Turn it on when I arrive
*
* Author: Scott Jones
* 25 Aug 13
*/
preferences {
section("When a presence sensor arrives this location..") {
input "presence", "capability.presenceSensor", title: "Which sensor?", multiple: true
}
section("Turn on a light...") {
input "switches", "capability.switch", multiple: true
}
}
def installed() {
subscribe(presence, "presence", presenceHandler)
}
def updated() {
unsubscribe()
subscribe(presence, "presence", presenceHandler)
}
def presenceHandler(evt) {
if (evt.value == "present") {
log.debug "${presence.label ?: presence.name} has arrived at the ${location}"
switches.on()
log.debug "Someone's home!"
}
}
Looks good.
Keep in mind that there is a chance the Presence sensor may have some brief flash-glitch of state change, even while still in range. It is a little quirk, though I don’t know how common it occurs.
This would be a minor problem if you turn the light off manually (or from some other SmartApp) and then it suddenly turns on again at some random time, thinking you’ve arrived back home (when you never actually left).
I think someone already demonstrated this in another code sample; but the idea is to try to filter these glitches out by saving a timestamp in the state.* structure of the App and ignoring a “not present / present” change if it is within a certain number of seconds. I haven’t written any presence tag event code, so I don’t have that handy; but let’s follow-up if you experience this glitch, or some other creative variations.
…CP
I think what CP is talking about is your real problem. Most of these type of programs only look for a state change. If it’s polled later and shows present that won’t do anything if it was present before. It’s only if it changes from not-present to present that the event happens.
The problem is a glitch with the presents sensors that causes them to disappear for a few seconds or minutes. ST is working on it, but in the mean time it’s still happens.
If you look at the ridiculously automated garage door opener program, there is code in there to setup a delay. Essentially what it does is say that the presence tag has to be “not present” for x-number of minutes before the program will fire on a state change to present.
Unfortunately I haven’t really broken down the code fully to know exactly what it does, but here’s the relevant part:
def carPresence(evt)
{
log.info "$evt.name: $evt.value"
// time in which there must be no "not present" events in order to open the door
final openDoorAwayInterval = falseAlarmThreshold ? falseAlarmThreshold * 60 : 600
if (evt.value == "present") {
// A car comes home
def car = getCar(evt)
def t0 = new Date(now() - (openDoorAwayInterval * 1000))
def states = car.statesSince("presence", t0)
def recentNotPresentState = states.find{it.value == "not present"}
if (recentNotPresentState) {
log.debug "Not opening ${doorSwitch.displayName} since car was not present at ${recentNotPresentState.date}, less than ${openDoorAwayInterval} sec ago"
}
else {
if (doorSensor.currentContact == "closed") {
openDoor()
sendPush "Opening garage door due to arrival of ${car.displayName}"
state.appOpenedDoor = now()
}
Honestly, it might be easier to take the full code from this program and cut out the parts you don’t need rather than trying to recreate what they did here.
Thanks guys for the help. My family uses 4 cell phones for presence. Also, I’ve made the fence around my locations pretty big. So now I do not have in false “not present” to “present” issues. It’s been rock solid since I increased the fence size to about 150-200 yards.
I’ll save learning the false presence change for a rainy day I’m still trying to learn how to incorporate Sunset/Sunrise with offsets into my apps. I’m tired of relying on a mode change via the Sunset/Sunrise app.
Cheers,
Scott