My first Smart App. Help needed


(Alex) #1

Good day SmartThingers!

I’m writing my first app, which is a Service Manager for Pushbullet. My end goal is to push notifications to certain devices.

I have trouble reading input on dynamic page of settings. I read into “devices” property, but it does not seem to be set. Whenever I try to output contents of “settings”, “devices” is not present, only “apiKey”.

Any help will be appreciated.

Thanks in advance!

Here is the code:


    definition(
    name: "PushBullet Manager",
    namespace: "625alex",
    author: "Alex Malikov",
    description: "PushBullet Service Manager",
    category: "My Apps",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png"
)


preferences {   
    page(name: "Credentials", title: "Enter Credentials", nextPage: "listDevices", install: false) {
        section("Enter API key...") {
            input("apiKey", "text", title: "API Key", description: "Your Pushbullet API Key", required: true)
        }
    }
    
    page(name: "listDevices", title: "Pushbullet Devices", content: "listDevices", install: false)
    
    
}

def listDevices()
{
    def devices = listDevicesData()
    def data = [:]
    devices.each {
        data[it.id] = it.name
    }
    
    log.debug "Device List = ${data}"
    state.deviceData = devices

    return dynamicPage(name: "listDevices", title: "Choose devices", install: true) {
        section("Devices") {
            input "devices", "enum", title: "Select Device(s)", required: false, multiple: true, options: data
        }
    }
}


def listDevicesData() {
    def url = "https://${apiKey}@api.pushbullet.com/v2/devices"
    
    httpGet(uri: url) { response ->
      def devs = []
      if (response?.data?.devices) {
          response.data.devices.each { device ->
            devs << [name: device.nickname, id: device.iden]
        }
      }
      log.debug "Devices found: ${devs}"
      return devs
    }
}

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

    //listDevices()
}

def updated() {
    initialize()
    //listDevices()
    
    log.debug "Updated with settings: ${settings}"
    log.debug "updated: $settings.devices"
}

def initialize() {
    // TODO: subscribe to attributes, devices, locations, etc.
    log.debug "initialize with settings: ${settings.devices}"
    log.debug "state.deviceData: ${state.deviceData}"
    
}


(Chris LeBlanc) #2

I’ve not used the multipage feature (yet) for any apps I’ve built so sorry I can’t be more helpful. I find this Pushbullet app interesting though, thanks for mentioning it.


(Alex) #3

Bump.

I’m anxiously trying to get it working. There must be some minor mistake there. Please help!


(Andrew Urman) #4

It looks like you never actually install the app. Both pages have install: false

Last one should be install: true


(Alex) #5

I’m trying to write some code and the results are discouraging…

I don’t know if it’s me or the IDE.

Is the simulator working at this moment? I copied a basic On/Off Button Tile from device type samples and I have no output from logs.


(Alex) #6

Hi!

I’m having some trouble with my device type.

When I run the following method:

def push(def message) { // ln 50
    log.debug "state: $state" // ln 51
    def toIden = state["iden"] // same for state.iden // ln 52
    log.debug "iden: " + toIden // ln 53
    parent.push(message, toIden) // ln 54
}

The log outputs the following:
3:54:15 PM: error java.lang.NullPointerException: Cannot get property ‘iden’ on null object @ line 53
3:54:15 PM: debug iden: 123
3:54:15 PM: debug state: [iden:123]

This is strange since getting this attribute works previously, state is not null and there’s nothing happening on line 53.

Any help will be appreciated.

Thanks


(Alex) #7

Hi there,

Is there a way to make HTTP DELETE call?

Thanks


(Brian Steere) #8

Yep. httpDelete

https://graph.api.smartthings.com/ide/doc/smartApp


(Alex) #9

Perfect! Thank you!

I missed that…


(Alex) #10

Do we have an option to connect to a Web Socket in the IDE?


Why some SmartApps may not be publishable
(Brian Steere) #11

Not right now. I’ve mentioned it to them, but there isn’t a way to do it yet.


(Alex) #12

Not even from SM to a third party service?
Polling frequently might get too expensive for both clouds…


(Brian Steere) #13

Not that I’m aware of.

/cc @urman @dlieberman @bflorian


(Alex) #14

What’s the proper way of using runIn command?

I’ve tried the following and I have nothing in the logs:

runIn(90, schedulePoll, [overwrite: false])
runIn(90, schedulePoll(), [overwrite: false])
runIn(90, "schedulePoll", [overwrite: false])

Also, there seems to be a zombie app running. Every now and then I see a log message from an instance that’s been uninstalled. That log message comes from same schedulePoll method, so it must have worked at some point. Not sure how to detect and permanently disable that instance…


(Brian Steere) #15
runIn(90, schedulePoll, [overwrite: false])

That should work. If there isn’t anything in the logs, it’s quite possible there is some kind of error occurring in that method (or one that it calls). Or, it’s trying to log something too large.

Someday I’m hoping that all errors will actually make it to the log. Preferably with line numbers.


(Alex) #17

I was testing with this skeleton app, and “runIn” command dies randomly after a number of runs. Is this a known issue. Is it only happening in the simulator?

Also, if I update the app, the scheduler resumes, but it runs twice.

definition(
    name: "Scheduler Tester",
    namespace: "625alex",
    author: "Alex",
    description: "test runIn",
    category: "My Apps",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png"
)


preferences {
    section("Title") {
    }
}

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

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

    unsubscribe()
    initialize()
    
}

def initialize() {
    myJob()
}

def myJob() {
    log.debug "running my job"
    runIn(10, myJob, [overwrite: false])
}

(Brian Steere) #18

Not sure why it’s dying. It’s possible the log just isn’t updating anymore. One thing you could try if you want a function to run every 1 or more minutes is using schedule("0 * * * * ?", myJob) in your initialize function. (schedule isn’t allowed more than once per minute)

As for it running twice, try adding unschedule() to your updated function.