Das Forum für Zigarren und andere Genüsse dieser Welt
Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Das smarte DIY Hygrometer
#1
Moiin  zusammen,

Ich möchte euch hier einmal eine Kurzvorstellung eines Projektes geben, an dem ich seit einigen Wochen werkel:
Ein smartes DIY Hygrometer.

   

Leider lassen sich die Displays nur recht schlecht fotografieren, da man auf dem Bild immer einen blinden Streifen durch die Dsiplayaktualisierung hat (mit bloßem Auge nicht zu sehen).
   

Ich hatte einfach keine Lust mehr immer die Feuchtigkeit meiner Humidore per Hand zu prüfen um zu merken, wenn meine Boveda Packs wieder gewechselt werden müssen.

Ich hab da sofort an ein ESP8266 Board gedacht (sehr ähnlich einem Arduino, aber mit eingebautem WIFI), dass einem automatisch eine Mail schickt, wenn die Luftfeuchtigkeit abweicht.

Was braucht man noch?

Ein Webinterface wäre was schönes, und auch ein Display ist ja was feines.

An Hardware braucht man:
ESP8266 mit eingebautem OLED = ca. 3€
Zwei Flachbandkabel Adapter = ca. 3€
Flachbandkabel = 2€
Einen Sensor nach Wahl (ich habe einen SHT45 genommen) = 13€
Strom kriegt alles über USB

Der Spaß kostet also ca. 20€, etwas Lötgeschick und Spaß am Programmieren.

Es liegt tatsächlich nur der Sensor selbst im Himidor, da er leicht per Flachbandkabel angebunden werden kann und so alles durch die bestehende Tür passt.
(Selbst mit Zipper Beuteln und Tupperdosen ist die Lösung Nutzbar...ich habs auch schon mit nem Weck Glas probiert...klappt wunderbar.)
   

Das Modul selbst liegt dann draußen (man kann übrigens auch statt eines ESP8266 mit OLED einfach ein Wemos D1 (liegt im Bild daneben) nehmen).


Ich habe am Anfang viel mit dem Bosch BME280 Sensor probiert, aber der erzeugt nur schwachsinnige Werte (das seht ihr auf dem ESP rechts im Bild).
Letztendlich bin ich jetzt beim SHT45 hängen geblieben.
Während mein eingestelltes Haar Hygrometer im Humidor (mit 72er Boveda Pack) 71% misst, misst der Sensor 68,3%.
Wer von beidem da abweichungen hat, kann ich noch nicht genau sagen, aber ich glaube der Sensor hinkt linear (also auch bei 50% etc) um 2,6% hinterher.
Wenn der Wert wirklich so linear ist, kann ich ihn einfach per Software angleichen.

Was macht das Teil jetzt?

Man legt erstmal neben Mailadresse, WiFi und so Weiter einen Namen, die Ziel-Luftfeuchtigkeit und erlaubte Toleranz fest.
Der ESP verbindet sich beim Start automatisch mit dem WiFi und schickt einem erstmal eine Welcome Mail mit allen Daten des Webinterface.
Das sieht sowohl per Mail als auch per Browser so aus:
   

Das Display zeigt die gewünschten Werte in Echtzeit an.
Ist die Luftfeuchtigkeit außerhalb der Toleranz, wechselt das Display sofort in einen leuchtmodus (siehe rechtes Gerät) um einen Alarm optisch anzuzeigen.

Bewegt sich die Luftfeuchtigkeit jetzt länger als 5 Minuten (ohne Unterbrechung) außerhalb der Toleranz, schickt der ESP eine Warnmail raus, dass die Luftfeuchtigkeit kritisch ist.
Ist sie wieder konstant 5 Minuten in der Norm gibt es eine Entwarnungsmail.

Um es direkt zu sagen, man sollte sich mir der Arduino Software etwas auskennen oder Lust haben sich mit ihr auseinander zu setzen.
Es gibt keine Config GUI, alles muss direkt in die Software eingetragen werden.
Ich habe zwar zugesehen, dass alles, was geändert werden muss direkt am Anfang kommt und gut Beschriftet ist, aber der Code hat über 500 Zeilen, da kann man den Überblick verlieren.

Ich bin jetzt soweit, dass ich für mich sage, dass die Software stabil ist und tut, was sie soll.

