mirror of https://github.com/lumapu/ahoy.git
				
				
			
							committed by
							
								 GitHub
								GitHub
							
						
					
				
				 20 changed files with 1216 additions and 502 deletions
			
			
		| @ -0,0 +1,7 @@ | |||
| License | |||
| 
 | |||
| CC-CY-NC-SA 3.0 | |||
| 
 | |||
| https://creativecommons.org/licenses/by-nc-sa/3.0/de | |||
| 
 | |||
| This project is for non-commercial use only! | |||
| @ -0,0 +1,113 @@ | |||
| #ifndef __DISPLAY__ | |||
| #define __DISPLAY__ | |||
| 
 | |||
| #include <Timezone.h> | |||
| #include <U8g2lib.h> | |||
| 
 | |||
| #include "../../hm/hmSystem.h" | |||
| #include "../../utils/helper.h" | |||
| #include "Display_Mono.h" | |||
| #include "Display_ePaper.h" | |||
| 
 | |||
| template <class HMSYSTEM> | |||
| class Display { | |||
|    public: | |||
|         Display() {} | |||
| 
 | |||
|         void setup(display_t *cfg, HMSYSTEM *sys, uint32_t *utcTs, uint8_t disp_reset, const char *version) { | |||
|             mCfg = cfg; | |||
|             mSys = sys; | |||
|             mUtcTs = utcTs; | |||
|             mNewPayload = false; | |||
|             mLoopCnt = 0; | |||
|             mVersion = version; | |||
| 
 | |||
|             if (mCfg->type == 0) | |||
|                 return; | |||
| 
 | |||
|             if ((1 < mCfg->type) && (mCfg->type < 10)) { | |||
|                 mMono.config(mCfg->pwrSaveAtIvOffline, mCfg->pxShift, mCfg->contrast); | |||
|                 mMono.init(mCfg->type, mCfg->rot, mCfg->disp_cs, mCfg->disp_dc, mCfg->disp_reset, mCfg->disp_clk, mCfg->disp_data, mUtcTs, mVersion); | |||
|             } else if (mCfg->type >= 10) { | |||
|                 #if defined(ESP32) | |||
|                 mRefreshCycle = 0; | |||
|                 mEpaper.config(mCfg->rot); | |||
|                 mEpaper.init(mCfg->type, mCfg->disp_cs, mCfg->disp_dc, mCfg->disp_reset, mCfg->disp_busy, mCfg->disp_clk, mCfg->disp_data, mUtcTs, mVersion); | |||
|                 #endif | |||
|             } | |||
|         } | |||
| 
 | |||
|         void payloadEventListener(uint8_t cmd) { | |||
|             mNewPayload = true; | |||
|         } | |||
| 
 | |||
|         void tickerSecond() { | |||
|             if (mNewPayload || ((++mLoopCnt % 10) == 0)) { | |||
|                 mNewPayload = false; | |||
|                 mLoopCnt = 0; | |||
|                 DataScreen(); | |||
|             } | |||
|         } | |||
| 
 | |||
|     private: | |||
|         void DataScreen() { | |||
|             if (mCfg->type == 0) | |||
|                 return; | |||
|             if (*mUtcTs == 0) | |||
|                 return; | |||
| 
 | |||
|             float totalPower = 0; | |||
|             float totalYieldDay = 0; | |||
|             float totalYieldTotal = 0; | |||
| 
 | |||
|             uint8_t isprod = 0; | |||
| 
 | |||
|             Inverter<> *iv; | |||
|             record_t<> *rec; | |||
|             for (uint8_t i = 0; i < mSys->getNumInverters(); i++) { | |||
|                 iv = mSys->getInverterByPos(i); | |||
|                 rec = iv->getRecordStruct(RealTimeRunData_Debug); | |||
|                 if (iv == NULL) | |||
|                     continue; | |||
| 
 | |||
|                 if (iv->isProducing(*mUtcTs)) | |||
|                     isprod++; | |||
| 
 | |||
|                 totalPower += iv->getChannelFieldValue(CH0, FLD_PAC, rec); | |||
|                 totalYieldDay += iv->getChannelFieldValue(CH0, FLD_YD, rec); | |||
|                 totalYieldTotal += iv->getChannelFieldValue(CH0, FLD_YT, rec); | |||
|             } | |||
| 
 | |||
|             if ((1 < mCfg->type) && (mCfg->type < 10)) { | |||
|                 mMono.loop(totalPower, totalYieldDay, totalYieldTotal, isprod); | |||
|             } else if (mCfg->type >= 10) { | |||
|                 #if defined(ESP32) | |||
|                 mEpaper.loop(totalPower, totalYieldDay, totalYieldTotal, isprod); | |||
|                 mRefreshCycle++; | |||
|                 #endif | |||
|             } | |||
| 
 | |||
|             #if defined(ESP32) | |||
|             if (mRefreshCycle > 480) { | |||
|                 mEpaper.fullRefresh(); | |||
|                 mRefreshCycle = 0; | |||
|             } | |||
|             #endif | |||
|         } | |||
| 
 | |||
|         // private member variables
 | |||
|         bool mNewPayload; | |||
|         uint8_t mLoopCnt; | |||
|         uint32_t *mUtcTs; | |||
|         const char *mVersion; | |||
|         display_t *mCfg; | |||
|         HMSYSTEM *mSys; | |||
|         uint16_t mRefreshCycle; | |||
| 
 | |||
|         #if defined(ESP32) | |||
|         DisplayEPaper mEpaper; | |||
|         #endif | |||
|         DisplayMono mMono; | |||
| }; | |||
| 
 | |||
| #endif /*__DISPLAY__*/ | |||
| @ -0,0 +1,149 @@ | |||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | |||
| #include "Display_Mono.h" | |||
| 
 | |||
| #ifdef ESP8266 | |||
|     #include <ESP8266WiFi.h> | |||
| #elif defined(ESP32) | |||
|     #include <WiFi.h> | |||
| #endif | |||
| #include "../../utils/helper.h" | |||
| 
 | |||
