/*
 * AppVersion.h
 *
 * Projekt: EPS8266 Energy Meter
 *
 * -----------------------------------------------------
 * Version 1.0: 2018-02-02
 * - Basisversion
 * -----------------------------------------------------
 * Version 1.1: 2018-03-08
 * - Update des Web-Interface
 */
 
#ifndef APPVERSION_H_
#define APPVERSION_H_

#define VERSION_MAJOR 1
#define VERSION_MINOR 1
#define VERSION_BUILD 30

#define APP_AUTHOR  "Ulli"
#define APP_NAME    "ESP8266 Energy Meter"
#define APP_WEBSITE "http://bienonline.magix.net/public/eps8266-energy-meter.html"

static void PrintAppInfo(Print & p = Serial);

#pragma region [Interner Bereich]
// -------------------------------------------------------------------
// ---------------------- Interner Bereich ---------------------------
// -------------------------------------------------------------------

#include <FS.h>

//Zum Zusammenbau der Versionsnummer als String
#define APPVERSION_STR_HELPER(x) #x
#define APPVERSION_STR(x) APPVERSION_STR_HELPER(x)

#define VERSIONSTRING APPVERSION_STR(VERSION_MAJOR) "." APPVERSION_STR(VERSION_MINOR) "." APPVERSION_STR(VERSION_BUILD)
#define APP_VERSION VERSIONSTRING


// Rechtsbündige Ausgabe und Tausender-Trennzeichen "."
// Value: auszugebender Wert
// Width: Anzahl minimal auszugebender Zeichen (max. 18)
// Fill: Füllzeichen für linksbündige Füllung
static String PrintDotted(uint32_t Value, uint8_t Width, char Fill = ' ', uint8_t base = 10) {
  char buf[20];
  char fmt[20];

  if (Width > 18) Width = 18; // Breite begrenzen

  itoa(Value, buf, base);  // Normale Ausgabe in Puffer

                          // Rückwärts umkopieren, dabei Punkte einfügen
  int8_t l = strlen(buf); // Länge des Puffers
  int8_t i = 0;           // Index Ziel
  int8_t j = 0;           // Ziffernindex für Punkte
  int8_t k = l - 1;       // Index Quelle

  while (k >= 0) {
    fmt[i++] = buf[k--];
    if ((++j % 3) == 0)
      if (j < l)
        fmt[i++] = '.';
  }
  while (i < Width) // Auf die gewünschte Lünge auffüllen
    fmt[i++] = Fill;

  fmt[i] = 0; // String-Ende

              // Wieder in die richtige Reihenfolge bringen
  l = strlen(fmt);
  for (i = 0, k = l - 1; i < l; i++, k--)
    buf[i] = fmt[k];
  buf[i] = 0;

  return String(buf);
}

String getFlashChipTypeByChipId(void) {
  uint32_t chipId = ESP.getFlashChipId();
  switch (chipId) {
    // GigaDevice;
  case 0x1740C8: return("GD25Q64B");
  case 0x1640C8: return("GD25Q32B");
  case 0x1540C8: return("GD25Q16B");
  case 0x1440C8: return("GD25Q80");
  case 0x1340C8: return("GD25Q40");
  case 0x1240C8: return("GD25Q20");
  case 0x1140C8: return("GD25Q10");
  case 0x1040C8: return("GD25Q12");
    // Winbond
  case 0x1640EF: return("W25Q32");
  case 0x1540EF: return("W25Q16");
  case 0x1440EF: return("W25Q80");
  case 0x1340EF: return("W25Q40");
    // BergMicro;
  case 0x1640E0: return("BG25Q32");
  case 0x1540E0: return("BG25Q16");
  case 0x1440E0: return("BG25Q80");
  case 0x1340E0: return("BG25Q40");

  default:
    return "unknown";
  }
}

static const char Bytes[] PROGMEM = " Bytes";
static void PrintAppInfo(Print & p) {
#define FC 183 // Füllzeichen "." für rechtsbündige Zahlenausgabe
#define FL 9   // Breite für Zahlenausgabe
  p.println(F(APP_NAME " Version " VERSIONSTRING));
  p.println(F("Author: " APP_AUTHOR " " APP_WEBSITE));
  p.println(F("-------------------------------------------"));
  p.print(F(" Last reset reason: ")); p.println(ESP.getResetReason().c_str());
  p.print(F("           Chip ID: ")); p.println(ESP.getChipId());
  p.print(F("     CPU frequency: ")); p.print(PrintDotted(ESP.getCpuFreqMHz(), FL, FC)); p.println(F(" MHz"));
  p.print(F("Memory size  (SDK): ")); p.print(PrintDotted(ESP.getFlashChipSize(), FL, FC)); p.println(FPSTR(Bytes));
  p.print(F("Memory size (CHIP): ")); p.print(PrintDotted(ESP.getFlashChipRealSize(), FL, FC)); p.println(FPSTR(Bytes));
  p.print(F("   Flash Chip Type: ")); p.println(getFlashChipTypeByChipId());
  p.print(F("         Free heap: ")); p.print(PrintDotted(ESP.getFreeHeap(), FL, FC)); p.println(FPSTR(Bytes));
  p.print(F("       Sketch size: ")); p.print(PrintDotted(ESP.getSketchSize(), FL, FC)); p.println(FPSTR(Bytes));
  p.print(F("  Free sketch size: ")); p.print(PrintDotted(ESP.getFreeSketchSpace(), FL, FC)); p.println(FPSTR(Bytes));

  // SPIFFS
  if (SPIFFS.begin()) { // Der ggf. mehrfach erfolgende Aufruf von SPIFFS.begin() ist unkritisch.
    FSInfo fs_info;
    SPIFFS.info(fs_info);
    p.println(F("File system"));
    p.print(F("        total size: ")); p.print(PrintDotted(fs_info.totalBytes, FL, FC)); p.println(FPSTR(Bytes));
    p.print(F("         used size: ")); p.print(PrintDotted(fs_info.usedBytes, FL, FC)); p.println(FPSTR(Bytes));
    p.print(F("        block size: ")); p.print(PrintDotted(fs_info.blockSize, FL, FC)); p.println(FPSTR(Bytes));
    p.print(F("         page size: ")); p.print(PrintDotted(fs_info.pageSize, FL, FC)); p.println(FPSTR(Bytes));
    p.print(F("   max path length: ")); p.print(PrintDotted(fs_info.maxPathLength, FL, FC)); p.println(FPSTR(Bytes));
    p.print(F("    max open files: ")); p.println(PrintDotted(fs_info.maxOpenFiles, FL, FC));
  }
}
#endif /* APPVERSION_H_ */
#pragma endregion























































































































































































































































































































































































































































































































































































































































































































































































































































































