Für mich sind jetzt noch als Baustellen:
-Mir die Abweichung des Sensors anschauen.
-Mit über die 5 Minuten Wartezeit gedanken machen => Was ich komplett vergessen hatte, war dass jedes Öffnen des Humidors einen drastischen Abfall der Luftfeuchtigkeit bedeutet. Das dauert auch länger als 5 Minuten, bis die Luftfeuchtigkeit wiederhergestellt ist...eher so 15-20 Minuten. Man könnte es natürlich nutzen um sofort zu sehen, wenn jemand am Humidor war😂
-Mir Gedanken um ein Gehäuse machen.

So, viel geschrieben, ich hoffe jemanden interessiert das ganze überhaupt.

Wer mag, kann gern den Code in den nächsten Tagen bekommen.

Anmerkung: In bester DIY Manier sind einige Zeilen Code aus anderen Projekten übernommen (z.B. die Formatierung der Tabelle).
Die Logik habe ich aber komplett per Hand geschrieben.

Grüße,
Felix
[+] 9 Mitglieder gefällt Crix1990's Beitrag
Zitieren
#2
Schönes Hygrometer das du da gebastelt hast. Proxy_007
Verwendest du die Heizung des SHT4x?
Ich kann das nur empfehlen, da der Sensor sonst wegdriftet: https://zigarren-community.de/thread-177...l#pid73822
Zitieren
#3
(17.08.2024, 02:00)Crix1990 schrieb: So, viel geschrieben, ich hoffe jemanden interessiert das ganze überhaupt.
Servus Felix,

ja, interessiert. Hab zwar aktuell nicht die Zeit mich mit sowas zu beschäfftigen aber interessieren tut es mich schon. Vielleicht kommt ja bald ein Lebensabschnitt, der dieses Problem löst Augen

Mich würde noch interessieren, wie die Programmierung von sowas aussieht. Bin zwar nicht ganz unbedarft, aber nicht in diesem Segment der Microcontroller.

Gruss, Klaus
Schmauchende Grüsse
Klaus smoke1
Zitieren
#4
(17.08.2024, 08:00)CigarNerd schrieb: Schönes Hygrometer das du da gebastelt hast. Proxy_007
Verwendest du die Heizung des SHT4x?
Ich kann das nur empfehlen, da der Sensor sonst wegdriftet: https://zigarren-community.de/thread-177...l#pid73822

Die Heitzungsfunktionen sind im Code implementiert, ich habe sie aber noch nicht eingesetzt, da ich mich gerade erst mit der Frage auseinandersetze, welchen Effekt die Heitzung genau hat.

Du hattest dich mit dem Thema schon auseinander gesetzt, oder?

Für interessierte hier der Code in Version 0.96:
Code:
/*********
  Various code snipped frankensteined together with a lot of try & error by Crix1990.
  Modded for Humidor use by Crix1990.
*********/

// Load Wi-Fi library
#include <ESP8266WiFi.h>
#include <Wire.h>
#include "Adafruit_SHT4x.h"
#include <Arduino.h>
#include <U8g2lib.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

#include <ESP_Mail_Client.h>

#include <time.h>                   // time() ctime()
time_t now;                         // this is the epoch
tm myTimeInfo;                      // the structure tm holds time information in a more convient way




Adafruit_SHT4x sht4 = Adafruit_SHT4x();
#define SDA_PIN 14 //GPIO14 / 5
#define SCL_PIN 12 //GPIO12 / 6
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL_PIN, SDA_PIN, U8X8_PIN_NONE);
int intervalOledRun = 10000;
unsigned long previousOledRun = 0;
String HumidityPrint = "Humidity:";
String TemperaturePrint = "Temperature:";

//Humidor Setup
//Name you Humidor:
String HumidorName = "Tisch Humidor";
//Define target humidity
double TargetHumidity = 69;
//Define your humidity tolerance (1 = 1% tolerance, 2 = 2% tolerance, etc.)
double TargetTolerance = 5;
//Define your Mail delay in Miliseconds
int MailDelay = 300000;


// Replace with your network credentials
const char* ssid     = "WIFINAME";
const char* password = "WIFIPW";

// Configure NTP services
const char* ntpServer = "10.10.70.1";
const long  gmtOffset_sec = 1;
const int   daylightOffset_sec = 7200;

