JsonSlurper exception in driver parse() method

I'm getting the following error when calling JsonSlurper from my driver's parse() method:

2019-11-16 12:30:51.944 pm [error] groovy.lang.MissingMethodException: No signature of method: user_driver_jem_Pixelblaze_Controller_563.parse() is applicable for argument types: (groovy.json.internal.LazyMap) values: [[vars:[PCP_PACKET:[0, 0, 0, 0, -1]]]]

I remember this working a couple of Hubitat updates ago, and I didn't notice the exception 'till now, because I had commented out the method that asked the device for a json-ized list of its internal variables.

The driver is still clearly calling parse() when it gets a packet - the section that deals with the binary frames of pattern id data is working fine.

What am I missing here? Do I somehow need to specify namespace for JsonSlurper when in a callback? Did they change parse() so it automatically gets called with a map parameter when it gets recognizable json? For the moment, I'm kinda stumped.

Here's the code, which is called in response to any packet arriving via the websocket connection. (Edit: The relevant portion starts with the "else if" about halfway down. I know we're getting there because the "JSON getVariables frame detected" always shows up in the log.)

def parse(String frame) {

// determine what kind of frame it is. Variable lists come in as JSON
// strings, program lists are hexStrings, with a signature 0x07 as the 
// first encoded byte.  
  if (frame.startsWith("07")) {
      logDebug "Found program list binary frame"

// convert the data portion of the hex string to a normal string 
      def byte[] listFrame = hubitat.helper.HexUtils.hexStringToByteArray(frame)
      def rawList = new String(listFrame,2,listFrame.length - 2)
      
// since program listings can be spread across multiple frames, we need to check
// for start and end frame tags, which are in the second decoded byte      
	  if (listFrame[1] & 0x01) {  //look for 0x01 start frame indicator
	    logDebug "Start Frame Detected"
  	    state.patternList = [ : ]	          
	  }
	  if (listFrame[1] & 0x04) { // look for 0x04 completion frame indicator
	    logDebug "End Frame Detected"   
	 } 
	 // convert list entries into a map, indexed by pattern name
     def newMap = rawList.tokenize("\n").collectEntries {
       it.tokenize("\t").with {[(it[1]):it[0]]}
     }
	 state.patternList << newMap  
  }  
  else if (frame.startsWith("{\"vars\":")) {
   // The frame contains exported variables 
   // from the currently running pixelblaze pattern. 

   logDebug "JSON getVariables frame detected"
   json = null
   try {
      json = new groovy.json.JsonSlurper().parseText(frame)
        if (json == null){
          logDebug "JsonSlurper failed (null result)"
		  logDebug frame
          return
        } 
    }
	catch(e) {
       log.error("Exception while parsing json frame: ",e)
	   log.error frame
       return
    } 
    logDebug json	// TBD - do something fun with this data!
  }
}

Solved: The problem wasn't JsonSlurper. It was the last line of the function. Just me being fuzzy about exactly how type conversion works in Groovy.

logDebug json

should have been:

logDebug (json.toString())

My bad! The original error message um, could've been a little more helpful though...

2 Likes