mobizt/ESP-Mail-Client

ESP32 Email SMTP Server Greeting Failed on Every second Attempt

BrenMaartens opened this issue · 1 comments

Build tool used:

  • Arudino
  • Platformio (Visual Studio Code plugin)
  • Platformio CLI
  • Other

Board used (ESP32/ESP8266/Arudino):

  • ESP8266-based
  • ESP32-based

Other Libraries That are used:

#include <OneWire.h>
#include <DallasTemperature.h>

Description of problem:

The code snippet just monitors if a temperature goes out of bounds of two upper and lower thresholds and sends an alert. Then waits for a period of time before it sends another.

Problem:
The mail sends successfully from first reboot. The second one fails, the third one sends, the forth one fails. etc etc.
It's always met with the same error message "SMTP Greeting Failed" - What would cause this to happen only every second time it sends?

Share code snippet to reproduce the issue:

#include <Arduino.h>
#include <ESP_Mail_Client.h>



#if defined(ESP32)
  #include <WiFi.h>
#elif defined(ESP8266)
  #include <ESP8266WiFi.h>
#endif

#include <OneWire.h>
#include <DallasTemperature.h>

// DS18B20 temperature probe pin
#define TEMPERATURE_PIN 4
#define STATUS_LED 17
int emailretry = 0;

//**********************************SETUP PROCESS*************************************************

//---------------------------TIME & TEMPERATURE VARIABLES-----------------------------------------

//Name of the Freezer unit to be used in emails as Identification
#define FREEZER_NAME "Freezer 1"

// Temperature thresholds for Freezers in degrees Celsius
//#define TEMPERATURE_THRESHOLD_UPPER -10 // Upper temperature to reach to hit the Alarm
//#define TEMPERATURE_THRESHOLD_LOWER -20 // Lower Temperature to reach to hit the Alarm
//define TEMPERATURE_CALIBRATION_OFFSET 0 //Calibration Offset for Temperature (degrees C)

// Temperature thresholds for Fridges in degrees Celsius
#define TEMPERATURE_THRESHOLD_UPPER 20 // Upper temperature to reach to hit the Alarm
#define TEMPERATURE_THRESHOLD_LOWER 15 // Lower Temperature to reach to hit the Alarm
#define TEMPERATURE_CALIBRATION_OFFSET 0 //Calibration Offset for Temperature (degrees C)


//This is our Start-up Timer to allow the probe to get down to temperature before monitoring.
#define TIME_INTERVAL 30000 // 30 Seconds

// Minimum time between email notifications in milliseconds 
//#define EMAIL_INTERVAL 7200000 //2 hours
//#define EMAIL_INTERVAL 30000 // 30 seconds
#define EMAIL_INTERVAL 240000 // 4 minutes


//---------------------------TIME & TEMPERATURE VARIABLES-----------------------------------------

 // ---------------------------SET UP WIFI CREDENTIALS -------------------------------------------
#define WIFI_SSID "Water"
#define WIFI_PASSWORD ""
 // ---------------------------SET UP WIFI CREDENTIALS -------------------------------------------

 //---------------------------- SET UP EMAIL CREDEMTIALS -----------------------------------------

 /* The sign in credentials */
#define AUTHOR_EMAIL "snctempalarm@gmail.com"
#define AUTHOR_PASSWORD ""
#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465

#define ESP_MAIL_USE_PSRAM

/* Recipient's email*/
#define RECIPIENT_EMAIL ""
 //---------------------------- SET UP EMAIL CREDEMTIALS -----------------------------------------

//**********************************SETUP PROCESS*************************************************



// Variable to store the starting time
unsigned long startTime;
// Variable to store the time since last email
unsigned long lastEmailTime;

// Declare the temperature probe and OneWire objects
OneWire oneWire(TEMPERATURE_PIN);
DallasTemperature sensors(&oneWire);

// Variable to store the measured temperature
float temperature;
float temperatureoffset;
float finaltemperature;

// Flags to indicate if the timers have expired
bool timerExpired = false;
bool emailSent = false;

/* Declare the global used SMTPSession object for SMTP transport */
SMTPSession smtp;

/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status);

// -------------------------SET UP EMAIL CREDENTIALS --------------------------------------------------------

