Smartthings Multisensor Orientation/Tilt

I’d like to know if there is a way to create a notification for when the sensors is tilted? I can see the metrics for this on the device itself. I see no smart apps to do this though. If anyone can guide me that would be awesome. I’ve not used any custom smartapps or device types…

Thanks in advance!

Edit: wanted to elaborate a bit more. I have this mounted to a garage door. I see a tile with 3 numbers.

I think I saw a thread about a cube with a device type similar to what you speak of

Try this Awesome SmartApp: Mood Cube (with critical bug)

1 Like

I’ll spend some time reading through that but it looks like it will have a lot of extra fluff that won’t be necessary. Plus, not sure there is anything in there for notifications. Keep in mind I’m still very new to this… :smile:

I’m new here too, I just remembered seeing that thread as I’ve been lurking since v2 was announced.

I would think that code would be a good start because it should know the orientation of the multi.

I think there is a garage door app with the multi that might do what your looking for too, I guess it just depends on what level of reporting you need. Or what you are looking to accomplish.

1 Like

With due respect, RTFM… Read the friendly manual.

The online Developer Documentation has excellent examples for the very simple case you are looking for, and/or can help you understand what existing code does as you walk thru it.

You can even download entire Docs as a printable PDF.

Yeah, yeah… it’s all about finding the time. I wish I was about 8 years younger! :smile:

Anyways, I was able to re-purpose one of the builtin smartapps from the IDE. It sends a notification when the garage door is open for “too long”. Not exactly like what was built in before where I would just get a notification once the value (in this case the Z value) would cross from one side to the other. One side being open, the other side of the value is closed.

The other thing about this one is that it resends the notification/text every 5 minutes, etc.

Thanks for the encouragement. (I guess is what I’ll call that!)

/**
 *  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.
 *
 *  Garage Door Monitor
 *
 *  Author: SmartThings
 */
definition(
    name: "Garage Door Monitor",
    namespace: "smartthings",
    author: "SmartThings",
    description: "Monitor your garage door and get a text message if it is open too long",
    category: "Safety & Security",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/garage_contact.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/garage_contact@2x.png"
)

preferences {
    section("When the garage door is open...") {
        input "multisensor", "capability.threeAxis", title: "Which?"
    }
    section("For too long...") {
        input "maxOpenTime", "number", title: "Minutes?"
    }
    section("Text me at (optional, sends a push notification if not specified)...") {
        input("recipients", "contact", title: "Notify", description: "Send notifications to") {
            input "phone", "phone", title: "Phone number?", required: false
        }
    }
}

def installed()
{
    subscribe(multisensor, "acceleration", accelerationHandler)
}

def updated()
{
    unsubscribe()
    subscribe(multisensor, "acceleration", accelerationHandler)
}

def accelerationHandler(evt) {
    def latestThreeAxisState = multisensor.threeAxisState // e.g.: 0,0,-1000
    if (latestThreeAxisState) {
        def isOpen = Math.abs(latestThreeAxisState.xyzValue.z) > -150 // TODO: Test that this value works in most cases...
        def isNotScheduled = state.status != "scheduled"

        if (!isOpen) {
            clearSmsHistory()
            clearStatus()
        }

        if (isOpen && isNotScheduled) {
            runIn(maxOpenTime * 60, takeAction, [overwrite: false])
            state.status = "scheduled"
        }

    }
    else {
        log.warn "COULD NOT FIND LATEST 3-AXIS STATE FOR: ${multisensor}"
    }
}

def takeAction(){
    if (state.status == "scheduled")
    {
        def deltaMillis = 1000 * 60 * maxOpenTime
        def timeAgo = new Date(now() - deltaMillis)
        def openTooLong = multisensor.threeAxisState.dateCreated.toSystemDate() < timeAgo

        def recentTexts = state.smsHistory.find { it.sentDate.toSystemDate() > timeAgo }

        if (!recentTexts) {
            sendTextMessage()
        }
        runIn(maxOpenTime * 60, takeAction, [overwrite: false])
    } else {
        log.trace "Status is no longer scheduled. Not sending text."
    }
}

def sendTextMessage() {
    log.debug "$multisensor was open too long, texting $phone"

    updateSmsHistory()
    def openMinutes = maxOpenTime * (state.smsHistory?.size() ?: 1)
    def msg = "Your ${multisensor.label ?: multisensor.name} has been open for more than ${openMinutes} minutes!"
    if (location.contactBookEnabled) {
        sendNotificationToContacts(msg, recipients)
    }
    else {
        if (phone) {
            sendSms(phone, msg)
        } else {
            sendPush msg
        }
    }
}

def updateSmsHistory() {
    if (!state.smsHistory) state.smsHistory = []

    if(state.smsHistory.size() > 9) {
        log.debug "SmsHistory is too big, reducing size"
        state.smsHistory = state.smsHistory[-9..-1]
    }
    state.smsHistory << [sentDate: new Date().toSystemFormat()]
}

def clearSmsHistory() {
    state.smsHistory = null
}

def clearStatus() {
    state.status = null
}
1 Like

Don’t we all?!

Pointing to the Docs is a “teach to fish” sorta thing… It should pay off, but you’ll find help here if you get stuck.