diff --git a/src/plugins/Display/Display_ePaper.cpp b/src/plugins/Display/Display_ePaper.cpp index 8a72a485..c2f93938 100644 --- a/src/plugins/Display/Display_ePaper.cpp +++ b/src/plugins/Display/Display_ePaper.cpp @@ -1,9 +1,9 @@ #include "Display_ePaper.h" #ifdef ESP8266 - #include +#include #elif defined(ESP32) - #include +#include #endif #include "../../utils/helper.h" #include "imagedata.h" @@ -21,7 +21,6 @@ DisplayEPaper::DisplayEPaper() { mHeadFootPadding = 16; } - //*************************************************************************** void DisplayEPaper::init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, uint8_t _BUSY, uint8_t _SCK, uint8_t _MOSI, uint32_t *utcTs, const char *version) { mUtcTs = utcTs; @@ -54,6 +53,9 @@ void DisplayEPaper::init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, u headlineIP(); + _version = version; + versionFooter(); + // call the PowerPage to change the PV Power Values actualPowerPaged(0, 0, 0, 0); } @@ -123,6 +125,26 @@ void DisplayEPaper::lastUpdatePaged() { } while (_display->nextPage()); } //*************************************************************************** +void DisplayEPaper::versionFooter() { + int16_t tbx, tby; + uint16_t tbw, tbh; + + _display->setFont(&FreeSans9pt7b); + _display->setTextColor(GxEPD_WHITE); + + _display->setPartialWindow(0, _display->height() - mHeadFootPadding, _display->width(), mHeadFootPadding); + _display->fillScreen(GxEPD_BLACK); + do { + snprintf(_fmtText, sizeof(_fmtText), "Version: %s", _version); + + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + uint16_t x = ((_display->width() - tbw) / 2) - tbx; + + _display->setCursor(x, (_display->height() - 3)); + _display->println(_fmtText); + } while (_display->nextPage()); +} +//*************************************************************************** void DisplayEPaper::offlineFooter() { int16_t tbx, tby; uint16_t tbw, tbh; @@ -154,9 +176,11 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa _display->setPartialWindow(0, mHeadFootPadding, _display->width(), _display->height() - (mHeadFootPadding * 2)); _display->fillScreen(GxEPD_WHITE); + do { + // actual Production if (totalPower > 9999) { - snprintf(_fmtText, sizeof(_fmtText), "%.1f kW", (totalPower / 10000)); + snprintf(_fmtText, sizeof(_fmtText), "%.1f kW", (totalPower / 1000)); _changed = true; } else if ((totalPower > 0) && (totalPower <= 9999)) { snprintf(_fmtText, sizeof(_fmtText), "%.0f W", totalPower); @@ -164,8 +188,9 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa } else { snprintf(_fmtText, sizeof(_fmtText), "offline"); } - if (totalPower == 0){ - _display->fillRect(0, mHeadFootPadding, 200,200, GxEPD_BLACK); + + if ((totalPower == 0) && (mEnPowerSafe)) { + _display->fillRect(0, mHeadFootPadding, 200, 200, GxEPD_BLACK); _display->drawBitmap(0, 0, logo, 200, 200, GxEPD_WHITE); } else { _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); @@ -173,33 +198,70 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa _display->setCursor(x, mHeadFootPadding + tbh + 10); _display->print(_fmtText); + if ((totalYieldDay > 0) && (totalYieldTotal > 0)) { + // Today Production + _display->setFont(&FreeSans18pt7b); + y = _display->height() / 2; + _display->setCursor(5, y); + + if (totalYieldDay > 9999) { + snprintf(_fmtText, _display->width(), "%.1f", (totalYieldDay / 1000)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - ((tbh + 30) / 2), myToday, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 50, y); + _display->setFont(&FreeSans12pt7b); + _display->println("kWh"); + } else if (totalYieldDay <= 9999) { + snprintf(_fmtText, _display->width(), "%.0f", (totalYieldDay)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - tbh, myToday, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 38, y); + _display->setFont(&FreeSans12pt7b); + _display->println("Wh"); + } + y = y + tbh + 15; + + // Total Production + _display->setFont(&FreeSans18pt7b); + _display->setCursor(5, y); + if (totalYieldTotal > 9999) { + snprintf(_fmtText, _display->width(), "%.1f", (totalYieldTotal / 1000)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 59, y); + _display->setFont(&FreeSans12pt7b); + _display->println("MWh"); + } else if (totalYieldTotal <= 9999) { + snprintf(_fmtText, _display->width(), "%.0f", (totalYieldTotal)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 50, y); + _display->setFont(&FreeSans12pt7b); + _display->println("kWh"); + } + } + + // Inverter online _display->setFont(&FreeSans12pt7b); - y = _display->height() / 2; - _display->setCursor(5, y); - _display->print("today:"); - snprintf(_fmtText, _display->width(), "%.0f", totalYieldDay); + y = _display->height() - (mHeadFootPadding + 10); + snprintf(_fmtText, sizeof(_fmtText), " %d online", isprod); _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - x = ((_display->width() - tbw) / 2) - tbx; + _display->drawInvertedBitmap(10, y - tbh, myWR, 20, 20, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; _display->setCursor(x, y); - _display->print(_fmtText); - _display->setCursor(_display->width() - 38, y); - _display->println("Wh"); - - y = y + tbh + 7; - _display->setCursor(5, y); - _display->print("total:"); - snprintf(_fmtText, _display->width(), "%.1f", totalYieldTotal); - _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - x = ((_display->width() - tbw) / 2) - tbx; - _display->setCursor(x, y); - _display->print(_fmtText); - _display->setCursor(_display->width() - 50, y); - _display->println("kWh"); - - _display->setCursor(10, _display->height() - (mHeadFootPadding + 10)); - snprintf(_fmtText, sizeof(_fmtText), "%d Inverter online", isprod); _display->println(_fmtText); - } } while (_display->nextPage()); } @@ -219,10 +281,10 @@ void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYield if ((isprod > 0) && (_changed)) { _changed = false; lastUpdatePaged(); - } else if((0 == totalPower) && (mEnPowerSafe)) + } else if ((0 == totalPower) && (mEnPowerSafe)) offlineFooter(); _display->powerOff(); } //*************************************************************************** -#endif // ESP32 +#endif // ESP32 diff --git a/src/plugins/Display/Display_ePaper.h b/src/plugins/Display/Display_ePaper.h index d9b24e34..65c5b91a 100644 --- a/src/plugins/Display/Display_ePaper.h +++ b/src/plugins/Display/Display_ePaper.h @@ -25,27 +25,28 @@ class DisplayEPaper { public: - DisplayEPaper(); - void fullRefresh(); - void init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, uint8_t _BUSY, uint8_t _SCK, uint8_t _MOSI, uint32_t *utcTs, const char* version); - void config(uint8_t rotation, bool enPowerSafe); - void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod); - + DisplayEPaper(); + void fullRefresh(); + void init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, uint8_t _BUSY, uint8_t _SCK, uint8_t _MOSI, uint32_t* utcTs, const char* version); + void config(uint8_t rotation, bool enPowerSafe); + void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod); private: - void headlineIP(); - void actualPowerPaged(float _totalPower, float _totalYieldDay, float _totalYieldTotal, uint8_t _isprod); - void lastUpdatePaged(); - void offlineFooter(); - - uint8_t mDisplayRotation; - bool _changed = false; - char _fmtText[35]; - const char* _settedIP; - uint8_t mHeadFootPadding; - GxEPD2_GFX* _display; - uint32_t *mUtcTs; - bool mEnPowerSafe; + void headlineIP(); + void actualPowerPaged(float _totalPower, float _totalYieldDay, float _totalYieldTotal, uint8_t _isprod); + void lastUpdatePaged(); + void offlineFooter(); + void versionFooter(); + + uint8_t mDisplayRotation; + bool _changed = false; + char _fmtText[35]; + const char* _settedIP; + uint8_t mHeadFootPadding; + GxEPD2_GFX* _display; + uint32_t* mUtcTs; + bool mEnPowerSafe; + const char* _version; }; -#endif // ESP32 +#endif // ESP32 diff --git a/src/plugins/Display/imagedata.h b/src/plugins/Display/imagedata.h index baaddec8..b136193b 100644 --- a/src/plugins/Display/imagedata.h +++ b/src/plugins/Display/imagedata.h @@ -9,6 +9,47 @@ #include #endif +// 'Sigma', 30x30px +const unsigned char mySigma[] PROGMEM = { + 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x3f, 0x80, 0x07, 0xf0, 0x3f, 0x80, 0x07, 0xf0, 0x3f, 0x9f, 0xe7, 0xf0, 0x3f, 0xcf, 0xe7, 0xf0, + 0x3f, 0xcf, 0xff, 0xf0, 0x3f, 0xe7, 0xff, 0xf0, 0x3f, 0xe7, 0xff, 0xf0, 0x3f, 0xf3, 0xff, 0xf0, + 0x3f, 0xf3, 0xff, 0xf0, 0x3f, 0xf9, 0xff, 0xf0, 0x3f, 0xf8, 0xff, 0xf0, 0x3f, 0xf8, 0xff, 0xf0, + 0x3f, 0xf9, 0xff, 0xf0, 0x3f, 0xf3, 0xff, 0xf0, 0x3f, 0xf3, 0xff, 0xf0, 0x3f, 0xe7, 0xff, 0xf0, + 0x3f, 0xe7, 0xff, 0xf0, 0x3f, 0xcf, 0xff, 0xf0, 0x3f, 0xcf, 0xe7, 0xf0, 0x3f, 0x9f, 0xe7, 0xf0, + 0x3f, 0x80, 0x07, 0xf0, 0x3f, 0x80, 0x07, 0xf0, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04 +}; +// 'Sun', 30x30px +const unsigned char mySun[] PROGMEM = { + 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xfb, 0xf0, + 0x3f, 0xfc, 0xfb, 0xf0, 0x3f, 0xfc, 0xfb, 0xf0, 0x3e, 0xfc, 0xf3, 0xf0, 0x3c, 0x7c, 0xf3, 0xf0, + 0x3e, 0x30, 0x33, 0xf0, 0x3f, 0x0f, 0xcb, 0xf0, 0x3f, 0x9f, 0xeb, 0xf0, 0x3f, 0xbf, 0xeb, 0xf0, + 0x3f, 0x7f, 0xd8, 0x30, 0x3f, 0x7f, 0xdf, 0xb0, 0x30, 0x7f, 0xdf, 0xb0, 0x30, 0x7f, 0xbf, 0x70, + 0x3f, 0x7f, 0xbf, 0x70, 0x3f, 0x7f, 0x83, 0x70, 0x3f, 0xbf, 0xf2, 0xf0, 0x3f, 0x9f, 0xe2, 0xf0, + 0x3f, 0x0f, 0xca, 0xf0, 0x3e, 0x30, 0x39, 0xf0, 0x3c, 0x7c, 0xf9, 0xf0, 0x3e, 0xfc, 0xf9, 0xf0, + 0x3f, 0xfc, 0xfb, 0xf0, 0x3f, 0xfc, 0xfb, 0xf0, 0x3f, 0xff, 0xfb, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04 +}; +// 'Today', 30x30px +const unsigned char myToday[] PROGMEM = { + 0xf3, 0xff, 0xff, 0x3c, 0xf3, 0xff, 0xff, 0x3c, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x33, 0xff, 0xff, 0x30, 0x33, 0xff, 0xff, 0x30, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xfc, 0xf0, 0x3f, 0xff, 0xf8, 0xf0, 0x3f, 0xff, 0xf1, 0xf0, + 0x3f, 0xff, 0xe3, 0xf0, 0x3f, 0xff, 0xc7, 0xf0, 0x3f, 0xff, 0x8f, 0xf0, 0x3f, 0xff, 0x1f, 0xf0, + 0x3f, 0xfe, 0x3f, 0xf0, 0x3e, 0x7c, 0x7f, 0xf0, 0x3e, 0x38, 0xff, 0xf0, 0x3f, 0x11, 0xff, 0xf0, + 0x3f, 0x83, 0xff, 0xf0, 0x3f, 0xc7, 0xff, 0xf0, 0x3f, 0xef, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04 +}; +// 'WR', 20x20px +const unsigned char myWR[] PROGMEM = { + 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x3f, 0xff, 0x40, 0x30, 0x7e, 0xc0, 0x3f, + 0xfd, 0xc0, 0x30, 0x7b, 0xc0, 0x3f, 0xf7, 0xc0, 0x3f, 0xef, 0xc0, 0x3f, 0xdf, 0xc0, 0x3f, 0xbf, + 0xc0, 0x3f, 0x7f, 0xc0, 0x3e, 0xff, 0xc0, 0x3d, 0xf7, 0xc0, 0x3b, 0xea, 0xc0, 0x37, 0xfd, 0xc0, + 0x2f, 0xff, 0xc0, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10 +}; + // 'Logo', 200x200px const unsigned char logo[] PROGMEM = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,