Hilfe zur Verbesserung meines Programmes

Hallo ,

ich moechte alle 5 minuten von der Rest Api die Werte holen und in einer csv Datei abspeichern. Sobald der letzte Wert vor 5minuten abgerufen wurde soll die csv Datei geloecht werden und eine neue angelegt werden. Sobald eine neue Uhrzeitstunde angeschlagen ist sollen die bisherigen Werte gemittelt werden und in einer Monatsdatei abgespeichert werden. Jedem Monat soll eine neue Datei angelegt werden.

Anbei mein Code ist dieser so in Ordnung oder laesst er sich noch besser schreiben?
Aktuell wird nur ein Wert geschrieben zum testen.

Danke fuer eure Hilfe und Unterstuetzung.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include <LittleFS.h>
#include "time.h"

ESP8266WebServer server(80);

const char* ssid = "";
const char* password = "";

// == http://makesmartesp.local/
const char* dns_name = "makesmartesp";
HTTPClient http;
WiFiClient client;
#define MY_NTP_SERVER "at.pool.ntp.org"
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03"
time_t now;
tm tm;
String last;
String first;


void setup() {
  Serial.begin(115200);
  Serial.println("ESP Gestartet");
  if (!LittleFS.begin()) {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }
  WiFi.begin(ssid, password);

  Serial.print("Verbindung wird hergestellt ...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  Serial.print("Verbunden! IP-Adresse: ");
  Serial.println(WiFi.localIP());

  configTime(MY_TZ, MY_NTP_SERVER);
  showTime();
  server.onNotFound([]() {
    server.send(404, "text/plain", "Link wurde nicht gefunden!");
  });

  server.serveStatic("/", LittleFS, "/test.txt");


  server.begin();
  Serial.println("Webserver gestartet.");

  int httpResponse = 0;
  HTTPClient http;
  http.begin(client, "swd.weatherflow.com", 80, "/swd/rest/observations/station/32220?token=dda25f0f-e7e1-414d-a91d-6e586c6279e3");
  httpResponse = http.GET();
  if (httpResponse == HTTP_CODE_OK) {
    DynamicJsonDocument doc(3072);

    DeserializationError error = deserializeJson(doc, http.getStream());

    if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.f_str());
      return;
    }


    JsonObject obs_0 = doc["obs"][0];
    long obs_0_timestamp = obs_0["timestamp"];                                             // 1682485382
    float obs_0_air_temperature = obs_0["air_temperature"];                                // 2.8
    float obs_0_barometric_pressure = obs_0["barometric_pressure"];                        // 972.9
    float obs_0_station_pressure = obs_0["station_pressure"];                              // 972.9
    int obs_0_sea_level_pressure = obs_0["sea_level_pressure"];                            // 1018
    int obs_0_relative_humidity = obs_0["relative_humidity"];                              // 93
    int obs_0_precip = obs_0["precip"];                                                    // 0
    int obs_0_precip_accum_last_1hr = obs_0["precip_accum_last_1hr"];                      // 0
    int obs_0_precip_accum_local_day = obs_0["precip_accum_local_day"];                    // 0
    double obs_0_precip_accum_local_yesterday = obs_0["precip_accum_local_yesterday"];     // 13.822592
    int obs_0_precip_minutes_local_day = obs_0["precip_minutes_local_day"];                // 0
    int obs_0_precip_minutes_local_yesterday = obs_0["precip_minutes_local_yesterday"];    // 323
    float obs_0_wind_avg = obs_0["wind_avg"];                                              // 0.9
    int obs_0_wind_direction = obs_0["wind_direction"];                                    // 236
    float obs_0_wind_gust = obs_0["wind_gust"];                                            // 1.1
    float obs_0_wind_lull = obs_0["wind_lull"];                                            // 0.8
    int obs_0_solar_radiation = obs_0["solar_radiation"];                                  // 15
    float obs_0_uv = obs_0["uv"];                                                          // 0.1
    int obs_0_brightness = obs_0["brightness"];                                            // 1759
    long obs_0_lightning_strike_last_epoch = obs_0["lightning_strike_last_epoch"];         // 1682390491
    int obs_0_lightning_strike_last_distance = obs_0["lightning_strike_last_distance"];    // 17
    int obs_0_lightning_strike_count = obs_0["lightning_strike_count"];                    // 0
    int obs_0_lightning_strike_count_last_1hr = obs_0["lightning_strike_count_last_1hr"];  // 0
    int obs_0_lightning_strike_count_last_3hr = obs_0["lightning_strike_count_last_3hr"];  // 0
    float obs_0_feels_like = obs_0["feels_like"];                                          // 2.8
    float obs_0_heat_index = obs_0["heat_index"];                                          // 2.8
    float obs_0_wind_chill = obs_0["wind_chill"];                                          // 2.8
    float obs_0_dew_point = obs_0["dew_point"];                                            // 1.8
    float obs_0_wet_bulb_temperature = obs_0["wet_bulb_temperature"];                      // 2.4
    float obs_0_wet_bulb_globe_temperature = obs_0["wet_bulb_globe_temperature"];          // 2.6
    float obs_0_delta_t = obs_0["delta_t"];                                                // 0.4
    float obs_0_air_density = obs_0["air_density"];                                        // 1.2282
    const char* obs_0_pressure_trend = obs_0["pressure_trend"];                            // "steady"


    File file = LittleFS.open("/test.txt", "r");

    if (!file) {
      Serial.println("There was an error opening the file for reading");

    } else {
      char Zeichen;
      String ZKette;

      int countrow = 0;
      while (file.available()) {
        // Dateiinhalt Zeichen für Zeichen lesen und ausgeben
        Zeichen = file.read();
        if ((byte)Zeichen != 13 && (byte)Zeichen != 10) {
          ZKette += Zeichen;

        } else {

          //Serial.println(ZKette);
          if (countrow == 0) {
            first = ZKette;
          }
          last = ZKette;
          ZKette = "";
          countrow++;
        }

        //Serial.write(file.read());
      }
    }
    file.close();

    String fullMsg = last;
    String msgField[2];

    byte sentencePos = 0;
    int commaCount = 0;
    msgField[commaCount] = "";
    while (sentencePos < fullMsg.length()) {
      if (fullMsg.charAt(sentencePos) == ';') {
        commaCount++;
        msgField[commaCount] = "";
        sentencePos++;
      } else {
        msgField[commaCount] += fullMsg.charAt(sentencePos);
        sentencePos++;
      }
    }
    time_t newTimeVar = msgField[0].toInt();
    localtime_r(&newTimeVar, &tm);

    localtime_r(&now, &tm);

    time(&now);  // read the current time

    time_t newTimeDif = now - newTimeVar;

    if (newTimeDif > 300) {
      LittleFS.remove("/test.txt");
      Serial.println("Zeit differenz groesser als 5min");
      File file = LittleFS.open("/test.txt", "a");

      if (!file) {
        Serial.println("There was an error opening the file for writing");
        return;
      }
      String message = String(now) + ";" + String(obs_0_brightness) + "\n";
      if (file.print(message)) {
        Serial.println("File was written");
      } else {
        Serial.println("File write failed");
      }
      file.close();
    }



    fullMsg = first;
    sentencePos = 0;
    commaCount = 0;
    msgField[commaCount] = "";
    while (sentencePos < fullMsg.length()) {
      if (fullMsg.charAt(sentencePos) == ';') {
        commaCount++;
        msgField[commaCount] = "";
        sentencePos++;
      } else {
        msgField[commaCount] += fullMsg.charAt(sentencePos);
        sentencePos++;
      }
    }


    newTimeVar = msgField[0].toInt();
    localtime_r(&newTimeVar, &tm);

    int day = tm.tm_mday;
    int month = tm.tm_mon;
    time(&now);
    localtime_r(&now, &tm);
    if (month != tm.tm_mon) {

      LittleFS.remove("/" + String(tm.tm_mon) + ".txt");
      File file_m = LittleFS.open("/" + String(tm.tm_mon) + ".txt", "w");
      file_m.close();
    }
    if (day != tm.tm_mday) {
      float totalvalue = 0;
      File file = LittleFS.open("/test.txt", "r");



      if (!file) {
        Serial.println("There was an error opening the file for reading");
        return;
      }
      char Zeichen;
      String ZKette;
      String last;
      String first;
      int countrow = 0;
      while (file.available()) {
        // Dateiinhalt Zeichen für Zeichen lesen und ausgeben
        Zeichen = file.read();
        if ((byte)Zeichen != 13 && (byte)Zeichen != 10) {
          ZKette += Zeichen;

        } else {
          //Serial.println(ZKette);
          fullMsg = ZKette;
          sentencePos = 0;
          commaCount = 0;
          msgField[commaCount] = "";
          while (sentencePos < fullMsg.length()) {
            if (fullMsg.charAt(sentencePos) == ';') {
              commaCount++;
              msgField[commaCount] = "";
              sentencePos++;
            } else {
              msgField[commaCount] += fullMsg.charAt(sentencePos);
              sentencePos++;
            }
          }
          totalvalue = totalvalue + msgField[1].toFloat();
          countrow++;
          ZKette = "";
        }

        //Serial.write(file.read());
      }

      File file_m = LittleFS.open("/" + String(month) + ".txt", "a");
      if (!file_m) {
        Serial.println("There was an error opening the file for writing");

      } else {


        totalvalue = totalvalue / countrow;
        if (file_m.print(String(month) + ";" + String(day) + ";" + String(totalvalue))) {
          Serial.println("File was written");
        } else {
          Serial.println("File write failed");
        }


        Serial.println(last);
      }
      file_m.close();
      file.close();

      LittleFS.remove("/test.txt");
      file = LittleFS.open("/test.txt", "a");

      if (!file) {
        Serial.println("There was an error opening the file for writing");
      } else {
        String message = String(now) + ";" + String(obs_0_brightness) + "\n";
        if (file.print(message)) {
          Serial.println("File was written");
        } else {
          Serial.println("File write failed");
        }
      }
      file.close();
    }



    file = LittleFS.open("/test.txt", "a");

    if (!file) {
      Serial.println("There was an error opening the file for writing");

    } else {
      String message = String(now) + ";" + String(obs_0_brightness) + "\n";
      if (file.print(message)) {
        Serial.println("File was written");
      } else {
        Serial.println("File write failed");
      }
    }
    file.close();



    Serial.println("Going to deep sleep...");
    ESP.deepSleep(5 * 1000000);
    yield();
  }
}

