Browse Source

refactor display class

Display class gets access to App interface and HmRadio
Display class prepares relevant online information for displays in new DisplayData structure
Displays get pointer to DisplayData and only use information received from there
pull/1136/head
Wusaweki 1 year ago
parent
commit
f1bff0b824
  1. 2
      src/app.cpp
  2. 4
      src/app.h
  3. 4
      src/hm/hmRadio.h
  4. 10
      src/hm/miPayload.h
  5. 38
      src/plugins/Display/Display.h
  6. 30
      src/plugins/Display/Display_Mono.h
  7. 57
      src/plugins/Display/Display_Mono_128X32.h
  8. 61
      src/plugins/Display/Display_Mono_128X64.h
  9. 57
      src/plugins/Display/Display_Mono_64X48.h
  10. 67
      src/plugins/Display/Display_Mono_84X48.h
  11. 20
      src/plugins/Display/Display_data.h
  12. 8
      src/plugins/Display/Display_ePaper.cpp
  13. 4
      src/plugins/Display/Display_ePaper.h

2
src/app.cpp

@ -115,7 +115,7 @@ void app::setup() {
// Plugins // Plugins
if (mConfig->plugin.display.type != 0) if (mConfig->plugin.display.type != 0)
mDisplay.setup(&mConfig->plugin.display, &mSys, &mTimestamp, mVersion); mDisplay.setup(this, &mConfig->plugin.display, &mSys, &mNrfRadio, &mTimestamp);
mPubSerial.setup(mConfig, &mSys, &mTimestamp); mPubSerial.setup(mConfig, &mSys, &mTimestamp);

4
src/app.h

@ -55,7 +55,8 @@ typedef PubSerial<HmSystemType> PubSerialType;
// PLUGINS // PLUGINS
#include "plugins/Display/Display.h" #include "plugins/Display/Display.h"
typedef Display<HmSystemType> DisplayType; #include "plugins/Display/Display_data.h"
typedef Display<HmSystemType, HmRadio<>> DisplayType;
class app : public IApp, public ah::Scheduler { class app : public IApp, public ah::Scheduler {
public: public:
@ -362,6 +363,7 @@ class app : public IApp, public ah::Scheduler {
// plugins // plugins
DisplayType mDisplay; DisplayType mDisplay;
DisplayData mDispData;
}; };
#endif /*__APP_H__*/ #endif /*__APP_H__*/

4
src/hm/hmRadio.h

@ -272,8 +272,8 @@ class HmRadio {
isLastPackage = true; // response from dev control command isLastPackage = true; // response from dev control command
} }
} }
yield(); yield();
} }
return isLastPackage; return isLastPackage;
} }

10
src/hm/miPayload.h

@ -96,16 +96,16 @@ class MiPayload {
} else { } else {
mStat->rxFail++; // got "fragments" (part of the required messages) mStat->rxFail++; // got "fragments" (part of the required messages)
// but no complete set of responses // but no complete set of responses
if (mSerialDebug) { if (mSerialDebug) {
DBGPRINT(F("no complete Payload received! (retransmits: ")); DBGPRINT(F("no complete Payload received! (retransmits: "));
DBGPRINT(String(mPayload[iv->id].retransmits)); DBGPRINT(String(mPayload[iv->id].retransmits));
DBGPRINTLN(F(")")); DBGPRINTLN(F(")"));
}
} }
}
iv->setQueuedCmdFinished(); // command failed iv->setQueuedCmdFinished(); // command failed
}
} }
} }
}
reset(iv->id); reset(iv->id);
mPayload[iv->id].requested = true; mPayload[iv->id].requested = true;

38
src/plugins/Display/Display.h

