Ubidots POST&GET - An Arduino IDE example

Here is an example sketch that makes a Post or Get request to Ubidots.
It’s a work in progress and needs improvement. If you are able to make any improvements please do so and share them with this community.

The sketch is setup such that in order for it to make the request you have to have the serial console(Modem Port) open and you must manually send anything to serial. I just hit “Enter” on my keyboard with the serial monitor open. It will then run once and will not make another request until you again send something to serial. This is a flow control measure.

You’ll need a Ubidots account, which is free. And you need to update the code with your Variable ID and api token key.

Also, my cell carriers doesn’t use APNs or proxies. If yours does then you must place those credentials in the “_https.cpp” file. Don’t forget to comment that section in and comment out the section directly above it.

To use this sketch you need the five blocks of code below, each with its own tab. I tried to attach the .ino to this post, but that was not allowed. The original source for these files come from Arduino for Rephone libraries, but I had to make some changes to get this example to work.

Simply create a new sketch in the Arduino IDE and paste the Ubidots_POST_GET code in the main tab.
Create four additional tabs in the sketch. Name them as indicated below and paste the code below in the corresponding tab.

The sketch will make a GET or POST depending on what is indicated on line 5 of the main sketch. “POST” or “GET”. As it is, the sketch POSTs an arbitrary int sensorReading of 25 to Ubidots. It then prints to serial the response from Ubidots, parses out the value from the request and prints that too. To make a GET you will enter “GET” in line five and reload the sketch to the RePhone mod.

Hope someone is able to use this. Please provide any suggestions on how the code can be make better.

Thank you

“Ubidots_POST_GET”

#include "L_https.h"
#include "string.h"

String action = "POST";  // Edit to build your command - "GET" or "POST"
char server[27] = "https://things.ubidots.com";
char path[100] = "/api/v1.6/variables/56aba69576254273c1b328/values?page_size=1&token=";  // Edit Path to include you Variable ID
char token[31] = "h5g5rSjUeYksa3GFQxiEbI8mrmu3";  // Edit to insert you API Token
char TEST_URL[256] = {0};
char part1[20] = "{\"value\": ";
char HTTP_BODY[100];
int sensorReading = 25;                     //Just a random value
int value_index = 0;
String response_body,value_string, value;   // We'll use these strings to parse the response from Ubidots
char *buffer;

void setup()
{
  
  Serial.begin(115200);
  
}

void loop()
{
  
    while(!Serial.available());
    
    sprintf(TEST_URL, "%s%s%s",server,path,token);
    
    sprintf(HTTP_BODY, "%s%i}",part1,sensorReading);
    
    Serial.println("Connecting to...");
    
    https.connect(TEST_URL); 
 
    https.get_handle(print_url);
      
    Serial.flush();
   
}

void print_url(char *content, unsigned long len)
{
  
  //Serial.println("Connecting to...");
  
  Serial.println(content);
  
  response_body = (content);
  
  value_index = response_body.indexOf("\"value\": ");
  
  // Chop the response from that index, until the end of the response string
  value_string = response_body.substring(value_index);
  
  // Get the value that is between the nine (9) characters of "\"-v-a-l-u-e-\"-: " and the next comma
  value = value_string.substring(9, value_string.indexOf(","));
  
  Serial.println(value);
  
  Serial.flush();
  
}

“L_https.cpp”

#include "L_https.h"      
#include "_https.h"       


void LHttpsClass::connect(char* url)
{
	remoteCall(https_connect, url);
}

void LHttpsClass::stop(void)
{
	remoteCall(https_stop, NULL);
}

void LHttpsClass::get_handle(void(*callback)(char *, unsigned long))
{
	https_set_new_event_callback(callback);
}

LHttpsClass https;

“L_https.h”

#ifndef _L_HTTPS_H
#define _L_HTTPS_H

#include "LTask.h"

