This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Extracting topic data from JSON topic received from AWS broker (using nRF9160dk)

Hi

I am using nRF9160dk board.

I started with the aws_iot example, compiling it within VS Code.

I set up my board as a ‘thing’ in Amazon’s AWS, along with policy, certificates etc.

 

I will explain an issue I am having, however I will probably use the wrong terminology etc., because I am relatively new to using Nordic, and just as new to Amazon AWS.

 

Using AWS’s MQTT Test Client, I subscribed to all topics from my board, and I could see that I received the following two topics every 60 seconds:

$aws/things/my-nRF9160dk_thing01/shadow/update

and

$aws/things/my-nRF9160dk_thing01/shadow/update/accepted

 

All good so far…

 

The next thing I wanted to do was publish a change of value, using the MQTT Test Client in AWS

So I entered the following:

Topic name:

$aws/things/imme-nRF9160dk_thing01_eu/shadow/update

Message payload:

{

  "state": {

    "desired": {

      "batv": 123

    }

  }

}

 

Immediately, I can see on the board’s NRF Terminal output that this message was received, as the board received the following topic:

$aws/things/my-nRF9160dk_thing01/shadow/update/delta

along with the new batv desired value

 

Still good so far…

 

The next thing I wanted to do, and this is where |I am struggling, is to parse this received JSON delta topic, and just extract the new value for batv

 

I added additional code to the print_received_data() function in the aws_iot application:

 

const cJSON * batVal = NULL;    // <-- added this

 

root_obj = cJSON_Parse(buf);

if (root_obj == NULL) {

  printk("cJSON Parse failure");

  return;

}

 

str = cJSON_Print(root_obj);

if (str == NULL) {

  printk("Failed to print JSON object");

  goto clean_exit;

}

 

batVal = cJSON_GetObjectItemCaseSensitive(root_obj, "batv");      // <-- added this

 

However, I think I might be using this function call incorrectly, because I seem to get nothing back.

Any of the following calls, return false:

if (cJSON_IsInvalid(batVal)

if (cJSON_IsFalse (batVal)

if (cJSON_IsTrue (batVal)

if (cJSON_IsNull (batVal)

if (cJSON_IsNumber (batVal)

if (cJSON_IsString (batVal)

if (cJSON_IsArray (batVal)

if (cJSON_IsRaw (batVal)

 

If anyone can understand this post Blush can you spot what I am doing wrong?

Thanks

Garrett

  • Hi,

    Could you try replacing the line

    batVal = cJSON_GetObjectItemCaseSensitive(root_obj, "batv");


    with the following 2 lines

    cJSON *json_parsed = cJSON_Parse(str);
    batVal = cJSON_GetObjectItemCaseSensitive(json_parsed, "batv");


    You could then print with

    char *str2 = cJSON_Print(batVal);
    printk("batVal: %s\n", str2);


    Best regards,
    Dejan

  • Hi Dejan

    Thanks for the suggestion.

    I have been going around in circles with this :) 

    Here is what I have at the moment - it's a bit messy as I have been adding a lot of debug feedback etc.

    For some reason, it doesn't seem to extract the "batv" value

    Code:

    static void print_received_data(const char *buf, const char *topic,
    				size_t topic_len)
    {
    	char *str = NULL;
    	cJSON *root_obj = NULL;
    		
    	printk("\n. . . . . . . . \n");
    	printk("print_received_data");
    	printk("\n. . . . . . . . \n");
    	printk("Received buffer: \n%s\n", buf);
    	printk("Received topic: \n%s\n", topic);
    	printk("Received topic len: \n%d", topic_len);
    	printk("\n. . . . . . . . \n");
    
    	printk("\n1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
    	root_obj = cJSON_Parse(buf);
    	if (root_obj == NULL) {
    		printk("cJSON Parse failure");
    		return;
    	}
    
    	printk("\n2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
    	str = cJSON_Print(root_obj);
    	if (str == NULL) {
    		printk("Failed to print JSON object");
    		goto clean_exit;
    	}
    	printk("\n3 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
    
    	cJSON *batval;
    	cJSON *json_parsed = cJSON_Parse(str);
    	batval = cJSON_GetObjectItemCaseSensitive(json_parsed, "batv");
    	if (batval == NULL)
    	{
    		printk("\n3a bat_val is null");
    	} else {
    		char *str2 = cJSON_Print(batval);
    		printk("\n3b ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
    		printk("batval: %s\n", str2);
    		printk("\n3c ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
    
    	}
    	printk("\n4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
    
    

    Output on the terminal:

    . . . . . . . . 
    print_received_data
    . . . . . . . . 
    Received buffer: 
    {"state":{"desired":{"dbg":444,"batv":445,"dbgStr":"apples"},"reported":{"app_version":"v1.0.0","batv":5019,"ts":69521,"dbg":0,"dbgStr":""},"delta":{"dbg":444,"batv":445,"dbgStr":"apples"}},"metadata":{"desired":{"dbg":{"timestamp":1648562859},"batv":{"timestamp":1648562859},"dbgStr":{"timestamp":1648562859}},"reported":{"app_version":{"timestamp":1648567600},"batv":{"timestamp":1648567659},"ts":{"timestamp":1648567659},"dbg":{"timestamp":1648567659},"dbgStr":{"timestamp":1648567659}}},"version":2102,"timestamp":1648567687}
    Received topic: 
    $aws/things/my-nRF9160dk_thing01/shadow/get/accepted
    Received topic len: 
    57
    . . . . . . . . 
    
    1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    3 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    3a bat_val is null
    4 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  • Hi,

    Currently, you are accessing batv at the root level. Based on your structure, batv cannot be read directly (as if it is in the root level) because it is nested inside "state" and "desired".

    Best regards,
    Dejan

  • Thank you Dejan

    You are correct - and I got it working.

    Below is an example of how it worked for me.

    Again, this is rough and ready - just trying to get the concept etc.

    	cJSON *objState;
    	cJSON *objDesired;
    	cJSON *objBatval;
    	cJSON *json_parsed = cJSON_Parse(str);
    
    	objState = cJSON_GetObjectItemCaseSensitive(json_parsed, "state");
    	if (objState == NULL)
    	{
    		printk("\n3a objState is null");
    	} else {
    		str2 = cJSON_Print(objState);
    		json_parsed = cJSON_Parse(str2);
    		objDesired = cJSON_GetObjectItemCaseSensitive(json_parsed, "desired");
    		if (objDesired == NULL)
    		{
    			printk("\n3b objDesired is null");
    		} else {
    			str2 = cJSON_Print(objDesired);
    			json_parsed = cJSON_Parse(str2);
    			objBatval = cJSON_GetObjectItemCaseSensitive(json_parsed, "batv");
    			if (objBatval == NULL)
    			{
    				printk("\n3c objBatval is null");
    			} else {
    				printk("\n3d objBatval is NOT null");
    				str2 = cJSON_Print(objBatval);
    				printk("\n3e ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
    				printk("objBatval: %s\n", str2);
    				printk("\n3f ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
    			}
    		}
    	}

    Regards

    Garrett

Related