Ubidots Community

[SOLVED] Get multiple variables from Ubidots at the same time

I am working with an esp8266, with the ubidots.h library and the http protocol, I use two devices, in one I send data to the server and in the other I receive and process them, in general I send 18 variables to the server and they take 2 seconds to arrive , but when requesting them in the other device it takes an average of 40 seconds, (2 or 3 seconds per variable), I am something new working with ubidots, I understand how multiple variables are sent at the same time, is there a way to receive all variables at the same time?
I send the variables with ubidots.add and ubidots.send, and to receive with ubidots.get (DEVICE_LABEL, LAB_SEND11), I do not pretend that it is in real time but for the project in which I work 40 seconds is a long time. thanks for your help

Good day @YesidGarcia

Thank you for reaching out to Ubidots, we’re glad that you are building an application with us.

To answer your questions:

If you use the HTTP protocol with the Ubidots library, it is normal that reading the 18 variables from the second ESP8266 takes up to 40 seconds because it is sequential, and each GET query might take anywhere between 1 to 3 seconds. On top of that, as you have a STEM account, this type of account only allows 1 request per second. In addition to this, the ESP8266 HTTP’s library doesn’t include a method to retrieve multiple variable’s last value at once.

With this being clear, I’d like to recommend using the MQTT protocol in the second device (the one that receive the values from Ubidots), that way, you could subscribe to all the variables and get the updates almost instantaneously. Makes sense?

NOTE: Please refer to this link to know how to use the MQTT protocol with your ESP8266. Also, You must include the UbitosESPMQTT library, please download it here. If you need to know anything else about how to use the MQTT protocol with Ubidots, please refer to this link.

However, the next week we’d share a code example of the MQTT subscription.

All the best,
Ángela

1 Like

Hello @YesidGarcia

Here’s the code example of the MQTT subscription for your second device. This way, you’ll be able to receive all variables at the same time.

//Include Libraries
#include "UbidotsESPMQTT.h"

//Define Constants
#define TOKEN "YOUR-UBIDOTS-TOKEN"   
#define WIFINAME "YOUR-WIFI" 
#define WIFIPASS "YOUR-WIFI-PASSWORD"  
#define DEVICE_LABEL "YOUR-DEVICE-LABEL"
char *var_labels[] = {
  "YOUR-VARIABLE-LABEL-1",
  "YOUR-VARIABLE-LABEL-2",
  "YOUR-VARIABLE-LABEL-3",
  "YOUR-VARIABLE-LABEL-4"
  // Add more variable labels here. Do not forget the comma ;)
};

#define DIMENSION_OF(x) (sizeof(x)/sizeof(x[0]))

float var_last_values[DIMENSION_OF(var_labels)] = {};
Ubidots client(TOKEN);

//Callback function
void callback(char* topic, byte* payload, unsigned int length) {
  // Limitations: Variable label must not be the same as device label
  
  char *topic_cpy = strdup(topic);
  char *payload_str = (char *) malloc(length + sizeof(""));
  char *topic_item = strtok(topic_cpy, "/");
  char *label = NULL;
  float value = NAN;
  size_t index = DIMENSION_OF(var_labels);
  size_t i;

  memcpy(payload_str, payload, length);
  payload_str[length] = '\0';
  
  while ((NULL != topic_item) && (NULL == label)) {
    for (i = 0; i < DIMENSION_OF(var_labels); i++) {
      if (0 == strcmp(var_labels[i], topic_item)) {
        label = topic_item;
        value = atof((char *) payload);
        index = i;
        break;
      }
    }
    topic_item = strtok(NULL, "/");
  }

  if (index < DIMENSION_OF(var_labels)) {
    var_last_values[index] = value;

    Serial.print(label);
    Serial.print(": ");
    Serial.println(value);
  }

  free(topic_cpy);
  free(payload_str);
}

//Suscribe function
void subscribe_to_vars(char **labels, size_t n_labels) {
  size_t i;
  for (i = 0; i < n_labels; i++) {
    char *label = labels[i];
    client.ubidotsSubscribe(DEVICE_LABEL, label);
  }
}

//Print last values function
void print_last_values(void) {
  char str_buff[64] = "";
  size_t i;

  for (i = 0; i < DIMENSION_OF(var_labels); i++) {
    snprintf(str_buff, sizeof(str_buff), "%s: %f", var_labels[i], var_last_values[i]);
    Serial.println(str_buff);
  }
}

//Main functions
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  client.setDebug(true);  // Pass a true or false bool value to activate debug messages
  client.wifiConnection(WIFINAME, WIFIPASS);
  client.begin(callback);
  subscribe_to_vars(var_labels, DIMENSION_OF(var_labels));
}

void loop() {
  // put your main code here, to run repeatedly:
  if (!client.connected()) {
    client.reconnect();
    subscribe_to_vars(var_labels, DIMENSION_OF(var_labels));
  }
  client.loop();
}

Please be aware that firstly, you need to define the constants of your code with your account information (in the below segment):

//Define Constants
#define TOKEN "YOUR-UBIDOTS-TOKEN"   
#define WIFINAME "YOUR-WIFI" 
#define WIFIPASS "YOUR-WIFI-PASSWORD"  
#define DEVICE_LABEL "YOUR-DEVICE-LABEL"
char *var_labels[] = {
  "YOUR-VARIABLE-LABEL-1",
  "YOUR-VARIABLE-LABEL-2",
  "YOUR-VARIABLE-LABEL-3",
  "YOUR-VARIABLE-LABEL-4"
  // Add more variable labels here. Do not forget the comma ;)
};

NOTE: Bear in mind that the Ubidots library only supports the ESP8266 platform version v.2.7.4. Please, when installing this platform, make sure that you’re using the correct version.
Let me know if you need anything else!

All the best,
Ángela