#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>

#include <WiFi.h>
#include <PubSubClient.h>

#define DHTPIN 2      
#define DHTTYPE DHT22 


//{{{{{{{{{{{{{{Lampe 
#define rot 27            //LED anschlüsse 
#define blau 26
#define gruen 25
#define blinken 200       //Zeit von Warnungen LED blinkt

//##### }}}}}}}}}}}}} 

DHT dht(DHTPIN, DHTTYPE); 

LiquidCrystal_I2C lcd(0x27, 16, 2); 

float globalCO2 = 0; // Globale Variable für den CO2-Wert


// WiFi Credentials


// MQTT Server

// für die Simulation bei WOKWI könnt ihr das so lassen. 
// Wenn ihr das aber auf Arduino installiert müsst ihr eure WLAN Name und Passwort eingeben. 
//{{{{{{{{{{{{{{{{{{{
const char* ssid = "Wokwi-GUEST"; // Dein WiFi-SSID
const char* password = ""; // Dein WiFi-Passwort
//}}}}}}}}}}}}}}}}}}}



//{{{{{{{{{{{{{{{ Hier nichts ändern

const char* mqtt_server = "sftskls-tk.informatik.uni-oldenburg.de";
const int mqtt_port = 1883;
const char* mqtt_user = "krenbeh_manar";
const char* mqtt_password = "1234";
bool x = true;
WiFiClient espClient;
PubSubClient client(espClient);
 //##############     }}}}}}}}}}}}}}}


// Globale Variablen für Temperatur und Feuchtigkeit
float globalTemperature = 0;
float globalHumidity = 0;

void setup() {

  //{{{{{{{{{{{{{{{ Hier nichts ändern
  Serial.begin(115200); 
  dht.begin();
  lcd.init(); 
  lcd.backlight(); 
  lcd.setCursor(0, 0);
  lcd.print("Temp:         C"); 
  lcd.setCursor(0, 1); 
  lcd.print("Humi:         %");
  //###############   }}}}}}}}}}}}}}}}}}

  

  // {{{{{{{{{{{{{{ Lampe 
  pinMode(rot, OUTPUT);
  pinMode(gruen, OUTPUT);
  pinMode(blau, OUTPUT);
  // ########    }}}}}}}}}}}}}}}}



  //{{{{{{{{{{{{{{{ Hier nichts ändern

  // WiFi und MQTT
  Serial.print("Connecting to WiFi");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" WiFi connected");

  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  reconnect();
//###############   }}}}}}}}}}}}}}}}}}

}

void loop() {
  
  delay(2000); 

    //{{{{{{{{{{{{{{{ Hier nichts ändern
  
  // Falls MQTT nicht verbunden ist, versuche zu reconnecten
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  //############# }}}}}}}}}}}}}}}}}}}}}}


  // Temperatur- und Feuchtigkeitsüberprüfung und Servosteuerung
  Serial.println(globalTemperature);



//{{{{{{{{{{{{{{{{{{{{ Muss ersetzt werden mit dem was der Ventilator tun Soll bei bestimmten Temperaturen ############################

  if (globalTemperature < 25 && globalTemperature > 5 ){    //LED einbinden mit Temperaturgrenzen
    digitalWrite(rot, LOW);
    digitalWrite(blau, LOW);
    digitalWrite(gruen, HIGH);}
if (globalTemperature > 25) {
    digitalWrite(blau, HIGH);
    digitalWrite(gruen, LOW);
    digitalWrite(rot, LOW);}
if (globalTemperature > 45){
    digitalWrite(rot, HIGH);
    digitalWrite(blau, LOW);}
if (globalTemperature > 65){
    digitalWrite(rot, HIGH);
    delay(blinken);
    digitalWrite(rot, LOW);
    delay(blinken);}
if (globalHumidity < 5){                            
    digitalWrite(gruen, HIGH);
    digitalWrite(blau, HIGH);
    delay(blinken);
    digitalWrite(gruen, LOW);
    digitalWrite(blau, LOW);
    delay(blinken);}

    // #######################}}}}}}}}}}}}}}}}}}}}

  // CO2-Warnung






  if (globalCO2 > 120) {
    x = true;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Mach Fenster auf!");
    //{{{{{{{{{{{{{{{ Hier nichts ändern
  } else {
    if(x){
      lcd.clear();
      x = false;
    }
    // LCD mit Temperatur und Feuchtigkeit aktualisieren
    lcd.setCursor(0, 0);
    lcd.print("Temp:         C");
    lcd.setCursor(7, 0); 
    lcd.print(globalTemperature); 
    lcd.setCursor(0, 1);
    lcd.print("Humi:         %");
    lcd.setCursor(7, 1); 
    lcd.print(globalHumidity); 
    lcd.setCursor(14, 1);
    lcd.print("%");
  }

}

void callback(char* topic, byte* payload, unsigned int length) {
  // Erstelle eine temporäre Kopie der Nutzdaten
  char message[length + 1];
  strncpy(message, (char*)payload, length);
  message[length] = '\0';

  String topicStr = String(topic);
  if (topicStr == "/ThinkIOT/temp") {
    globalTemperature = atof(message);
  } else if (topicStr == "/ThinkIOT/hum") {
    globalHumidity = atof(message);
  } else if (topicStr == "/ThinkIOT/co2") {
    globalCO2 = atof(message);
  }
  Serial.print("Message arrived [");
  Serial.print(topicStr);
  Serial.print("] ");
  Serial.println(message);
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    if (client.connect("ESP32Client", mqtt_user, mqtt_password)) {
      Serial.println("connected");
      client.subscribe("/ThinkIOT/temp");
      client.subscribe("/ThinkIOT/hum");
      client.subscribe("/ThinkIOT/co2");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      delay(5000);
    }
  }
}
//############################## }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}