2 * Copyright 2015 SmartThings
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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
13 * Severe Weather Alert
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"
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." }
34 if (location.channelName != 'samsungtv') {
35 section( "Set your location" ) { input "zipCode", "text", title: "Zip code" }
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
48 log.debug "Installed with settings: ${settings}"
53 log.debug "Updated with settings: ${settings}"
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")
65 def checkForSevereWeather() {
67 if(locationIsDefined()) {
68 if(zipcodeIsValid()) {
69 alerts = getWeatherFeature("alerts", zipCode)?.alerts
71 log.warn "Severe Weather Alert: Invalid zipcode entered, defaulting to location's zipcode"
72 alerts = getWeatherFeature("alerts")?.alerts
75 log.warn "Severe Weather Alert: Location is not defined"
78 def newKeys = alerts?.collect{it.type + it.date_epoch} ?: []
79 log.debug "Severe Weather Alert: newKeys: $newKeys"
81 def oldKeys = state.alertKeys ?: []
82 log.debug "Severe Weather Alert: oldKeys: $oldKeys"
84 if (newKeys != oldKeys) {
86 state.alertKeys = newKeys
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}"
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 }
106 def locationIsDefined() {
107 zipcodeIsValid() || location.zipCode || ( location.latitude && location.longitude )
110 def zipcodeIsValid() {
111 zipcode && zipcode.isNumber() && zipcode.size() == 5
114 private send(message) {
115 if (location.contactBookEnabled) {
116 log.debug("sending notifications to: ${recipients?.size()}")
117 sendNotificationToContacts(msg, recipients)
121 if (settings.phone1) {
122 sendSms phone1, message
124 if (settings.phone2) {
125 sendSms phone2, message
127 if (settings.phone3) {
128 sendSms phone3, message