class LHttpsClass : public _LTaskClass 
{
public:
    LHttpsClass() {};
	
public:
        	
        void connect(char* url);
	void get_handle(void(*callback)(char *, unsigned long));
	void stop(void);
	
private:
	int read_ok;
};

extern LHttpsClass https;


#endif

“_https.cpp”

#include "Arduino.h"
#include "vmlog.h" 
#include "vmhttps.h"
#include "vmgsm_gprs.h"
#include "stdio.h"
#include "string.h"
#include "_https.h"      


//My cellular carrier doesn't require APNs or Proxy so I use these settings
#define CUST_APN    	""         	// The APN of your test SIM
#define USING_PROXY 	VM_FALSE         	// Whether your SIM uses proxy
#define PROXY_ADDRESS   ""    	// The proxy address
#define PROXY_PORT  	80              	// The proxy port

//If your carrier does use APNs comment out the code block above and comment in the code below with your carriers settings.
/*
#define CUST_APN    	"cmwap"         	// The APN of your test SIM
#define USING_PROXY 	VM_TRUE         	// Whether your SIM uses proxy
#define PROXY_ADDRESS   "10.0.0.172"    	// The proxy address
#define PROXY_PORT  	80              	// The proxy port
*/


#define HTTP_HEADER "Content-Type: application/json\r\n"

#define MAX_READ_LENGHT	256
#define MAX_LENGHT		(MAX_READ_LENGHT + 16) 

char url[MAX_LENGHT] = {0,};
char content[MAX_LENGHT] = {0, };

extern String action;
extern char HTTP_BODY[100];

VMUINT8 g_channel_id;
VMUINT16 g_request_id;
VMINT g_read_seg_num;
VMINT g_read_ok;


void (*g_http_new_event_cb)(char *, unsigned long) = NULL;

static void https_send_request_set_channel_rsp_cb(VMUINT32 req_id, VMUINT8 channel_id, VM_HTTPS_RESULT result)
{
  VMINT ret = -1;
  
  if (action == "GET")
  {

    ret = vm_https_send_request(
        0,                  				/* Request ID */
        VM_HTTPS_METHOD_GET,                /*!!!!!!!CHANGED this from GET to POST for HTTP Method Constant */
        VM_HTTPS_OPTION_NO_CACHE,           /* HTTP request options */
        VM_HTTPS_DATA_TYPE_BUFFER,          /* Reply type (wps_data_type_enum) */
        MAX_READ_LENGHT,                    /* bytes of data to be sent in reply at a time. If data is more that this, multiple response would be there */
        (VMSTR)url,        					/* The request URL */
        strlen(url),           				// The request URL length 
        NULL,                               // These lines compile. The request header 
        0,                                  // These lines compile. The request header length 
        NULL,                               // These lines compile. The request body
        0);                                 // These lines compile. The request body length
        
  }
  else if (action == "POST"){

    ret = vm_https_send_request(
        0,                  				/* Request ID */
        VM_HTTPS_METHOD_POST,                /*!!!!!!!CHANGED this from GET to POST for HTTP Method Constant */
        VM_HTTPS_OPTION_NO_CACHE,           /* HTTP request options */
        VM_HTTPS_DATA_TYPE_BUFFER,          /* Reply type (wps_data_type_enum) */
        MAX_READ_LENGHT,                    /* bytes of data to be sent in reply at a time. If data is more that this, multiple response would be there */
        (VMSTR)url,        					/* The request URL */
        strlen(url), 
        (VMSTR)HTTP_HEADER,                       //!!!!!!!!CHANGED this for header. The request header 
        strlen(HTTP_HEADER),               // The request header length
        (VMSTR)HTTP_BODY,                         //!!!!!!!!CHANGED this for body. The request body 
        strlen(HTTP_BODY));                // The request body length
  }  
        
    if(ret != 0)
	{
        vm_https_unset_channel(channel_id);
  }
}