| //#ifdef U8X8_HAVE_HW_SPI
 | |||
| //#include <SPI.h>
 | |||
| //#endif
 | |||
| //#ifdef U8X8_HAVE_HW_I2C
 | |||
| //#include <Wire.h>
 | |||
| //#endif
 | |||
| 
 | |||
| DisplayMono::DisplayMono() { | |||
|     mEnPowerSafe = true; | |||
|     mEnScreenSaver = true; | |||
|     mLuminance = 60; | |||
|     _dispY = 0; | |||
|     mTimeout = DISP_DEFAULT_TIMEOUT;  // interval at which to power save (milliseconds)
 | |||
|     mUtcTs = NULL; | |||
| } | |||
| 
 | |||
| 
 | |||
| 
 | |||
| void DisplayMono::init(uint8_t type, uint8_t rot, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, uint32_t *utcTs, const char* version) { | |||
|     if ((0 < type) && (type < 4)) { | |||
|         u8g2_cb_t *rot = (u8g2_cb_t *)((rot != 0x00) ? U8G2_R2 : U8G2_R0); | |||
|         switch(type) { | |||
|             case 1: | |||
|                 mDisplay = new U8G2_PCD8544_84X48_F_4W_HW_SPI(rot, cs, dc, reset); | |||
|                 break; | |||
|             case 2: | |||
|                 mDisplay = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(rot, reset, clock, data); | |||
|                 break; | |||
|             default: | |||
|             case 3: | |||
|                 mDisplay = new U8G2_SH1106_128X64_NONAME_F_HW_I2C(rot, reset, clock, data); | |||
|                 break; | |||
|         } | |||
| 
 | |||
|         mUtcTs = utcTs; | |||
| 
 | |||
|         mDisplay->begin(); | |||
| 
 | |||
|         mIsLarge = (mDisplay->getWidth() > 120); | |||
|         calcLineHeights(); | |||
| 
 | |||
|         mDisplay->clearBuffer(); | |||
|         mDisplay->setContrast(mLuminance); | |||
|         printText("AHOY!", 0, 35); | |||
|         printText("ahoydtu.de", 2, 20); | |||
|         printText(version, 3, 46); | |||
|         mDisplay->sendBuffer(); | |||
|     } | |||
| } | |||
| 
 | |||
| void DisplayMono::config(bool enPowerSafe, bool enScreenSaver, uint8_t lum) { | |||
|     mEnPowerSafe = enPowerSafe; | |||
|     mEnScreenSaver = enScreenSaver; | |||
|     mLuminance = lum; | |||
| } | |||
| 
 | |||
| void DisplayMono::loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { | |||
|     if (mEnPowerSafe) | |||
|         if(mTimeout != 0) | |||
|            mTimeout--; | |||
| 
 | |||
|     mDisplay->clearBuffer(); | |||
| 
 | |||
|     // set Contrast of the Display to raise the lifetime
 | |||
|     mDisplay->setContrast(mLuminance); | |||
| 
 | |||
|     if ((totalPower > 0) && (isprod > 0)) { | |||
|         mTimeout = DISP_DEFAULT_TIMEOUT; | |||
|         mDisplay->setPowerSave(false); | |||
|         if (totalPower > 999) { | |||
|             snprintf(_fmtText, DISP_FMT_TEXT_LEN, "%2.2f kW", (totalPower / 1000)); | |||
|         } else { | |||
|             snprintf(_fmtText, DISP_FMT_TEXT_LEN, "%3.0f W", totalPower); | |||
|         } | |||
|         printText(_fmtText, 0); | |||
|     } else { | |||
|         printText("offline", 0, 25); | |||
|         // check if it's time to enter power saving mode
 | |||
|         if (mTimeout == 0) | |||
|             mDisplay->setPowerSave(mEnPowerSafe); | |||
|     } | |||
| 
 | |||
|     snprintf(_fmtText, DISP_FMT_TEXT_LEN, "today: %4.0f Wh", totalYieldDay); | |||
|     printText(_fmtText, 1); | |||
| 
 | |||
|     snprintf(_fmtText, DISP_FMT_TEXT_LEN, "total: %.1f kWh", totalYieldTotal); | |||
|     printText(_fmtText, 2); | |||
| 
 | |||
|     IPAddress ip = WiFi.localIP(); | |||
|     if (!(_mExtra % 10) && (ip)) { | |||
|         printText(ip.toString().c_str(), 3); | |||
|     } else if (!(_mExtra % 5)) { | |||
|         snprintf(_fmtText, DISP_FMT_TEXT_LEN, "#%d Inverter online", isprod); | |||
|         printText(_fmtText, 3); | |||
|     } else { | |||
|         if(mIsLarge && (NULL != mUtcTs)) | |||
|             printText(ah::getDateTimeStr(gTimezone.toLocal(*mUtcTs)).c_str(), 3); | |||
|         else | |||
|             printText(ah::getTimeStr(gTimezone.toLocal(*mUtcTs)).c_str(), 3); | |||
|     } | |||
| 
 | |||
|     mDisplay->sendBuffer(); | |||
| 
 | |||
|     _dispY = 0; | |||
|     _mExtra++; | |||
| } | |||
| 
 | |||
| void DisplayMono::calcLineHeights() { | |||
|     uint8_t yOff = 0; | |||
|     for (uint8_t i = 0; i < 4; i++) { | |||
|         setFont(i); | |||
|         yOff += (mDisplay->getMaxCharHeight()); | |||
|         mLineOffsets[i] = yOff; | |||
|     } | |||
| } | |||
| 
 | |||
| inline void DisplayMono::setFont(uint8_t line) { | |||
|     switch (line) { | |||
|         case 0: | |||
|             mDisplay->setFont((mIsLarge) ? u8g2_font_ncenB14_tr : u8g2_font_logisoso16_tr); | |||
|             break; | |||
|         case 3: | |||
|             mDisplay->setFont(u8g2_font_5x8_tr); | |||
|             break; | |||
|         default: | |||
|             mDisplay->setFont((mIsLarge) ? u8g2_font_ncenB10_tr : u8g2_font_5x8_tr); | |||
|             break; | |||
|     } | |||
| } | |||
| 
 | |||