void setup(){
  Serial.begin(115200);
  Serial.println();
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  pinMode(STATUS_LED, OUTPUT);
  while (WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    digitalWrite(STATUS_LED,HIGH);
    delay(1000);
    digitalWrite(STATUS_LED,LOW);
    delay(1000);
    
  }

  // Store the current time as the starting time and store the last Email Time
   startTime = millis();
   lastEmailTime = millis() - EMAIL_INTERVAL +1;
  
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  digitalWrite(STATUS_LED,HIGH);
  Serial.println();
  Serial.println("Start time Started: " + String(TIME_INTERVAL));

  /*  Set the network reconnection option */
  MailClient.networkReconnect(true);

  /** Enable the debug via Serial port
   * 0 for no debugging
   * 1 for basic level debugging
   *
   * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h
   */
  smtp.debug(1);

}

void sendEmail(){




    /* Set the callback function to get the sending results */
  smtp.callback(smtpCallback);

    /* Declare the Session_Config for user defined session credentials */
  Session_Config config;
/* Set the session config */
  config.server.host_name = SMTP_HOST;
  config.server.port = SMTP_PORT;
  config.login.email = AUTHOR_EMAIL;
  config.login.password = AUTHOR_PASSWORD;
  config.login.user_domain = "mydomain.net";

  /*
  Set the NTP config time
  For times east of the Prime Meridian use 0-12
  For times west of the Prime Meridian add 12 to the offset.
  Ex. American/Denver GMT would be -6. 6 + 12 = 18
  See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets
  */
  config.time.ntp_server = F("ntp2.inx.net.za,ntp1.inx.net.za");
  config.time.gmt_offset = -2;
  config.time.day_light_offset = 0;

  /* Declare the message class */
  SMTP_Message message;

  /* Set the message headers */
  message.sender.name = F(FREEZER_NAME);
  message.sender.email = AUTHOR_EMAIL;
  message.subject = F("FREEZER ALARM ALERT");
  message.addRecipient(F("SNC Team"), RECIPIENT_EMAIL);
    
  /*Send HTML message*/
  /*String htmlMsg = "<div style=\"color:#2f4468;\"><h1>Hello World!</h1><p>- Sent from ESP board</p></div>";
  message.html.content = htmlMsg.c_str();
  message.html.content = htmlMsg.c_str();
  message.text.charSet = "us-ascii";
  message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;*/

   
  //Send raw text message
  String textMsg = "This is an alert for " + String(FREEZER_NAME) + ". Temperature is currently " + String(finaltemperature);
  message.text.content = textMsg.c_str();
  message.text.charSet = "us-ascii";
  message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
  
  message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;
  message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;
  message.addHeader(F("Message-ID: <abcde.fghij@gmail.com>"));


  /* Connect to the server */
  if (!smtp.connect(&config)){
      ESP_MAIL_PRINTF("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
      return;
  }

  if (!smtp.isLoggedIn()){
    Serial.println("\nNot yet logged in.");
  }
  else{
    if (smtp.isAuthenticated())
      Serial.println("\nSuccessfully logged in.");
    else
      Serial.println("\nConnected with no Auth.");
  }

  /* Start sending Email and close the session */
  if (!MailClient.sendMail(&smtp, &message))
    ESP_MAIL_PRINTF("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
    smtp.sendingResult.clear();
    digitalWrite(STATUS_LED, HIGH);
    delay(800);
     digitalWrite(STATUS_LED, LOW);
    delay(800);
     digitalWrite(STATUS_LED, HIGH);
    delay(800);
     digitalWrite(STATUS_LED, LOW);
    delay(800);

}

  void loop() {
  // Check if the timer has expired
  if (!timerExpired) {
    // Calculate the elapsed time
    unsigned long elapsedTime = millis() - startTime;

    // Check if the elapsed time is greater than the time interval
    if (elapsedTime >= TIME_INTERVAL) {
      // Timer has expired, set the flag to true
      timerExpired = true;
    }
  }

  // Check if the timer has expired and start checking the temperature
  if (timerExpired) {
    // Request temperature readings
    sensors.requestTemperatures();

    // Read the temperature in degrees Celsius
    temperature = sensors.getTempCByIndex(0);
    temperatureoffset = TEMPERATURE_CALIBRATION_OFFSET;
    finaltemperature = temperature + temperatureoffset;

    Serial.print("Temperature: ");
    Serial.println(finaltemperature);

    // Check if the temperature exceeds the threshold
    if (finaltemperature > TEMPERATURE_THRESHOLD_UPPER || finaltemperature < TEMPERATURE_THRESHOLD_LOWER ) {
      // Check if enough time has passed since the last email was sent
      if (millis() - lastEmailTime >= EMAIL_INTERVAL) {
        // Temperature is too hot or too vold, send an email

        Serial.println("WiFi Connected");

          smtp.sendingResult.clear();
  // clear any previous failed attemps in memory
        sendEmail();

        // Update the last email time
        lastEmailTime = millis();
      }
      else{
      // Reset the last email time since the temperature is below the threshold
      Serial.println("Threshold Reached but can't send email within the last 2 hours");
      digitalWrite(STATUS_LED, HIGH);
      delay(200);
     digitalWrite(STATUS_LED, LOW);
      delay(200);
     digitalWrite(STATUS_LED, HIGH);
      delay(200);
     digitalWrite(STATUS_LED, LOW);
      delay(200);

      }
    } else {
            // Reset the last email time since the temperature is below the threshold
      Serial.println("At Safe Temperature");
      digitalWrite(STATUS_LED, HIGH);

    }

    // Reset the timer
   // startTime = millis();
    timerExpired = false;
  }

  // Add your other code here...

  // Ensure a minimum delay of 1 second between iterations
  delay(1000);
}


void smtpCallback(SMTP_Status status){
  /* Print the current status */
  Serial.println(status.info());

  /* Print the sending result */
  if (status.success()){
    // ESP_MAIL_PRINTF used in the examples is for format printing via debug Serial port
    // that works for all supported Arduino platform SDKs e.g. AVR, SAMD, ESP32 and ESP8266.
    // In ESP8266 and ESP32, you can use Serial.printf directly.

    Serial.println("----------------");
    ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());
    ESP_MAIL_PRINTF("Message sent failed: %d\n", status.failedCount());
    Serial.println("----------------\n");

    for (size_t i = 0; i < smtp.sendingResult.size(); i++)
    {
      /* Get the result item */
      SMTP_Result result = smtp.sendingResult.getItem(i);

      // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if
      // your device time was synched with NTP server.
      // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970.
      // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970)
      
      ESP_MAIL_PRINTF("Message No: %d\n", i + 1);
      ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed");
      ESP_MAIL_PRINTF("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str());
      ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients.c_str());
      ESP_MAIL_PRINTF("Subject: %s\n", result.subject.c_str());
    }
    Serial.println("----------------\n");

    // You need to clear sending result as the memory usage will grow up.
    smtp.sendingResult.clear();
  }

}


Additional information and things you've tried:

  • I've tried using port 587 - This behaves the same way (every second email) instead with error message:
#### Connecting to SMTP server...
> C: ESP Mail Client v3.1.11
! W: PSRAM was enabled but not detected.
> C: connecting to SMTP server
> C: Host > smtp.gmail.com
> C: Port > 587

#### SMTP server connected
> C: SMTP server connected, wait for greeting...
< S: 220 smtp.gmail.com ESMTP g16-20020adff3d0000000b00318147fd2d3sm7366394wrp.41 - gsmtp

#### Sending greeting response...
> C: send SMTP command, EHLO
< S: 250-smtp.gmail.com at your service, [165.255.8.181]
< S: 250-SIZE 35882577
< S: 250-8BITMIME
< S: 250-STARTTLS
< S: 250-ENHANCEDSTATUSCODES
< S: 250-PIPELINING
< S: 250-CHUNKING
< S: 250 SMTPUTF8

#### Sending STARTTLS command...
> C: send command, STARTTLS
< S: 220 2.0.0 Ready to start TLS
> C: perform SSL/TLS handshake

> C: SSL/TLS negotiation
> C: seeding the random number generator
> C: setting up the SSL/TLS structure
! W: Skipping SSL Verification. INSECURE!
> C: setting hostname for TLS session
> C: perform the SSL/TLS handshake
> C: verifying peer X.509 certificate

#### Sending greeting response...
> C: send SMTP command, EHLO
> C: cleaning SSL connection
#### Error, data sending failed
! E: data sending failed
Connection error, Status Code: 220, Error Code: -2, Reason: data sending failed

LOGS For Port 465

WiFi Connected
#### Connecting to SMTP server...
> C: ESP Mail Client v3.1.11
! W: PSRAM was enabled but not detected.
> C: connecting to SMTP server
> C: Host > smtp.gmail.com
> C: Port > 465

> C: SSL/TLS negotiation
> C: seeding the random number generator
> C: setting up the SSL/TLS structure
! W: Skipping SSL Verification. INSECURE!
> C: setting hostname for TLS session
> C: perform the SSL/TLS handshake
> C: verifying peer X.509 certificate

#### SMTP server connected
> C: SMTP server connected, wait for greeting...
< S: 221 2.0.0 closing connection t7-20020a5d49c7000000b00317ab75748bsm7289453wrs.49 - gsmtp
#### Error, SMTP server greeting failed
! E: SMTP server greeting failed
> C: cleaning SSL connection
Connection error, Status Code: 221, Error Code: -101, Reason: SMTP server greeting failed
mobizt commented

Please check the library version and update.