Best way to get Email notifications based on events?


#1

We do managed IT services and have installed Smartthings Hubs at 4 or 5 of our clients to monitor their server room / IT closet environments for door access and temperatures. So I have one smartthings account with multiple locations to cover these various rooms and hubs. Each room has 1 smartthings multi contact sensor.

Up until now, I have configured each room to send me a SMS message if the temperature gets too high, or too low, or if the door opens during a time that it shouldn’t be opening. Unfortunately, I can’t have it SMS multiple phone numbers in SHM. Ideally though, I’d like to get these notifications via email.

The only semi-reasonable way that I have found to get email notifications based on certain device capabilities is a IFTTT recipe. Unfortunately, IFTTT only works with one location. I’ve heard mixed results on creating multiple IFTTT accounts to link to a single SmartThings account, yet a different location for each IFTTT account.

It seems so simple to me, yet it doesn’t seem to be readily available. If temperature exceeds certain degree, email [address] with subject: [location name], [device name], [temperature reading], and then have it only do so once per X hours. Same thing with open/close. Email me with location name, device name, door opened at time.

My only thought is to re-write the “Notify Me When” app to do a web request, instead of push or SMS notification, and somehow include certain parameters like location name and device name, and then use a more powerful web scripting language to process that web request, and have it send me the email?


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #2

Yes… that is the correct approach.

Folks that know me from back in early 2015, know that I advocate for new common standard “Capabilities” for the platform.

SMS, Push Notifications, Emails, etc., etc., etc., should, IMHO, be implemented modularly via a Device Type Instance; just as you can allow a SmartApp user to select and use a light switch to indicate an Alert, you should be able to let the user select and use any number of “capability.sendMessage” devices.

Regardless, you can hard code this into your SmartApp for now, and/or write a DTH with custom Commands. Or follow this Topic below for more info and advocacy?


#3

Sounds good. Is there a more updated “Notify Me When” app? The built-in ST one doesn’t have a ton of capabilities and I’d rather spend my time coding the web services portion than re-coding the types of notifications I can configure in Notify Me When (example: temperature sensing isn’t a capability to event monitor it seems).


(ActionTiles.com co-founder Terry @ActionTiles; GitHub: @cosmicpuppy) #4

Frankly, if you do have some time, it would be wonderful if you tried writing email service as a DTH so that it could be plugged into any SmartApp.

It seems that a Capability officially does exist now; though I’m sure there are very few, if any, examples to work from. Search the SmartThings Public github just in case.

http://docs.smartthings.com/en/latest/capabilities-reference.html#notification


#5

I’ve written a custom smartapp in conjunction with 10 lines of PHP code that you would also need to host somewhere. It works great for me! I’m thrilled to finally have this capability across multiple locations on a single SmartThings account. I’ve written the code specifically for my purposes, but it wouldn’t take long to make it more generically acceptable. I’m heading out of town for a week but if there is interest I will generalize the code and post it when I get back.


#6

Email Notifications SmartApp v1.0 (requires this SmartApp and the PHP code below)

Note you need to change the URI field (2 spots) in this smartapp to match the location of the notify.php file below!

/**
 *  Copyright 2016 Inbound Computer Solutions, LLC
 *
 *  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.
 *
 *	Version 1.0
 *
 */
definition(
	name: "Email Notifications",
	namespace: "InboundCS",
	author: "InboundCS",
	description: "Receive email notifications when certain things happen....",
	category: "Convenience",
	iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/mail_contact.png",
	iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/mail_contact@2x.png"
)

preferences {
	section("Notify which email address:"){
		input "email", "text", title: "E-Mail Address", required: true
	}
    
    section("When the following happens:"){
		input "lowbatt", "capability.battery", title: "Batteries Get Below 20%", multiple: true, required: false
		input "tempSensor", "capability.temperatureMeasurement", title: "Temperature Sensor", required: false, multiple: true
		input "temperature", "number", title: "Temp Gets Above", defaultValue: 80, required: false
		input "temperaturelow", "number", title: "Temp Gets Below", defaultValue: 50, required: false
		input "contact", "capability.contactSensor", title: "Door Opens", required: false, multiple: true
		input "contactClosed", "capability.contactSensor", title: "Door Closes", required: false, multiple: true	
		input "water", "capability.waterSensor", title: "Water Detected", required: false, multiple: true
		input "smoke", "capability.smokeDetector", title: "Smoke Detected", required: false, multiple: true
		input "button", "capability.button", title: "Button Pushed", required: false, multiple: true
		input "motion", "capability.motionSensor", title: "Motion Here", required: false, multiple: true
		input "acceleration", "capability.accelerationSensor", title: "Acceleration Detected", required: false, multiple: true
		input "mySwitch", "capability.switch", title: "Switch Turned On", required: false, multiple: true
		input "mySwitchOff", "capability.switch", title: "Switch Turned Off", required: false, multiple: true
		input "arrivalPresence", "capability.presenceSensor", title: "Arrival Of", required: false, multiple: true
		input "departurePresence", "capability.presenceSensor", title: "Departure Of", required: false, multiple: true
	}
	
	section("Minimum time between messages (optional, defaults to every message)") {
		input "frequency", "decimal", title: "Minutes", required: false
	}
}

def installed() {
	log.debug "Installed with settings: ${settings}"
	subscribeToEvents()
}

