[SOLVED] Getting context data from ubidots to my arduino mega through ethernet

I want to know what is the arduino code to get context values from my ubidots variable ?

Dear @kareemshamel ,

The Arduno Ethernet library doesn’t support get the context of a variable, it just support get the last value received.

Based on that, I recommend you build your own code to handle the request directly to the Ubidots REST API to obtain the context of a variable.

As developer tips I recommend following the next steps:

  • Test a basic WebClient example to verify if your device is able to reach out internet and send a HTTP Request. In this guide you will find the example needed.
  • Once you are able to run properly the code provided above, modify the request to Ubidots instead of google. To learn how to build the GET request to Ubidots please reference to the documentation.
  • Once your are GET all the variable information using the Ubidots REST API, you ought to parse the response of the server in order to retrieve just the context.

To get a better idea, you can reference to this section of another Ubidots library that already support get the context of a variable. (Just as reference).

I hope this would help you.

All the best,
Maria C.

The code below get the context of a variable from ubidots using an Arduino Ethernet Shield:

#include <SPI.h>
#include <Ethernet.h>

namespace {
  const char * TOKEN = "xxxxxxx"; // Assign your Ubidots TOKEN
  const char * DEVICE_LABEL = "xxxxxxx"; // Assign the device label where the variable is located
  const char * VARIABLE_LABEL = "xxxxxxx"; // Assign variable label to obtain the context
  const char * SERVER = "things.ubidots.com";
  const int PORT = 80;
  const char* ERROR_VALUE = "-3.4028235E+8";
  bool _debug = false;
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
  char* response = (char *) malloc(sizeof(char) * 400);
}

EthernetClient client;

void setup() {
  Serial.begin(9600);
  Serial.print(F("Starting ethernet..."));
  if (!Ethernet.begin(mac)) {
    Serial.println(F("failed"));
  } else {
    Serial.println(Ethernet.localIP());
  }
  delay(2000);
  Serial.println(F("Ready"));
  // comment the line below to debug messages from the server
  //setDebug(true);
}

void loop() {
  // If using a static IP, comment out the next line
  Ethernet.maintain();
  char* context = getVariableContext(DEVICE_LABEL, VARIABLE_LABEL);
  Serial.print("the context is: ");
  Serial.println(context);
  delay(5000);
}

char* getVariableContext(const char* deviceLabel, const char* variableLabel) {

  uint8_t max_retries = 0;
  uint8_t timeout = 0;

  for (int i = 0; i<400; i++) {
    response[i] = '\0';
  }

  if (_debug) {
    Serial.print(F("Connecting to the Server..."));
  }

  // Initial connection
  client.connect(SERVER, PORT);

  // Reconnect the client when is disconnected
  while (!client.connected()) {
    if (_debug) {
      Serial.println(F("Attemping to connect"));
    }

    if (client.connect(SERVER, PORT)) {
      break;
    }

    max_retries++;
    if (max_retries > 5) {
      if (_debug) {
        Serial.println(F("Could not connect to server"));
      }
      return ERROR_VALUE;
    }
    delay(5000);
  }

  if (_debug) {
    Serial.println(F("Connected!"));
    Serial.println(F("Sending the GET Request..."));
  }
  
  // making the request
  client.print(F("GET /api/v1.6/devices/"));
  client.print(deviceLabel);
  client.print(F("/"));
  client.print(variableLabel);
  client.println(F("/values?page_size=1 HTTP/1.1"));
  client.println(F("Host: things.ubidots.com"));
  client.print(F("X-Auth-Token: "));
  client.println(TOKEN);
  client.println("Connection: close");
  client.println();

  // Reach timeout when the server is unavailable
  while (!client.available() && timeout < 2000) {
    timeout++;
    delay(1);
    if (timeout >= 2000) {
      if (_debug) {
        Serial.println(F("Error, max timeout reached"));
      }
      client.stop();
      return ERROR_VALUE;
    }
  }

  int i = 0;

    /* Reads the response from the server */
  while (client.connected()) {
    while (client.available()) {
      char c = client.read();
      if (c == -1) {
        if (_debug) {
          Serial.println(F("Error reading data from server"));
        }
        client.stop();
        return ERROR_VALUE;
      }
      response[i++] = c;
    }
  }
  
  Serial.println(response);
  
  // Parses the answer
  char * pch = strchr(response, '[');
  if (pch != NULL){
    char context[100];
    for (int i = 0; i<100; i++) {
      context[i] = '\0';
    }
    char * pch2 = strchr(pch + 2, '{');
    pch = strchr(pch2, '}');
    int index = (int)(pch - pch2 + 1);
    memcpy(context, pch2, index);
    context[99] = '\0';
    if (_debug) {
      Serial.println();
      Serial.println(F("disconnecting."));
    }
    client.flush();
    client.stop();
    return context;
  }
  client.flush();
  client.stop();
  return NULL;
}

void setDebug(bool debug) {
     _debug = debug;
}
1 Like

Hi! Maria!
.
Thank you in advance for a help here.
I have an application where I need to submit a set of numbers arranged like the example below.{3364,1688,464,1236,492,400,460,404,468,396,464,428,460,404} to my esp32.
Everything works fine with my device and the Ubidots platform but I couldn’t find ways to send it. I tried using the Manual imput widget and context data , but the function (ubidots.get) only takes the assigned numeric values, not the characters.
.
I will be immensely happy with your advice.
.
Dino Canalli.