#include <Wire.h>
#include <Adafruit_MCP9808.h> // Bibliothèque pour le capteur MCP9808
#include <WiFi.h>
#include <ThingsBoard.h>
#include <Arduino_MQTT_Client.h>
#include <LiquidCrystal_I2C.h> // Bibliothèque pour l'afficheur LCD
#include <ESP_Mail_Client.h>
#include <WiFiClientSecure.h>

#define SENSOR_ADDR 0x18 // Adresse I2C du capteur MCP9808
Adafruit_MCP9808 mcp = Adafruit_MCP9808(); // Instance du capteur MCP9808

#define WIFI_AP "Wokwi-GUEST"
#define WIFI_PASS ""

#define TB_SERVER "thingsboard.cloud"
#define TOKEN "cKukYPLJUJMTR2A5y97v"
const char* smtpServer = "smtp.gmail.com";
const int smtpServerPort = 465; // Define the SMTP server port
const char* emailSenderAccount = "[email protected]"; // Remplacez par votre adresse email
const char* emailSenderPassword = "mdms iash bbme xmrw";
const char* emailRecipient = "[email protected]";
constexpr uint16_t MAX_MESSAGE_SIZE = 256U;

WiFiClient espClient;
Arduino_MQTT_Client mqttClient(espClient);
ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE);

// Définir la plage de température acceptable
#define TEMP_MIN 10.0
#define TEMP_MAX 30.0

// Définir la broche de la LED
#define LED_PIN 2
const int VIBRATION_SENSOR_PIN = 12;

SMTPSession smtp; // Define the SMTP session
void smtpCallback(SMTP_Status status);

void sendEmail(const String& subject, const String& messageText) {
  smtp.callback(smtpCallback);

  ESP_Mail_Session session;
  session.server.host_name = smtpServer;
  session.server.port = smtpServerPort;
  session.login.email = emailSenderAccount;
  session.login.password = emailSenderPassword;

  smtp.connect(&session);

  SMTP_Message message;
  message.sender.name = "ESP32";
  message.sender.email = emailSenderAccount;
  message.subject = subject;
  message.addRecipient("Recipient", emailRecipient);

  message.text.content = messageText.c_str();
  message.text.charSet = "us-ascii";
  message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;

  if (!MailClient.sendMail(&smtp, &message)) {
    Serial.println("Error sending email: " + smtp.errorReason());
  }

  message.clear();
}

void smtpCallback(SMTP_Status status) {
  // Handle SMTP callback
}

// Initialisation de l'afficheur LCD
LiquidCrystal_I2C lcd(0x27, 16, 2);

void connectToWiFi() {
  Serial.println("Connecting to WiFi...");
  int attempts = 0;

  while (WiFi.status() != WL_CONNECTED && attempts < 20) {
    WiFi.begin(WIFI_AP, WIFI_PASS, 6);
    delay(500);
    Serial.print(".");
    attempts++;
  }

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("\nFailed to connect to WiFi.");
  } else {
    Serial.println("\nConnected to WiFi");
  }
}

void connectToThingsBoard() {
  if (!tb.connected()) {
    Serial.println("Connecting to ThingsBoard server");

    if (!tb.connect(TB_SERVER, TOKEN)) {
      Serial.println("Failed to connect to ThingsBoard");
    } else {
      Serial.println("Connected to ThingsBoard");
    }
  }
}

void sendDataToThingsBoard(float temp, int vibration) {
  String jsonData = "{\"tempIn\":" + String(temp) + ", \"vibration\":" + String(vibration) + "}";
  tb.sendTelemetryJson(jsonData.c_str());
  Serial.println("Data sent");
}

void setup() {
  Serial.begin(115200);

  // Initialisation du capteur MCP9808
  if (!mcp.begin(SENSOR_ADDR)) {
    Serial.println("Couldn't find MCP9808!");
    while (1);
  }
   pinMode(VIBRATION_SENSOR_PIN, INPUT);

  connectToWiFi();
  connectToThingsBoard();
  sendEmail("Test Email", "This is a test email from ESP32.");

  // Initialisation de l'afficheur LCD
  lcd.init();
  lcd.backlight();
}

void loop() {
  connectToWiFi();

  // Lecture de la température depuis le capteur MCP9808
  float temp = mcp.readTempC();

  // Lecture de la valeur du capteur de vibration
  int vibrationValue = digitalRead(VIBRATION_SENSOR_PIN);

  // Affichage et contrôle de la température et de la vibration
  if ((temp > 45 || temp < 20) && (vibrationValue == HIGH)) {
    digitalWrite(LED_PIN, HIGH);
    lcd.setCursor(0, 0);
    lcd.print("Temp out of range!");
  } else {
    digitalWrite(LED_PIN, LOW);
    lcd.setCursor(0, 0);
    lcd.print("TEMP: ");
    lcd.print(temp);
    lcd.print(" C");
    lcd.setCursor(0, 1);
    lcd.print("Vibration: ");
    lcd.print(vibrationValue == HIGH ? "Detected" : "None");
  }

  Serial.println("Temperature: " + String(temp));
  Serial.println("Vibration: " + String(vibrationValue == HIGH ? "Detected" : "None"));
  sendEmail("Vibration Alert", "Vibration Détected:" );
  sendEmail("Temperature Alert", "Temperature is out of range: " + String(temp) + " C"); 
  if (!tb.connected()) {
    connectToThingsBoard();
  }

  sendDataToThingsBoard(temp, vibrationValue);
  }
  delay(3000);
  tb.loop();
}


$abcdeabcde151015202530354045505560fghijfghij
MCP9808Breakout