//Configure mail credentials
#define RECIPIENT_EMAIL "REC@MAIL.de"
#define AUTHOR_EMAIL "SEND@MAIL.de"
#define AUTHOR_PASSWORD "MAILPW"
#define SMTP_HOST "smtp.xxx.de"
#define SMTP_PORT 465


// Set web server port number to 80
WiFiServer server(80);

// Variable to store the HTTP request
String header;

// Declare the global used SMTPSession object for SMTP transport
SMTPSession smtp;
// Declare global message class
SMTP_Message message;

unsigned long previousMillis = 0;
unsigned long AlarmStateMillis = 0;
unsigned long currentMillis = 0;
const long interval = 60000;  // 30 seconds

//Alert states
int AlarmState = 0;
int AlarmStateOld = 0;

// Declare the Session_Config
// GLOBAL for user defined session credentials */
Session_Config config;

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

  PrintFileNameDateTime();

  // default settings
   Serial.println("Adafruit SHT4x test");
  if (! sht4.begin()) {
    Serial.println("Couldn't find SHT4x");
    while (1) delay(1);
  }
  Serial.println("Found SHT4x sensor");
  Serial.print("Serial number 0x");
  Serial.println(sht4.readSerial(), HEX);
   // You can have 3 different precisions, higher precision takes longer
  sht4.setPrecision(SHT4X_HIGH_PRECISION);
  switch (sht4.getPrecision()) {
     case SHT4X_HIGH_PRECISION:
       Serial.println("High precision");
       break;
     case SHT4X_MED_PRECISION:
       Serial.println("Med precision");
       break;
     case SHT4X_LOW_PRECISION:
       Serial.println("Low precision");
       break;
  }

  // You can have 6 different heater settings
  // higher heat and longer times uses more power
  // and reads will take longer too!
  sht4.setHeater(SHT4X_NO_HEATER);
  switch (sht4.getHeater()) {
     case SHT4X_NO_HEATER:
       Serial.println("No heater");
       break;
     case SHT4X_HIGH_HEATER_1S:
       Serial.println("High heat for 1 second");
       break;
     case SHT4X_HIGH_HEATER_100MS:
       Serial.println("High heat for 0.1 second");
       break;
     case SHT4X_MED_HEATER_1S:
       Serial.println("Medium heat for 1 second");
       break;
     case SHT4X_MED_HEATER_100MS:
       Serial.println("Medium heat for 0.1 second");
       break;
     case SHT4X_LOW_HEATER_1S:
       Serial.println("Low heat for 1 second");
       break;
     case SHT4X_LOW_HEATER_100MS:
       Serial.println("Low heat for 0.1 second");
       break;
  }


  // Connect to Wi-Fi network with SSID and password
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  // Print local IP address and start web server
  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  server.begin();
  u8g2.begin();
  u8g2.enableUTF8Print();


  synchroniseWith_NTP_Time();
  MailClient.networkReconnect(true);
  setupEmailConfig();
  sendEmail();
  AlarmState = 1;

}