@ -5,6 +5,7 @@
#include <U8g2lib.h> #include <U8g2lib.h>
#include "../../hm/hmSystem.h" #include "../../hm/hmSystem.h"
#include "../../hm/hmRadio.h"
#include "../../utils/helper.h" #include "../../utils/helper.h"
#include "Display_Mono.h" #include "Display_Mono.h"
#include "Display_Mono_128X32.h" #include "Display_Mono_128X32.h"
@ -12,21 +13,25 @@
#include "Display_Mono_84X48.h" #include "Display_Mono_84X48.h"
#include "Display_Mono_64X48.h" #include "Display_Mono_64X48.h"
#include "Display_ePaper.h" #include "Display_ePaper.h"
#include "Display_data.h"
template <class HMSYSTEM> template <class HMSYSTEM, class HMRADIO>
class Display { class Display {
public: public:
Display() { Display() {
mMono = NULL; mMono = NULL;
} }
void setup(display_t *cfg, HMSYSTEM *sys, uint32_t *utcTs, const char *version) { void setup(IApp *app, display_t *cfg, HMSYSTEM *sys, HMRADIO *radio, uint32_t *utcTs) {
mApp = app;
mHmRadio = radio;
mCfg = cfg; mCfg = cfg;
mSys = sys; mSys = sys;
mUtcTs = utcTs; mUtcTs = utcTs;
mNewPayload = false; mNewPayload = false;
mLoopCnt = 0; mLoopCnt = 0;
mVersion = version;
mDisplayData.version = app->getVersion(); // version never changes, so only set once
switch (mCfg->type) { switch (mCfg->type) {
case 0: mMono = NULL; break; case 0: mMono = NULL; break;
@ -41,7 +46,7 @@ class Display {
mMono = NULL; // ePaper does not use this mMono = NULL; // ePaper does not use this
mRefreshCycle = 0; mRefreshCycle = 0;
mEpaper.config(mCfg->rot, mCfg->pwrSaveAtIvOffline); mEpaper.config(mCfg->rot, mCfg->pwrSaveAtIvOffline);
mEpaper.init(mCfg->type, mCfg->disp_cs, mCfg->disp_dc, mCfg->disp_reset, mCfg->disp_busy, mCfg->disp_clk, mCfg->disp_data, mUtcTs, mVersion); mEpaper.init(mCfg->type, mCfg->disp_cs, mCfg->disp_dc, mCfg->disp_reset, mCfg->disp_busy, mCfg->disp_clk, mCfg->disp_data, mUtcTs, mDisplayData.version);
break; break;
#endif #endif
@ -49,7 +54,7 @@ class Display {
} }
if(mMono) { if(mMono) {
mMono->config(mCfg->pwrSaveAtIvOffline, mCfg->pxShift, mCfg->contrast); mMono->config(mCfg->pwrSaveAtIvOffline, mCfg->pxShift, mCfg->contrast);
mMono->init(mCfg->type, mCfg->rot, mCfg->disp_cs, mCfg->disp_dc, 0xff, mCfg->disp_clk, mCfg->disp_data, mUtcTs, mVersion); mMono->init(mCfg->type, mCfg->rot, mCfg->disp_cs, mCfg->disp_dc, 0xff, mCfg->disp_clk, mCfg->disp_data, &mDisplayData);
} }
} }
@ -75,8 +80,6 @@ class Display {
void DataScreen() { void DataScreen() {
if (mCfg->type == 0) if (mCfg->type == 0)
return; return;
if (*mUtcTs == 0)
return;
float totalPower = 0; float totalPower = 0;
float totalYieldDay = 0; float totalYieldDay = 0;
@ -100,8 +103,23 @@ class Display {
totalYieldTotal += iv->getChannelFieldValue(CH0, FLD_YT, rec); totalYieldTotal += iv->getChannelFieldValue(CH0, FLD_YT, rec);
} }
// prepare display data
mDisplayData.isProducing = isprod;
mDisplayData.totalPower = totalPower;
mDisplayData.totalYieldDay = totalYieldDay;
mDisplayData.totalYieldTotal = totalYieldTotal;
mDisplayData.RadioSymbol = mHmRadio->isChipConnected();
mDisplayData.wifiRSSI = (WiFi.status() == WL_CONNECTED) ? WiFi.RSSI() : SCHAR_MIN;
mDisplayData.WiFiSymbol = (WiFi.status() == WL_CONNECTED);
mDisplayData.ipAddress = WiFi.localIP();
time_t utc= mApp->getTimestamp();
if (year(utc) > 2020)
mDisplayData.utcTs = utc;
else
mDisplayData.utcTs = 0;
if (mMono ) { if (mMono ) {
mMono->disp(totalPower, totalYieldDay, totalYieldTotal, isprod); mMono->disp();
} }
#if defined(ESP32) #if defined(ESP32)
else if (mCfg->type == 10) { else if (mCfg->type == 10) {
@ -117,12 +135,14 @@ class Display {
} }
// private member variables // private member variables
IApp *mApp;
DisplayData mDisplayData;
bool mNewPayload; bool mNewPayload;
uint8_t mLoopCnt; uint8_t mLoopCnt;
uint32_t *mUtcTs; uint32_t *mUtcTs;
const char *mVersion;
display_t *mCfg; display_t *mCfg;
HMSYSTEM *mSys; HMSYSTEM *mSys;
HMRADIO *mHmRadio;
uint16_t mRefreshCycle; uint16_t mRefreshCycle;
#if defined(ESP32) #if defined(ESP32)

30
src/plugins/Display/Display_Mono.h

@ -9,6 +9,7 @@
#define DISP_FMT_TEXT_LEN 32 #define DISP_FMT_TEXT_LEN 32
#define BOTTOM_MARGIN 5 #define BOTTOM_MARGIN 5
#include "defines.h"
#ifdef ESP8266 #ifdef ESP8266
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
@ -16,25 +17,29 @@
#include <WiFi.h> #include <WiFi.h>
#endif #endif
#include "../../utils/helper.h" #include "../../utils/helper.h"
#include "Display_data.h"
class DisplayMono { class DisplayMono {
public: public:
DisplayMono() {}; DisplayMono() {};
virtual 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) = 0; virtual void init(uint8_t type, uint8_t rot, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, DisplayData *displayData) = 0;
virtual void config(bool enPowerSafe, bool enScreenSaver, uint8_t lum) = 0; virtual void config(bool enPowerSave, bool enScreenSaver, uint8_t lum) = 0;
virtual void loop(uint8_t lum) = 0; virtual void loop(uint8_t lum) = 0;
virtual void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) = 0; virtual void disp(void) = 0;
protected: protected:
U8G2* mDisplay; U8G2* mDisplay;
DisplayData *mDisplayData;
uint8_t mType; uint8_t mType;
bool mEnPowerSafe, mEnScreenSaver; uint16_t mDispWidth;
uint16_t mDispHeight;
bool mEnPowerSave, mEnScreenSaver;
uint8_t mLuminance; uint8_t mLuminance;
uint8_t mLoopCnt; uint8_t mLoopCnt;
uint32_t* mUtcTs;
uint8_t mLineXOffsets[5] = {}; uint8_t mLineXOffsets[5] = {};
uint8_t mLineYOffsets[5] = {}; uint8_t mLineYOffsets[5] = {};
@ -42,4 +47,17 @@ class DisplayMono {
uint8_t mExtra; uint8_t mExtra;
uint16_t mTimeout; uint16_t mTimeout;
char mFmtText[DISP_FMT_TEXT_LEN];}; char mFmtText[DISP_FMT_TEXT_LEN];
// Common initialization function to be called by subclasses
void monoInit(U8G2* display, uint8_t type, DisplayData *displayData) {
mDisplay = display;
mType = type;
mDisplayData = displayData;
mDisplay->begin();
mDisplay->setContrast(mLuminance);
mDisplay->clearBuffer();
mDispWidth = mDisplay->getDisplayWidth();
mDispHeight = mDisplay->getDisplayHeight();
}
};

57
src/plugins/Display/Display_Mono_128X32.h

@ -9,45 +9,32 @@
class DisplayMono128X32 : public DisplayMono { class DisplayMono128X32 : public DisplayMono {
public: public:
DisplayMono128X32() : DisplayMono() { DisplayMono128X32() : DisplayMono() {
mEnPowerSafe = true; mEnPowerSave = true;
mEnScreenSaver = true; mEnScreenSaver = true;
mLuminance = 60; mLuminance = 60;
mExtra = 0; mExtra = 0;
mDispY = 0; mDispY = 0;
mTimeout = DISP_DEFAULT_TIMEOUT; // interval at which to power save (milliseconds) mTimeout = DISP_DEFAULT_TIMEOUT; // interval at which to power save (milliseconds)
mUtcTs = NULL;
mType = 0;
} }
void config(bool enPowerSave, bool enScreenSaver, uint8_t lum) {
mEnPowerSave = enPowerSave;
mEnScreenSaver = enScreenSaver;
mLuminance = lum;
}
void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, uint32_t *utcTs, const char *version) { void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, DisplayData *displayData) {
u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0); u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0);
mType = type; monoInit(new U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C(rot, reset, clock, data), type, displayData);
mDisplay = new U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C(rot, reset, clock, data);
mUtcTs = utcTs;
mDisplay->begin();
calcLinePositions(); calcLinePositions();
printText("Ahoy!", 0);
mDisplay->clearBuffer();
mDisplay->setContrast(mLuminance);
printText("AHOY!", 0);
printText("ahoydtu.de", 2); printText("ahoydtu.de", 2);
printText(version, 3); printText(mDisplayData->version, 3);
mDisplay->sendBuffer(); mDisplay->sendBuffer();
} }
void config(bool enPowerSafe, bool enScreenSaver, uint8_t lum) {
mEnPowerSafe = enPowerSafe;
mEnScreenSaver = enScreenSaver;
mLuminance = lum;
}
void loop(uint8_t lum) { void loop(uint8_t lum) {
if (mEnPowerSafe) { if (mEnPowerSave) {
if (mTimeout != 0) if (mTimeout != 0)
mTimeout--; mTimeout--;
} }
@ -58,43 +45,43 @@ class DisplayMono128X32 : public DisplayMono {
} }
} }
void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { void disp(void) {
mDisplay->clearBuffer(); mDisplay->clearBuffer();
// set Contrast of the Display to raise the lifetime // set Contrast of the Display to raise the lifetime
if (3 != mType) if (3 != mType)
mDisplay->setContrast(mLuminance); mDisplay->setContrast(mLuminance);
if ((totalPower > 0) && (isprod > 0)) { if ((mDisplayData->totalPower > 0) && (mDisplayData->isProducing > 0)) {
mTimeout = DISP_DEFAULT_TIMEOUT; mTimeout = DISP_DEFAULT_TIMEOUT;
mDisplay->setPowerSave(false); mDisplay->setPowerSave(false);
if (totalPower > 999) if (mDisplayData->totalPower > 999)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%2.2f kW", (totalPower / 1000)); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%2.2f kW", (mDisplayData->totalPower / 1000));
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%3.0f W", totalPower); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%3.0f W", mDisplayData->totalPower);
printText(mFmtText, 0); printText(mFmtText, 0);
} else { } else {
printText("offline", 0); printText("offline", 0);
// check if it's time to enter power saving mode // check if it's time to enter power saving mode
if (mTimeout == 0) if (mTimeout == 0)
mDisplay->setPowerSave(mEnPowerSafe); mDisplay->setPowerSave(mEnPowerSave);
} }
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "today: %4.0f Wh", totalYieldDay); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "today: %4.0f Wh", mDisplayData->totalYieldDay);
printText(mFmtText, 1); printText(mFmtText, 1);
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "total: %.1f kWh", totalYieldTotal); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "total: %.1f kWh", mDisplayData->totalYieldTotal);
printText(mFmtText, 2); printText(mFmtText, 2);
IPAddress ip = WiFi.localIP(); IPAddress ip = WiFi.localIP();
if (!(mExtra % 10) && (ip)) if (!(mExtra % 10) && (ip))
printText(ip.toString().c_str(), 3); printText(ip.toString().c_str(), 3);
else if (!(mExtra % 5)) { else if (!(mExtra % 5)) {
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%d Inverter on", isprod); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%d Inverter on", mDisplayData->isProducing);
printText(mFmtText, 3); printText(mFmtText, 3);
} else if (NULL != mUtcTs) } else if (0 != mDisplayData->utcTs)
printText(ah::getTimeStr(gTimezone.toLocal(*mUtcTs)).c_str(), 3); printText(ah::getTimeStr(gTimezone.toLocal(mDisplayData->utcTs)).c_str(), 3);
mDisplay->sendBuffer(); mDisplay->sendBuffer();

