/****************************************
 * Include Libraries
 ****************************************/
#include <DHT.h>          
#include <WiFi.h>
#include <PubSubClient.h>
#include <stdio.h>


/****************************************
 * Define Constants
 ****************************************/
#define DHTTYPE  DHT22   
#define DHTPIN    27     
#define TOKEN "BBUS-PlgH6XzFHyXzEkyWC9PVAeAGOUAEsI" // Put your Ubidots' TOKEN
#define VARIABLE_LABEL "sensor1" // Assing the variable label
#define VARIABLE_LABEL2 "sensor2" // Assing the variable label
#define VARIABLE_CONTROL "led"
#define DEVICE_LABEL "proyecto-1" // Assig the device label
#define MQTT_CLIENT_NAME "0001" // MQTT client Name, put a Random ASCII
#define pinled 2

const char* WIFISSID = "Wokwi-GUEST";
const char* PASSWORD = "";

char mqttBroker[] = "industrial.api.ubidots.com";
char payload[700];
char topic[150];
char topicControl[150];
unsigned long ReadTime = 0;
int delayTime = 10000;

// Space to store values to send
char str_val[6];
char str_val2[6];

/****************************************
 * Initializate constructors for objects
 ****************************************/

//ESP8266WiFiMulti WiFiMulti;
WiFiClient ubidots;
PubSubClient client(ubidots);

DHT dht(DHTPIN, DHTTYPE, 22); 

/****************************************
 * Auxiliar Functions
 ****************************************/
 
void callback(char* topic, byte* payload, unsigned int length) 
{
  //Serial.println("incoming: " + topic + " - " + payload);
  String incoming = "";
  Serial.print("Message received from -> ");
  Serial.print(topic);
  Serial.println("");
  for (int i = 0; i < length; i++) {
    incoming += (char)payload[i];
  }
  incoming.trim();
  Serial.println("Message -> " + incoming);
  int p = incoming.indexOf("."); 
  char led = (char)payload[p-1];
  Serial.println(led);
  Serial.println("LED goes to status" + String(led));
    
  if (led == '0'){
      Serial.println("LED Off");
      digitalWrite(pinled,LOW);
    }
  else if (led == '1'){
      Serial.println("LED On");
      digitalWrite(pinled,HIGH);
    }
}  

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
  Serial.println("Attempting MQTT connection...");

  // Attempt to connect
  if (client.connect(MQTT_CLIENT_NAME, TOKEN,"")) {
    Serial.println("connected");
    client.subscribe(topicControl);
  } else {
    Serial.print("failed, rc=");
    Serial.print(client.state());
    Serial.println(" try again in 2 seconds");
    // Wait 2 seconds before retrying
    delay(2000);
  }
  }
}

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

void setup() {
  Serial.begin(115200);
  pinMode(pinled, OUTPUT);
  digitalWrite(pinled, LOW);
  dht.begin(); 
  WiFi.begin(WIFISSID, PASSWORD);
  Serial.println();
  Serial.println();
  Serial.print("Wait for WiFi... ");

  while(WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);

  sprintf(topicControl, "%s", ""); // Cleans the topic content
  sprintf(topicControl, "%s%s%s%s", "/v1.6/devices/", DEVICE_LABEL,"/",VARIABLE_CONTROL);
  client.subscribe(topicControl);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  unsigned long now = millis();
  int deltaTime = now - ReadTime;
  
  //Read each detail
  if(deltaTime > delayTime)
  {
  float hum = dht.readHumidity(); 
  float temp = dht.readTemperature();

  /*Data to Ubidots*/
  //Headboard
  sprintf(topic, "%s", ""); // Cleans the topic content
  sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
  //start
  sprintf(payload, "%s", ""); // Cleans the payload content
  sprintf(payload, "{\"%s\":", VARIABLE_LABEL); // Adds the variable label   
  sprintf(payload, "%s {\"value\": %s", payload, String(temp)); // Adds the value
  //intermediate
  sprintf(payload, "%s },\"%s\":", payload, VARIABLE_LABEL2); // Adds the variable label2
  sprintf(payload, "%s {\"value\": %s", payload, String(hum)); // Adds the value2
  //closing
  sprintf(payload, "%s } }", payload); // Closes the dictionary brackets
  Serial.println(String(payload));
  client.publish(topic, payload);
  ReadTime = now;
  }
  client.loop();
}