void loop(){
currentMillis = millis();
  sensors_event_t humidity, temp;
  sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
  if(currentMillis - previousOledRun >= intervalOledRun) {




  //Display Configuration
  HumidityPrint = "Hum: " + String(humidity.relative_humidity) + " %";
  TemperaturePrint = "Temp: " + String(temp.temperature) + " °C";
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_t0_16_tf);
  if (humidity.relative_humidity < TargetHumidity - TargetTolerance) {
      u8g2.drawButtonUTF8(0, 13, U8G2_BTN_INV, 0,  2,  2, HumidorName.c_str());
      u8g2.drawButtonUTF8(0, 36, U8G2_BTN_INV, 0,  2,  5, TemperaturePrint.c_str());
      u8g2.drawButtonUTF8(0, 60, U8G2_BTN_INV, 0,  2,  5, HumidityPrint.c_str());

            }
  else if (humidity.relative_humidity > TargetHumidity + TargetTolerance) {
      u8g2.drawButtonUTF8(0, 13, U8G2_BTN_INV, 0,  2,  2, HumidorName.c_str());
      u8g2.drawButtonUTF8(0, 36, U8G2_BTN_INV, 0,  2,  5, TemperaturePrint.c_str());
      u8g2.drawButtonUTF8(0, 60, U8G2_BTN_INV, 0,  2,  5, HumidityPrint.c_str());

            }
  else {
     u8g2.drawUTF8(0,13,HumidorName.c_str());
     u8g2.drawUTF8(0,36,TemperaturePrint.c_str());
     u8g2.drawUTF8(0,60,HumidityPrint.c_str());
            }



  u8g2.sendBuffer();

  }
    currentMillis = millis();

  if(currentMillis - previousOledRun >= intervalOledRun) {



  }
    delay(1000);
  //Mail Config
  currentMillis = millis();
  //Too Low
  if (humidity.relative_humidity < TargetHumidity - TargetTolerance) {
    if (AlarmState == 2){
    }
    else if (AlarmState == 20) {
      if (currentMillis >= AlarmStateMillis + MailDelay || currentMillis < AlarmStateMillis) {
      AlarmState = 2;
      sendEmail();
      }
    }
    else if (AlarmState == 10 && AlarmStateOld == 2) {
    AlarmState = 2; 
    }
    else {
    AlarmState = 20;
    AlarmStateMillis = currentMillis;
    }


    }
  //Too High         
  else if (humidity.relative_humidity > TargetHumidity + TargetTolerance) {
    if (AlarmState == 3){
    }
    else if (AlarmState == 30) {
      if (currentMillis >= AlarmStateMillis + MailDelay || currentMillis < AlarmStateMillis) {
      AlarmState = 3;
      sendEmail();
      }
    }
    else if (AlarmState == 10 && AlarmStateOld == 3) {
    AlarmState = 3; 
    }   
    else {
    AlarmState = 30;
    AlarmStateMillis = currentMillis;
    }


    }

  //Normal         
  else {
    if (AlarmState == 20 || AlarmState == 30) {
      AlarmState = 1;
      AlarmStateMillis = currentMillis;
    }
    else if (AlarmState == 2 || AlarmState == 3) {
      AlarmStateOld = AlarmState;
      AlarmState = 10;
      AlarmStateMillis = currentMillis;
    }
    else if (AlarmState == 10) {
      if (currentMillis >= AlarmStateMillis + 300000 || currentMillis < AlarmStateMillis) {
      AlarmState = 1;
      sendEmail();
      }
    }

       }


  WiFiClient client = server.available();   // Listen for incoming clients

  if (client) {                             // If a new client connects,
    Serial.println("New Client.");          // print a message out in the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected

//Serial.println("1");



      if (client.available()) {             // if there's bytes to read from the client,
      Serial.println("2");
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        header += c;
        if (c == '\n') {                    // if the byte is a newline character
          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
           
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
           // client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<head><meta http-equiv=refresh content=1>");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            // CSS to style the table
            client.println("<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}");
            client.println("table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }");
            client.println("th { padding: 12px; background-color: #0043af; color: white; }");
            client.println("tr { border: 1px solid #ddd; padding: 12px; }");
            client.println("tr:hover { background-color: #0088FF; }");
            client.println("td { border: none; padding: 12px; }");
            if (humidity.relative_humidity < TargetHumidity - TargetTolerance) {
              client.println(".sensor { color:black; font-weight: bold; background-color: #CC3333; padding: 1px; }");

            }
            else if (humidity.relative_humidity > TargetHumidity + TargetTolerance) {
              client.println(".sensor { color:black; font-weight: bold; background-color: #CC3333; padding: 1px; }");

            }
            else {
              client.println(".sensor { color:black; font-weight: bold; background-color: #FFFFFF; padding: 1px; }");
            }

            // Web Page Heading
            client.println("</style></head><body><h1>");
            client.println(HumidorName);
            client.println("</h1>");
            client.println("<table><tr><th>MEASUREMENT</th><th>VALUE</th></tr>");
            client.println("<tr><td>Temp. Celsius</td><td><span class=\"sensor\">");
            client.println(temp.temperature);
            client.println(" *C</span></td></tr>"); 
            client.println("<tr><td>Temp. Fahrenheit</td><td><span class=\"sensor\">");
            client.println(1.8 * temp.temperature + 32);
            client.println(" *F</span></td></tr>");       
            client.println("<tr><td>Humidity</td><td><span class=\"sensor\">");
            client.println(humidity.relative_humidity);
            client.println(" %</span></td></tr>");
            client.println("<tr><td>Target Humidity</td><td><span class=\"sensor\">");
            client.println(TargetHumidity);
            client.println(" %</span></td></tr>");
            client.println("<tr><td>Humidity Tolerance</td><td><span class=\"sensor\">");
            client.println(TargetTolerance);
            client.println(" %</span></td></tr>");
            client.println("</body></html>");
           
            // The HTTP response ends with another blank line
            client.println();
           

            // Break out of the while loop
            Serial.println("3");
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }
}

void synchroniseWith_NTP_Time() {
  Serial.print("configTime uses ntpServer ");
  Serial.println(ntpServer);
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  Serial.print("synchronising time");

  while (myTimeInfo.tm_year + 1900 < 2000 ) {
    time(&now);                       // read the current time
    localtime_r(&now, &myTimeInfo);
    delay(100);
    Serial.print(".");
  }
  Serial.print("\n time synchronsized \n");
  showTime();
}

String getTimeString() {
  unsigned long currentTime = millis();  // Get the current time in milliseconds
  int seconds = (currentTime / 1000) % 60;
  int minutes = (currentTime / 60000) % 60;
  int hours = (currentTime / 3600000) % 24;

  // Create a formatted time string
  String timeStr = String(hours) + ":" + (minutes < 10 ? "0" : "") + String(minutes) + ":" + (seconds < 10 ? "0" : "") + String(seconds);
  return timeStr;
}

void showTime() {
  time(&now);                       // read the current time
  localtime_r(&now, &myTimeInfo);           // update the structure tm with the current time
  Serial.print("year:");
  Serial.print(myTimeInfo.tm_year + 1900);  // years since 1900
  Serial.print("\tmonth:");
  Serial.print(myTimeInfo.tm_mon + 1);      // January = 0 (!)
  Serial.print("\tday:");
  Serial.print(myTimeInfo.tm_mday);         // day of month
  Serial.print("\thour:");
  Serial.print(myTimeInfo.tm_hour);         // hours since midnight  0-23
  Serial.print("\tmin:");
  Serial.print(myTimeInfo.tm_min);          // minutes after the hour  0-59
  Serial.print("\tsec:");
  Serial.print(myTimeInfo.tm_sec);          // seconds after the minute  0-61*
  Serial.print("\twday");
  Serial.print(myTimeInfo.tm_wday);         // days since Sunday 0-6
  if (myTimeInfo.tm_isdst == 1)             // Daylight Saving Time flag
    Serial.print("\tDST");
  else
    Serial.print("\tstandard");

  Serial.println();
}

void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("  compiled ") );
  Serial.print( F(__DATE__) );
  Serial.print( F(" ") );
  Serial.println( F(__TIME__) ); 
}