static void https_unset_channel_rsp_cb(VMUINT8 channel_id, VM_HTTPS_RESULT result)
{
	Serial.print("\r\nhttps_unset_channel_rsp_cb()\r\n");
	
}

static void https_send_release_all_req_rsp_cb(VM_HTTPS_RESULT result)
{
	Serial.print("\r\nhttps_send_release_all_req_rsp_cb()\r\n");
}

static void https_send_termination_ind_cb(void)
{
	Serial.print("\r\nhttps_send_termination_ind_cb()\r\n");
}

static void https_send_read_request_rsp_cb(VMUINT16 request_id, VM_HTTPS_RESULT result, 
                                           VMUINT16 status, VMINT32 cause, VM_HTTPS_PROTOCOL protocol, 
                                           VMUINT32 content_length,VMBOOL more,
                                           VMSTR content_type, VMUINT8 content_type_len,  
                                           VMSTR new_url, VMUINT32 new_url_len,
                                           VMSTR reply_header, VMUINT32 reply_header_len,  
                                           VMSTR reply_segment, VMUINT32 reply_segment_len)
{
    VMINT ret = -1;
	
	Serial.print("\r\nhttps_send_request_rsp_cb()\r\n");
	
	g_request_id = request_id;
	
    if(result != 0)
	{
        vm_https_cancel(request_id);
        vm_https_unset_channel(g_channel_id);
		
		g_read_ok = false;
    }
    else
	{
		//Serial.print((char *)reply_segment);
		//memset(content, MAX_LENGHT, 0);
		//memcpy(content, reply_segment, reply_segment_len);
		g_http_new_event_cb((char *)reply_segment, reply_segment_len);
		
        ret = vm_https_read_content(request_id, ++g_read_seg_num, MAX_READ_LENGHT);
        if(ret != 0)
		{
            vm_https_cancel(request_id);
            vm_https_unset_channel(g_channel_id);
			
			g_read_ok = false;
        }
		else g_read_ok = true;
    }
}
static void https_send_read_read_content_rsp_cb(VMUINT16 request_id, VMUINT8 seq_num, 
                                                VM_HTTPS_RESULT result, VMBOOL more, 
                                                VMWSTR reply_segment, VMUINT32 reply_segment_len)
{
    VMINT ret = -1;
	
	g_request_id = request_id;		
	
	//Serial.print((char *)reply_segment);
	//memset(content, MAX_LENGHT, 0);
	//memcpy(content, reply_segment, reply_segment_len);
	g_http_new_event_cb((char *)reply_segment, reply_segment_len);
		
    if(more > 0)
	{
        ret = vm_https_read_content(
            request_id,                       /* Request ID */
            ++g_read_seg_num,                 /* Sequence number (for debug purpose) */
            MAX_READ_LENGHT);                 /* The suggested segment data length of replied data in the peer buffer of 
                                                 response. 0 means use reply_segment_len in MSG_ID_WPS_HTTP_REQ or 
                                                 read_segment_length in previous request. */
        if(ret != 0)
		{
            vm_https_cancel(request_id);
            vm_https_unset_channel(g_channel_id);
			
			g_read_ok = false;
        }
		else g_read_ok = true;
    }
    else
	{
        /* don't want to send more requests, so unset channel */
        vm_https_cancel(request_id);
        vm_https_unset_channel(g_channel_id);
        g_channel_id = 0;
        g_read_seg_num = 0;
		
		g_read_ok = false;
    }
}

static void https_send_cancel_rsp_cb(VMUINT16 request_id, VM_HTTPS_RESULT result)
{
	Serial.print("\r\nhttps_send_cancel_rsp_cb()");
}

static void https_send_status_query_rsp_cb(VMUINT8 status)
{
	Serial.print("\r\nhttps_send_status_query_rsp_cb()");
}

