Handling http requests in Hubitat App with mappings()

Hubitat is one of smart home hubs. It scripting model resembles one SmartThings one, and consists of Groovy scripts of two types – apps and device drivers.

Today we’re going to talk about one aspect of App functionality – handling http requests. Here’s an example app, mostly taken from this Hubitat forum post.

definition(
        name: "Http server app sample",
        namespace: "me.biocomp",
        author: "biocomp",
        description: "Testing",
        iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
        iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
        iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
        oauth: [displayName: "HTML Endpoint", displayLink: "https://sharptools.io"])

preferences() {
    page(name: "setupScreen")
}

private def makeUri(String extraPath) {
    return getFullLocalApiServerUrl() + extraPath + "?access_token=${state.accessToken}"
}

def setupScreen() {
    if (!state.accessToken) {	
        // Enable OAuth in the app settings or this call will fail
        createAccessToken()	
    }
    
    String uri = makeUri("/");
    return dynamicPage(name: "setupScreen", uninstall: true, install: true) {
        section(){ 
            paragraph("Use the following URI to access the page: <a href='${uri}'>${uri}</a>")
        }
    }
}

mappings {
    // The root path - you can also map other paths or use parameters in paths and posted data
    path("/") { action: [GET: "mainPage"]}
    path("/nested_page") { action: [GET: "nestedPage" ]}
}

def mainPage() {
    log.info "Rendering main page"
    String uri = makeUri("/nested_page");
    html = "<html><head><title>Http server - main page</title></head><body>Use <a href='${uri}'>${uri}</a> to get to nested page</body></html>"
    render contentType: "text/html", data: html, status: 200
}

def nestedPage() {
    log.info "Rendering nested page"
    html = "<html><head><title>Http server - nested page</title></head><body>It's a nested page</body></html>"
    render contentType: "text/html", data: html, status: 200
}

You’ll need to enable OAuth for this app for it to work:

After adding this app, you will see this page generated, and if you click on the provided link, you’ll get to app’s main page:

You can then follow that URL, and will get onto main page, which has a link to the nested page: http://192.168.1.1/apps/api/709/nested_page?access_token=e7a261d8-bfa7-4dd6-8480-0662c13fcbe0

Mappings API for SmartThings is described here and here, could not find good documentation for Hubitat, but they’re pretty much the same. Here’s more or less full list of supported commands and options:

mappings {
    path("/foo") {
        action: [
            GET: "getFoo",
            PUT: "putFoo",
            POST: "postFoo",
            DELETE: "deleteFoo"
        ]
    }
    path("/bar") {
        action: [
            GET: "getBar"
        ]
    }
}

def getFoo() {}
def putFoo() {}
def postFoo() {}
def deleteFoo() {}
def getBar() {}

Another example – using path parameters:

mappings {
    path("/foo/:param1/:param2") {
        action: [GET: "getFoo"]
    }
}

// You can then access them like so in the handler method:
def getFoo() {
    def param1 = params.param1
    def param2 = params.param2
}

Including Schlage be469nx z-wave lock

I had a lot of trouble while moving the lock from VeraPlus to Hubitat. Hubitat would just not add the lock whatever I tried.

After reading multiple forums, I’ve found that combination of these steps would solve most of the problems.

  1. Don’t forget to exclude the lock! This is the most important thing. If pairing is not happening for no apparent reason, just try excluding the lock from your current controller. Mine was not indicating that it is included (it should blink its led when battery is attached, if it’s included into z-wave network). But it would fail to be included all the time, with different controllers. When I excluded it, everything started to be OK.
  2. Use fresh batteries. Even half-dead batteries would cause issues with pairing. My pairing issues started with this I believe.
  3. Be sure to have lock and controller in their final locations. If you move controller close to the lock (or vice versa), pair them, and then move it back, the lock (apparently) won’t be able to change the route to the controller. The lock needs to know the correct final z-wave route during pairing.
  4. If your lock is too far from controller, you’ll need to have a z-wave device nearby that supports beaming (most wired devices support it, except for old ones). You can find out which devices support beaming on https://products.z-wavealliance.org (for example: https://products.z-wavealliance.org/products/2306/embedpics). Beaming allows efficient communication with battery-powered devices.
    supportsbeaming

I did not need this, but it was mentioned on forums:

  1. See if lock’s firmware is new-ish. Seems like version 5.8 and above is OK (you can find firmware on lock’s sticker). Some people mentioned that Schlage would even send new locks if firmware is old and you ask them to reflash the lock.
  2. Try resetting the lock? But it doesn’t reset z-wave settings.