JSON - Map conversion fun

Hi, struggled with this for too long, think i need to ask for help. Its a door opener, with a wifi LAN connection.
I have an asynchttpGet call returning a JSON string. No problems.
A wee lil' JsonSlurper().parseText(getResp.data) later and i thought i was good to go, accessing the door data goodness in the Map.

BUT - when i try to read/use the Map elements it just won't work. I'm sure its ignorance of data types etc but i'm stuck.

def sendGetHandler(getResp, data) {
if (debugEnable) { log.debug "sendGetHandler: getResp raw JSON: {$getResp.data}" }
def jsonResp = new groovy.json.JsonSlurper().parseText(getResp.data)
if (debugEnable) { log.debug "sendGetHandler: jsonResp.deviceId: {$jsonResp.deviceId}" }
if (debugEnable) { log.debug "sendGetHandler: jsonResp.door: {$jsonResp.state.doorState}" }
if (debugEnable) { log.debug "sendGetHandler: jsonResp.openPercent: {$jsonResp.state.openPercent}" }
def device = jsonResp.devices
try {
    if (getResp.getStatus() == 200) {
        if (device.state.doorState) { sendEvent(name:"door", value: device.state.doorState) }
        if (device.state.openPercent || device.state.openPercent == 0) { sendEvent(name:"openPercent", value: device.state.openPercent ) }
        if (device.deviceId) { sendEvent(name:"SDOdeviceID", value: device.deviceId) }
    }
    if (getResp.getStatus() == 401) { log.debug "sendGetHandler: asynchttp error 401: Unauthorised - invalid (or missing) API key" }
    if (getResp.getStatus() == 404) { log.debug "sendGetHandler: asynchttp error 404: Device Not Found" }
    
} catch(e) { 
    if (debugEnable) { log.debug "sendPostHandler: asynchttp call unsuccessful: {$e}" }
}

}

I have checked out the JSON string on http://jsonviewer.stack.hu/ it helps to visualise but that about it.
Here is the raw JSON:
{"devices":[{"state":{"doorState":"open","openPercent":100,"deviceState":"online"},"lastUpdated":1622001584354,"model":"1234 ","deviceType":"garage","deviceId":"L12dUrkM","name":"My Garage"}]}

Here is the log output:

  • errorjava.lang.NullPointerException: Cannot get property 'doorState' on null object on line 236 (sendGetHandler)
  • debugsendGetHandler: jsonResp.deviceId: {null}
  • debugsendGetHandler: getResp raw JSON: {{"devices":[{"state":{"doorState":"open","openPercent":100,"deviceState":"online"},"lastUpdated":1622001584354,"model":"ABCD ","deviceType":"garage","deviceId":"12345678","name":"My Device"}]}}
  • debuggetSDOstatus: {[uri:http://10.0.0.1:8888, path:/wifi/devices, requestContentType:application/json, contentType:application/json, headers:[Authorization:Basic SHViblahblahblahE53], timeout:10]}

NOTE: Line 236 in the sendGetHandler method is this one:
if (debugEnable) { log.debug "sendGetHandler: jsonResp.door: {$jsonResp.state.doorState}" }

So I can see the error is complaining about the null value, i interpret this that it can't see the Map element for some reason.
tbh I stole the 'how' from some internet guy Groovy Goodness: Parse JSON with JsonSlurper - Messages from mrhaki.
Whats strange is that the methods in my driver that use asynchttpPost to the same device, using and this parsing code works fine.

I didn't look too closely, but a quick glance and the JSON is a List of Maps i.e. "devices" could be multiple (denoted by what's between the square brackets []), so you need to access each device by its position in the List.

Something like:

def devices = jsonResp.devices
def device = devices[0]
if (device.state.doorState ......

You could also iterate them if there's more than one ...... but the above should get you on the right track.

1 Like

thanks @martyn you just spotted in 2 minutes what i spent 4 hours hunting for.
sigh omg...woods for the trees and all that...

@Hubitat_Team: 200 "Legendary Dev Helper" Points for @martyn please!