mirror of
https://github.com/mtan93/SmartThingsPublic.git
synced 2026-03-15 13:10:51 +00:00
Compare commits
1 Commits
MSA-1794-1
...
MSA-1786-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
827f92179d |
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Smart Humidifier
|
||||
*
|
||||
* Copyright 2014 Sheikh Dawood
|
||||
*
|
||||
* 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: "Smart Dehumidifier",
|
||||
namespace: "Sheikhsphere",
|
||||
author: "Sheikh Dawood",
|
||||
description: "Turn on/off dehumidifier based on relative humidity from a sensor.",
|
||||
category: "Convenience",
|
||||
iconUrl: "https://graph.api.smartthings.com/api/devices/icons/st.Weather.weather12-icn",
|
||||
iconX2Url: "https://graph.api.smartthings.com/api/devices/icons/st.Weather.weather12-icn?displaySize=2x",
|
||||
iconX3Url: "https://graph.api.smartthings.com/api/devices/icons/st.Weather.weather12-icn?displaySize=3x",
|
||||
oauth: true)
|
||||
|
||||
|
||||
preferences {
|
||||
section("Monitor the humidity of:") {
|
||||
input "humiditySensor1", "capability.relativeHumidityMeasurement"
|
||||
}
|
||||
section("When the humidity rises above:") {
|
||||
input "humidityHigh", "number", title: "Percentage ?"
|
||||
}
|
||||
section("When the humidity drops below:") {
|
||||
input "humidityLow", "number", title: "Percentage ?"
|
||||
}
|
||||
section("Control Humidifier:") {
|
||||
input "switch1", "capability.switch"
|
||||
}
|
||||
section( "Notifications" ) {
|
||||
input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false
|
||||
input "phone1", "phone", title: "Send a Text Message?", required: false
|
||||
}
|
||||
}
|
||||
|
||||
def installed() {
|
||||
subscribe(humiditySensor1, "humidity", humidityHandler)
|
||||
}
|
||||
|
||||
def updated() {
|
||||
unsubscribe()
|
||||
subscribe(humiditySensor1, "humidity", humidityHandler)
|
||||
}
|
||||
|
||||
def humidityHandler(evt) {
|
||||
log.trace "humidity: $evt.value"
|
||||
log.trace "set high point: $humidityHigh"
|
||||
log.trace "set low point: $humidityLow"
|
||||
|
||||
def currentHumidity = Double.parseDouble(evt.value.replace("%", ""))
|
||||
def humidityHigh1 = humidityHigh
|
||||
def humidityLow1 = humidityLow
|
||||
def mySwitch = settings.switch1
|
||||
|
||||
if (currentHumidity >= humidityHigh1) {
|
||||
log.debug "Checking how long the humidity sensor has been reporting >= $humidityHigh1"
|
||||
|
||||
// Don't send a continuous stream of text messages
|
||||
def deltaMinutes = 10
|
||||
def timeAgo = new Date(now() - (1000 * 60 * deltaMinutes).toLong())
|
||||
def recentEvents = humiditySensor1.eventsSince(timeAgo)
|
||||
log.trace "Found ${recentEvents?.size() ?: 0} events in the last $deltaMinutes minutes"
|
||||
def alreadySentSms1 = recentEvents.count { Double.parseDouble(it.value.replace("%", "")) >= humidityHigh1 } > 1
|
||||
|
||||
if (alreadySentSms1) {
|
||||
log.debug "Notification already sent within the last $deltaMinutes minutes"
|
||||
|
||||
} else {
|
||||
if (state.lastStatus != "on") {
|
||||
log.debug "Humidity Rose Above $humidityHigh1: sending SMS and deactivating $mySwitch"
|
||||
send("${humiditySensor1.label} sensed high humidity level of ${evt.value}, turning on ${switch1.label}")
|
||||
switch1?.on()
|
||||
state.lastStatus = "on"
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (currentHumidity <= humidityLow1) {
|
||||
log.debug "Checking how long the humidity sensor has been reporting <= $humidityLow1"
|
||||
|
||||
// Don't send a continuous stream of text messages
|
||||
def deltaMinutes = 10
|
||||
def timeAgo = new Date(now() - (1000 * 60 * deltaMinutes).toLong())
|
||||
def recentEvents = humiditySensor1.eventsSince(timeAgo)
|
||||
log.trace "Found ${recentEvents?.size() ?: 0} events in the last $deltaMinutes minutes"
|
||||
def alreadySentSms2 = recentEvents.count { Double.parseDouble(it.value.replace("%", "")) <= humidityLow1 } > 1
|
||||
|
||||
if (alreadySentSms2) {
|
||||
log.debug "Notification already sent within the last $deltaMinutes minutes"
|
||||
|
||||
} else {
|
||||
if (state.lastStatus != "off") {
|
||||
log.debug "Humidity Dropped Below $humidityLow1: sending SMS and activating $mySwitch"
|
||||
send("${humiditySensor1.label} sensed low humidity level of ${evt.value}, turning off ${switch1.label}")
|
||||
switch1?.off()
|
||||
state.lastStatus = "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
//log.debug "Humidity remained in threshold: sending SMS to $phone1 and activating $mySwitch"
|
||||
//send("${humiditySensor1.label} sensed humidity level of ${evt.value} is within threshold, keeping off ${switch1.label}")
|
||||
//switch1?.off()
|
||||
}
|
||||
}
|
||||
|
||||
private send(msg) {
|
||||
if ( sendPushMessage != "No" ) {
|
||||
log.debug( "sending push message" )
|
||||
sendPush( msg )
|
||||
}
|
||||
|
||||
if ( phone1 ) {
|
||||
log.debug( "sending text message" )
|
||||
sendSms( phone1, msg )
|
||||
}
|
||||
|
||||
log.debug msg
|
||||
}
|
||||
|
||||
@@ -1,334 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Speaker Control
|
||||
*
|
||||
* Author: SmartThings
|
||||
*
|
||||
* Date: 2013-12-10
|
||||
* Modifications Author: Richard Bourne
|
||||
* Date: 2017-18-02
|
||||
* Volume control currently does not work for R1 speakers.
|
||||
*/
|
||||
definition(
|
||||
name: "Samsung Multiroom URL Speaker Control",
|
||||
namespace: "smartthings",
|
||||
author: "Richard Bourne",
|
||||
description: "Play or pause your Samsung Speaker when certain actions take place in your home. Use the URL to define source of audio e.g. Radio/audio server.",
|
||||
category: "SmartThings Labs",
|
||||
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
|
||||
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png"
|
||||
)
|
||||
|
||||
preferences {
|
||||
page(name: "mainPage", title: "Control your Speaker when something happens", install: true, uninstall: true)
|
||||
page(name: "timeIntervalInput", title: "Only during a certain time") {
|
||||
section {
|
||||
input "starting", "time", title: "Starting", required: false
|
||||
input "ending", "time", title: "Ending", required: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def mainPage() {
|
||||
dynamicPage(name: "mainPage") {
|
||||
def anythingSet = anythingSet()
|
||||
if (anythingSet) {
|
||||
section("When..."){
|
||||
ifSet "motion", "capability.motionSensor", title: "Motion Here", required: false, multiple: true
|
||||
ifSet "contact", "capability.contactSensor", title: "Contact Opens", required: false, multiple: true
|
||||
ifSet "contactClosed", "capability.contactSensor", title: "Contact Closes", required: false, multiple: true
|
||||
ifSet "acceleration", "capability.accelerationSensor", title: "Acceleration Detected", required: false, multiple: true
|
||||
ifSet "mySwitch", "capability.switch", title: "Switch Turned On", required: false, multiple: true
|
||||
ifSet "mySwitchOff", "capability.switch", title: "Switch Turned Off", required: false, multiple: true
|
||||
ifSet "arrivalPresence", "capability.presenceSensor", title: "Arrival Of", required: false, multiple: true
|
||||
ifSet "departurePresence", "capability.presenceSensor", title: "Departure Of", required: false, multiple: true
|
||||
ifSet "smoke", "capability.smokeDetector", title: "Smoke Detected", required: false, multiple: true
|
||||
ifSet "water", "capability.waterSensor", title: "Water Sensor Wet", required: false, multiple: true
|
||||
ifSet "button1", "capability.button", title: "Button Press", required:false, multiple:true //remove from production
|
||||
ifSet "triggerModes", "mode", title: "System Changes Mode", required: false, multiple: true
|
||||
ifSet "timeOfDay", "time", title: "At a Scheduled Time", required: false
|
||||
}
|
||||
}
|
||||
section(anythingSet ? "Select additional triggers" : "When...", hideable: anythingSet, hidden: true){
|
||||
ifUnset "motion", "capability.motionSensor", title: "Motion Here", required: false, multiple: true
|
||||
ifUnset "contact", "capability.contactSensor", title: "Contact Opens", required: false, multiple: true
|
||||
ifUnset "contactClosed", "capability.contactSensor", title: "Contact Closes", required: false, multiple: true
|
||||
ifUnset "acceleration", "capability.accelerationSensor", title: "Acceleration Detected", required: false, multiple: true
|
||||
ifUnset "mySwitch", "capability.switch", title: "Switch Turned On", required: false, multiple: true
|
||||
ifUnset "mySwitchOff", "capability.switch", title: "Switch Turned Off", required: false, multiple: true
|
||||
ifUnset "arrivalPresence", "capability.presenceSensor", title: "Arrival Of", required: false, multiple: true
|
||||
ifUnset "departurePresence", "capability.presenceSensor", title: "Departure Of", required: false, multiple: true
|
||||
ifUnset "smoke", "capability.smokeDetector", title: "Smoke Detected", required: false, multiple: true
|
||||
ifUnset "water", "capability.waterSensor", title: "Water Sensor Wet", required: false, multiple: true
|
||||
ifUnset "button1", "capability.button", title: "Button Press", required:false, multiple:true //remove from production
|
||||
ifUnset "triggerModes", "mode", title: "System Changes Mode", required: false, multiple: true
|
||||
ifUnset "timeOfDay", "time", title: "At a Scheduled Time", required: false
|
||||
}
|
||||
section("Perform this action"){
|
||||
input "actionType", "enum", title: "Action?", required: true, defaultValue: "play", options: [
|
||||
"Play URL",
|
||||
"Play",
|
||||
"Stop Playing",
|
||||
"Toggle Play/Pause",
|
||||
"Skip to Next Track",
|
||||
"Play Previous Track"
|
||||
|
||||
]
|
||||
}
|
||||
section {
|
||||
input "samsungspeaker", "capability.musicPlayer", title: "Speaker music player", required: true
|
||||
}
|
||||
section("More options", hideable: true, hidden: true) {
|
||||
input "volume", "number", title: "Set the volume", description: "0-100%", required: false
|
||||
input "frequency", "decimal", title: "Minimum time between actions (defaults to every event)", description: "Minutes", required: false
|
||||
href "timeIntervalInput", title: "Only during a certain time", description: timeLabel ?: "Tap to set", state: timeLabel ? "complete" : "incomplete"
|
||||
input "days", "enum", title: "Only on certain days of the week", multiple: true, required: false,
|
||||
options: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
|
||||
if (settings.modes) {
|
||||
input "modes", "mode", title: "Only when mode is", multiple: true, required: false
|
||||
}
|
||||
input "oncePerDay", "bool", title: "Only once per day", required: false, defaultValue: false
|
||||
}
|
||||
section([mobileOnly:true]) {
|
||||
label title: "Assign a name", required: false
|
||||
mode title: "Set for specific mode(s)"
|
||||
}
|
||||
section("Define a URL") {
|
||||
input "URL", "text", title: "URL link:", defaultValue: "http://bbcmedia.ic.llnwd.net/stream/bbcmedia_radio1_mf_p", required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private anythingSet() {
|
||||
for (name in ["motion","contact","contactClosed","acceleration","mySwitch","mySwitchOff","arrivalPresence","departurePresence","smoke","water","button1","triggerModes","timeOfDay"]) {
|
||||
if (settings[name]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private ifUnset(Map options, String name, String capability) {
|
||||
if (!settings[name]) {
|
||||
input(options, name, capability)
|
||||
}
|
||||
}
|
||||
|
||||
private ifSet(Map options, String name, String capability) {
|
||||
if (settings[name]) {
|
||||
input(options, name, capability)
|
||||
}
|
||||
}
|
||||
|
||||
def installed() {
|
||||
log.debug "Installed with settings: ${settings}"
|
||||
subscribeToEvents()
|
||||
}
|
||||
|
||||
def updated() {
|
||||
log.debug "Updated with settings: ${settings}"
|
||||
unsubscribe()
|
||||
unschedule()
|
||||
subscribeToEvents()
|
||||
}
|
||||
|
||||
def subscribeToEvents() {
|
||||
log.trace "subscribeToEvents()"
|
||||
subscribe(app, appTouchHandler)
|
||||
subscribe(contact, "contact.open", eventHandler)
|
||||
subscribe(contactClosed, "contact.closed", eventHandler)
|
||||
subscribe(acceleration, "acceleration.active", eventHandler)
|
||||
subscribe(motion, "motion.active", eventHandler)
|
||||
subscribe(mySwitch, "switch.on", eventHandler)
|
||||
subscribe(mySwitchOff, "switch.off", eventHandler)
|
||||
subscribe(arrivalPresence, "presence.present", eventHandler)
|
||||
subscribe(departurePresence, "presence.not present", eventHandler)
|
||||
subscribe(smoke, "smoke.detected", eventHandler)
|
||||
subscribe(smoke, "smoke.tested", eventHandler)
|
||||
subscribe(smoke, "carbonMonoxide.detected", eventHandler)
|
||||
subscribe(water, "water.wet", eventHandler)
|
||||
subscribe(button1, "button.pushed", eventHandler)
|
||||
|
||||
if (triggerModes) {
|
||||
subscribe(location, modeChangeHandler)
|
||||
}
|
||||
|
||||
if (timeOfDay) {
|
||||
schedule(timeOfDay, scheduledTimeHandler)
|
||||
}
|
||||
}
|
||||
|
||||
def eventHandler(evt) {
|
||||
if (allOk) {
|
||||
def lastTime = state[frequencyKey(evt)]
|
||||
if (oncePerDayOk(lastTime)) {
|
||||
if (frequency) {
|
||||
if (lastTime == null || now() - lastTime >= frequency * 60000) {
|
||||
takeAction(evt)
|
||||
}
|
||||
else {
|
||||
log.debug "Not taking action because $frequency minutes have not elapsed since last action"
|
||||
}
|
||||
}
|
||||
else {
|
||||
takeAction(evt)
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.debug "Not taking action because it was already taken today"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def modeChangeHandler(evt) {
|
||||
log.trace "modeChangeHandler $evt.name: $evt.value ($triggerModes)"
|
||||
if (evt.value in triggerModes) {
|
||||
eventHandler(evt)
|
||||
}
|
||||
}
|
||||
|
||||
def scheduledTimeHandler() {
|
||||
eventHandler(null)
|
||||
}
|
||||
|
||||
def appTouchHandler(evt) {
|
||||
takeAction(evt)
|
||||
}
|
||||
|
||||
private takeAction(evt) {
|
||||
log.debug "takeAction($actionType)"
|
||||
def options = [:]
|
||||
|
||||
if (settings.volume) {
|
||||
log.debug "volume altered ($options)"
|
||||
samsungspeaker.setLevel(settings.volume as Number)
|
||||
pause(500)
|
||||
}
|
||||
|
||||
switch (actionType) {
|
||||
case "Play":
|
||||
options ? samsungspeaker.on(options) : samsungspeaker.on()
|
||||
break
|
||||
case "Stop Playing":
|
||||
options ? samsungspeaker.off(options) : samsungspeaker.off()
|
||||
break
|
||||
case "Toggle Play/Pause":
|
||||
def currentStatus = samsungspeaker.currentValue("status")
|
||||
if (currentStatus == "playing") {
|
||||
options ? samsungspeaker.pause(options) : samsungspeaker.pause()
|
||||
}
|
||||
else {
|
||||
options ? samsungspeaker.play(options) : samsungspeaker.play()
|
||||
}
|
||||
break
|
||||
case "Skip to Next Track":
|
||||
options ? samsungspeaker.nextTrack(options) : samsungspeaker.nextTrack()
|
||||
break
|
||||
case "Play Previous Track":
|
||||
options ? samsungspeaker.previousTrack(options) : samsungspeaker.previousTrack()
|
||||
break
|
||||
case "Play URL":
|
||||
samsungspeaker.playTrack(settings.URL as String)
|
||||
break
|
||||
case "5":
|
||||
samsungspeaker.playTrack(settings.URL as String)
|
||||
break
|
||||
break
|
||||
default:
|
||||
log.error "Action type '$actionType' not defined"
|
||||
}
|
||||
|
||||
if (frequency) {
|
||||
state.lastActionTimeStamp = now()
|
||||
}
|
||||
}
|
||||
|
||||
private frequencyKey(evt) {
|
||||
//evt.deviceId ?: evt.value
|
||||
"lastActionTimeStamp"
|
||||
}
|
||||
|
||||
private dayString(Date date) {
|
||||
def df = new java.text.SimpleDateFormat("yyyy-MM-dd")
|
||||
if (location.timeZone) {
|
||||
df.setTimeZone(location.timeZone)
|
||||
}
|
||||
else {
|
||||
df.setTimeZone(TimeZone.getTimeZone("America/New_York"))
|
||||
}
|
||||
df.format(date)
|
||||
}
|
||||
|
||||
private oncePerDayOk(Long lastTime) {
|
||||
def result = true
|
||||
if (oncePerDay) {
|
||||
result = lastTime ? dayString(new Date()) != dayString(new Date(lastTime)) : true
|
||||
log.trace "oncePerDayOk = $result"
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
// TODO - centralize somehow
|
||||
private getAllOk() {
|
||||
modeOk && daysOk && timeOk
|
||||
}
|
||||
|
||||
private getModeOk() {
|
||||
def result = !modes || modes.contains(location.mode)
|
||||
log.trace "modeOk = $result"
|
||||
result
|
||||
}
|
||||
|
||||
private getDaysOk() {
|
||||
def result = true
|
||||
if (days) {
|
||||
def df = new java.text.SimpleDateFormat("EEEE")
|
||||
if (location.timeZone) {
|
||||
df.setTimeZone(location.timeZone)
|
||||
}
|
||||
else {
|
||||
df.setTimeZone(TimeZone.getTimeZone("America/New_York"))
|
||||
}
|
||||
def day = df.format(new Date())
|
||||
result = days.contains(day)
|
||||
}
|
||||
log.trace "daysOk = $result"
|
||||
result
|
||||
}
|
||||
|
||||
private getTimeOk() {
|
||||
def result = true
|
||||
if (starting && ending) {
|
||||
def currTime = now()
|
||||
def start = timeToday(starting, location?.timeZone).time
|
||||
def stop = timeToday(ending, location?.timeZone).time
|
||||
result = start < stop ? currTime >= start && currTime <= stop : currTime <= stop || currTime >= start
|
||||
}
|
||||
log.trace "timeOk = $result"
|
||||
result
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
(starting && ending) ? hhmm(starting) + "-" + hhmm(ending, "h:mm a z") : ""
|
||||
}
|
||||
// TODO - End Centralize
|
||||
|
||||
Reference in New Issue
Block a user