61
src/plugins/Display/Display_Mono_128X64.h

@ -9,53 +9,42 @@
class DisplayMono128X64 : public DisplayMono { class DisplayMono128X64 : public DisplayMono {
public: public:
DisplayMono128X64() : DisplayMono() { DisplayMono128X64() : DisplayMono() {
mEnPowerSafe = true; mEnPowerSave = true;
mEnScreenSaver = true; mEnScreenSaver = true;
mLuminance = 60; mLuminance = 60;
mDispY = 0; mDispY = 0;
mTimeout = DISP_DEFAULT_TIMEOUT; // interval at which to power save (milliseconds) mTimeout = DISP_DEFAULT_TIMEOUT; // interval at which to power save (milliseconds)
mUtcTs = NULL;
mType = 0;
} }
void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, uint32_t *utcTs, const char *version) { void config(bool enPowerSave, bool enScreenSaver, uint8_t lum) {
mEnPowerSave = enPowerSave;
mEnScreenSaver = enScreenSaver;
mLuminance = lum;
}
void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, DisplayData *displayData) {
u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0); u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0);
mType = type;
switch (type) { switch (type) {
case 1: case 1:
mDisplay = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(rot, reset, clock, data); monoInit(new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(rot, reset, clock, data), type, displayData);
break; break;
case 2: case 2:
mDisplay = new U8G2_SH1106_128X64_NONAME_F_HW_I2C(rot, reset, clock, data); monoInit(new U8G2_SH1106_128X64_NONAME_F_HW_I2C(rot, reset, clock, data), type, displayData);
break; break;
case 6: case 6:
mDisplay = new U8G2_SSD1309_128X64_NONAME0_F_HW_I2C(rot, reset, clock, data); default:
monoInit(new U8G2_SSD1309_128X64_NONAME0_F_HW_I2C(rot, reset, clock, data), type, displayData);
break; break;
} }
mUtcTs = utcTs;
mDisplay->begin();
calcLinePositions(); calcLinePositions();
printText("Ahoy!", 0, 35);
mDisplay->clearBuffer();
mDisplay->setContrast(mLuminance);
printText("AHOY!", 0, 35);
printText("ahoydtu.de", 2, 20); printText("ahoydtu.de", 2, 20);
printText(version, 3, 46); printText(mDisplayData->version, 3, 46);
mDisplay->sendBuffer(); mDisplay->sendBuffer();
} }
void config(bool enPowerSafe, bool enScreenSaver, uint8_t lum) {
mEnPowerSafe = enPowerSafe;
mEnScreenSaver = enScreenSaver;
mLuminance = lum;
}
void loop(uint8_t lum) { void loop(uint8_t lum) {
if (mEnPowerSafe) { if (mEnPowerSave) {
if (mTimeout != 0) if (mTimeout != 0)
mTimeout--; mTimeout--;
} }
@ -66,43 +55,43 @@ class DisplayMono128X64 : public DisplayMono {
} }
} }
void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { void disp(void) {
mDisplay->clearBuffer(); mDisplay->clearBuffer();
// set Contrast of the Display to raise the lifetime // set Contrast of the Display to raise the lifetime
mDisplay->setContrast(mLuminance); mDisplay->setContrast(mLuminance);
if ((totalPower > 0) && (isprod > 0)) { if ((mDisplayData->totalPower > 0) && (mDisplayData->isProducing > 0)) {
mTimeout = DISP_DEFAULT_TIMEOUT; mTimeout = DISP_DEFAULT_TIMEOUT;
mDisplay->setPowerSave(false); mDisplay->setPowerSave(false);
if (totalPower > 999) if (mDisplayData->totalPower > 999)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%2.2f kW", (totalPower / 1000)); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%2.2f kW", (mDisplayData->totalPower / 1000));
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%3.0f W", totalPower); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%3.0f W", mDisplayData->totalPower);
printText(mFmtText, 0); printText(mFmtText, 0);
} else { } else {
printText("offline", 0, 25); printText("offline", 0, 25);
// check if it's time to enter power saving mode // check if it's time to enter power saving mode
if (mTimeout == 0) if (mTimeout == 0)
mDisplay->setPowerSave(mEnPowerSafe); mDisplay->setPowerSave(mEnPowerSave);
} }
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "today: %4.0f Wh", totalYieldDay); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "today: %4.0f Wh", mDisplayData->totalYieldDay);
printText(mFmtText, 1); printText(mFmtText, 1);
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "total: %.1f kWh", totalYieldTotal); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "total: %.1f kWh", mDisplayData->totalYieldTotal);
printText(mFmtText, 2); printText(mFmtText, 2);
IPAddress ip = WiFi.localIP(); IPAddress ip = WiFi.localIP();
if (!(mExtra % 10) && (ip)) if (!(mExtra % 10) && (ip))
printText(ip.toString().c_str(), 3); printText(ip.toString().c_str(), 3);
else if (!(mExtra % 5)) { else if (!(mExtra % 5)) {
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%d Inverter on", isprod); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%d Inverter on", mDisplayData->isProducing);
printText(mFmtText, 3); printText(mFmtText, 3);
} else if (NULL != mUtcTs) } else if (0 != mDisplayData->utcTs)
printText(ah::getDateTimeStr(gTimezone.toLocal(*mUtcTs)).c_str(), 3); printText(ah::getDateTimeStr(gTimezone.toLocal(mDisplayData->utcTs)).c_str(), 3);
mDisplay->sendBuffer(); mDisplay->sendBuffer();

