Turn on Fishtank for motion at night


(Freetobelee) #1

preferences {
section(“Turn on when there’s movement…”){
input “motion1”, “capability.motionSensor”, title: “Where?”
}
section(“And off when there’s been no movement for…”){
input “minutes1”, “number”, title: “Minutes?”
}

section("And after this time..."){
      input "ontime", "time", title: "Time of Day"
 }

/** section(“or after sunset in this ZIP code…”){
input “onzip”, “number”, title: “ZIP?”
} **/

section("And before this time..."){
      input "offtime", "time", title: "Time of Day"
 }

/** section(“or before sunrise in this ZIP code…”){
input “offzip”, “number”, title: “ZIP?”
} **/

 section("Turn on/off light(s)..."){
      input "switches", "capability.switch", multiple: true
 }

}


(Freetobelee) #2

That’s the basic idea, but I’m not really sure where to start - especially with the determining sunset/sunrise time by ZIP. Anyone want to help me work through this one? you will be paid handsomely in cheap beer :stuck_out_tongue:


(Egarl005) #3

I’m playing around with it now! I don’t have much experience but I’ll give it a go. Thinking there may be 4 if statements based upon zip code selection to use as an offset for the time. The complicated part is gathering what time the sun is setting that day and I have no idea how to use OAUTH to get the apis to work.

I’ve wanted to create an app that acts a certain way between two chosen times yet I’ve failed. Had to resort to setting up a mode that was a scheduled change but it seems to me that will complicate the whole “mode magic” when you don’t want your entire house to act a certain way at a certain time all the time. So what I have done so far is use schedule(scheduleCheck) to initiate a motionHandler(evt).

Way out of my league at this point but I’ll sure give it a go. Learning experience for me and my bar tab from last night was way out of budget… I’ll be looking forward to the cheap beer!

I’ll post my progress tonight and follow up tomorrow if I haven"t finished.


(Freetobelee) #4

Awesome, man! I can sort of piece things together but my background is in interface design, not full on development. I feel like Modes really over complicate things, and shouldn’t be used for this purpose.

I’ve accomplished what I want for now with the ‘sunrise/sunset’ mode magic, and the ‘light follows me’ app, but I think this would be a very popular program if we can get it to work! Personally, it’s the first thing I would automate if I had compatible switches on every light, and motion sensors in every room. I wonder how many days of our entire life are wasted turning on and off light switches?


(Jinx) #5

Conceptually, this requirement sounds straightforward to code: Setup an event handler for movement on the motion sensors - each time there is movement, check that the current time is in the user defined window (With now() ) and turn on the light if it is. When the light is turned on, setup a schedule to turn it off after the timer expires with the schedule() command. Reset this timer each time motion happens within the schedule (Haven’t figured out this part yet!)

I wanted to setup an app to do just all that, except I did not think of using zip codes to get standard sunset and sunrise times. I started with coding a sample app today but cannot seem to get the IDE to save any code i write! Will post back here once i figure out more of the basics and can get some code saved…


(Egarl005) #6

Annnnnnd here we go (based on a schedule, zip code will follow). I haven’t had a chance to test it more than a few times but it seems to be working just fine on both the simulator and with my things. Within the app on my phone, I created two new modes for setting up the time frame.

