mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-10 21:03:04 +00:00
238 lines
8.4 KiB
Groovy
238 lines
8.4 KiB
Groovy
/**
|
|
* Switch Timer
|
|
*
|
|
* Copyright 2016 Joe Saporito
|
|
*
|
|
* 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.
|
|
*
|
|
*/
|
|
definition(
|
|
name: "Switch Timer",
|
|
namespace: "js",
|
|
author: "Joe Saporito",
|
|
description: "Turns on switches that are not already on for a determined amount of time after an event. ",
|
|
category: "Convenience",
|
|
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
|
|
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
|
|
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
|
|
|
|
|
|
preferences {
|
|
|
|
page(name: "settings")
|
|
page(name: "certainTime")
|
|
page(name: "renameLabel")
|
|
}
|
|
|
|
def settings() {
|
|
dynamicPage(name: "settings", title: "Turn switches off after some minutes, unless already on", uninstall: true, install: true) {
|
|
section("Choose one or more, when..."){
|
|
input "people", "capability.presenceSensor", title: "Arrival Of", required: false, multiple: true
|
|
input "doors", "capability.contactSensor", title: "Doors", required: false, multiple: true
|
|
input "motion", "capability.motionSensor", title: "Motion Here", required: false, multiple: true
|
|
}
|
|
section("Turn on switches"){
|
|
input "switches", "capability.switch", multiple: true, required: true
|
|
}
|
|
section("Turn off after") {
|
|
input "waitTime", "decimal", title: "Minutes", required: true
|
|
}
|
|
section(title: "Additional Options") {
|
|
def timeLabel = timeIntervalLabel()
|
|
href "certainTime", title: "Only during a certain time", description: timeLabel ?: "Tap to set", state: timeLabel ? "complete" : null
|
|
def appLabel = getDefaultLabel()
|
|
href "renameLabel", title: "Rename '" + appLabel + "'", description: ""
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
def certainTime() {
|
|
dynamicPage(name:"certainTime",title: "Only during a certain time", uninstall: false) {
|
|
section() {
|
|
input "startEnum", "enum", title: "Starting at", options: ["A specific time", "Sunrise", "Sunset"], defaultValue: "A specific time", submitOnChange: true
|
|
if(startEnum in [null, "A specific time"]) input "startTime", "time", title: "Start time", required: false
|
|
else {
|
|
if(startEnum == "Sunrise") input "startSunriseOffset", "number", range: "*..*", title: "Offset in minutes (+/-)", required: false
|
|
else if(startEnum == "Sunset") input "startSunsetOffset", "number", range: "*..*", title: "Offset in minutes (+/-)", required: false
|
|
}
|
|
}
|
|
|
|
section() {
|
|
input "endEnum", "enum", title: "Ending at", options: ["A specific time", "Sunrise", "Sunset"], defaultValue: "A specific time", submitOnChange: true
|
|
if(endEnum in [null, "A specific time"]) input "endTime", "time", title: "End time", required: false
|
|
else {
|
|
if(endEnum == "Sunrise") input "endSunriseOffset", "number", range: "*..*", title: "Offset in minutes (+/-)", required: false
|
|
else if(endEnum == "Sunset") input "endSunsetOffset", "number", range: "*..*", title: "Offset in minutes (+/-)", required: false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
def renameLabel() {
|
|
dynamicPage(name:"renameLabel",title: "Rename", uninstall: false) {
|
|
section() {
|
|
input "appLabelText", "text", title: "Rename to", defaultValue: (appLabelText ? appLabelText : getDefaultLabel()), required: false
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
def installed() {
|
|
log.debug "Installed with settings: ${settings}"
|
|
|
|
initialize()
|
|
updateLabel()
|
|
}
|
|
|
|
def updated() {
|
|
log.debug "Updated with settings: ${settings}"
|
|
unsubscribe()
|
|
initialize()
|
|
updateLabel()
|
|
}
|
|
|
|
def initialize() {
|
|
subscribeToEvents()
|
|
}
|
|
|
|
def subscribeToEvents() {
|
|
subscribe(doors, "contact.open", activateHandler)
|
|
subscribe(people, "presence.present", activateHandler)
|
|
subscribe(motion, "motion.active", activateHandler)
|
|
}
|
|
|
|
// TODO: implement event handlers
|
|
def activateHandler(evt) {
|
|
if (checkTime()) {
|
|
log.trace("$evt.name triggered")
|
|
turnOn()
|
|
}
|
|
}
|
|
|
|
def turnOn() {
|
|
if(state.offSwitches) {
|
|
runIn(waitTime * 60, turnOff)
|
|
return
|
|
}
|
|
def offSwitches = getOffSwitches()
|
|
for (s in offSwitches) {
|
|
s.on()
|
|
}
|
|
if (offSwitches.size() > 0) {
|
|
state.offSwitches = offSwitches.displayName
|
|
runIn(waitTime * 60, turnOff)
|
|
}
|
|
}
|
|
|
|
def turnOff() {
|
|
if (state.offSwitches) {
|
|
def offSwitches = switches.findAll {
|
|
it.displayName in state.offSwitches
|
|
}
|
|
for (s in offSwitches) {
|
|
s.off()
|
|
}
|
|
state.offSwitches = null
|
|
}
|
|
}
|
|
|
|
def updateLabel() {
|
|
if (appLabelText) {
|
|
if (appLabelText != app.label) {
|
|
log.trace("Renamed to $appLabelText")
|
|
app.updateLabel(appLabelText)
|
|
}
|
|
}
|
|
else {
|
|
def label = getDefaultLabel()
|
|
log.trace("Renamed to $label")
|
|
app.updateLabel(label)
|
|
|
|
}
|
|
}
|
|
|
|
private getDefaultLabel() {
|
|
def label = "Switch Timer"
|
|
|
|
if (switches) {
|
|
label = "Timer for " + switches[0].displayName
|
|
}
|
|
|
|
return label
|
|
}
|
|
|
|
private getOffSwitches() {
|
|
def offSwitches = switches.findAll {
|
|
it.currentSwitch == "off" ||
|
|
it.currentSwitch == null
|
|
}
|
|
return offSwitches
|
|
}
|
|
private checkTime() {
|
|
def result = true
|
|
|
|
if ((startTime && endTime) ||
|
|
(startTime && endEnum in ["Sunrise", "Sunset"]) ||
|
|
(startEnum in ["Sunrise", "Sunset"] && endTime) ||
|
|
(startEnum in ["Sunrise", "Sunset"] && endEnum in ["Sunrise", "Sunset"])) {
|
|
def currentTime = now()
|
|
def start = null
|
|
def stop = null
|
|
def sun = getSunriseAndSunset(zipCode: zipCode, sunriseOffset: startSunriseOffset, sunsetOffset: startSunsetOffset)
|
|
|
|
if (startEnum == "Sunrise")
|
|
start = sun.sunrise.time
|
|
else if (startEnum == "Sunset")
|
|
start = sun.sunset.time
|
|
else if (startTime)
|
|
start = timeToday(startTime,location.timeZone).time
|
|
|
|
sun = getSunriseAndSunset(zipCode: zipCode, sunriseOffset: endSunriseOffset, sunsetOffset: endSunsetOffset)
|
|
if (endEnum == "Sunrise")
|
|
stop = sun.sunrise.time
|
|
else if (endEnum == "Sunset")
|
|
stop = sun.sunset.time
|
|
else if (endTime)
|
|
stop = timeToday(endTime,location.timeZone).time
|
|
|
|
result = start < stop ? currentTime >= start && currentTime <= stop : currentTime <= stop || currentTime >= start
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
private hideOptionsSection() {
|
|
(startTime || endTime || startEnum || endEnum) ? false : true
|
|
}
|
|
|
|
private offset(value) {
|
|
def result = value ? ((value > 0 ? "+" : "") + value + " min") : ""
|
|
}
|
|
|
|
private hhmm(time, fmt = "h:mm a") {
|
|
def t = timeToday(time, location.timeZone)
|
|
def f = new java.text.SimpleDateFormat(fmt)
|
|
f.setTimeZone(location.timeZone ?: timeZone(time))
|
|
f.format(t)
|
|
}
|
|
|
|
private timeIntervalLabel() {
|
|
def result = ""
|
|
if (startEnum == "Sunrise" && endEnum == "Sunrise") result = "Sunrise" + offset(startSunriseOffset) + " to " + "Sunrise" + offset(endSunriseOffset)
|
|
else if (startEnum == "Sunrise" && endEnum == "Sunset") result = "Sunrise" + offset(startSunriseOffset) + " to " + "Sunset" + offset(endSunsetOffset)
|
|
else if (startEnum == "Sunset" && endEnum == "Sunrise") result = "Sunset" + offset(startSunsetOffset) + " to " + "Sunrise" + offset(endSunriseOffset)
|
|
else if (startEnum == "Sunset" && endEnum == "Sunset") result = "Sunset" + offset(startSunsetOffset) + " to " + "Sunset" + offset(endSunsetOffset)
|
|
else if (startEnum == "Sunrise" && endTime) result = "Sunrise" + offset(startSunriseOffset) + " to " + hhmm(endTime, "h:mm a z")
|
|
else if (startEnum == "Sunset" && endTime) result = "Sunset" + offset(startSunsetOffset) + " to " + hhmm(endTime, "h:mm a z")
|
|
else if (startTime && endEnum == "Sunrise") result = hhmm(startTime) + " to " + "Sunrise" + offset(endSunriseOffset)
|
|
else if (startTime && endEnum == "Sunset") result = hhmm(startTime) + " to " + "Sunset" + offset(endSunsetOffset)
|
|
else if (startTime && endTime) result = hhmm(startTime) + " to " + hhmm(endTime, "h:mm a z")
|
|
} |