#include <Wire.h> //Biblioteca do I2C
#include "DHTesp.h"
#include<LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid = "Wokwi-GUEST";       //string com nome da rede onde o esp vai se conectar
const char* password =  "";         //string com a senha da rede. Deixar em branco caso a rede seja aberta
const char* mqttServer = "broker.hivemq.com";   //string com a url do Broker que vai receber e transmitir as mensagens
const int   mqttPort = 1883;                    //inteiro com o número da porta utilizada na conexão
const char* mqttUser = "";                      //string com nome de usuário no Broker, quando for necessário
const char* mqttPassword = "";                  //string com senha do Broker, quando necessário
const char* topico_teste = "cps/batmaman/rele";          //tópico a ser assinado
const char* topico_envia = "cps/batmaman/temp";
const char* topico_condicaoTemp = "cps/batmaman/TempString";
const char* topico_estoque = "cps/batmaman/estoque";
const int DHT_PIN = 27;
const int RELE = 15;

int tempEstragado = 0;


DHTesp dhtSensor;
WiFiClient    espClient;                     //criação do objeto espClient do tipo WiFiClient
PubSubClient  client(espClient);           //

char mensagem[30];     
float temp = 0;

#define I2C_ADDR    0x27
#define LCD_COLUMNS 16
#define LCD_LINES   2

LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);

// LED
const int ledG=4, ledR=5, ledB=2;
// Btn++:
const int Btnsoma= 13;
bool stateBtnAtualsoma = LOW;
bool stateBtnAnteriorsoma = LOW;
int count = 0;
float count2 = 0;
//Btn--:
const int Btnsub = 12; 
bool stateBtnAtualsub = LOW;
bool stateBtnAnteriorsub = LOW;
//
char str[16];
char strCond[40];
char estoqueStr[5];


void setup() {
  Serial.begin(115200);
  lcd.init();
  lcd.backlight();
  pinMode(ledG, OUTPUT);
  pinMode(ledR, OUTPUT);
  pinMode(ledB, OUTPUT);
  pinMode(Btnsoma, INPUT_PULLUP);
  pinMode(Btnsub, INPUT_PULLUP);

  dhtSensor.setup(DHT_PIN, DHTesp::DHT22);
  pinMode(RELE, OUTPUT);
  WiFi.begin(ssid, password,6);             //inicia a conexão WiFi com a rede
  while (WiFi.status() != WL_CONNECTED)   //verifica se a conexão ainda não estabilizou
  {
    delay(400);                           //espera 500 ms
    Serial.println("Iniciando conexao com a rede WiFi.."); //"printa" na tela a frase entre aspas
    digitalWrite(ledB, HIGH);
    delay(400);
    digitalWrite(ledB, LOW);
  }

  Serial.println("Conectado na rede WiFi!");  //quando sai do laço, print a frase entre aspas
  digitalWrite(ledB, HIGH);
  client.setCallback(callback);  
}



void loop() {
  if(!client.connected()){
    reconectabroker();                      //chama função de conexão ao Broker
  }
  //Para checar a rotina de callback
  client.loop();

  for(int i=0; i<100;i++){
    temp = temp + dhtSensor.getTemperature();
  }
  temp = temp/100;
  count2 = count;
  sprintf(mensagem, "%.2f", temp);
  sprintf(strCond, "A TEMPERATURA ESTÁ IDEAL PARA ARMAZENAMENTO DOS CAMARÕES.");


  if(temp > -15){
    tempEstragado += 1;
    sprintf(strCond,"PERIGO! TEMPERATURA MUITO ACIMA DO IDEAL.");
    if(tempEstragado >= 10){
        count = 0;
        tempEstragado = 0;
        lcd.clear();
        sprintf(str, "%d KG.", count);
        lcd.print(str);
    }
    delay(450);
  }
  
  //Envia a mensagem ao broker
  sprintf(estoqueStr, "%.2f", count2);
  client.publish(topico_estoque, estoqueStr);
  client.publish(topico_envia, mensagem);
  client.publish(topico_condicaoTemp, strCond);
  if(temp>37.8){
    digitalWrite(RELE, LOW);
  }
  if(temp<37.4){
    digitalWrite(RELE, HIGH);
  }
  // delay(1000); // Wait for a new reading from the sensor (DHT22 has ~0.5Hz sample rate)


  

  // BTN+:
  stateBtnAtualsoma = digitalRead(Btnsoma);
  if (stateBtnAtualsoma == LOW && stateBtnAnteriorsoma == HIGH){
    count++;
    
   Serial.println("Mensagem enviada com sucesso...");
    
    lcd.clear();
    sprintf(str, "%d KG.", count);
    lcd.print(str);

    digitalWrite(ledG, HIGH);
    tone(14, 262, 100); // Toca um tom de 262Hz por 0,250 segundos

    stateBtnAnteriorsoma = LOW;
 
     delay(300);

     digitalWrite(ledG, LOW);
 
  }
  if(stateBtnAtualsoma == HIGH && stateBtnAnteriorsoma == LOW){
    stateBtnAnteriorsoma = HIGH;
  }

  //BTN-:
  stateBtnAtualsub = digitalRead(Btnsub);
  if (stateBtnAtualsub == LOW && stateBtnAnteriorsub == HIGH){
    count--;
    
   Serial.println("Mensagem enviada com sucesso...");

    lcd.clear();
    sprintf(str, "%d KG.", count);
    lcd.print(str);
    digitalWrite(ledR, HIGH);
    tone(14, 262, 100); // Toca um tom de 262Hz por 0,250 segundos


    stateBtnAnteriorsub = LOW;
    delay(300);
    digitalWrite(ledR, LOW);
  }
    if(stateBtnAtualsub == HIGH && stateBtnAnteriorsub == LOW){
    stateBtnAnteriorsub = HIGH;
    }
  
  
  }
  void reconectabroker()
{
  //Conexao ao broker MQTT
  client.setServer(mqttServer, mqttPort);
  while (!client.connected())
  {
    Serial.println("Conectando ao broker MQTT...");
    if (client.connect("", mqttUser, mqttPassword ))
    {
      Serial.println("Conectado ao broker!");
      client.subscribe(topico_teste);               //assina o esp32 no tópico topico_teste definido no inicio do programa
    }
    else
    {
      Serial.print("Falha na conexao ao broker - Estado: ");
      Serial.print(client.state());
      delay(4000);
    }
  }

}//definição da funçao de callback.
void callback(char* topic, byte* message, unsigned int length) {
  Serial.println("Chegou mensagem no topico: ");
  Serial.print(topic);
  Serial.print(". Mensagem: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {  //escreve mensagem caractere por caractere
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  if (String(topic) == topico_teste) {
    Serial.print("Trocando o estado do Relé para: ");
    if(messageTemp == "on"){
      Serial.println("Ligado");
      digitalWrite(RELE, HIGH);
    }
    else if(messageTemp == "off"){
      Serial.println("Desligado");
      digitalWrite(RELE, LOW);
    }else{}
  }
}
$abcdeabcde151015202530fghijfghij
$abcdeabcde151015202530fghijfghij
NOCOMNCVCCGNDINLED1PWRRelay Module