void loop() {
  server.handleClient();
}

Gedanken zu Deinem Programm:

  1. SSID und Password speichere ich in einer eigenen Datei, damit ich sie nicht versehendlich weitergebe und weil sie für alle Programme gleich sind.

  2. Ich verwende NTP_SERVER = "fritz.box";, da werde ich bei zu häufiger Nutzung nicht gesperrt.

  3. Bei der Fehlerbehandlung sehe ich return oder eine Endlosschleife dank while. Mit dem ESP8266 fehlt mir die Erfahrung, aber passiert da wirklich, was Du möchtest? Beim Programmieren benötigt die Fehlerbehandlung nicht selten mehr Zeit als die eigentliche Fagestellung.

  4. Könntest Du den Zeitstempel von weatherflow.com eventuell anstelle vom NTP-Server nutzen?

  5. Für neue Programme verwende ich OTA, was den seriellen Monitor ausschließt. Stattdessen benutze ich Debug mit Telnet. Bei meinem ESP32 am Stromzähler funktioniert das sehr gut, allerdings schläft der nicht. Auf einem OLED stehen weitere Infos.

  6. Mein setup ruft Funktionen auf, die ich in Tabs der IDE abgelegt habe. Das fördert zumindest für mich die Übersichtlichkeit.

  7. Anstelle von Serial.print verwende ich eine "ausschaltbare" Ausgabe:

