#include <LiquidCrystal_PCF8574.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ESP8266WiFi.h>
#include <ThingSpeak.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);

// Datos de red WiFi (modificar)
const char* ssid = "your-ssid"; // Nombre de la red 
const char* password = "your-password"; // Contraseña

// Informaciòn disponible en ThingSpeak:
unsigned long channel = 1234567;  // Número de canal ThingSpeak
const char * ClaveEscrituraAPI = "A1B2C3D4E5F6G7H8";  // Clave de escritura ThingSpeak

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

float sensor_ant;
float temp_ant;

WiFiClient  client;

#define I0 16
#define I1 14
#define I2 12

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

#define estado_I0 digitalRead(I0)
#define estado_I1 digitalRead(I1)
#define estado_I2 digitalRead(I2)

boolean estado_I0_ant;
boolean estado_I1_ant;
boolean estado_I2_ant;

byte alto[] = {
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B00000,
};

byte bajo[] = {
  B11111,
  B10001,
  B10001,
  B10001,
  B10001,
  B10001,
  B11111,
  B00000,
};

void estados() {
  if (WiFi.status() == WL_CONNECTED)
  {
    lcd.setCursor(0,0);
    lcd.print("Conectado a T_Speak ");
    lcd.setCursor(0,1);
    lcd.print("I: ");
    lcd.write(digitalRead(I0));
    lcd.print(" ");
    lcd.write(digitalRead(I1));
    lcd.print(" ");
    lcd.write(digitalRead(I2));
    lcd.setCursor(0,2);
    lcd.print("   0 1 2");
    lcd.setCursor(0,3);
    lcd.print("Q: ");
    lcd.write(digitalRead(Q0));
    lcd.print(" ");
    lcd.write(digitalRead(Q1));
    lcd.print(" ");
    lcd.write(digitalRead(Q2)); 
  }
  else
  {
    lcd.clear();
    delay(500);
    lcd.print("Conectando a T_Speak");
    delay(500);
  }
}

void setup() {
  // put your setup code here, to run once:
  pinMode(I0, INPUT);
  pinMode(I1, INPUT);
  pinMode(I2, INPUT);
  pinMode(Q0, OUTPUT);
  pinMode(Q1, OUTPUT);
  pinMode(Q2, OUTPUT);

  sensors.begin();

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

  WiFi.begin(ssid, password);

  estados();

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

  ThingSpeak.begin(client);
}

void loop() {
  // put your main code here, to run repeatedly:

  sensor = analogRead(A0);

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

  if (sensor != sensor_ant || temp != temp_ant || estado_I0 != estado_I0_ant || estado_I1 != estado_I1_ant || estado_I2 != estado_I2_ant)
  {
    ThingSpeak.setField(1, sensor);
    ThingSpeak.setField(2, temp);
    ThingSpeak.setField(3, estado_I0);
    ThingSpeak.setField(4, estado_I1);
    ThingSpeak.setField(5, estado_I2);

    // Escribe en ThingSpeak: (número del canal, clave de escritura)
    ThingSpeak.writeFields(channel, ClaveEscrituraAPI);
  }

  int field6 = ThingSpeak.readIntField(channel, 6);
  int field7 = ThingSpeak.readIntField(channel, 7);
  int field8 = ThingSpeak.readIntField(channel, 8);

  digitalWrite(Q0, field6);
  digitalWrite(Q1, field7);
  digitalWrite(Q2, field8);

  estados();
  delay(1000);

  sensor_ant = sensor;
  temp_ant = temp;
  estado_I0_ant = estado_I0;
  estado_I1_ant = estado_I1;
  estado_I2_ant = estado_I2;
}