57
src/plugins/Display/Display_Mono_64X48.h

@ -9,46 +9,33 @@
class DisplayMono64X48 : public DisplayMono { class DisplayMono64X48 : public DisplayMono {
public: public:
DisplayMono64X48() : DisplayMono() { DisplayMono64X48() : DisplayMono() {
mEnPowerSafe = true; mEnPowerSave = true;
mEnScreenSaver = false; mEnScreenSaver = false;
mLuminance = 20; mLuminance = 20;
mExtra = 0; mExtra = 0;
mDispY = 0; mDispY = 0;
mTimeout = DISP_DEFAULT_TIMEOUT; // interval at which to power save (milliseconds) mTimeout = DISP_DEFAULT_TIMEOUT; // interval at which to power save (milliseconds)
mUtcTs = NULL;
mType = 0;
} }
void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, uint32_t *utcTs, const char *version) { void config(bool enPowerSave, bool enScreenSaver, uint8_t lum) {
mEnPowerSave = enPowerSave;
mEnScreenSaver = enScreenSaver;
mLuminance = lum;
}
void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, DisplayData *displayData) {
u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0); u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0);
mType = type;
// Wemos OLed Shield is not defined in u8 lib -> use nearest compatible // Wemos OLed Shield is not defined in u8 lib -> use nearest compatible
mDisplay = new U8G2_SSD1306_64X48_ER_F_HW_I2C(rot, reset, clock, data); monoInit(new U8G2_SSD1306_64X48_ER_F_HW_I2C(rot, reset, clock, data), type, displayData);
mUtcTs = utcTs;
mDisplay->begin();
calcLinePositions(); calcLinePositions();
printText("Ahoy!", 0);
mDisplay->clearBuffer();
mDisplay->setContrast(mLuminance);
printText("AHOY!", 0);
printText("ahoydtu.de", 1); printText("ahoydtu.de", 1);
printText(version, 2); printText(mDisplayData->version, 2);
mDisplay->sendBuffer(); mDisplay->sendBuffer();
} }
void config(bool enPowerSafe, bool enScreenSaver, uint8_t lum) {
mEnPowerSafe = enPowerSafe;
mEnScreenSaver = enScreenSaver;
mLuminance = lum;
}
void loop(uint8_t lum) { void loop(uint8_t lum) {
if (mEnPowerSafe) { if (mEnPowerSave) {
if (mTimeout != 0) if (mTimeout != 0)
mTimeout--; mTimeout--;
} }
@ -59,43 +46,43 @@ class DisplayMono64X48 : public DisplayMono {
} }
} }
void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { void disp(void) {
mDisplay->clearBuffer(); mDisplay->clearBuffer();
// set Contrast of the Display to raise the lifetime // set Contrast of the Display to raise the lifetime
mDisplay->setContrast(mLuminance); mDisplay->setContrast(mLuminance);
if ((totalPower > 0) && (isprod > 0)) { if ((mDisplayData->totalPower > 0) && (mDisplayData->isProducing > 0)) {
mTimeout = DISP_DEFAULT_TIMEOUT; mTimeout = DISP_DEFAULT_TIMEOUT;
mDisplay->setPowerSave(false); mDisplay->setPowerSave(false);
if (totalPower > 999) if (mDisplayData->totalPower > 999)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%2.2f kW", (totalPower / 1000)); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%2.2f kW", (mDisplayData->totalPower / 1000));
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%3.0f W", totalPower); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%3.0f W", mDisplayData->totalPower);
printText(mFmtText, 0); printText(mFmtText, 0);
} else { } else {
printText("offline", 0); printText("offline", 0);
// check if it's time to enter power saving mode // check if it's time to enter power saving mode
if (mTimeout == 0) if (mTimeout == 0)
mDisplay->setPowerSave(mEnPowerSafe); mDisplay->setPowerSave(mEnPowerSave);
} }
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "D: %4.0f Wh", totalYieldDay); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "D: %4.0f Wh", mDisplayData->totalYieldDay);
printText(mFmtText, 1); printText(mFmtText, 1);
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "T: %4.0f kWh", totalYieldTotal); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "T: %4.0f kWh", mDisplayData->totalYieldTotal);
printText(mFmtText, 2); printText(mFmtText, 2);
IPAddress ip = WiFi.localIP(); IPAddress ip = WiFi.localIP();
if (!(mExtra % 10) && (ip)) if (!(mExtra % 10) && (ip))
printText(ip.toString().c_str(), 3); printText(ip.toString().c_str(), 3);
else if (!(mExtra % 5)) { else if (!(mExtra % 5)) {
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "active Inv: %d", isprod); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "active Inv: %d", mDisplayData->isProducing);
printText(mFmtText, 3); printText(mFmtText, 3);
} else if (NULL != mUtcTs) } else if (0 != mDisplayData->utcTs)
printText(ah::getTimeStr(gTimezone.toLocal(*mUtcTs)).c_str(), 3); printText(ah::getTimeStr(gTimezone.toLocal(mDisplayData->utcTs)).c_str(), 3);
mDisplay->sendBuffer(); mDisplay->sendBuffer();