| void DisplayMono::printText(const char* text, uint8_t line, uint8_t dispX) { | |||
|     if (!mIsLarge) { | |||
|         dispX = (line == 0) ? 10 : 5; | |||
|     } | |||
|     setFont(line); | |||
| 
 | |||
|     dispX += (mEnPowerSafe) ? (_mExtra % 7) : 0; | |||
|     mDisplay->drawStr(dispX, mLineOffsets[line], text); | |||
| } | |||
| @ -0,0 +1,36 @@ | |||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | |||
| #pragma once | |||
| 
 | |||
| #include <U8g2lib.h> | |||
| #define DISP_DEFAULT_TIMEOUT 60  // in seconds
 | |||
| #define DISP_FMT_TEXT_LEN    32 | |||
| 
 | |||
| class DisplayMono { | |||
|    public: | |||
|       DisplayMono(); | |||
| 
 | |||
|       void init(uint8_t type, uint8_t rot, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, uint32_t *utcTs, const char* version); | |||
|       void config(bool enPowerSafe, bool enScreenSaver, uint8_t lum); | |||
|       void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod); | |||
| 
 | |||
|    private: | |||
|       void calcLineHeights(); | |||
|       void setFont(uint8_t line); | |||
|       void printText(const char* text, uint8_t line, uint8_t dispX = 5); | |||
| 
 | |||
|       U8G2* mDisplay; | |||
| 
 | |||
|       bool mEnPowerSafe, mEnScreenSaver; | |||
|       uint8_t mLuminance; | |||
| 
 | |||
|       bool mIsLarge = false; | |||
|       uint8_t mLoopCnt; | |||
|       uint32_t* mUtcTs; | |||
|       uint8_t mLineOffsets[5]; | |||
| 
 | |||
|       uint16_t _dispY; | |||
| 
 | |||
|       uint8_t _mExtra; | |||
|       uint16_t mTimeout; | |||
|       char _fmtText[DISP_FMT_TEXT_LEN]; | |||
| }; | |||
| @ -0,0 +1,197 @@ | |||
| #include "Display_ePaper.h" | |||
| 
 | |||
| #ifdef ESP8266 | |||
|     #include <ESP8266WiFi.h> | |||
| #elif defined(ESP32) | |||
|     #include <WiFi.h> | |||
| #endif | |||
| #include "../../utils/helper.h" | |||
| #include "imagedata.h" | |||
| 
 | |||
| #if defined(ESP32) | |||
| 
 | |||
| static const uint32_t spiClk = 4000000;  // 4 MHz
 | |||
| 
 | |||
| #if defined(ESP32) && defined(USE_HSPI_FOR_EPD) | |||
| SPIClass hspi(HSPI); | |||
| #endif | |||
| 
 | |||
| DisplayEPaper::DisplayEPaper() { | |||
|     mDisplayRotation = 2; | |||
|     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; | |||
| 
 | |||
|     if (type > 9) { | |||
|         Serial.begin(115200); | |||
|         _display = new GxEPD2_BW<GxEPD2_150_BN, GxEPD2_150_BN::HEIGHT>(GxEPD2_150_BN(_CS, _DC, _RST, _BUSY)); | |||
|         hspi.begin(_SCK, _BUSY, _MOSI, _CS); | |||
| 
 | |||
| #if defined(ESP32) && defined(USE_HSPI_FOR_EPD) | |||
|         _display->epd2.selectSPI(hspi, SPISettings(spiClk, MSBFIRST, SPI_MODE0)); | |||
| #endif | |||
|         _display->init(115200, true, 2, false); | |||
|         _display->setRotation(mDisplayRotation); | |||
|         _display->setFullWindow(); | |||
| 
 | |||
|         // Logo
 | |||
|         _display->fillScreen(GxEPD_BLACK); | |||
|         _display->drawBitmap(0, 0, logo, 200, 200, GxEPD_WHITE); | |||
|         while (_display->nextPage()) | |||
|             ; | |||
| 
 | |||
|         // clean the screen
 | |||
|         delay(2000); | |||
|         _display->fillScreen(GxEPD_WHITE); | |||
|         while (_display->nextPage()) | |||
|             ; | |||
| 
 | |||
|         headlineIP(); | |||
| 
 | |||
|         // call the PowerPage to change the PV Power Values
 | |||
|         actualPowerPaged(0, 0, 0, 0); | |||
|     } | |||
| } | |||
| 
 | |||
| void DisplayEPaper::config(uint8_t rotation) { | |||
|     mDisplayRotation = rotation; | |||
| } | |||
| 
 | |||
| //***************************************************************************
 | |||
| void DisplayEPaper::fullRefresh() { | |||
|     // screen complete black
 | |||
|     _display->fillScreen(GxEPD_BLACK); | |||
|     while (_display->nextPage()) | |||
|         ; | |||
|     delay(2000); | |||
|     // screen complete white
 | |||
|     _display->fillScreen(GxEPD_WHITE); | |||
|     while (_display->nextPage()) | |||
|         ; | |||
| } | |||
| //***************************************************************************
 | |||
| void DisplayEPaper::headlineIP() { | |||
|     int16_t tbx, tby; | |||
|     uint16_t tbw, tbh; | |||
| 
 | |||
|     _display->setFont(&FreeSans9pt7b); | |||
|     _display->setTextColor(GxEPD_WHITE); | |||
| 
 | |||
|     _display->setPartialWindow(0, 0, _display->width(), mHeadFootPadding); | |||
|     _display->fillScreen(GxEPD_BLACK); | |||
| 
 | |||
|     do { | |||
|         if ((WiFi.isConnected() == true) && (WiFi.localIP() > 0)) { | |||
|             snprintf(_fmtText, sizeof(_fmtText), "%s", WiFi.localIP().toString().c_str()); | |||
|         } else { | |||
|             snprintf(_fmtText, sizeof(_fmtText), "WiFi not connected"); | |||
|         } | |||
|         _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); | |||
|         uint16_t x = ((_display->width() - tbw) / 2) - tbx; | |||
| 
 | |||
|         _display->setCursor(x, (mHeadFootPadding - 2)); | |||
|         _display->println(_fmtText); | |||
|     } while (_display->nextPage()); | |||
| } | |||
| //***************************************************************************
 | |||