/**

preferences {
section(“When there’s movement”) {
input “motion1”, “capability.motionSensor”, title: “Where?”, multiple: true
}

section("Turn on") {
input "switch1", "capability.switch", title: "Switch"
}

section("After this time") {
input "onTime", "time", title: "Time of Day", required: false
}

section("Change to this mode") {
input "newMode", "text", title: "Mode"
}

section("Until when") {
input"offTime", "time", title: "Time of Day", required: false
}

section("Then change to this mode") {
input"oldMode", "text", title: "mode"
}

section("And stay on for") {
input "minutes1", "number", title: "Amount"
}

}

def installed() {
subscribe(motion1, “motion.active”, motionActiveHandler)
schedule(“0 * * * * ?”, “scheduleCheck”)
initialize()
}

def updated() {
unsubscribe()
subscribe(motion1, “motion.active”, motionActiveHandler)
unschedule()
schedule(“0 * * * * ?”, “scheduleCheck”)
initialize()
}

def initialize() {
schedule(onTime, changeModeOn)
schedule(offTime, changeModeOff)
}

def changeModeOn() {
setLocationMode(newMode)
}

def changeModeOff() {
setLocationMode(oldMode)
}

def motionActiveHandler(evt) {
log.debug "$evt.name: $evt.value"
if (location.mode == newMode) {
if (evt.value == “active”) {
log.debug "turning on light"
switch1.on()
}
state.inactiveAt = now()
}
else if (evt.value == “inactive”) {
if(!state.inactiveAt) {
state.inactiveAt = now()
}
}
}
def scheduleCheck() {
log.debug "schedule check, ts = ${state.inactiveAt}"
if (state.inactiveAt) {
def elapsed = now() - state.inactiveAt
def threshold = 1000 * 60 * minutes1
if (elapsed >= threshold) {
log.debug "turning off lights"
switch1.off()
state.inactiveAt = null
}
else {
log.debug “${elapsed / 1000} sec since motion stopped”
}
}
}


(Freetobelee) #7

Cool! I will test it tonight when I get home :slight_smile:

If you can get this to work with the Weather Underground API and without the use of modes, Pabst isn’t going to be a good enough payment
:stuck_out_tongue:


(Egarl005) #8

Pabst! Pabst! Pabst! :slight_smile:

A very big thanks to Kris who put up something using wunderground up in the projects section. Made it a breeze to complete. If I knew his user name I’d tag him but I suppose a link will suffice

http://build.smartthings.com/projects/lightsongarageopen/hello-smarter-world/

So, the only thing you have to do is register for the wunderground api. Then you’ll plug that into your app or simulator.

/**

preferences {
section(“When there’s movement”) {
input “motion1”, “capability.motionSensor”, title: “Where?”, multiple: true
}

section("After sunset, turn on") {
input "switch1", "capability.switch", title: "Switch"
}

section("And stay on for") {
input "minutes1", "number", title: "Amount"
}

section ("ZIP") {
input "zipCode", "number", title: "Zip Code"
}

section ("Enter API key for Wunderground") {
input "apiKey", "text", title: "API Key"
}

}

def installed()
{
subscribe(motion1, “motion.active”, motionActiveHandler)
schedule(“0 * * * * ?”, “scheduleCheck”)
}

def updated()
{
unsubscribe()
subscribe(motion1, “motion.active”, motionActiveHandler)
schedule(“0 * * * * ?”, “scheduleCheck”)
}

def checkNighttime() {
httpGet(“http://api.wunderground.com/api/${apiKey}/astronomy/q/${zipCode}.json”) { response ->
def sunsettime = response.data.moon_phase.sunset.hour + response.data.moon_phase.sunset.minute
def sunrisetime = response.data.moon_phase.sunrise.hour + response.data.moon_phase.sunrise.minute
def currenttime = response.data.moon_phase.current_time.hour + response.data.moon_phase.current_time.minute
if ((currenttime.toInteger() >= sunsettime.toInteger()) || (currenttime.toInteger() <= sunrisetime.toInteger())) {
return true
}
else {
return false
}
}
}

def motionActiveHandler(evt) {
log.debug "$evt.name: $evt.value"
if (evt.value == “active”) {
if (checkNighttime()) {
log.debug "turning on light"
switch1.on()
state.inactiveAt = now()
}
else if (evt.value == “inactive”) {
if(!state.inactiveAt) {
state.inactiveAt = now()
}
}
}
}

def scheduleCheck() {
log.debug "schedule check, ts = ${state.inactiveAt}"
if (state.inactiveAt) {
def elapsed = now() - state.inactiveAt
def threshold = 1000 * 60 * minutes1
if (elapsed >= threshold) {
log.debug "turning off lights"
switch1.off()
state.inactiveAt = null
}
else {
log.debug “${elapsed / 1000} sec since motion stopped”
}
}
}


(Freetobelee) #9

Paid work caught up to me, and I havn’t had a chance to test/debug this. any one else have luck?


(Emerson) #10

The post directly above this works with the api for sunrise and sunset if thats what you’re wondering.


(Freetobelee) #11

sweet, thanks!
I have some minor usability changes I think it could benefit from. is it possible to hardcode the underground API, so every user won’t have to register their own?


(Emerson) #12

I think the “call limit” is 500 api calls per day per free developer account. So that’s the only restriction.