I have the rough initial smartapps setup. If these work reliably I will enhance when I find time.
To notify of pump inactivity for xx hours, using a very basic runIn for now until I find a better but simple solution. I had an “only in these modes” input but realized that could cause notifications to be skipped if we are coming and going and pump is not activating. Later I may figure out some kind of vacation silence method since the pump won’t run for days when we are not home to add contents to the tank. For now I can just remove the phone number in the app to avoid a daily text during vacations.
preferences {
section("When . . .") {
input "accSensor", "capability.accelerationSensor", title: "Pump sensor inactive"
input "numHours", "number", title: "For how many hours"
input "messageText", "text", title: "Send notification that says"
input "phoneNumber", "phone", title: "Send SMS message to"
}
}
def installed() {
subscribe(accSensor, "acceleration", onAccelerationChange);
}
def updated() {
unsubscribe()
subscribe(accSensor, "acceleration", onAccelerationChange);
}
def onAccelerationChange(evt) {
log.debug "onAccelerationChange";
if (evt.value == "inactive") {
runIn(numHours * 3600, onAccelerationInactiveHandler);
} else {
unschedule(onAccelerationInactiveHandler);
}
}
def onAccelerationInactiveHandler() {
log.debug "onAccelerationInactiveHandler";
sendPush(messageText);
sendSms(phoneNumber, messageText);
}
For sending data to thingspeak.com I am using florianz’s code, reduced to watch acceleration events. Thingspeak charting looks very basic at first glance, but I can also export the data for more analysis.
preferences {
section("Log devices...") {
input "accelerations", "capability.accelerationSensor", title: "Accelerations", required: false, multiple: true
}
section ("ThinkSpeak channel id...") {
input "channelId", "number", title: "Channel id"
}
section ("ThinkSpeak write key...") {
input "channelKey", "text", title: "Channel key"
}
}
def installed() {
initialize()
}
def updated() {
unsubscribe()
initialize()
}
def initialize() {
subscribe(accelerations, "acceleration", handleAccelerationEvent)
updateChannelInfo()
log.debug state.fieldMap
}
def handleAccelerationEvent(evt) {
logField(evt) { it == "active" ? "1" : "0" }
}
private getFieldMap(channelInfo) {
def fieldMap = [:]
channelInfo?.findAll { it.key?.startsWith("field") }.each { fieldMap[it.value?.trim()] = it.key }
return fieldMap
}
private updateChannelInfo() {
log.debug "Retrieving channel info for ${channelId}"
def url = "http://api.thingspeak.com/channels/${channelId}/feed.json?key=${channelKey}&results=0"
httpGet(url) {
response ->
if (response.status != 200 ) {
log.debug "ThingSpeak data retrieval failed, status = ${response.status}"
} else {
state.channelInfo = response.data?.channel
}
}
state.fieldMap = getFieldMap(state.channelInfo)
}
private logField(evt, Closure c) {
def deviceName = evt.displayName.trim()
def fieldNum = state.fieldMap[deviceName]
if (!fieldNum) {
log.debug "Device '${deviceName}' has no field"
return
}
def value = c(evt.value)
log.debug "Logging to channel ${channelId}, ${fieldNum}, value ${value}"
def url = "http://api.thingspeak.com/update?key=${channelKey}&${fieldNum}=${value}"
httpGet(url) {
response ->
if (response.status != 200 ) {
log.debug "ThingSpeak logging failed, status = ${response.status}"
}
}
}
Not using anymore, but this provides notification each time pump activates for testing initial setup. It seemed to reliably notify on each event. Shortened deltaSeconds to capture both pump on and off events.
preferences {
section("When Septic Pump Runs..."){
input "accelerationSensor", "capability.accelerationSensor", title: "Where?"
}
section("Text me at..."){
input "phone1", "phone", title: "Phone number?"
}
}
def installed() {
subscribe(accelerationSensor, "acceleration.active", accelerationActiveHandler)
}
def updated() {
unsubscribe()
subscribe(accelerationSensor, "acceleration.active", accelerationActiveHandler)
}
def accelerationActiveHandler(evt) {
// Don't send a continuous stream of text messages
def deltaSeconds = 1
def timeAgo = new Date(now() - (1 * deltaSeconds))
def recentEvents = accelerationSensor.eventsSince(timeAgo)
log.trace "Found ${recentEvents?.size() ?: 0} events in the last $deltaSeconds seconds"
def alreadySentSms = recentEvents.count { it.value && it.value == "active" } > 1
if (alreadySentSms) {
log.debug "SMS already sent to $phone1 within the last $deltaSeconds seconds"
} else {
log.debug "$accelerationSensor has moved, texting $phone1"
sendSms(phone1, "Septic pump just activated!")
}
}