| void DisplayEPaper::lastUpdatePaged() { | |||
|     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 { | |||
|         if (NULL != mUtcTs) { | |||
|             snprintf(_fmtText, sizeof(_fmtText), ah::getDateTimeStr(gTimezone.toLocal(*mUtcTs)).c_str()); | |||
| 
 | |||
|             _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::actualPowerPaged(float _totalPower, float _totalYieldDay, float _totalYieldTotal, uint8_t _isprod) { | |||
|     int16_t tbx, tby; | |||
|     uint16_t tbw, tbh, x, y; | |||
| 
 | |||
|     _display->setFont(&FreeSans24pt7b); | |||
|     _display->setTextColor(GxEPD_BLACK); | |||
| 
 | |||
|     _display->setPartialWindow(0, mHeadFootPadding, _display->width(), _display->height() - (mHeadFootPadding * 2)); | |||
|     _display->fillScreen(GxEPD_WHITE); | |||
|     do { | |||
|         if (_totalPower > 9999) { | |||
|             snprintf(_fmtText, sizeof(_fmtText), "%.1f kW", (_totalPower / 10000)); | |||
|             _changed = true; | |||
|         } else if ((_totalPower > 0) && (_totalPower <= 9999)) { | |||
|             snprintf(_fmtText, sizeof(_fmtText), "%.0f W", _totalPower); | |||
|             _changed = true; | |||
|         } else { | |||
|             snprintf(_fmtText, sizeof(_fmtText), "offline"); | |||
|         } | |||
|         _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); | |||
|         x = ((_display->width() - tbw) / 2) - tbx; | |||
|         _display->setCursor(x, mHeadFootPadding + tbh + 10); | |||
|         _display->print(_fmtText); | |||
| 
 | |||
|         _display->setFont(&FreeSans12pt7b); | |||
|         y = _display->height() / 2; | |||
|         _display->setCursor(0, y); | |||
|         _display->print("today:"); | |||
|         snprintf(_fmtText, _display->width(), "%.0f", _totalYieldDay); | |||
|         _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() - 33, y); | |||
|         _display->println("Wh"); | |||
| 
 | |||
|         y = y + tbh + 7; | |||
|         _display->setCursor(0, 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() - 45, y); | |||
|         _display->println("kWh"); | |||
| 
 | |||
|         _display->setCursor(0, _display->height() - (mHeadFootPadding + 10)); | |||
|         snprintf(_fmtText, sizeof(_fmtText), "#%d Inverter online", _isprod); | |||
|         _display->println(_fmtText); | |||
| 
 | |||
|     } while (_display->nextPage()); | |||
| } | |||
| //***************************************************************************
 | |||
| void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { | |||
|     // check if the IP has changed
 | |||
|     if (_settedIP != WiFi.localIP().toString().c_str()) { | |||
|         // save the new IP and call the Headline Funktion to adapt the Headline
 | |||
|         _settedIP = WiFi.localIP().toString().c_str(); | |||
|         headlineIP(); | |||
|     } | |||
| 
 | |||
|     // call the PowerPage to change the PV Power Values
 | |||
|     actualPowerPaged(totalPower, totalYieldDay, totalYieldTotal, isprod); | |||
| 
 | |||
|     // if there was an change and the Inverter is producing set a new Timestam in the footline
 | |||
|     if ((isprod > 0) && (_changed)) { | |||
|         _changed = false; | |||
|         lastUpdatePaged(); | |||
|     } | |||
| 
 | |||
|     _display->powerOff(); | |||
| } | |||
| //***************************************************************************
 | |||
| #endif // ESP32
 | |||
| @ -0,0 +1,52 @@ | |||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | |||
| #pragma once | |||
| 
 | |||
| #if defined(ESP32) | |||
| 
 | |||
| // uncomment next line to use HSPI for EPD (and VSPI for SD), e.g. with Waveshare ESP32 Driver Board
 | |||
| #define USE_HSPI_FOR_EPD | |||
| 
 | |||
| /// uncomment next line to use class GFX of library GFX_Root instead of Adafruit_GFX, to use less code and ram
 | |||
| // #include <GFX.h>
 | |||
| // base class GxEPD2_GFX can be used to pass references or pointers to the display instance as parameter, uses ~1.2k more code
 | |||
| // enable GxEPD2_GFX base class
 | |||
| #define ENABLE_GxEPD2_GFX 1 | |||
| 
 | |||
| #include <GxEPD2_3C.h> | |||
| #include <GxEPD2_BW.h> | |||
| #include <SPI.h> | |||
| 
 | |||
| #include <map> | |||
| // FreeFonts from Adafruit_GFX
 | |||
| #include <Fonts/FreeSans12pt7b.h> | |||
| #include <Fonts/FreeSans18pt7b.h> | |||
| #include <Fonts/FreeSans24pt7b.h> | |||
| #include <Fonts/FreeSans9pt7b.h> | |||
| 
 | |||
| // GDEW027C44   2.7 " b/w/r 176x264, IL91874
 | |||
| // GDEH0154D67  1.54" b/w   200x200
 | |||
| 
 | |||
| 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); | |||
|       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(); | |||
| 
 | |||
|       uint8_t mDisplayRotation; | |||
|       bool _changed = false; | |||
|       char _fmtText[35]; | |||
|       const char* _settedIP; | |||
|       uint8_t mHeadFootPadding; | |||
|       GxEPD2_GFX* _display; | |||
|       uint32_t *mUtcTs; | |||
| }; | |||
| 
 | |||
| #endif // ESP32
 | |||
| @ -0,0 +1,329 @@ | |||
| // GxEPD2_ESP32_ESP8266_WifiData_V1_und_V2
 | |||
