/****************************************
 * Include Libraries
 ****************************************/
#include <LiquidCrystal_PCF8574.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "Ubidots.h"

LiquidCrystal_PCF8574 lcd(0x27); // set the LCD address to 0x27 for a 16 chars and 2 line display

// DS18B20 data wire
#define ONE_WIRE_BUS 0

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

const char* UBIDOTS_TOKEN = "your-ubidots_token";  // Put here your Ubidots TOKEN
const char* WIFI_SSID = "your-ssid";      // Put here your Wi-Fi SSID
const char* WIFI_PASS = "your-password";      // Put here your Wi-Fi password
Ubidots ubidots(UBIDOTS_TOKEN, UBI_HTTP);
// Ubidots ubidots(UBIDOTS_TOKEN, UBI_TCP); // Uncomment to use TCP
// Ubidots ubidots(UBIDOTS_TOKEN, UBI_UDP); // Uncomment to use UDP

int sensor; // Variable para almacenar el valor leído por el sensor
float tempC;

#define PIN_I0 16
#define PIN_I1 14
#define PIN_I2 12

#define I0 digitalRead(PIN_I0)
#define I1 digitalRead(PIN_I1)
#define I2 digitalRead(PIN_I2)

#define Q0 2
#define Q1 15
#define Q2 13

byte alto[] = {0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x00,};
byte bajo[] = {0x00,0x1F,0x11,0x11,0x11,0x11,0x1F,0x00,};

void estados() {
  if (WiFi.status() == WL_CONNECTED)
  {
    lcd.setCursor(0,0);
    lcd.print("Conectado a Ubidots ");
    lcd.setCursor(0,1);
    lcd.print("I: ");
    lcd.write(I0);
    lcd.write(I1);
    lcd.write(I2);
    lcd.setCursor(0,2);
    lcd.print("   012");
    lcd.setCursor(0,3);
    lcd.print("Q: ");
    lcd.write(digitalRead(Q0));
    lcd.write(digitalRead(Q1));
    lcd.write(digitalRead(Q2));
    lcd.setCursor(12,1);
    lcd.print("A0:    ");
    lcd.setCursor(15,1);
    lcd.print(sensor);
    lcd.setCursor(12,2);
    lcd.print("T");
    lcd.print((char)223);
    lcd.print(":     ");
    lcd.setCursor(15,2);
    if (tempC == -127)
      lcd.print("Error");
    else
      lcd.print(tempC,1);
  }
  else
  {
    lcd.clear();
    delay(1000);
    lcd.print("Conectando a Ubidots");
    delay(1000);
  }
}

void setup() {
  // put your setup code here, to run once:
  pinMode(PIN_I0, INPUT);
  pinMode(PIN_I1, INPUT);
  pinMode(PIN_I2, INPUT);
  pinMode(Q0, OUTPUT);
  pinMode(Q1, OUTPUT);
  pinMode(Q2, OUTPUT);

  sensors.begin();
  Serial.begin(115200);

  lcd.begin(20, 4); // initialize the lcd
  lcd.createChar(0, bajo);
  lcd.createChar(1, alto);
  delay(200);
  lcd.setBacklight(255);

  estados();

  while (!ubidots.wifiConnect(WIFI_SSID, WIFI_PASS))
  {
    delay(500);
  }

  ubidots.setDebug(true);  // Uncomment this line for printing debug messages
}

void loop() {
  // put your main code here, to run repeatedly:
  sensor = analogRead(A0);

  sensors.requestTemperatures(); // Send the command to get temperatures
  tempC = sensors.getTempCByIndex(0);

  estados();

  ubidots.add("sensor", sensor);  // Change for your variable name
  ubidots.add("temperatura", tempC);
  ubidots.add("i0", I0);
  ubidots.add("i1", I1);
  ubidots.add("i2", I2);

  bool bufferSent = false;
  bufferSent = ubidots.send();  // Will send data to a device label that matches the device Id

  if (bufferSent) {
    // Do something if values were sent properly
    Serial.println("Values sent by the device");
  }

  digitalWrite(Q0, ubidots.get("your-device_label", "q0"));
  digitalWrite(Q1, ubidots.get("your-device_label", "q1"));
  digitalWrite(Q2, ubidots.get("your-device_label", "q2"));

  delay(1000);
}