void setupEmailConfig() {
  // 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);

  // Set the 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 = "";

  message.addRecipient(F("Me-myself-and-I"), RECIPIENT_EMAIL);
}

void sendEmail() {
  sensors_event_t humidity, temp;
  sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
  // Set the message headers

  String StyleBody = "";
  String MessageSubject = "Humidor Control System of " + HumidorName + " just started.";

if (AlarmState == 0) {
  MessageSubject = "Humidor Control System of " + HumidorName + " just started.";
  StyleBody = "<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }th { padding: 12px; background-color: #0043af; color: white; }tr { border: 1px solid #ddd; padding: 12px; }tr:hover { background-color: #0088FF; }td { border: none; padding: 12px; }.sensor { color:black; font-weight: bold; background-color: #FFFFFF; padding: 1px; }";
            }

  else if (AlarmState == 1) {
      MessageSubject = HumidorName + " went back to normal conditions.";
      StyleBody = "<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }th { padding: 12px; background-color: #0043af; color: white; }tr { border: 1px solid #ddd; padding: 12px; }tr:hover { background-color: #0088FF; }td { border: none; padding: 12px; }.sensor { color:black; font-weight: bold; background-color: #FFFFFF; padding: 1px; }";
            }

  else if (AlarmState == 2) {
      MessageSubject = "WARNING: " + HumidorName + " has too low humidity!";
      StyleBody = "<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }th { padding: 12px; background-color: #0043af; color: white; }tr { border: 1px solid #ddd; padding: 12px; }tr:hover { background-color: #0088FF; }td { border: none; padding: 12px; }.sensor { color:black; font-weight: bold; background-color: #CC3333; padding: 1px; }";
            }

  else if (AlarmState == 3) {
      MessageSubject = "WARNING: " + HumidorName + " has too high humidity!";
      StyleBody = "<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }th { padding: 12px; background-color: #0043af; color: white; }tr { border: 1px solid #ddd; padding: 12px; }tr:hover { background-color: #0088FF; }td { border: none; padding: 12px; }.sensor { color:black; font-weight: bold; background-color: #CC3333; padding: 1px; }";
            }

  else {
      MessageSubject = "Unknown Mail Reason " + String(AlarmState);
      StyleBody = "<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}table { border-collapse: collapse; width:35%; margin-left:auto; margin-right:auto; }th { padding: 12px; background-color: #0043af; color: white; }tr { border: 1px solid #ddd; padding: 12px; }tr:hover { background-color: #0088FF; }td { border: none; padding: 12px; }.sensor { color:black; font-weight: bold; background-color: #FFFFFF; padding: 1px; }";
            }           

  message.sender.name = HumidorName;
  message.sender.email = AUTHOR_EMAIL;
  //Send HTML message
  message.subject = MessageSubject;
  String Mail1 = "</style></head><body><h1>" + HumidorName + "</h1><table><tr><th>MEASUREMENT</th><th>VALUE</th></tr><tr><td>Temp. Celsius</td><td><span class=\"sensor\">" + temp.temperature + " *C</span></td></tr><tr><td>Temp. Fahrenheit</td><td><span class=\"sensor\">" + 1.8 * temp.temperature + 32 + " *F</span></td></tr><tr><td>Humidity</td><td><span class=\"sensor\">" + humidity.relative_humidity;
  String Mail2 = " %</span></td></tr><tr><td>Target Humidity</td><td><span class=\"sensor\">" + String(TargetHumidity) + " %</span></td></tr><tr><td>Humidity Tolerance</td><td><span class=\"sensor\">" + String(TargetTolerance) + " %</span></td></tr></body></html>";

  String htmlMsg = StyleBody + Mail1 + Mail2;
  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;

  message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_high;
  message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;

  // 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;
  }
  Serial.println("smtp.connect(&config) done");

  Serial.print("sending email to #");
  Serial.print(RECIPIENT_EMAIL);
  Serial.println("#");
  /* Start sending Email and close the session */
  if (!MailClient.sendMail(&smtp, &message)) {
    Serial.println("error MailClient.sendMail(&smtp, &message)");
    ESP_MAIL_PRINTF("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
  }
  Serial.print("sending email to #");
  Serial.print(RECIPIENT_EMAIL);
  Serial.println("# done");

  Serial.println("MailClient.sendMail(&smtp, &message) done");
}