| 
 | |||
| #ifndef __IMAGEDATA_H__ | |||
| #define __IMAGEDATA_H__ | |||
| 
 | |||
| #if defined(__AVR__) || defined(ARDUINO_ARCH_SAMD) | |||
| #include <avr/pgmspace.h> | |||
| #elif defined(ESP8266) || defined(ESP32) | |||
| #include <pgmspace.h> | |||
| #endif | |||
| 
 | |||
| // 'Logo', 200x200px
 | |||
| const unsigned char logo[] PROGMEM = { | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, | |||
|     0x0b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x0f, 0xfe, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x06, | |||
|     0x0f, 0xff, 0xff, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x7e, 0x0f, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, | |||
|     0x03, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x19, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xfe, | |||
|     0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xe0, 0x70, 0x7f, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xe0, 0x3f, 0x07, 0xff, 0xff, | |||
|     0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xfc, 0x0f, 0xe0, 0x3f, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xe0, 0x1f, 0x83, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xe0, 0x1f, 0x83, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xe0, | |||
|     0x0f, 0x83, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xe0, 0x0f, 0x83, 0xff, 0xff, 0xff, 0xff, 0xfe, | |||
|     0x07, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, | |||
|     0xff, 0xc1, 0x07, 0x80, 0x07, 0xfe, 0xff, 0xff, 0xfc, 0x07, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xe1, 0x07, 0xc0, 0x01, 0xe0, 0x0f, | |||
|     0xff, 0xfc, 0x0f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xfc, 0xff, 0xe1, 0x83, 0xc0, 0x01, 0xc0, 0x07, 0xff, 0xf8, 0x0f, 0xfc, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xe1, 0x83, 0xc0, 0x00, | |||
|     0xc0, 0x07, 0x8f, 0xf8, 0x1f, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xfe, 0x7f, 0xe0, 0x01, 0xc0, 0x00, 0x81, 0x83, 0x07, 0xf0, 0x3f, 0xf9, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xe0, 0x01, | |||
|     0xe0, 0xe0, 0x87, 0xe3, 0x0f, 0xf0, 0x3f, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xe0, 0x00, 0xe0, 0xe0, 0x87, 0xe1, 0x0c, 0x60, 0x7f, | |||
|     0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, | |||
|     0xe0, 0x00, 0xe1, 0xf0, 0x87, 0xe1, 0x08, 0x60, 0x7f, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xe0, 0xe0, 0xe0, 0xe0, 0x87, 0xc2, 0x00, | |||
|     0x40, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0x8f, 0xc0, 0xe0, 0x60, 0xe0, 0xc0, 0x82, 0x00, 0xc0, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xc0, 0xe0, 0x60, 0xe0, 0xc0, | |||
|     0x06, 0x01, 0x81, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xcf, 0xe0, 0xe0, 0x20, 0xe0, 0xe0, 0x0c, 0x03, 0x81, 0xff, 0x1f, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xc0, 0xf0, 0x30, | |||
|     0xe1, 0xf8, 0x18, 0x07, 0xe1, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xc0, 0xf0, 0x7f, 0xff, 0xff, 0xf0, 0x1f, 0xf3, 0xfe, 0x01, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xc0, | |||
|     0xfb, 0xff, 0xff, 0xff, 0xe0, 0x3e, 0x1f, 0xfc, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xfc, 0x0f, | |||
|     0xf8, 0xfc, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, | |||
|     0x33, 0xef, 0xff, 0xff, 0xff, 0xff, 0x81, 0xfc, 0x0f, 0xf1, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf1, 0xff, 0xff, 0xa0, 0x00, 0x7f, 0xe3, | |||
|     0xfc, 0x0f, 0xf3, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xf1, 0xf9, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x0f, 0xe7, 0xff, 0xe0, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xf9, 0xff, 0x80, 0x3f, 0xff, | |||
|     0xe0, 0x0f, 0xfe, 0x1f, 0xc7, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xcf, 0xf8, 0xf0, 0x07, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0x8f, 0xff, 0xfc, | |||
|     0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xfc, 0x70, 0x3f, | |||
|     0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0x1f, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xfc, 0x63, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0x3f, | |||
|     0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfe, | |||
|     0x23, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7e, 0x3f, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x23, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, | |||
|     0x0c, 0x7f, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, | |||
|     0x7f, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xfc, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xf8, | |||
|     0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0x87, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xfc, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x55, 0x00, 0x3f, 0xf8, 0x00, | |||
|     0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0x01, 0xff, 0xff, 0xf8, 0x0f, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0x9f, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x0f, 0xff, 0xff, 0xff, 0x03, | |||
|     0xfc, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xe3, 0xf1, 0xff, | |||
|     0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xe0, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xe7, 0xf9, 0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, | |||
|     0xff, 0xf8, 0x7e, 0x06, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xcf, | |||
|     0xf8, 0xff, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0x03, 0x3f, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xcf, 0xfc, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0x1f, 0x23, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, | |||
|     0xff, 0x9f, 0xfe, 0x7f, 0xff, 0xf3, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xf1, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0x9f, 0xfe, 0x7f, 0xff, 0xe3, 0xf8, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xfe, 0x7f, 0xff, 0x9f, 0xff, 0x0f, 0xff, 0x8f, 0xf1, 0xff, 0xff, 0xff, 0xfe, 0xf5, 0x90, 0x07, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0x9f, 0xff, 0x03, 0xff, | |||
|     0x1f, 0xe3, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xfe, 0x7f, 0xff, 0x3f, 0xfe, 0x31, 0xfe, 0x7f, 0xe7, 0xff, 0x80, 0x00, 0x40, 0x00, | |||
|     0x07, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0x3f, 0x3c, | |||
|     0xf9, 0xfc, 0xff, 0xe7, 0xfe, 0x3f, 0xc9, 0xff, 0xf1, 0x1f, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0x3f, 0x3c, 0xf9, 0xf9, 0xff, 0xc7, 0xfc, 0xff, 0x90, | |||
|     0x7f, 0xf3, 0x03, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, | |||
|     0x3f, 0x39, 0xfd, 0xf3, 0xff, 0xcf, 0xfc, 0xff, 0x90, 0x3f, 0xf3, 0x83, 0xf8, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0x3f, 0x39, 0xf9, 0xc7, 0xff, 0xcf, 0xfc, | |||
|     0xff, 0x32, 0x7f, 0xe4, 0x77, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, | |||
|     0xff, 0xff, 0x7f, 0x33, 0xf9, 0x8f, 0xff, 0xcf, 0xf9, 0xff, 0x00, 0x7f, 0xe0, 0x67, 0xfc, 0x7f, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0x7f, 0xb3, 0xf3, 0xbf, 0xff, | |||
|     0xcf, 0xf9, 0xff, 0x00, 0xff, 0xfe, 0x47, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xf9, 0xff, 0xff, 0x7f, 0xf7, 0xf3, 0xff, 0xff, 0xcf, 0xf9, 0xff, 0xe0, 0xff, 0xfc, 0x0f, | |||
|     0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0x7f, 0xe7, 0xe7, | |||
|     0xff, 0xff, 0xcf, 0xf9, 0xff, 0xe1, 0xff, 0xfc, 0x1f, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0x3f, 0xef, 0xe7, 0xef, 0xff, 0xc7, 0xf9, 0xff, 0xc3, 0xff, | |||
|     0xfc, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0x3f, | |||
|     0xef, 0xef, 0xc0, 0xff, 0xe7, 0xf9, 0xff, 0xc3, 0xff, 0xf8, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0x3f, 0xef, 0xcf, 0xf0, 0x01, 0xe7, 0xf1, 0xff, | |||
|     0x87, 0xff, 0xf8, 0x7f, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, | |||
|     0xff, 0xbf, 0xcf, 0xe7, 0xff, 0xc1, 0xe3, 0xe1, 0xff, 0x8f, 0xff, 0xf0, 0xff, 0xff, 0x9f, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0x9f, 0xef, 0xe7, 0xff, 0xff, 0xf3, | |||
|     0xc1, 0xff, 0x96, 0xaf, 0xf9, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xf9, 0xff, 0xff, 0x9f, 0xe7, 0xe3, 0xff, 0xff, 0xf1, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, | |||
|     0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xcf, 0xe7, 0xf3, 0xff, | |||
|     0xff, 0xf8, 0xc0, 0x00, 0x4a, 0x90, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xf9, 0xff, 0xff, 0xef, 0xf3, 0xf3, 0x9f, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, | |||
|     0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xe7, 0xf1, | |||
|     0xe7, 0xc7, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xf3, 0xf0, 0x07, 0xe3, 0xff, 0xff, 0x81, 0xff, 0xff, | |||
|     0xff, 0xff, 0xfe, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, | |||
|     0xf8, 0x07, 0x1f, 0xf1, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xfc, 0x1f, 0x9f, 0xf8, 0xff, 0xff, 0xc3, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, | |||
|     0xff, 0xff, 0xf8, 0xff, 0x9f, 0xfe, 0x7f, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xf9, 0xff, 0x9f, 0xfe, 0x3f, | |||
|     0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xfd, 0xff, 0xff, 0xf1, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0xf3, 0xff, 0x3f, 0x3f, 0xff, 0xff, | |||
|     0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xe1, 0xff, 0xcf, | |||
|     0xff, 0xc7, 0xff, 0xf3, 0xff, 0x3f, 0x9f, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xe1, 0xff, 0x8f, 0xff, 0xe7, 0xff, 0xf3, 0xff, 0x3f, 0x9f, | |||
|     0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xc1, | |||
|     0xff, 0xcf, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0x3f, 0x9f, 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0x81, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xf3, 0xff, | |||
|     0x3f, 0x9f, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, | |||
|     0xff, 0x91, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x3f, 0x9f, 0xff, 0xff, 0xfe, 0x3f, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x11, 0xff, 0x9f, 0xff, 0xff, 0xff, | |||
|     0xf3, 0xff, 0x1f, 0x9f, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xfe, 0x7f, 0xff, 0x21, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xbf, 0x9f, 0xff, 0xff, 0xfe, | |||
|     0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x20, 0xff, 0x9f, 0xff, | |||
|     0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x60, 0x7f, 0x9f, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0x64, 0x3f, | |||
|     0x1f, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xfc, 0xe7, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, | |||
|     0xff, 0x3f, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xfc, | |||
|     0xe7, 0x80, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xf1, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9f, 0xf8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, | |||
|     0xff, 0xff, 0xfe, 0x7f, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0x9f, 0xf9, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xe7, 0xff, 0xfe, 0x7f, 0xff, 0xc3, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xf9, 0xe7, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xf3, 0xf3, 0xff, 0xfc, 0x7f, 0xff, 0x87, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xcf, 0xf9, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf3, 0xff, 0xf8, 0xff, 0xff, | |||
|     0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xf9, 0xe7, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xf3, 0xf9, 0xff, 0xe1, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xfc, 0x3f, 0x07, | |||
|     0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xf3, 0xe7, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xfe, 0x00, 0x1f, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xf3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, | |||
|     0xe0, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, | |||
|     0xf3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xe3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xf7, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xf8, 0x83, 0xe7, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x13, 0xe7, 0xff, 0xfc, 0x03, | |||
|     0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xfc, 0x31, 0xe7, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xfe, | |||
|     0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x39, 0xe3, 0xff, | |||
|     0xfc, 0x00, 0x1f, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x31, 0xf3, 0xff, 0xfc, 0x00, 0x1f, 0xff, 0xc7, 0xff, 0xff, | |||
|     0xff, 0xf8, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x19, | |||
|     0xf3, 0xff, 0xfc, 0x00, 0x07, 0xff, 0x87, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xf3, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x07, | |||
|     0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0x83, 0xf3, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xf3, 0xff, 0xff, 0xff, 0xff, | |||
|     0xf8, 0x07, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xe3, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xfe, 0x1f, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xe1, 0xff, 0xfe, | |||
|     0x01, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xe1, 0xff, 0xf0, 0x00, 0x3f, 0x80, 0x07, 0xff, 0xff, 0xf0, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x4c, | |||
|     0xff, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x0c, 0xff, 0xf0, 0x00, 0x00, 0x0b, 0x87, 0xff, | |||
|     0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0x0e, 0x7f, 0xf8, 0x00, 0x3f, 0xff, 0xc7, 0xff, 0xfe, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x86, 0x7f, 0xfe, 0x00, 0xff, 0xff, | |||
|     0xc3, 0xff, 0xf8, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0x80, 0x7f, 0xff, 0x87, 0xff, 0xff, 0xf3, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, | |||
|     0xff, 0xff, 0xf3, 0xff, 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xfe, 0x07, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, | |||
|     0xff, 0xff, 0xff, 0xff, 0xf3, 0xf0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xff, 0xf3, 0xc0, 0x7f, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xf8, 0x1f, 0xff, 0xff, 0xff, 0xe3, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0xe0, | |||
|     0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xe0, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x03, 0xff, | |||
|     0xfe, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xf0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xa0, 0x17, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | |||
|     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | |||
| }; | |||
| 
 | |||