67
src/plugins/Display/Display_Mono_84X48.h

@ -9,46 +9,32 @@
class DisplayMono84X48 : public DisplayMono { class DisplayMono84X48 : public DisplayMono {
public: public:
DisplayMono84X48() : DisplayMono() { DisplayMono84X48() : DisplayMono() {
mEnPowerSafe = true; mEnPowerSave = true;
mEnScreenSaver = true; mEnScreenSaver = true;
mLuminance = 60; mLuminance = 140;
mExtra = 0; mExtra = 0;
mDispY = 0; mDispY = 0;
mTimeout = DISP_DEFAULT_TIMEOUT; // interval at which to power save (milliseconds) mTimeout = DISP_DEFAULT_TIMEOUT; // interval at which to power save (milliseconds)
mUtcTs = NULL;
mType = 0;
mDispWidth = 0;
} }
void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, uint32_t *utcTs, const char *version) { void config(bool enPowerSave, bool enScreenSaver, uint8_t lum) {
mEnPowerSave = enPowerSave;
mEnScreenSaver = enScreenSaver;
mLuminance = lum;
}
void init(uint8_t type, uint8_t rotation, uint8_t cs, uint8_t dc, uint8_t reset, uint8_t clock, uint8_t data, DisplayData *displayData) {
u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0); u8g2_cb_t *rot = (u8g2_cb_t *)((rotation != 0x00) ? U8G2_R2 : U8G2_R0);
mType = type; monoInit(new U8G2_PCD8544_84X48_F_4W_SW_SPI(rot, clock, data, cs, dc, reset), type, displayData);
mDisplay = new U8G2_PCD8544_84X48_F_4W_SW_SPI(rot, clock, data, cs, dc, reset);
mUtcTs = utcTs;
mDisplay->begin();
mDispWidth = mDisplay->getDisplayWidth();
calcLinePositions(); calcLinePositions();
printText("Ahoy!", l_Ahoy);
mDisplay->clearBuffer();
mDisplay->setContrast(mLuminance);
printText("AHOY!", l_Ahoy);
printText("ahoydtu.de", l_Website); printText("ahoydtu.de", l_Website);
printText(version, l_Version); printText(mDisplayData->version, l_Version);
mDisplay->sendBuffer(); mDisplay->sendBuffer();
} }
void config(bool enPowerSafe, bool enScreenSaver, uint8_t lum) {
mEnPowerSafe = enPowerSafe;
mEnScreenSaver = enScreenSaver;
mLuminance = lum;
}
void loop(uint8_t lum) { void loop(uint8_t lum) {
if (mEnPowerSafe) { if (mEnPowerSave) {
if (mTimeout != 0) if (mTimeout != 0)
mTimeout--; mTimeout--;
} }
@ -59,43 +45,43 @@ class DisplayMono84X48 : public DisplayMono {
} }
} }
void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { void disp(void) {
mDisplay->clearBuffer(); mDisplay->clearBuffer();
// set Contrast of the Display to raise the lifetime // set Contrast of the Display to raise the lifetime
mDisplay->setContrast(mLuminance); mDisplay->setContrast(mLuminance);
if ((totalPower > 0) && (isprod > 0)) { if ((mDisplayData->totalPower > 0) && (mDisplayData->isProducing > 0)) {
mTimeout = DISP_DEFAULT_TIMEOUT; mTimeout = DISP_DEFAULT_TIMEOUT;
mDisplay->setPowerSave(false); mDisplay->setPowerSave(false);
if (totalPower > 999) if (mDisplayData->totalPower > 999)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f kW", (totalPower / 1000)); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f kW", (mDisplayData->totalPower / 1000));
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f W", totalPower); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f W", mDisplayData->totalPower);
printText(mFmtText, l_TotalPower); printText(mFmtText, l_TotalPower);
} else { } else {
printText("offline", l_TotalPower); printText("offline", l_TotalPower);
// check if it's time to enter power saving mode // check if it's time to enter power saving mode
if (mTimeout == 0) if (mTimeout == 0)
mDisplay->setPowerSave(mEnPowerSafe); mDisplay->setPowerSave(mEnPowerSave);
} }
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "Today: %4.0f Wh", totalYieldDay);
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "Today: %.0f Wh", mDisplayData->totalYieldDay);
printText(mFmtText, l_YieldDay); printText(mFmtText, l_YieldDay);
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "Total: %.1f kWh", totalYieldTotal); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "Total: %.1f kWh", mDisplayData->totalYieldTotal);
printText(mFmtText, l_YieldTotal); printText(mFmtText, l_YieldTotal);
if (NULL != mUtcTs) if (0 != mDisplayData->utcTs)
printText(ah::getDateTimeStrShort(gTimezone.toLocal(*mUtcTs)).c_str(), l_Time); printText(ah::getDateTimeStrShort(gTimezone.toLocal(mDisplayData->utcTs)).c_str(), l_Time);
IPAddress ip = WiFi.localIP(); if (!(mExtra % 5) && (mDisplayData->ipAddress))
if (!(mExtra % 5) && (ip)) snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%s", (mDisplayData->ipAddress).toString().c_str());
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%s", ip.toString().c_str());
else else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "Inv.On: %d", isprod); snprintf(mFmtText, DISP_FMT_TEXT_LEN, "Inv.On: %d", mDisplayData->isProducing);
printText(mFmtText, l_Status); printText(mFmtText, l_Status);
mDisplay->sendBuffer(); mDisplay->sendBuffer();
@ -153,3 +139,4 @@ class DisplayMono84X48 : public DisplayMono {
mDisplay->drawStr(dispX, mLineYOffsets[line], text); mDisplay->drawStr(dispX, mLineYOffsets[line], text);
} }
}; };