#define DEBUGGING                     // Einkommentieren für die Serielle Ausgabe

#ifdef DEBUGGING
#define DEBUG_B(...) Serial.begin(__VA_ARGS__)
#define DEBUG_P(...) Serial.print(__VA_ARGS__)
#define DEBUG_L(...) Serial.println(__VA_ARGS__)
#define DEBUG_F(...) Serial.printf(__VA_ARGS__)
#else
#define DEBUG_B(...)
#define DEBUG_P(...)
#define DEBUG_L(...)
#define DEBUG_F(...)
#endif

Ist jetzt nicht das geworden, wonach Du gefragt hast, aber eventuell konnte ich Dir doch die eine oder andere Anregung geben.

Hallo,

warum immer neue define Monster erfinden?

der Schalter:
constexpr bool DEBUG {false};

anwenden:
if (DEBUG) { Serial.println("text"); }

Problem nicht jeder hat eine fritz, und mansche andere Router unterstützen NTP nicht

Und der Rest ist gut vom Code ?

Hallo,

etwas mehr Unterteilung in Funktionen wäre nicht falsch.
Was passiert mit den Variablen zwischen Zeile 72 und 105?
Werden die irgendwo verarbeitet?
Und wofür benötigt man den Aufruf von yield() nach Sleep?
Warum überhaupt Sleep?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.