| #endif /*__IMAGEDATA_H__*/ | |||
| @ -1,217 +0,0 @@ | |||
| #ifndef __MONOCHROME_DISPLAY__ | |||
| #define __MONOCHROME_DISPLAY__ | |||
| 
 | |||
| #include <U8g2lib.h> | |||
| #include <Timezone.h> | |||
| 
 | |||
| #include "../../utils/helper.h" | |||
| #include "../../hm/hmSystem.h" | |||
| 
 | |||
| #define DISP_DEFAULT_TIMEOUT        60  // in seconds
 | |||
| 
 | |||
| 
 | |||
| static uint8_t bmp_logo[] PROGMEM = { | |||
|     B00000000, B00000000, // ................
 | |||
|     B11101100, B00110111, // ..##.######.##..
 | |||
|     B11101100, B00110111, // ..##.######.##..
 | |||
|     B11100000, B00000111, // .....######.....
 | |||
|     B11010000, B00001011, // ....#.####.#....
 | |||
|     B10011000, B00011001, // ...##..##..##...
 | |||
|     B10000000, B00000001, // .......##.......
 | |||
|     B00000000, B00000000, // ................
 | |||
|     B01111000, B00011110, // ...####..####...
 | |||
|     B11111100, B00111111, // ..############..
 | |||
|     B01111100, B00111110, // ..#####..#####..
 | |||
|     B00000000, B00000000, // ................
 | |||
|     B11111100, B00111111, // ..############..
 | |||
|     B11111110, B01111111, // .##############.
 | |||
|     B01111110, B01111110, // .######..######.
 | |||
|     B00000000, B00000000 // ................
 | |||
| }; | |||
| 
 | |||
