Has Barkley Been Fed (Two Times a day)?


#1

I’m attempting to tweak the original Barkley smartapp to work for our use case, that is, feeding our dogs twice a day. Has anyone else got after it to work? I’ve tried creating two instances of the original Barkley smartapp, but then I always get a notification at night because of the way the time formatting works relative to midnight.

So, I’m trying to rewrite Barkley so that there is an AM & PM, but a little confused programmatically how to best achieve that (see ///HELP BELOW HERE/// section)

Thanks!

definition(
    name: "Has Barkley Been Fed?",
    namespace: "smartthings",
    author: "SmartThings",
    description: "Setup a schedule to be reminded to feed your pet. Purchase any SmartThings certified pet food feeder and install the Feed My Pet app, and set the time. You and your pet are ready to go. Your life just got smarter.",
    category: "Pets",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/dogfood_feeder.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/dogfood_feeder@2x.png"
)

preferences {
	section("Choose your pet feeder...") {
		input "feeder1", "capability.contactSensor", title: "Where?"
	}
	section("AM Feeding Time...") {
		input "timeAM", "time", title: "When?"
	}
	section("PM Feeding Time...") {
		input "timePM", "time", title: "When?"
	}
	section("Text me if I forget...") {
        input("recipients", "contact", title: "Send notifications to") {
            input "phone1", "phone", title: "Phone number?"
        }
	}
}

def installed()
{
	schedule(timeAM, "scheduleCheck")
	schedule(timePM, "scheduleCheck")
}

def updated()
{
	unsubscribe() //TODO no longer subscribe like we used to - clean this up after all apps updated
	unschedule()
	schedule(time, "scheduleCheck")
}

def scheduleCheck()
{
	log.trace "scheduledCheck"

	// def midnight = (new Date()).clearTime()
	def AM = new Date()
	AM.set(hourOfDay: 7)
	def PM = new Date()
	PM.set(hourOfDay: 17)
	def now = new Date()
	def AMfeederEvents = feeder1.eventsBetween(AM, now)
	def PMfeederEvents = feeder1.eventsBetween(PM, now)
	
	//HELP BELOW HERE///
	log.trace "Found ${feederEvents?.size() ?: 0} feeder events since $midnight"
	def feederOpened = feederEvents.count { it.value && it.value == "open" } > 0

	if (feederOpened) {
		log.debug "Feeder was opened since $midnight, no SMS required"
	} else {
        if (location.contactBookEnabled) {
            log.debug "Feeder was not opened since $midnight, texting contacts:${recipients?.size()}"
            sendNotificationToContacts("No one has fed the dog", recipients)
        }
        else {
            log.debug "Feeder was not opened since $midnight, texting $phone1"
            sendSms(phone1, "No one has fed the dog")
        }
	}
}

#2

Tried my best here, we’ll see how things go tonight when the PM conditionals get triggered.

definition(
    name: "Has Barkley Been Fed?",
    namespace: "smartthings",
    author: "SmartThings",
    description: "Setup a schedule to be reminded to feed your pet. Purchase any SmartThings certified pet food feeder and install the Feed My Pet app, and set the time. You and your pet are ready to go. Your life just got smarter.",
    category: "Pets",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/dogfood_feeder.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/dogfood_feeder@2x.png"
)

preferences {
	section("Choose your pet feeder...") {
		input "feeder1", "capability.contactSensor", title: "Where?"
	}
	section("AM Feeding Time...") {
		input "timeAM", "time", title: "When?"
	}
	section("PM Feeding Time...") {
		input "timePM", "time", title: "When?"
	}
	section("Text me if I forget...") {
        input("recipients", "contact", title: "Send notifications to") {
            input "phone1", "phone", title: "Phone number?"
        }
	}
}

def installed()
{
	schedule(timeAM, "scheduleCheck")
	schedule(timePM, "scheduleCheck")
}

def updated()
{
	unsubscribe() //TODO no longer subscribe like we used to - clean this up after all apps updated
	unschedule()
	schedule(time, "scheduleCheck")
}

def scheduleCheck()
{
	log.trace "scheduledCheck"

	// def midnight = (new Date()).clearTime()
	def AM = new Date()
	// set time for AM watcher to check for open event
	AM.set(hourOfDay: 6)
	def PM = new Date()
	// set time for PM watcher to check for open event
	PM.set(hourOfDay: 16)
	def now = new Date()
	def AMfeederEvents = feeder1.eventsBetween(AM, now)
	def PMfeederEvents = feeder1.eventsBetween(PM, now)
	
	//HELP BELOW HERE
	log.trace "Found ${AMfeederEvents?.size() ?: 0} feeder events since $AM"
	def AMfeederOpened = AMfeederEvents.count { it.value && it.value == "open" } > 0
	def PMfeederOpened = PMfeederEvents.count { it.value && it.value == "open" } > 0
	if (AMfeederOpened) {
		log.debug "Feeder was opened since $AM, no SMS required"
	} else {
        if (location.contactBookEnabled) {
            log.debug "Feeder was not opened since $AM, texting contacts:${recipients?.size()}"
            sendNotificationToContacts("No one has fed the dogs breakfast", recipients)
        }
        else {
            log.debug "Feeder was not opened since $AM, texting $phone1"
            sendSms(phone1, "No one has fed the dogs breakfast")
        }
	}
	
	if (PMfeederOpened) {
		log.debug "Feeder was opened since $PM, no SMS required"
		} else {
			if (location.contactBookEnabled) {
				log.debug "Feeder was not opened since $PM, texting contacts:${recipients?.size()}"
				sendNotificationToContacts("No one has fed the dogs supper", recipients)
			}
			else {
            log.debug "Feeder was not opened since $PM, texting $phone1"
            sendSms(phone1, "No one has fed the dogs supper")
        }
		}
	}



(Ricky) #3

How did this work out? I am looking for the same thing, pet food, twice a day.

Thanks!


#4

Not so hot. I have some ideas, but we just had our second baby and haven’t had any time to sit at a computer and test. I think the issue lies with the time specifications not interpreting as I expect


(Joe Purnell) #5

Congrats on the new baby! I’d love to see this feature added. I just bought a new sensor and set it up specifically for this use and was disappointed to realize it won’t work for my use case, two feedings a day. Would love to see this!


#6

I modified a smartapp for medicine reminders, so here’s what I’ve been using the past few months. Let’s you setup reminders up to four times a day :stuck_out_tongue:

/**

  • Copyright 2015 SmartThings
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.
  • Feed Perros Reminder
  • Author: SmartThings
    */

definition(
name: “Feed Perros Reminder”,
namespace: “smartthings”,
author: “SmartThings”,
description: “Set up a reminder so that if you forget to feed the dogs (determined by whether a cabinet or drawer has been opened) by specified time you get a notification or text message.”,
category: “Pets”,
iconUrl: “https://s3.amazonaws.com/smartapp-icons/Meta/dogfood_feeder.png”,
iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Meta/dogfood_feeder@2x.png
)

preferences {
section(“Choose your dog food container…”){
input “cabinet1”, “capability.contactSensor”, title: “Where?”
}
section(“Feed the dogs at…”){
input “time1”, “time”, title: "Time 1"
input “time2”, “time”, title: “Time 2”, required: false
input “time3”, “time”, title: “Time 3”, required: false
input “time4”, “time”, title: “Time 4”, required: false
}
section(“I forgot send me a notification and/or text message…”){
input(“recipients”, “contact”, title: “Send notifications to”) {
input “sendPush”, “enum”, title: “Push Notification”, required: false, options: [“Yes”, “No”]
input “phone1”, “phone”, title: “Phone Number”, required: false
}
}
section(“Time window (optional, defaults to plus or minus 15 minutes”) {
input “timeWindow”, “decimal”, title: “Minutes”, required: false
}
}

def installed()
{
initialize()
}

def updated()
{
unschedule()
initialize()
}

def initialize() {
def window = timeWindowMsec
[time1, time2, time3, time4].eachWithIndex {time, index ->
if (time != null) {
def endTime = new Date(timeToday(time, location?.timeZone).time + window)
log.debug “Scheduling check at $endTime”
//runDaily(endTime, “scheduleCheck${index}”)
switch (index) {
case 0:
schedule(endTime, scheduleCheck0)
break
case 1:
schedule(endTime, scheduleCheck1)
break
case 2:
schedule(endTime, scheduleCheck2)
break
case 3:
schedule(endTime, scheduleCheck3)
break
}
}
}
}

def scheduleCheck0() { scheduleCheck() }
def scheduleCheck1() { scheduleCheck() }
def scheduleCheck2() { scheduleCheck() }
def scheduleCheck3() { scheduleCheck() }

def scheduleCheck()
{
log.debug "scheduleCheck"
def t0 = new Date(now() - (2 * timeWindowMsec))
def t1 = new Date()
def cabinetOpened = cabinet1.eventsBetween(t0, t1).find{it.name == “contact” && it.value == “open”}
log.trace “Looking for events between $t0 and $t1: $cabinetOpened”

if (cabinetOpened) {
    log.trace "Dog food cabinet was opened since $midnight, no notification required"
} else {
    log.trace "Dog food cabinet was not opened since $midnight, sending notification"
    sendMessage()
}

}

private sendMessage() {
def msg = "Please remember to feed the dogs"
log.info msg
if (location.contactBookEnabled) {
sendNotificationToContacts(msg, recipients)
}
else {
if (phone1) {
sendSms(phone1, msg)
}
if (sendPush == “Yes”) {
sendPush(msg)
}
}
}

def getTimeWindowMsec() {
(timeWindow ?: 15) * 60000 as Long
}