Ubidots Community

Ubidots subscribe output LED

Hello friends, how are you? I have two nodemcu. One is measuring temperature and publishing in ubidots. the other nodemcu is as subscribe in ubidots. The one that is as subscribe is receiving the temperature variable. My question is: How do I do in the code of the nodemcu that is as subscribe so that when the temperature variable is greater than 15°C, I light a led.

Here is the code below:

/****************************************

  • Include Libraries
    ****************************************/
    #include “UbidotsESPMQTT.h”

/****************************************

  • Define Constants
    ****************************************/
    #define TOKEN “xxx” // Your Ubidots TOKEN
    #define WIFINAME “xxx” //Your SSID
    #define WIFIPASS “xxx” // Your Wifi Pass
    #define DEVICE_LABEL “xxx” // Put here your Ubidots device label
    #define VARIABLE_LABEL “temperatura” // Put here your Ubidots variable label
    #define MQTTCLIENTNAME “1vn30P282p” // Your MQTT Client Name, it must be unique so we recommend to choose a random ASCCI name
    Ubidots client(TOKEN);

int LED = D1;
/****************************************

  • Auxiliar Functions
    ****************************************/

void callback(char* topic, byte* payload, unsigned int length) {
Serial.print(“Message arrived [”);
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload[i]);
}
Serial.println();

}

/****************************************

  • Main Functions
    ****************************************/

void setup() {
pinMode(LED, OUTPUT);

// put your setup code here, to run once:
client.ubidotsSetBroker(“industrial.api.ubidots.com”); // Sets the broker properly for the Industrial account
client.setDebug(false); // Pass a true or false bool value to activate debug messages
Serial.begin(115200);
client.wifiConnection(WIFINAME, WIFIPASS);
client.begin(callback);
client.ubidotsSubscribe(DEVICE_LABEL, VARIABLE_LABEL); //Insert the dataSource and Variable’s Labels
}

void loop() {
// put your main code here, to run repeatedly:
if(!client.connected()){
client.reconnect();
client.ubidotsSubscribe(DEVICE_LABEL, VARIABLE_LABEL); //Insert the dataSource and Variable’s Labels
}
delay (100);

Serial.print("The value received form Ubidots is: ");

if ( VARIABLE > 15) {
digitalWrite(LED, HIGH);
} else {
digitalWrite(LED, LOW);
}
delay(1000);

client.loop();
}

Hello @CAEGRUBR, we are doing great, thank you. We hope everything is ok on your side, and that everyone is safe from the pandemic.

There were only a couple of things that had to be done to your code. The first is to create a function that parses the response from the subscription from the bytes array to a float value, and second, move the LED control routine from the loop into the callback, so that it runs the control loop only when there is data being received.

The code should work as presented below:

Include Libraries
****************************************/
#include "UbidotsESPMQTT.h"
/****************************************
Define Constants
****************************************/
#define TOKEN "xxx" // Your Ubidots TOKEN
#define WIFINAME "xxx" //Your SSID
#define WIFIPASS "xxx" // Your Wifi Pass
#define DEVICE_LABEL "xxx" // Put here your Ubidots device label
#define VARIABLE_LABEL "temperatura" // Put here your Ubidots variable label
#define MQTTCLIENTNAME "1vn30P282p" // Your MQTT Client Name, it must be unique so we recommend to choose a random ASCCI name
Ubidots client(TOKEN);
int LED = D1;
float value;
/****************************************
Auxiliar Functions
****************************************/
void callback(char* topic, byte* payload, unsigned int length){
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  value = btof(payload, length);
  Serial.print("The value received form Ubidots is: ");
  Serial.println(value);
  /* Place here your control routine */
  if (value > 15){
    digitalWrite(LED, HIGH);
  } else {
    digitalWrite(LED, LOW);
  }
}
// cast from an array of chars to float value.
float btof(byte * payload, unsigned int length) {
  char * demo_ = (char *) malloc(sizeof(char) * 10);
  for (int i = 0; i < length; i++) {
    demo_[i] = payload[i];
  }
  return atof(demo_);
}
/****************************************
Main Functions
****************************************/
void setup() {
  pinMode(LED, OUTPUT);
  // put your setup code here, to run once:
  client.ubidotsSetBroker("industrial.api.ubidots.com"); //       Sets the broker properly for the Industrial account
  client.setDebug(false); // Pass a true or false bool value to   activate debug messages
  Serial.begin(115200);
  client.wifiConnection(WIFINAME, WIFIPASS);
  client.begin(callback);
  client.ubidotsSubscribe(DEVICE_LABEL, VARIABLE_LABEL); //Insert the dataSource and Variable's Labels
}
void loop() {
// put your main code here, to run repeatedly:
if(!client.connected()){
  client.reconnect();
  client.ubidotsSubscribe(DEVICE_LABEL, VARIABLE_LABEL); //Insert the dataSource and Variable's Labels
  }
delay(1000);
client.loop();
}

I would be grateful if you confirmed once the code is up and running.

Best regards,
-Sebastián

Hi @Sebastian hope you and your family are well at this difficult time we are going through.

Thank you very much for your help! Yes, the code you put together works perfectly.
If possible could you help me with one more question? What if I were to monitor more boards and more variables? In the code that you made I am monitoring a variable of a device. What if there were more devices with more variables?

Thank you very much for using your time to help me.

Have a great day.