20
src/plugins/Display/Display_data.h

@ -0,0 +1,20 @@
#include "../../utils/helper.h"
#ifndef __DISPLAY_DATA__
#define __DISPLAY_DATA__
struct DisplayData {
const char *version=nullptr;
float totalPower=0.0f;
float totalYieldDay=0.0f;
float totalYieldTotal=0.0f;
uint32_t utcTs=0;
uint8_t isProducing=0;
int8_t wifiRSSI=SCHAR_MIN;
bool showRadioSymbol = false;
bool WiFiSymbol = false;
bool RadioSymbol = false;
IPAddress ipAddress;
};
#endif /*__DISPLAY_DATA__*/

8
src/plugins/Display/Display_ePaper.cpp

@ -46,9 +46,9 @@ void DisplayEPaper::init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, u
} }
} }
void DisplayEPaper::config(uint8_t rotation, bool enPowerSafe) { void DisplayEPaper::config(uint8_t rotation, bool enPowerSave) {
mDisplayRotation = rotation; mDisplayRotation = rotation;
mEnPowerSafe = enPowerSafe; mEnPowerSave = enPowerSave;
} }
//*************************************************************************** //***************************************************************************
@ -209,7 +209,7 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa
} else } else
snprintf(_fmtText, sizeof(_fmtText), "offline"); snprintf(_fmtText, sizeof(_fmtText), "offline");
if ((totalPower == 0) && (mEnPowerSafe)) { if ((totalPower == 0) && (mEnPowerSave)) {
_display->fillRect(0, mHeadFootPadding, 200, 200, GxEPD_BLACK); _display->fillRect(0, mHeadFootPadding, 200, 200, GxEPD_BLACK);
_display->drawBitmap(0, 0, logo, 200, 200, GxEPD_WHITE); _display->drawBitmap(0, 0, logo, 200, 200, GxEPD_WHITE);
} else { } else {
@ -291,7 +291,7 @@ void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYield
if ((isprod > 0) && (_changed)) { if ((isprod > 0) && (_changed)) {
_changed = false; _changed = false;
lastUpdatePaged(); lastUpdatePaged();
} else if ((0 == totalPower) && (mEnPowerSafe)) } else if ((0 == totalPower) && (mEnPowerSave))
offlineFooter(); offlineFooter();
_display->powerOff(); _display->powerOff();

4
src/plugins/Display/Display_ePaper.h

@ -28,7 +28,7 @@ class DisplayEPaper {
DisplayEPaper(); DisplayEPaper();
void fullRefresh(); 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 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 config(uint8_t rotation, bool enPowerSave);
void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod); void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod);
void refreshLoop(); void refreshLoop();
void tickerSecond(); void tickerSecond();
@ -56,7 +56,7 @@ class DisplayEPaper {
uint8_t mHeadFootPadding; uint8_t mHeadFootPadding;
GxEPD2_GFX* _display; GxEPD2_GFX* _display;
uint32_t* mUtcTs; uint32_t* mUtcTs;
bool mEnPowerSafe; bool mEnPowerSave;
const char* _version; const char* _version;
RefreshStatus mRefreshState, mNextRefreshState; RefreshStatus mRefreshState, mNextRefreshState;
uint8_t mSecondCnt; uint8_t mSecondCnt;

Loading…
Cancel
Save