Einen kleinen Fehler habe ich noch im Code:
Schaut man sich das Webinterface an und beendet den Browser, statt das Fenster zu schließen, denkt der ESP, dass die Websession noch offen ist, da der Browser sie nicht geschlossen hat, und der Code hängt für ca. eine Minute, bis der ESP die Session auf timeout setzt.

Grüße,
Felix
[+] 2 Mitglieder gefällt Crix1990's Beitrag
Zitieren
#5
(17.08.2024, 14:38)Crix1990 schrieb: Für interessierte hier der Code in Version 0.96:
Herzlichen Dank, Felix Augen Sieht so aus, wie wenn man sich da einarbeiten könnte ...
Schmauchende Grüsse
Klaus smoke1
Zitieren
#6
Dafür nicht!

Ich würde mich ja freuen, wenn viele den Code nutzen würden😁

Wenn du die Software nur nutzen möchtest, ohne sie anzupassen musst du nur am Anfang Werte anpassen.
Schon im Void Setup musst du nichts mehr machen.

Grüße,
Felix
[+] 1 Mitglied Gefällt Crix1990's Beitrag
Zitieren


Möglicherweise verwandte Themen…
Thema Antworten Letzter Beitrag
  Govee Thermo-Hygrometer 0 09.06.2022, 22:41
Letzter Beitrag: digitaL
  hygrometer kalibrieren 14 11.11.2021, 13:12
Letzter Beitrag: Grossinquisitor
  Billig-Hygrometer - ein kleiner Erfahrungsbericht 1 08.04.2020, 09:38
Letzter Beitrag: Zerocool
  Empfehlung Hygrometer 21 17.12.2019, 21:44
Letzter Beitrag: Zerocool



Benutzerbereich Nachrichten