Update auto-humidity-vent.groovy
[smartapps.git] / official / severe-weather-alert.groovy
1 /**
2  *  Copyright 2015 SmartThings
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  *  in compliance with the License. You may obtain a copy of the License at:
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
10  *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
11  *  for the specific language governing permissions and limitations under the License.
12  *
13  *  Severe Weather Alert
14  *
15  *  Author: SmartThings
16  *  Date: 2013-03-04
17  */
18 definition(
19     name: "Severe Weather Alert",
20     namespace: "smartthings",
21     author: "SmartThings",
22     description: "Get a push notification when severe weather is in your area.",
23     category: "Safety & Security",
24     iconUrl: "https://s3.amazonaws.com/smartapp-icons/SafetyAndSecurity/App-SevereWeather.png",
25     iconX2Url: "https://s3.amazonaws.com/smartapp-icons/SafetyAndSecurity/App-SevereWeather@2x.png"
26 )
27
28 preferences {
29
30   if (!(location.zipCode || ( location.latitude && location.longitude )) && location.channelName == 'samsungtv') {
31                 section { paragraph title: "Note:", "Location is required for this SmartApp. Go to 'Location Name' settings to setup your correct location." }
32         }
33
34   if (location.channelName != 'samsungtv') {
35                 section( "Set your location" ) { input "zipCode", "text", title: "Zip code" }
36   }
37
38         section ("In addition to push notifications, send text alerts to...") {
39       input("recipients", "contact", title: "Send notifications to") {
40           input "phone1", "phone", title: "Phone Number 1", required: false
41           input "phone2", "phone", title: "Phone Number 2", required: false
42           input "phone3", "phone", title: "Phone Number 3", required: false
43       }
44          }
45 }
46
47 def installed() {
48         log.debug "Installed with settings: ${settings}"
49         scheduleJob()
50 }
51
52 def updated() {
53         log.debug "Updated with settings: ${settings}"
54     unschedule()
55         scheduleJob()
56 }
57
58 def scheduleJob() {
59         def sec = Math.round(Math.floor(Math.random() * 60))
60         def min = Math.round(Math.floor(Math.random() * 60))
61         def cron = "$sec $min * * * ?"
62         schedule(cron, "checkForSevereWeather")
63 }
64
65 def checkForSevereWeather() {
66         def alerts
67         if(locationIsDefined()) {
68                 if(zipcodeIsValid()) {
69                         alerts = getWeatherFeature("alerts", zipCode)?.alerts
70                 } else {
71                         log.warn "Severe Weather Alert: Invalid zipcode entered, defaulting to location's zipcode"
72                         alerts = getWeatherFeature("alerts")?.alerts
73                 }
74         } else {
75                 log.warn "Severe Weather Alert: Location is not defined"
76         }
77
78         def newKeys = alerts?.collect{it.type + it.date_epoch} ?: []
79         log.debug "Severe Weather Alert: newKeys: $newKeys"
80
81         def oldKeys = state.alertKeys ?: []
82         log.debug "Severe Weather Alert: oldKeys: $oldKeys"
83
84         if (newKeys != oldKeys) {
85
86                 state.alertKeys = newKeys
87
88                 alerts.each {alert ->
89                         if (!oldKeys.contains(alert.type + alert.date_epoch) && descriptionFilter(alert.description)) {
90                                 def msg = "Weather Alert! ${alert.description} from ${alert.date} until ${alert.expires}"
91                                 send(msg)
92                         }
93                 }
94         }
95 }
96
97 def descriptionFilter(String description) {
98         def filterList = ["special", "statement", "test"]
99         def passesFilter = true
100         filterList.each() { word ->
101                 if(description.toLowerCase().contains(word)) { passesFilter = false }
102         }
103         passesFilter
104 }
105
106 def locationIsDefined() {
107         zipcodeIsValid() || location.zipCode || ( location.latitude && location.longitude )
108 }
109
110 def zipcodeIsValid() {
111         zipcode && zipcode.isNumber() && zipcode.size() == 5
112 }
113
114 private send(message) {
115     if (location.contactBookEnabled) {
116         log.debug("sending notifications to: ${recipients?.size()}")
117         sendNotificationToContacts(msg, recipients)
118     }
119     else {
120         sendPush message
121         if (settings.phone1) {
122             sendSms phone1, message
123         }
124         if (settings.phone2) {
125             sendSms phone2, message
126         }
127         if (settings.phone3) {
128             sendSms phone3, message
129         }
130     }
131 }