NRF Cloud multiple data points in one massage

Hello,

I edded the multi cloud serves to fit my needes. When the divice sends GNSS data after fix it looks like this:

"Received":{4 items
    "messageType":"DATA"
    "appId":"GNSS"
    "data":{3 items
        "lat":51.832831879576325
        "lng":4.849055562212727
        "acc":9.889153480529785
        }
    "ts":1723624845580
}

When a massage is sent from temperature if I remember it correctly (now it is V for voltage) it looks like this:

"Received":{4 items
    "messageType":"DATA"
    "appId":"V"
    "data":38.413185119628906
    "ts":1723624845562
}

I removed the queueing application and have another way to handle the not send messages. 

static int send_sensor_sample(const char *const sensor, double value){
	int ret;
	MSG_OBJ_DEFINE(msg_obj);

	ret = create_timestamped_device_message(&msg_obj, sensor, NRF_CLOUD_JSON_MSG_TYPE_VAL_DATA);
	if (ret) {
		return -EINVAL;
	}
	
	/* Populate the container object with the sensor value. */
	ret = nrf_cloud_obj_num_add(&msg_obj, NRF_CLOUD_JSON_DATA_KEY, value, false);
	if (ret) {
		LOG_ERR("Failed to append value to %s sample container object ",
			sensor);
		nrf_cloud_obj_free(&msg_obj);
		return -ENOMEM;
	}

	int err = nrf_cloud_coap_obj_send(&msg_obj, IS_ENABLED(CONFIG_COAP_SEND_CONFIRMABLE));
	if (err < 0) {
		LOG_ERR("Failed to send %s sample, error: %d", sensor, err);
		return err;
	}
}

I call this function a few times and every time the data is put in its own massage. Now I want to add all data in one massage somewhat like the GNSS data. I tried calling nrf_cloud_obj_num_add() multiple times and using  nrf_cloud_obj_str_array_add() with a return err that it can't encode unknown type.

Can someone help me further?
  • You can send a "bulk" message, which is just a JSON array of JSON messages.
    See the function details for nrf_cloud_coap_obj_send.

    Below is an example of how it could be used in the multi-service sample.


    A minor modification to the create_timestamped_device_message() function...
    CBOR encoding does not support bulk messages, so JSON will need to be used. 
    Include the "messageType" field so the message conforms to the schema.

    /* Create message object: CBOR encoding does not require the message type */
    err = nrf_cloud_obj_msg_init(msg, appid,
    			     msg->type == NRF_CLOUD_OBJ_TYPE_COAP_CBOR ? NULL : msg_type);
    if (err) {
    	LOG_ERR("Failed to initialize message with appid %s and msg type %s",
    		appid, msg_type);
    	return err;
    }



    Modifications to build a bulk JSON message:

    static int send_sensor_sample(const char *const sensor, double value)
    {
    	int ret;
    
    	NRF_CLOUD_OBJ_JSON_DEFINE(bulk_obj);
    	NRF_CLOUD_OBJ_JSON_DEFINE(msg_obj);
    	NRF_CLOUD_OBJ_JSON_DEFINE(another_msg_obj);
    
    	/* Create a timestamped message container object for the sensor sample. */
    	ret = create_timestamped_device_message(&msg_obj, sensor,
    						NRF_CLOUD_JSON_MSG_TYPE_VAL_DATA);
    	if (ret) {
    		return -EINVAL;
    	}
    
    	/* Populate the container object with the sensor value. */
    	ret = nrf_cloud_obj_num_add(&msg_obj, NRF_CLOUD_JSON_DATA_KEY, value, false);
    	if (ret) {
    		LOG_ERR("Failed to append value to %s sample container object ", sensor);
    		nrf_cloud_obj_free(&msg_obj);
    		return -ENOMEM;
    	}
    
    
    	/* Create another message... */
    	ret = create_timestamped_device_message(&another_msg_obj, "mySensor",
    						NRF_CLOUD_JSON_MSG_TYPE_VAL_DATA);
    	if (ret) {
    		return -EINVAL;
    	}
    
    	/* Add data... */
    	ret = nrf_cloud_obj_num_add(&another_msg_obj, NRF_CLOUD_JSON_DATA_KEY, 123.456, false);
    	if (ret) {
    	    nrf_cloud_obj_free(&msg_obj);
    		nrf_cloud_obj_free(&another_msg_obj);
    		return -ENOMEM;
    	}
    
    	/* Init the bulk container */
    	ret = nrf_cloud_obj_bulk_init(&bulk_obj);
    	if (ret) {
    		goto bulk_err_exit;
    	}
    
    	/* Add msg_obj to the bulk container */
    	ret = nrf_cloud_obj_bulk_add(&bulk_obj, &msg_obj);
    	if (ret) {
    		goto bulk_err_exit;
    	}
    	/* Item now belongs to the bulk container */
    	(void)nrf_cloud_obj_reset(&msg_obj);
    
    	/* Add another_msg_obj to the bulk container */
    	ret = nrf_cloud_obj_bulk_add(&bulk_obj, &another_msg_obj);
    	if (ret) {
    		goto bulk_err_exit;
    	}
    	/* Item now belongs to the bulk container */
    	(void)nrf_cloud_obj_reset(&another_msg_obj);
    
    	/* Send the sensor sample container object as a device message. */
    	return send_device_message(&bulk_obj);
    
    bulk_err_exit:
    	LOG_ERR("Error building bulk message: %d", ret);
    	nrf_cloud_obj_free(&msg_obj);
    	nrf_cloud_obj_free(&bulk_obj);
    	nrf_cloud_obj_free(&another_msg_obj);
    	return ret;
    }


    For CoAP, the nrf_cloud_coap_obj_send() function automatically handles the bulk message.


    The resulting bulk message looks like:

    [
      {
        "appId": "TEMP",
        "messageType": "DATA",
        "ts": 1723842519683,
        "data": 23.775
      },
      {
        "appId": "mySensor",
        "messageType": "DATA",
        "ts": 1723842519683,
        "data": 123.456
      }
    ]

  • using  nrf_cloud_obj_str_array_add() with a return err that it can't encode unknown type

    nrf_cloud_obj_str_array_add() only supports JSON.
    when using CoAP, the multi-service sample uses CBOR by default for device messages.
Related