JSON issue with device handler

Hi,

I am trying to write a device handler where a refresh button will do a local http get and the JSON output will be used to change a label to red or green.

This is what I have so far. But it doesn’t work.

import groovy.json.JsonSlurper

metadata {

	definition (name: "My Device", namespace: "mydevice", author: "kaznad") {
		capability "Refresh"

		attribute "level", "string"
	}


	simulator {
		// TODO: define status and reply messages here
	}

	tiles {
		standardTile("level", "device.level", width: 1, height: 1, inactiveLabel: false, canChangeIcon: false) {
			state ("default", label:'unknown')
			state ("low", label:'Battery Low', backgroundColor: "#bc2323")
			state ("ok", label:'Battery OK',  backgroundColor: "#79b821")
		}
        standardTile("refresh", "device.lock", inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}
        main "level"
		details(["level","refresh"])
	}
}

// parse events into attributes

def parse(String description) {

	log.debug "Parsing '${description}'"
	def slurper = new JsonSlurper()
    def result = slurper.parseText(description)
    switch (result.state.bri) {
			case "0":
            	sendEvent(name: "level", value: "low", isStateChange: true)
			log.debug "Failure"
			break;
                    case "254":
            	sendEvent(name: "level", value: "ok", isStateChange: true)
            	log.debug "Success"
                    break;
    }
}

// handle commands

def refresh() {

	log.debug "Executing 'refresh'"
	
    def hubAction = new physicalgraph.device.HubAction(
        method: "GET",
        path: "/api/username/lights/1922029999",
        headers: [HOST: "192.168.8.3:80", Accept: "application/json"])
    log.debug hubAction
    return hubAction
}

what am I missing? Thanks.

I am not an expert, but try raising the sendEvent calls in the refresh method.

Hi Eric, thanks for your help.

My sendEvent are based on the output of the JSON. How can I put the sendEvent in the refresh() method in this case?
So if the state.bri JSON output is “0” it will be the sendEvent with low value and if it is “254” it will be the the one with ok value.

Is it possible to get the JSON output in the refresh() method itself?

Thanks.

The HubAction command doesn’t get executed until it’s been returned from the method so the response has to be handled in the parse method.

Does the line below generate anything in Live Logging?

log.debug "Parsing '${description}'"

I’ve never seen an Import command used in a SmartApp or DTH so if the parse method is throwing an exception, try removing the import line and change the slurper declaration to;

def slurper = new groovy.json.JsonSlurper()

Where are you parsing the json response?

I did something similar with an external get statement. Here is he code that I had:
def refresh() {
log.debug "executing ‘refresh’"
checkStatus()

}
def checkStatus(){

httpGet(uri: "https://api.particle.io/v1/devices/${deviceId}/checkStatus1?access_token=${token}",
	contentType: 'application/json',)
{resp ->           
        log.debug "resp data: ${resp.data}"
        log.debug "result: ${resp.data.result}"
	sendEvent(name: "switch", value: "${resp.data.result}" )
}

}

1 Like

Can you confirm that the request is being made correctly?

Hi Kevin,

The line log.debug “Parsing ‘${description}’” does not generate any log.

I have removed the import command and defined the slurper as def slurper = new groovy.json.JsonSlurper() and it is still does not work.

Thanks.

Hi Justin,

I am parsing the JSON output to def parse(String description) so when the hubaction returns it is supposed to populate String description with the JSON output.

If I am not wrong, I remember reading somewhere that httpGet does not work with local LAN ip. I think for local LAN hubaction is required.

Thanks.

So the parse method’s not even getting called…

If you go to the url in a browser, do you get the response you’re expecting?

http://192.168.8.3:80/api/usename/lights/1922029999

You’re not wrong…If you’re using a local ip, you have to use hubaction

Hi Tim,

when i try http://192.168.8.3/api/username/lights/1922029999 on my browser I get the below JSON output.

{“state”:{“on”:false,“bri”:0,“hue”:34111,“sat”:254,“effect”:“none”,“xy”:[0.3132,0.3288],“ct”:153,“alert”:“none”,“colormode”:“xy”,“reachable”:true},“type”:“Extended color light”,“name”:“EuropAce Climate Control”,“modelid”:“LCT007”,“manufacturername”:“Philips”,“uniqueid”:“1922029999”,“swversion”:“5.38.1.14919”}

And when I log the hubaction return I get this;

GET /api/usename/lights/1922029999 HTTP/1.1
Accept: /
User-Agent: Linux UPnP/1.0 SmartThings
HOST: 192.168.8.3:80

Does this mean the request is made correctly?

Thanks.

I’m randomly guessing at this point, but does anything get logged by the parse method if you exclude the header below?

, Accept: "application/json"

I’m asking because it’s not in the example from the documentation, it wouldn’t be included when you tried it on your browser, and it doesn’t appear to be in the output generated by logging the hubaction object which makes me wonder if it was partially stripped out.

Hi Kevin,

Thanks for your help. When I remove the header, nothing gets logged the by parse method as well.

I just looked at one of my device handlers that does something similar and I think the query parameter might be required.

Try adding the following after the headers parameter:

query: []

Your problem is ${description} is not in your json. Everything in your json with a " " is what you would put a ${} around. Everything after the " " is what your json is returning. So for example you could say: log.debug “result: ${resp.data.bri}”.
sendEvent(name: “your Device”, “${resp.data.bri}”)

The result of this is that your device would be set to 0.

I tried adding the query and still nothing logged from the parse method. I think I read in the documentation that query parameter is optional though.
Thanks for your help.

Hi Justin,

I changed the line to log.debug (description) and nothing was logged. I then changed it to log.debug “parsing” still nothing was logged. I think the problem is with the hubaction not returning anything so the parse method was not called?

I tried looking at some hubaction examples with GET and they seem similar. Only thing is I am hardcoding the IP and Path and not using a variable. Would that cause a problem? I wouldn’t think so right?

Thanks for your help.

Try this.
log.debug "result: ${bri}"
And let me know if you get something in your log.

Hi Justin,
I change it to:
def parse(String description) {

log.debug (description)
log.debug "parse"
def slurper = new JsonSlurper()
def result = slurper.parseText(description)
log.debug "result: ${bri}"
switch (result.state.bri) {
		case "0":
        sendEvent(name: "level", value: "low", isStateChange: true)
		log.debug "Failure"
		break;
        case "254":
        sendEvent(name: "level", value: "ok", isStateChange: true)
        log.debug "Success"
        break;
}

}

Nothing was logged. Also tried log.debug “result: ${result.state.bri}”. Nothing was logged.

Thanks.

I agree, the problem’s not in your parse method, the problem is that the parse method isn’t getting called.

That’s why I was comparing your hubaction section against my device handler’s, but besides the things I mentioned, everything else matches so I have no idea why it’s not working.

I’m currently out of ideas so sorry I wasn’t able to help.

Try just state.bri