def updated() {
	log.debug "Updated with settings: ${settings}"
	unsubscribe()
	subscribeToEvents()
}

def subscribeToEvents() {
	subscribe(tempSensor, "temperature", tempHandler)
	subscribe(contact, "contact.open", eventHandler)
	subscribe(contactClosed, "contact.closed", eventHandler)
	subscribe(smoke, "smoke.detected", eventHandler)
	subscribe(smoke, "smoke.tested", eventHandler)
	subscribe(smoke, "carbonMonoxide.detected", eventHandler)
	subscribe(water, "water.wet", eventHandler)
	subscribe(button, "button.pushed", 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)

	if (lowbatt) {
		log.debug "Scheduling Battery Check"
		schedule("0 0 10am 1,15 * ?", checkBattery)
		checkBattery()
	}
}

def eventHandler(evt) {
	log.debug "Notify got event [Name: ${evt.name}], [Value: ${evt.value}], [Description: ${evt.descriptionText}]"

	if (frequency) {
		def lastTime = state[evt.deviceId]
		if (lastTime == null || now() - lastTime >= frequency * 60000) {
			sendMessage(evt)
		}
	}
	else {
		sendMessage(evt)
	}
}

def tempHandler(evt) {
	def tooHot = temperature
	def tooCold = temperaturelow
	log.debug "Notify got event [Name: ${evt.name}], [Value: ${evt.doubleValue}], [Thresholds: ${tooCold}, ${tooHot}], [Description: ${evt.descriptionText}]"

	if (evt.doubleValue >= tooHot || evt.doubleValue <= tooCold) {
		if (frequency) {
			def lastTime = state[evt.deviceId]
			if (lastTime == null || now() - lastTime >= frequency * 60000) {
				sendMessage(evt)
			}
		}
		else {
			sendMessage(evt)
		}
	}
}

def checkBattery() {
	log.debug "Checking Batteries"
	def battery = lowbatt.currentValue("battery")      
	def whichDevice
	def x=0
	def stamp = new Date().format('yyyy-MM-dd hh:mm:ss a',location.timeZone)
	while (x < 50) {
		whichDevice = lowbatt[x]
		if (whichDevice != null) {
			String descText = "The ${whichDevice} battery is at ${battery[x]}%"
			log.debug "${descText}"
			if (battery[x] < 20) {
				def params = [
					uri: "http://CHANGE.ME/notify.php",
					body: [
						email: "${email}",
						desc: "${descText}",
						location: "${location.name}",
						timestamp: "${stamp}"
					]
                ]
				log.debug params

				try {
					httpPostJson(params) { resp ->
						log.debug "Received Response: ${resp.status}"
					}
				} catch (e) {
					log.debug "Something went wrong: $e"
				}

				if (frequency) {
					state[evt.deviceId] = now()
                }
			}
		}   
		x=x+1
    } 
}

private sendMessage(evt) {
	def params = [
		uri: "http://CHANGE.ME/notify.php",
		body: [
        	email: "${email}",
			desc: "${evt.descriptionText}",
			location: "${location.name}",
			timestamp: "${evt.date.format('yyyy-MM-dd hh:mm:ss a',location.timeZone)}"
		]
	]
	log.debug params
   
	try {
		httpPostJson(params) { resp ->
			log.debug "Received Response: ${resp.status}"
		}
	} catch (e) {
		log.debug "Something went wrong: $e"
	}

    if (frequency) {
		state[evt.deviceId] = now()
	}
}

Then you need to find a spot to host this notify.php file (be sure to change the 2 URI locations in the smart app above to match wherever this file is):

Notify.php v1.0 (you may need to change the $from_name and $from_email variables.)

<?php
/**
 *  Copyright 2016 Inbound Computer Solutions, LLC
 *
 *  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.
 *
 *	Version 1.0
 *
 */
	$inputJSON = file_get_contents('php://input');
	$input= json_decode( $inputJSON, TRUE );
	
	$eventDescription = $input[desc][values][0];
	$location = $input[location][values][0];
	$time = $input[timestamp][values][0];
	$to_email = $input[email][values][0];
	$subject = "[SmartThings] {$location}";
	$body = "{$location}: {$eventDescription} at {$time}";
	$from_name = "SmartThings Notification";
	$from_email = "change@me.com";
	
	$headers = "From: \"".$from_name."\" <".$from_email.">\r\n";
	$headers .= "Reply-To: \"".$from_name."\" <".$from_email.">\r\n";
	$headers .= "Return-Path: \"".$from_name."\" <".$from_email.">\r\n";
	$headers .= "MIME-Version: 1.0\r\n";
	$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
	$headers .= "Content-Transfer-Encoding: 8bit\r\n";
	$headers .= "X-Priority: 3\r\n";
	$headers .= "X-Mailer: PHP". phpversion() ."\r\n\n";
	$headers .= $body."\n";
	mail($to_email, $subject, '', $headers, "-f$from_email");
?>

#7

I have SMS’s sent to a Google Voice number which is also configured to send me an email, so I get both SMS and email notifications.


#8

How can this ability not already exist in the smart things app (sending an email notification)? This seems like such basic functionality. Is there no development budget at all?


(Wendy Sarrett) #9

I actually want to do this as well…but where does the php file live? Do I have to put it on a website (ie. host it somewhere like a outside webhost? If that’s the case the google voice solution seems to make more sense.