Hi @CAEGRUBR, I’m glad that the code worked for you.

To be able to subscribe to various variables and devices, two more functions need to be added, which identify from which variable and device the last Subscribe message came from. It has the same structure from the previous code. Remember that whatever control routines go inside the callback function.

The comments should be pretty straight forward on how to use the code, but if you encounter any questions, please reply to this thread.

   Include Libraries
 ****************************************/
#include <string.h>
#include "UbidotsESPMQTT.h"
​
/****************************************
   Define Constants
 ****************************************/
#define TOKEN "YOUR_TOKEN" // Your Ubidots TOKEN
#define WIFINAME "SSID" //Your SSID
#define WIFIPASS "WIFI_PASSWORD" // Your Wifi Pass
#define DEVICE_LABEL  "YOUR_DEVICE_LABEL"  // Put here your Ubidots device label
#define VARIABLE_LABEL1  "VARLABEL1"  // Put here your Ubidots variable label
#define VARIABLE_LABEL2  "VARLABEL2"  // Put here your Ubidots variable label
​
const uint8_t NUMBER_OF_VARIABLES = 2; // Number of variable to subscribe to
char * variable_labels[NUMBER_OF_VARIABLES] = {"VARLABEL2", "VARLABEL1"}; // labels of the variable to subscribe to
​
float value; // To store incoming value.
​
Ubidots client(TOKEN);
​
/****************************************
   Auxiliar Functions
 ****************************************/
 
// Callback to handle subscription
void callback(char* topic, byte* payload, unsigned int length) {
  char* variable_label = (char *) malloc(sizeof(char) * 30);
  char* device_label = (char *) malloc(sizeof(char) * 30);
  get_variable_label_from_topic(topic, variable_label);
  get_device_label_from_topic(topic, device_label);
  value = btof(payload, length);
  Serial.print("The variable label is: ");
  Serial.println(variable_label);
  Serial.print("The device label is: ");
  Serial.println(device_label);
​
  /* PUT YOUR OWN CODE TO TAKE ACTIONS BASED ON THE VAR LABEL AND VALUE */
​
  free(variable_label);
  free(device_label);
}
​
// Parse topic to extract the variable label which changed value
void get_variable_label_from_topic(char * topic, char * variable_label) {
  Serial.print("topic:");
  Serial.println(topic);
  sprintf(variable_label, "");
  for (int i = 0; i < NUMBER_OF_VARIABLES; i++) {
    char * result_lv = strstr(topic, variable_labels[i]);
    if (result_lv != NULL) {
      uint8_t len = strlen(result_lv);      
      char result[100];
      uint8_t i = 0;
      for (i = 0; i < len - 3; i++) { 
        result[i] = result_lv[i];
      }
      result[i] = '\0';
      Serial.print("Label is: ");
      Serial.println(result);
      sprintf(variable_label, "%s", result);
      break;
    }
  }
}
​
// Parse topic to extract the variable label which changed value
void get_device_label_from_topic(char * topic, char * device_label) {
  const uint8_t topic_length = strnlen(topic); // The length of the topic
  const uint8_t k = 0;
  Serial.print("topic:");
  Serial.println(topic);
  sprintf(device_label, "");
  for(uint8_t i = 14; i < topic_length; i++) {
    if (topic[i] != '/') {
      device_label[k] = topic[i];
      k++;
    }
    if (topic[i] == '/') {
      break;
    }
  }
  device_label[k] = '\0';
}
​
// cast from an array of chars to float value.
float btof(byte * payload, unsigned int length) {
  char * demo_ = (char *) malloc(sizeof(char) * 10);
  for (int i = 0; i < length; i++) {
    demo_[i] = payload[i];
  }
  return atof(demo_);
}
​
/****************************************
   Main Functions
 ****************************************/
​
void setup() {
  // put your setup code here, to run once:
  client.ubidotsSetBroker("industrial.api.ubidots.com"); // Sets the broker properly for the business account
  client.setDebug(true); // Pass a true or false bool value to activate debug messages
  Serial.begin(115200);
  client.wifiConnection(WIFINAME, WIFIPASS);
  client.begin(callback);
  client.ubidotsSubscribe(DEVICE_LABEL, VARIABLE_LABEL1); //Insert the dataSource and Variable's Labels
  client.ubidotsSubscribe(DEVICE_LABEL, VARIABLE_LABEL2); //Insert the dataSource and Variable's Labels
  client.ubidotsSubscribe(DEVICE_LABEL, VARIABLE_LABEL3); //Insert the dataSource and Variable's Labels
  Serial.println(variable_labels[1]);
}
​
void loop() {
  // put your main code here, to run repeatedly:
  if (!client.connected()) {
    client.reconnect();
    client.ubidotsSubscribe(DEVICE_LABEL, VARIABLE_LABEL1); //Insert the dataSource and Variable's Labels
    client.ubidotsSubscribe(DEVICE_LABEL, VARIABLE_LABEL2); //Insert the dataSource and Variable's Labels
    client.ubidotsSubscribe(DEVICE_LABEL, VARIABLE_LABEL3); //Insert the dataSource and Variable's Labels
  }
  client.loop();
}

Have a great day.

Hi @Sebastian . Thank you very much indeed for your help. I already consider you a friend, because you helped me a lot. I will do the tests adding more devices, because I want to work with up to 20 devices. As soon as I perform the test I will let you know.

Thank you very much and good health to you and your family.

1 Like