#include <WiFi.h>
#include <PubSubClient.h>
#include <ESP32Servo.h>
#include <EEPROM.h> 

#define EEPROM_SIZE 1
#define SERVO_PIN 
// WiFi
const char *ssid = "fede"; // Enter your WiFi name
const char *password = "1234asdfy";  // Enter WiFi password

// MQTT Broker
const char *mqtt_server = "broker.hivemq.com";
const char *topic1 = "HorizonLab/Door1";
const char *topic2 = "HorizonLab/Light1";
const char *topic3 = "HorizonLab/Fan1";
const char *mqtt_username = "emqx";
const char *mqtt_password = "public";
const int mqtt_port = 1883;
const byte LED_pin = 15;
int servoPin = 13;
int pos=0;
const byte doorOpen_IND=0;
const int boolFirst_Add=1;
byte boolFirst;

//Vebtilatore 
int motor1Pin1 = 27; 
int enable1Pin = 26; 
int potenza=0;

String messageTemp;

WiFiClient espClientHori1;
PubSubClient client(espClientHori1);
Servo myservo;

void callback(char* topic, byte* message, unsigned int length)
{
  Serial.print("callabck entrato dove gestico le uscite");
  Serial.print(topic);
  for (int i = 0; i < length; i++)
  {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  if (strcmp(topic, topic1) == 0)
  {
    int  doorOpen=  EEPROM.read(doorOpen_IND);
    Serial.print(doorOpen);
    Serial.print("Commando porta ricevuto");
    Serial.print(topic);
    if (messageTemp == "true" and doorOpen ==0)
    {
      Serial.println("Porta aperta");
       for (pos =88; pos >= -90; pos -= 1)
       {
        //   in steps of 1 degree
          myservo.write(pos); 
          delay(15); // waits 15ms to reach the position
          doorOpen=1;
       }
       EEPROM.write(doorOpen_IND, doorOpen);
    }
    if (messageTemp == "false" and (doorOpen == 1) )
    {
      for (pos = -90; pos <= 88; pos += 1) 
      {
        myservo.write(pos); 
        delay(15); // waits 15ms to reach the position
        doorOpen=0;
      }
      EEPROM.write(doorOpen_IND, doorOpen);
      Serial.println("Porta chiusa");
    }
  }  
  if (strcmp(topic, topic2) == 0)
  {
    Serial.print("Command Per luce ricevuto");
    Serial.print(topic);
    Serial.print(messageTemp);
    if (messageTemp == "true")
    {
      digitalWrite(LED_pin, HIGH);
      Serial.println("LED is ON");
    }
    if (messageTemp == "false")
    {
      digitalWrite(LED_pin, LOW);
      delay(1000);
      Serial.println("LED is OFF");
      delay(1000);
    }
  }
   if (strcmp(topic, topic3) == 0)
   {
    Serial.print("Command Per ventilatore");
    Serial.print(messageTemp);
    if (messageTemp == "true")
    {
      potenza=20;
      Serial.println("Moving Forward");
      digitalWrite(motor1Pin1, HIGH);
      analogWrite(enable1Pin,potenza);
    }
    if (messageTemp == "false")
    {
      potenza=0;
      Serial.println("Moving Forward");
      digitalWrite(motor1Pin1, LOW);
      analogWrite(enable1Pin,potenza);
    }
    if (messageTemp == "25")
    {
      Serial.println("Aumento vetilatore");
      potenza=potenza+5;
      analogWrite(enable1Pin,potenza);
    }
    if (messageTemp == "-25")
    {
      Serial.println("diminuisco  vetilatore");
      potenza=potenza-5;
      analogWrite(enable1Pin,potenza);
    }
   }
  messageTemp = "";
}

boolean reconnect()
  {
    if (client.connect("espClientHori1",mqtt_username,mqtt_password))
    {
      Serial.println("conessione in corso");
      client.subscribe(topic3);
      client.subscribe(topic2);
      client.subscribe(topic1);
      //  client.subscribe("");
      //  client.subscribe("");
      return client.connected();
    }
    Serial.println("I think connect failed.");
    return 0;
  }
  
void setup()
{
  pinMode(LED_pin, OUTPUT);
  digitalWrite(LED_pin, LOW);
  pinMode(motor1Pin1, OUTPUT);
  pinMode(enable1Pin, OUTPUT);
  // Set software serial baud to 115200;
  Serial.begin(115200);
  
  EEPROM.begin(EEPROM_SIZE);
  boolFirst = EEPROM.read(boolFirst_Add);
  Serial.print(boolFirst);
  if ( boolFirst != 5 )
  {
    EEPROM.write(doorOpen_IND, 1);
    EEPROM.write(boolFirst_Add, 5);
  }
  

  // connecting to a WiFi network
  Serial.println("-----------------------------BOARD 1-------------------------------------");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.println("Connecting to WiFi..");
  }
  Serial.println("Connected to the WiFi network");
  //connecting to a mqtt broker
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  ESP32PWM::allocateTimer(0);
  ESP32PWM::allocateTimer(1);
  ESP32PWM::allocateTimer(2);
  ESP32PWM::allocateTimer(3);
  myservo.setPeriodHertz(50);    // standard 50 hz servo
  myservo.attach(servoPin, 500, 2400);
  Serial.println("Board 1");
}

void loop()
{
  if (!client.connected()) 
  {
    
    reconnect();
  }
  client.loop();
}