static void set_custom_apn(void)
{
    vm_gsm_gprs_apn_info_t apn_info;
    
    memset(&apn_info, 0, sizeof(apn_info));
    strcpy((char *)apn_info.apn, CUST_APN);
    strcpy((char *)apn_info.proxy_address, PROXY_ADDRESS);
    apn_info.proxy_port = PROXY_PORT;
    apn_info.using_proxy = USING_PROXY;
    vm_gsm_gprs_set_customized_apn_info(&apn_info);
}

static void https_send_request(void)
{
	VMINT ret = -1;
	VM_BEARER_DATA_ACCOUNT_TYPE apn = VM_BEARER_DATA_ACCOUNT_TYPE_GPRS_CUSTOMIZED_APN;
	
	vm_https_callbacks_t callbacks = {
		https_send_request_set_channel_rsp_cb,
		https_unset_channel_rsp_cb,
		https_send_release_all_req_rsp_cb,
		https_send_termination_ind_cb,
		https_send_read_request_rsp_cb,
		https_send_read_read_content_rsp_cb,
		https_send_cancel_rsp_cb,
		https_send_status_query_rsp_cb
	};

	set_custom_apn();
	ret = vm_https_register_context_and_callback(apn, &callbacks);

	if(ret != 0)
	{
		return;
	}

	/* set network profile information */
	ret = vm_https_set_channel(
	0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0,
	0, 0
	);
}


boolean https_set_new_event_callback(void(*cb)(char *, unsigned long))
{
    g_http_new_event_cb = cb;
	return true;
}

boolean https_connect(void* user_data)
{
	char *buf = (char *)user_data;
	
	if(strlen(buf) > MAX_LENGHT)return true;
	
        memset(url, 0, strlen(url));
        memcpy(url, buf, strlen(buf));
        
	Serial.println(url);
	
	https_send_request();
	
	return true;
}

boolean https_stop(void* user_data)
{
	vm_https_cancel(g_request_id);
	vm_https_unset_channel(g_channel_id);
	g_channel_id = 0;
	g_read_seg_num = 0;
	g_read_ok = false;
	
	return true;
}

“_https.h”

#ifndef __HTTPS_H
#define __HTTPS_H

boolean https_connect(void* user_data);
boolean https_stop(void* user_data);
boolean https_set_new_event_callback(void(*cb)(char *, unsigned long));


#endif

Finally… :smiley: i’ll try this now.

This is the message at the console.

[code]Connecting to…
https://things.ubidots.com/api/v1.6/variables/56dfd57c7625426a6123b88e/values?page_size=1&token=GP3z7iWlKYjzg4Kz5KERo8ogBNXMr8

https_send_request_rsp_cb()

https_unset_channel_rsp_cb()[/code]

the simcard is inserted. I still can’t get a good reply

@jared. I retried the sketch as it is posted above, but with my VariableID and token and it works for me. Response looks like this.

Connecting to...
https://things.ubidots.com/api/v1.6/variables/56e816577625420c7db596/values?page_size=1&token=h5g5rSjUeYksa3GFQxiEbI8mrmu3

https_send_request_rsp_cb()
{"url": "http://things.ubidots.com/api/v1.6/values/56e8186f7625421a696d9d", "value": 20.0, "timestamp": 1458051183956, "context": {}, "created_at": "2016-03-15T14:13:03.956"}òòòò
20.0

https_unset_channel_rsp_cb()

I went to the endpoint you posted above and it looks valid. Last updated 03/09/2016 with the value 25.
Would you post the code you are using so I can have a look at it?

Edit: In the “_https.cpp” tab you created double check that your carrier’s APN settings are correct and that the appropriate code section is commented in. If your carrier uses APNs and proxies comment in that section(lines 18-21) and update the details there. Then comment out the section above. Lines 11-14.

Yup, your right. I put carrier’s APN and it works. However, i don’t see http code response. Any idea how can i get it?

Same here; POST just looks Ok, but i can´t get any response using GET
Any ideas?

Ty vm,
David