| 
 | |||
| static uint8_t bmp_arrow[] PROGMEM = { | |||
|     B00000000, B00011100, B00011100, B00001110, B00001110, B11111110, B01111111, | |||
|     B01110000, B01110000, B00110000, B00111000, B00011000, B01111111, B00111111, | |||
|     B00011110, B00001110, B00000110, B00000000, B00000000, B00000000, B00000000 | |||
| }; | |||
| 
 | |||
| 
 | |||
| template<class HMSYSTEM> | |||
| class MonochromeDisplay { | |||
|     public: | |||
|         MonochromeDisplay() {} | |||
| 
 | |||
|         void setup(display_t *cfg, HMSYSTEM *sys, uint32_t *utcTs, uint8_t disp_reset, const char *version) { | |||
|             mCfg   = cfg; | |||
|             mSys   = sys; | |||
|             mUtcTs = utcTs; | |||
|             mNewPayload = false; | |||
|             mLoopCnt = 0; | |||
|             mTimeout = DISP_DEFAULT_TIMEOUT; // power off timeout (after inverters go offline)
 | |||
| 
 | |||
|             u8g2_cb_t *rot = (u8g2_cb_t *)((mCfg->rot180) ? U8G2_R2 : U8G2_R0); | |||
| 
 | |||
|             if(mCfg->type) { | |||
|                 switch(mCfg->type) { | |||
|                     case 1: | |||
|                         mDisplay = new U8G2_PCD8544_84X48_F_4W_HW_SPI(rot, mCfg->pin0, mCfg->pin1, disp_reset); | |||
|                         break; | |||
|                     case 2: | |||
|                         mDisplay = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(rot, disp_reset, mCfg->pin0, mCfg->pin1); | |||
|                         break; | |||
|                     case 3: | |||
|                         mDisplay = new U8G2_SH1106_128X64_NONAME_F_HW_I2C(rot, disp_reset, mCfg->pin0, mCfg->pin1); | |||
|                         break; | |||
|                 } | |||
|                 mDisplay->begin(); | |||
| 
 | |||
|                 mIsLarge = ((mDisplay->getWidth() > 120) && (mDisplay->getHeight() > 60)); | |||
|                 calcLineHeights(); | |||
| 
 | |||
|                 mDisplay->clearBuffer(); | |||
|                 mDisplay->setContrast(mCfg->contrast); | |||
|                 printText("Ahoy!", 0, 35); | |||
|                 printText("ahoydtu.de", 2, 20); | |||
|                 printText(version, 3, 46); | |||
|                 mDisplay->sendBuffer(); | |||
|             } | |||
|         } | |||
| 
 | |||
|         void payloadEventListener(uint8_t cmd) { | |||
|             mNewPayload = true; | |||
|         } | |||
| 
 | |||
|         void tickerSecond() { | |||
|             if(mCfg->pwrSaveAtIvOffline) { | |||
|                 if(mTimeout != 0) | |||
|                     mTimeout--; | |||
|             } | |||
|             if(mNewPayload || ((++mLoopCnt % 10) == 0)) { | |||
|                 mNewPayload = false; | |||
|                 mLoopCnt = 0; | |||
|                 DataScreen(); | |||
|             } | |||
|         } | |||
| 
 | |||
|     private: | |||
|         void DataScreen() { | |||
|             if (mCfg->type == 0) | |||
|                 return; | |||
|             if(*mUtcTs == 0) | |||
|                 return; | |||
| 
 | |||
|             float totalPower = 0; | |||
|             float totalYieldDay = 0; | |||
|             float totalYieldTotal = 0; | |||
| 
 | |||
|             bool isprod = false; | |||
| 
 | |||
|             Inverter<> *iv; | |||
|             record_t<> *rec; | |||
|             for (uint8_t i = 0; i < mSys->getNumInverters(); i++) { | |||
|                 iv = mSys->getInverterByPos(i); | |||
|                 rec = iv->getRecordStruct(RealTimeRunData_Debug); | |||
|                 if (iv == NULL) | |||
|                     continue; | |||
| 
 | |||
|                 if (iv->isProducing(*mUtcTs)) | |||
|                     isprod = true; | |||
| 
 | |||
|                 totalPower += iv->getChannelFieldValue(CH0, FLD_PAC, rec); | |||
|                 totalYieldDay += iv->getChannelFieldValue(CH0, FLD_YD, rec); | |||
|                 totalYieldTotal += iv->getChannelFieldValue(CH0, FLD_YT, rec); | |||
|             } | |||
| 
 | |||
|             mDisplay->clearBuffer(); | |||
| 
 | |||
|             // Logos
 | |||
|             //   pxMovement +x (0 - 6 px)
 | |||
|             uint8_t ex = (_mExtra % 7); | |||
|             if (isprod) { | |||
|                 mDisplay->drawXBMP(5 + ex, 1, 8, 17, bmp_arrow); | |||
|                 if (mCfg->logoEn) | |||
|                     mDisplay->drawXBMP(mDisplay->getWidth() - 24 + ex, 2, 16, 16, bmp_logo); | |||
|             } | |||
| 
 | |||
|             if ((totalPower > 0) && isprod) { | |||
|                 mTimeout = DISP_DEFAULT_TIMEOUT; | |||
|                 mDisplay->setPowerSave(false); | |||
|                 mDisplay->setContrast(mCfg->contrast); | |||
|                 if (totalPower > 999) | |||
|                     snprintf(_fmtText, sizeof(_fmtText), "%2.1f kW", (totalPower / 1000)); | |||
|                 else | |||
|                     snprintf(_fmtText, sizeof(_fmtText), "%3.0f W", totalPower); | |||
|                 printText(_fmtText, 0, 20); | |||
|             } else { | |||
|                 printText("offline", 0, 25); | |||
|                 if(mCfg->pwrSaveAtIvOffline) { | |||
|                     if(mTimeout == 0) | |||
|                         mDisplay->setPowerSave(true); | |||
|                 } | |||
|             } | |||
| 
 | |||
|             snprintf(_fmtText, sizeof(_fmtText), "today: %4.0f Wh", totalYieldDay); | |||
|             printText(_fmtText, 1); | |||
| 
 | |||
|             snprintf(_fmtText, sizeof(_fmtText), "total: %.1f kWh", totalYieldTotal); | |||
|             printText(_fmtText, 2); | |||
| 
 | |||
|             IPAddress ip = WiFi.localIP(); | |||
|             if (!(_mExtra % 10) && (ip)) { | |||
|                 printText(ip.toString().c_str(), 3); | |||
|             } else { | |||
|                 // Get current time
 | |||
|                 if(mIsLarge) | |||
|                     printText(ah::getDateTimeStr(gTimezone.toLocal(*mUtcTs)).c_str(), 3); | |||
|                 else | |||
|                     printText(ah::getTimeStr(gTimezone.toLocal(*mUtcTs)).c_str(), 3); | |||
|             } | |||
|             mDisplay->sendBuffer(); | |||
| 
 | |||
|             _mExtra++; | |||
|         } | |||
| 
 | |||
|         void calcLineHeights() { | |||
|             uint8_t yOff = 0; | |||
|             for(uint8_t i = 0; i < 4; i++) { | |||
|                 setFont(i); | |||
|                 yOff += (mDisplay->getMaxCharHeight() + 1); | |||
|                 mLineOffsets[i] = yOff; | |||
|             } | |||
|         } | |||
| 
 | |||
|         inline void setFont(uint8_t line) { | |||
|             switch (line) { | |||
|                 case 0:  mDisplay->setFont((mIsLarge) ? u8g2_font_ncenB14_tr : u8g2_font_lubBI14_tr); break; | |||
|                 case 3:  mDisplay->setFont(u8g2_font_5x8_tr); break; | |||
|                 default: mDisplay->setFont((mIsLarge) ? u8g2_font_ncenB10_tr : u8g2_font_5x8_tr); break; | |||
|             } | |||
|         } | |||
| 
 | |||
|         void printText(const char* text, uint8_t line, uint8_t dispX = 5) { | |||
|             if(!mIsLarge) | |||
|                 dispX = (line == 0) ? 10 : 5; | |||
|             setFont(line); | |||
|             if(mCfg->pxShift) | |||
|                 dispX += (_mExtra % 7); // add pixel movement
 | |||
|             mDisplay->drawStr(dispX, mLineOffsets[line], text); | |||
|         } | |||
| 
 | |||
|         // private member variables
 | |||
|         U8G2* mDisplay; | |||
| 
 | |||
|         uint8_t _mExtra; | |||
|         uint16_t mTimeout; // interval at which to power save (milliseconds)
 | |||
|         char _fmtText[32]; | |||
| 
 | |||
|         bool mNewPayload; | |||
|         bool mIsLarge; | |||
|         uint8_t mLoopCnt; | |||
|         uint32_t *mUtcTs; | |||
|         uint8_t mLineOffsets[5]; | |||
|         display_t *mCfg; | |||
|         HMSYSTEM *mSys; | |||
| }; | |||
| 
 | |||
| #endif /*__MONOCHROME_DISPLAY__*/ | |||
					Loading…
					
					
				
		Reference in new issue