mirror of
https://github.com/lumapu/ahoy.git
synced 2025-06-05 04:01:41 +02:00
0.7.46
* removed `delay` from ePaper * started improvements of `/system` * fix LEDs to check all configured inverters
This commit is contained in:
parent
201098ae0b
commit
f3192b49ab
16 changed files with 218 additions and 124 deletions
|
@ -1,5 +1,10 @@
|
||||||
# Development Changes
|
# Development Changes
|
||||||
|
|
||||||
|
## 0.7.46 - 2023-09-01
|
||||||
|
* removed `delay` from ePaper
|
||||||
|
* started improvements of `/system`
|
||||||
|
* fix LEDs to check all configured inverters
|
||||||
|
|
||||||
## 0.7.45 - 2023-08-29
|
## 0.7.45 - 2023-08-29
|
||||||
* change ePaper text to symbols PR #1131
|
* change ePaper text to symbols PR #1131
|
||||||
* added some invertes to dev info list #1111
|
* added some invertes to dev info list #1111
|
||||||
|
|
20
src/app.cpp
20
src/app.cpp
|
@ -567,11 +567,11 @@ void app::mqttSubRxCb(JsonObject obj) {
|
||||||
void app::setupLed(void) {
|
void app::setupLed(void) {
|
||||||
uint8_t led_off = (mConfig->led.led_high_active) ? LOW : HIGH;
|
uint8_t led_off = (mConfig->led.led_high_active) ? LOW : HIGH;
|
||||||
|
|
||||||
if (mConfig->led.led0 != 0xff) {
|
if (mConfig->led.led0 != DEF_PIN_OFF) {
|
||||||
pinMode(mConfig->led.led0, OUTPUT);
|
pinMode(mConfig->led.led0, OUTPUT);
|
||||||
digitalWrite(mConfig->led.led0, led_off);
|
digitalWrite(mConfig->led.led0, led_off);
|
||||||
}
|
}
|
||||||
if (mConfig->led.led1 != 0xff) {
|
if (mConfig->led.led1 != DEF_PIN_OFF) {
|
||||||
pinMode(mConfig->led.led1, OUTPUT);
|
pinMode(mConfig->led.led1, OUTPUT);
|
||||||
digitalWrite(mConfig->led.led1, led_off);
|
digitalWrite(mConfig->led.led1, led_off);
|
||||||
}
|
}
|
||||||
|
@ -582,17 +582,23 @@ void app::updateLed(void) {
|
||||||
uint8_t led_off = (mConfig->led.led_high_active) ? LOW : HIGH;
|
uint8_t led_off = (mConfig->led.led_high_active) ? LOW : HIGH;
|
||||||
uint8_t led_on = (mConfig->led.led_high_active) ? HIGH : LOW;
|
uint8_t led_on = (mConfig->led.led_high_active) ? HIGH : LOW;
|
||||||
|
|
||||||
if (mConfig->led.led0 != 0xff) {
|
if (mConfig->led.led0 != DEF_PIN_OFF) {
|
||||||
Inverter<> *iv = mSys.getInverterByPos(0);
|
Inverter<> *iv;
|
||||||
|
for (uint8_t id = 0; id < mSys.getNumInverters(); id++) {
|
||||||
|
iv = mSys.getInverterByPos(id);
|
||||||
if (NULL != iv) {
|
if (NULL != iv) {
|
||||||
if (iv->isProducing())
|
if (iv->isProducing()) {
|
||||||
|
// turn on when at least one inverter is producing
|
||||||
digitalWrite(mConfig->led.led0, led_on);
|
digitalWrite(mConfig->led.led0, led_on);
|
||||||
else
|
break;
|
||||||
|
}
|
||||||
|
else if(iv->config->enabled)
|
||||||
digitalWrite(mConfig->led.led0, led_off);
|
digitalWrite(mConfig->led.led0, led_off);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mConfig->led.led1 != 0xff) {
|
if (mConfig->led.led1 != DEF_PIN_OFF) {
|
||||||
if (getMqttIsConnected()) {
|
if (getMqttIsConnected()) {
|
||||||
digitalWrite(mConfig->led.led1, led_on);
|
digitalWrite(mConfig->led.led1, led_on);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -273,6 +273,7 @@ class app : public IApp, public ah::Scheduler {
|
||||||
#endif
|
#endif
|
||||||
if(mConfig->plugin.display.type != 0)
|
if(mConfig->plugin.display.type != 0)
|
||||||
mDisplay.payloadEventListener(cmd);
|
mDisplay.payloadEventListener(cmd);
|
||||||
|
updateLed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mqttSubRxCb(JsonObject obj);
|
void mqttSubRxCb(JsonObject obj);
|
||||||
|
|
|
@ -728,8 +728,8 @@ const byteAssign_t InfoAssignment[] = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void reset(uint8_t id, bool clrSts = false) {
|
void reset(uint8_t id, bool clrSts = false) {
|
||||||
DPRINT_IVID(DBG_INFO, id);
|
//DPRINT_IVID(DBG_INFO, id);
|
||||||
DBGPRINTLN(F("resetPayload"));
|
//DBGPRINTLN(F("resetPayload"));
|
||||||
memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES);
|
memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES);
|
||||||
mPayload[id].gotFragment = false;
|
mPayload[id].gotFragment = false;
|
||||||
/*mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES;
|
/*mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES;
|
||||||
|
|
|
@ -26,6 +26,7 @@ class CmtRadio {
|
||||||
public:
|
public:
|
||||||
CmtRadio() {
|
CmtRadio() {
|
||||||
mDtuSn = DTU_SN;
|
mDtuSn = DTU_SN;
|
||||||
|
mCmtAvail = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup(uint8_t pinCsb, uint8_t pinFcsb, bool genDtuSn = true) {
|
void setup(uint8_t pinCsb, uint8_t pinFcsb, bool genDtuSn = true) {
|
||||||
|
@ -63,6 +64,10 @@ class CmtRadio {
|
||||||
mSerialDebug = true;
|
mSerialDebug = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cmtIsAvail() {
|
||||||
|
return mCmtAvail;
|
||||||
|
}
|
||||||
|
|
||||||
void sendControlPacket(const uint64_t *ivId, uint8_t cmd, uint16_t *data, bool isRetransmit) {
|
void sendControlPacket(const uint64_t *ivId, uint8_t cmd, uint16_t *data, bool isRetransmit) {
|
||||||
DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x"));
|
DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x"));
|
||||||
DBGHEXLN(cmd);
|
DBGHEXLN(cmd);
|
||||||
|
@ -143,10 +148,14 @@ class CmtRadio {
|
||||||
inline void reset(bool genDtuSn) {
|
inline void reset(bool genDtuSn) {
|
||||||
if(genDtuSn)
|
if(genDtuSn)
|
||||||
generateDtuSn();
|
generateDtuSn();
|
||||||
if(!mCmt.reset())
|
if(!mCmt.reset()) {
|
||||||
|
mCmtAvail = false;
|
||||||
DPRINTLN(DBG_WARN, F("Initializing CMT2300A failed!"));
|
DPRINTLN(DBG_WARN, F("Initializing CMT2300A failed!"));
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
|
mCmtAvail = true;
|
||||||
mCmt.goRx();
|
mCmt.goRx();
|
||||||
|
}
|
||||||
|
|
||||||
mSendCnt = 0;
|
mSendCnt = 0;
|
||||||
mRetransmits = 0;
|
mRetransmits = 0;
|
||||||
|
@ -208,6 +217,7 @@ class CmtRadio {
|
||||||
bool mSerialDebug;
|
bool mSerialDebug;
|
||||||
bool mIrqRcvd;
|
bool mIrqRcvd;
|
||||||
bool mRqstGetRx;
|
bool mRqstGetRx;
|
||||||
|
bool mCmtAvail;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__HMS_RADIO_H__*/
|
#endif /*__HMS_RADIO_H__*/
|
||||||
|
|
|
@ -127,8 +127,6 @@ monitor_filters =
|
||||||
platform = espressif32@6.3.2
|
platform = espressif32@6.3.2
|
||||||
board = esp32-s3-devkitc-1
|
board = esp32-s3-devkitc-1
|
||||||
upload_protocol = esp-builtin
|
upload_protocol = esp-builtin
|
||||||
debug_tool = esp-builtin
|
|
||||||
debug_speed = 12000
|
|
||||||
build_flags = ${env.build_flags}
|
build_flags = ${env.build_flags}
|
||||||
-DDEF_NRF_CS_PIN=37
|
-DDEF_NRF_CS_PIN=37
|
||||||
-DDEF_NRF_CE_PIN=38
|
-DDEF_NRF_CE_PIN=38
|
||||||
|
@ -142,5 +140,7 @@ build_flags = ${env.build_flags}
|
||||||
-DDEF_LED0=18
|
-DDEF_LED0=18
|
||||||
-DDEF_LED1=17
|
-DDEF_LED1=17
|
||||||
-DLED_ACTIVE_HIGH
|
-DLED_ACTIVE_HIGH
|
||||||
|
-DARDUINO_USB_MODE=1
|
||||||
|
-DARDUINO_USB_CDC_ON_BOOT=1
|
||||||
monitor_filters =
|
monitor_filters =
|
||||||
esp32_exception_decoder
|
esp32_exception_decoder, colorize
|
||||||
|
|
|
@ -61,11 +61,14 @@ class Display {
|
||||||
if (mMono != NULL)
|
if (mMono != NULL)
|
||||||
mMono->loop();
|
mMono->loop();
|
||||||
|
|
||||||
if (mNewPayload || ((++mLoopCnt % 10) == 0)) {
|
if (mNewPayload || (((++mLoopCnt) % 30) == 0)) {
|
||||||
mNewPayload = false;
|
mNewPayload = false;
|
||||||
mLoopCnt = 0;
|
mLoopCnt = 0;
|
||||||
DataScreen();
|
DataScreen();
|
||||||
}
|
}
|
||||||
|
#if defined(ESP32)
|
||||||
|
mEpaper.tickerSecond();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -102,13 +105,10 @@ class Display {
|
||||||
}
|
}
|
||||||
#if defined(ESP32)
|
#if defined(ESP32)
|
||||||
else if (mCfg->type == 10) {
|
else if (mCfg->type == 10) {
|
||||||
|
|
||||||
mEpaper.loop(totalPower, totalYieldDay, totalYieldTotal, isprod);
|
mEpaper.loop(totalPower, totalYieldDay, totalYieldTotal, isprod);
|
||||||
mRefreshCycle++;
|
mRefreshCycle++;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ESP32)
|
|
||||||
if (mRefreshCycle > 480) {
|
if (mRefreshCycle > 480) {
|
||||||
mEpaper.fullRefresh();
|
mEpaper.fullRefresh();
|
||||||
mRefreshCycle = 0;
|
mRefreshCycle = 0;
|
||||||
|
|
|
@ -21,10 +21,14 @@ DisplayEPaper::DisplayEPaper() {
|
||||||
mHeadFootPadding = 16;
|
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) {
|
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;
|
mUtcTs = utcTs;
|
||||||
|
|
||||||
|
mRefreshState = RefreshStatus::LOGO;
|
||||||
|
mSecondCnt = 0;
|
||||||
|
|
||||||
if (type == 10) {
|
if (type == 10) {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
_display = new GxEPD2_BW<GxEPD2_150_BN, GxEPD2_150_BN::HEIGHT>(GxEPD2_150_BN(_CS, _DC, _RST, _BUSY));
|
_display = new GxEPD2_BW<GxEPD2_150_BN, GxEPD2_150_BN::HEIGHT>(GxEPD2_150_BN(_CS, _DC, _RST, _BUSY));
|
||||||
|
@ -38,26 +42,7 @@ void DisplayEPaper::init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, u
|
||||||
_display->init(115200, true, 20, false);
|
_display->init(115200, true, 20, false);
|
||||||
_display->setRotation(mDisplayRotation);
|
_display->setRotation(mDisplayRotation);
|
||||||
_display->setFullWindow();
|
_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();
|
|
||||||
|
|
||||||
_version = version;
|
_version = version;
|
||||||
versionFooter();
|
|
||||||
|
|
||||||
// call the PowerPage to change the PV Power Values
|
|
||||||
actualPowerPaged(0, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,15 +53,51 @@ void DisplayEPaper::config(uint8_t rotation, bool enPowerSafe) {
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
void DisplayEPaper::fullRefresh() {
|
void DisplayEPaper::fullRefresh() {
|
||||||
// screen complete black
|
if(RefreshStatus::DONE != mRefreshState)
|
||||||
|
return;
|
||||||
|
mSecondCnt = 2;
|
||||||
|
mRefreshState = RefreshStatus::BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***************************************************************************
|
||||||
|
void DisplayEPaper::refreshLoop() {
|
||||||
|
switch(mRefreshState) {
|
||||||
|
case RefreshStatus::LOGO:
|
||||||
_display->fillScreen(GxEPD_BLACK);
|
_display->fillScreen(GxEPD_BLACK);
|
||||||
while (_display->nextPage())
|
_display->drawBitmap(0, 0, logo, 200, 200, GxEPD_WHITE);
|
||||||
;
|
mNextRefreshState = RefreshStatus::PARTITIALS;
|
||||||
delay(2000);
|
mRefreshState = RefreshStatus::WAIT;
|
||||||
// screen complete white
|
break;
|
||||||
|
|
||||||
|
case RefreshStatus::BLACK:
|
||||||
|
_display->fillScreen(GxEPD_BLACK);
|
||||||
|
mNextRefreshState = RefreshStatus::WHITE;
|
||||||
|
mRefreshState = RefreshStatus::WAIT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RefreshStatus::WHITE:
|
||||||
|
if(mSecondCnt == 0) {
|
||||||
_display->fillScreen(GxEPD_WHITE);
|
_display->fillScreen(GxEPD_WHITE);
|
||||||
while (_display->nextPage())
|
mNextRefreshState = RefreshStatus::PARTITIALS;
|
||||||
;
|
mRefreshState = RefreshStatus::WAIT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RefreshStatus::WAIT:
|
||||||
|
if(!_display->nextPage())
|
||||||
|
mRefreshState = mNextRefreshState;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RefreshStatus::PARTITIALS:
|
||||||
|
headlineIP();
|
||||||
|
versionFooter();
|
||||||
|
mSecondCnt = 4; // display Logo time during boot up
|
||||||
|
mRefreshState = RefreshStatus::DONE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // RefreshStatus::DONE
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
void DisplayEPaper::headlineIP() {
|
void DisplayEPaper::headlineIP() {
|
||||||
|
@ -185,9 +206,8 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa
|
||||||
} else if ((totalPower > 0) && (totalPower <= 9999)) {
|
} else if ((totalPower > 0) && (totalPower <= 9999)) {
|
||||||
snprintf(_fmtText, sizeof(_fmtText), "%.0f W", totalPower);
|
snprintf(_fmtText, sizeof(_fmtText), "%.0f W", totalPower);
|
||||||
_changed = true;
|
_changed = true;
|
||||||
} else {
|
} else
|
||||||
snprintf(_fmtText, sizeof(_fmtText), "offline");
|
snprintf(_fmtText, sizeof(_fmtText), "offline");
|
||||||
}
|
|
||||||
|
|
||||||
if ((totalPower == 0) && (mEnPowerSafe)) {
|
if ((totalPower == 0) && (mEnPowerSafe)) {
|
||||||
_display->fillRect(0, mHeadFootPadding, 200, 200, GxEPD_BLACK);
|
_display->fillRect(0, mHeadFootPadding, 200, 200, GxEPD_BLACK);
|
||||||
|
@ -200,57 +220,43 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa
|
||||||
|
|
||||||
if ((totalYieldDay > 0) && (totalYieldTotal > 0)) {
|
if ((totalYieldDay > 0) && (totalYieldTotal > 0)) {
|
||||||
// Today Production
|
// Today Production
|
||||||
|
bool kwh = (totalYieldDay > 9999);
|
||||||
|
if(kwh)
|
||||||
|
snprintf(_fmtText, _display->width(), "%.1f", (totalYieldDay / 1000));
|
||||||
|
else
|
||||||
|
snprintf(_fmtText, _display->width(), "%.0f", (totalYieldDay));
|
||||||
|
|
||||||
_display->setFont(&FreeSans18pt7b);
|
_display->setFont(&FreeSans18pt7b);
|
||||||
y = _display->height() / 2;
|
y = _display->height() / 2;
|
||||||
_display->setCursor(5, y);
|
_display->setCursor(5, y);
|
||||||
|
|
||||||
if (totalYieldDay > 9999) {
|
|
||||||
snprintf(_fmtText, _display->width(), "%.1f", (totalYieldDay / 1000));
|
|
||||||
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||||
_display->drawInvertedBitmap(5, y - ((tbh + 30) / 2), myToday, 30, 30, GxEPD_BLACK);
|
_display->drawInvertedBitmap(5, ((kwh) ? (y - ((tbh + 30) / 2)) : (y - tbh)), myToday, 30, 30, GxEPD_BLACK);
|
||||||
x = ((_display->width() - tbw - 20) / 2) - tbx;
|
x = ((_display->width() - tbw - 20) / 2) - tbx;
|
||||||
_display->setCursor(x, y);
|
_display->setCursor(x, y);
|
||||||
_display->print(_fmtText);
|
_display->print(_fmtText);
|
||||||
_display->setCursor(_display->width() - 50, y);
|
_display->setCursor(_display->width() - ((kwh) ? 50 : 38), y);
|
||||||
_display->setFont(&FreeSans12pt7b);
|
_display->setFont(&FreeSans12pt7b);
|
||||||
_display->println("kWh");
|
_display->println((kwh) ? "kWh" : "Wh");
|
||||||
} else if (totalYieldDay <= 9999) {
|
|
||||||
snprintf(_fmtText, _display->width(), "%.0f", (totalYieldDay));
|
|
||||||
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
|
||||||
_display->drawInvertedBitmap(5, y - tbh, myToday, 30, 30, GxEPD_BLACK);
|
|
||||||
x = ((_display->width() - tbw - 20) / 2) - tbx;
|
|
||||||
_display->setCursor(x, y);
|
|
||||||
_display->print(_fmtText);
|
|
||||||
_display->setCursor(_display->width() - 38, y);
|
|
||||||
_display->setFont(&FreeSans12pt7b);
|
|
||||||
_display->println("Wh");
|
|
||||||
}
|
|
||||||
y = y + tbh + 15;
|
y = y + tbh + 15;
|
||||||
|
|
||||||
|
|
||||||
// Total Production
|
// Total Production
|
||||||
|
bool mwh = (totalYieldTotal > 9999);
|
||||||
|
if(mwh)
|
||||||
|
snprintf(_fmtText, _display->width(), "%.1f", (totalYieldTotal / 1000));
|
||||||
|
else
|
||||||
|
snprintf(_fmtText, _display->width(), "%.0f", (totalYieldTotal));
|
||||||
|
|
||||||
_display->setFont(&FreeSans18pt7b);
|
_display->setFont(&FreeSans18pt7b);
|
||||||
_display->setCursor(5, y);
|
_display->setCursor(5, y);
|
||||||
if (totalYieldTotal > 9999) {
|
|
||||||
snprintf(_fmtText, _display->width(), "%.1f", (totalYieldTotal / 1000));
|
|
||||||
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
||||||
_display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK);
|
_display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK);
|
||||||
x = ((_display->width() - tbw - 20) / 2) - tbx;
|
x = ((_display->width() - tbw - 20) / 2) - tbx;
|
||||||
_display->setCursor(x, y);
|
_display->setCursor(x, y);
|
||||||
_display->print(_fmtText);
|
_display->print(_fmtText);
|
||||||
_display->setCursor(_display->width() - 59, y);
|
_display->setCursor(_display->width() - ((mwh) ? 59 : 50), y);
|
||||||
_display->setFont(&FreeSans12pt7b);
|
_display->setFont(&FreeSans12pt7b);
|
||||||
_display->println("MWh");
|
_display->println((mwh) ? "MWh" : "kWh");
|
||||||
} else if (totalYieldTotal <= 9999) {
|
|
||||||
snprintf(_fmtText, _display->width(), "%.0f", (totalYieldTotal));
|
|
||||||
_display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh);
|
|
||||||
_display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK);
|
|
||||||
x = ((_display->width() - tbw - 20) / 2) - tbx;
|
|
||||||
_display->setCursor(x, y);
|
|
||||||
_display->print(_fmtText);
|
|
||||||
_display->setCursor(_display->width() - 50, y);
|
|
||||||
_display->setFont(&FreeSans12pt7b);
|
|
||||||
_display->println("kWh");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inverter online
|
// Inverter online
|
||||||
|
@ -263,14 +269,18 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa
|
||||||
_display->setCursor(x, y);
|
_display->setCursor(x, y);
|
||||||
_display->println(_fmtText);
|
_display->println(_fmtText);
|
||||||
}
|
}
|
||||||
|
yield();
|
||||||
} while (_display->nextPage());
|
} while (_display->nextPage());
|
||||||
}
|
}
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) {
|
void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) {
|
||||||
|
if(RefreshStatus::DONE != mRefreshState)
|
||||||
|
return;
|
||||||
|
|
||||||
// check if the IP has changed
|
// check if the IP has changed
|
||||||
if (_settedIP != WiFi.localIP().toString().c_str()) {
|
if (_settedIP != WiFi.localIP().toString()) {
|
||||||
// save the new IP and call the Headline Function to adapt the Headline
|
// save the new IP and call the Headline Function to adapt the Headline
|
||||||
_settedIP = WiFi.localIP().toString().c_str();
|
_settedIP = WiFi.localIP().toString();
|
||||||
headlineIP();
|
headlineIP();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,5 +296,11 @@ void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYield
|
||||||
|
|
||||||
_display->powerOff();
|
_display->powerOff();
|
||||||
}
|
}
|
||||||
|
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
|
void DisplayEPaper::tickerSecond() {
|
||||||
|
if(mSecondCnt != 0)
|
||||||
|
mSecondCnt--;
|
||||||
|
refreshLoop();
|
||||||
|
}
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
|
|
|
@ -30,6 +30,8 @@ class DisplayEPaper {
|
||||||
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 enPowerSafe);
|
||||||
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 tickerSecond();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void headlineIP();
|
void headlineIP();
|
||||||
|
@ -38,15 +40,26 @@ class DisplayEPaper {
|
||||||
void offlineFooter();
|
void offlineFooter();
|
||||||
void versionFooter();
|
void versionFooter();
|
||||||
|
|
||||||
|
enum class RefreshStatus : uint8_t {
|
||||||
|
DONE,
|
||||||
|
BLACK,
|
||||||
|
WHITE,
|
||||||
|
WAIT,
|
||||||
|
PARTITIALS,
|
||||||
|
LOGO
|
||||||
|
};
|
||||||
|
|
||||||
uint8_t mDisplayRotation;
|
uint8_t mDisplayRotation;
|
||||||
bool _changed = false;
|
bool _changed = false;
|
||||||
char _fmtText[35];
|
char _fmtText[35];
|
||||||
const char* _settedIP;
|
String _settedIP;
|
||||||
uint8_t mHeadFootPadding;
|
uint8_t mHeadFootPadding;
|
||||||
GxEPD2_GFX* _display;
|
GxEPD2_GFX* _display;
|
||||||
uint32_t* mUtcTs;
|
uint32_t* mUtcTs;
|
||||||
bool mEnPowerSafe;
|
bool mEnPowerSafe;
|
||||||
const char* _version;
|
const char* _version;
|
||||||
|
RefreshStatus mRefreshState, mNextRefreshState;
|
||||||
|
uint8_t mSecondCnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ESP32
|
#endif // ESP32
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
--success: #009900;
|
--success: #009900;
|
||||||
|
|
||||||
--input-bg: #eee;
|
--input-bg: #eee;
|
||||||
|
--table-border: #ccc;
|
||||||
|
|
||||||
--nav-bg: #333;
|
--nav-bg: #333;
|
||||||
--primary: #006ec0;
|
--primary: #006ec0;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
--success: #00bb00;
|
--success: #00bb00;
|
||||||
|
|
||||||
--input-bg: #333;
|
--input-bg: #333;
|
||||||
|
--table-border: #333;
|
||||||
|
|
||||||
--nav-bg: #333;
|
--nav-bg: #333;
|
||||||
--primary: #004d87;
|
--primary: #004d87;
|
||||||
|
|
|
@ -329,7 +329,7 @@ th {
|
||||||
|
|
||||||
.table td, .table th {
|
.table td, .table th {
|
||||||
padding: .75rem;
|
padding: .75rem;
|
||||||
border-bottom: 1px solid var(--nav-bg);
|
border-bottom: 1px solid var(--table-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
#wrapper {
|
#wrapper {
|
||||||
|
@ -737,3 +737,30 @@ h5 {
|
||||||
.pointer {
|
.pointer {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.badge-success {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #28a745;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-warning {
|
||||||
|
color: #212529;
|
||||||
|
background-color: #ffc107;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-error {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: .25em .4em;
|
||||||
|
font-size: 75%;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
vertical-align: baseline;
|
||||||
|
border-radius: .25rem;
|
||||||
|
}
|
||||||
|
|
|
@ -49,33 +49,47 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function badge(success, text) {
|
||||||
|
return ml("span", {class: "badge badge-" + ((success) ? "success" : "error")}, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
function headline(text) {
|
||||||
|
return ml("div", {class: "head p-2 mt-3"}, ml("div", {class: "row"}, ml("div", {class: "col a-c"}, text)))
|
||||||
|
}
|
||||||
|
|
||||||
|
function tr(val1, val2) {
|
||||||
|
if(typeof val2 == "number")
|
||||||
|
val2 = String(val2);
|
||||||
|
return ml("tr", {}, [
|
||||||
|
ml("th", {}, val1),
|
||||||
|
ml("td", {}, val2)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
function parseRadio(obj, stat) {
|
function parseRadio(obj, stat) {
|
||||||
const pa = ["MIN (recommended)", "LOW", "HIGH", "MAX"];
|
const pa = ["MIN (recommended)", "LOW", "HIGH", "MAX"];
|
||||||
const datarate = ["1 MBps", "2 MBps", "250 kbps"];
|
const datarate = ["1 MBps", "2 MBps", "250 kbps"];
|
||||||
|
|
||||||
var main = document.getElementById("radio");
|
document.getElementById("radio").append(
|
||||||
var h = div(["head", "p-2"]);
|
headline("NRF Radio"),
|
||||||
var r = div(["row"]);
|
ml("table", {class: "table"}, [
|
||||||
r.appendChild(div(["col", "a-c"], "Radio"));
|
ml("tbody", {}, [
|
||||||
h.appendChild(r);
|
tr("NRF24L01", badge(obj.isconnected, ((obj.isconnected) ? "" : "not ") + "connected")),
|
||||||
main.appendChild(h);
|
tr("Power Level", pa[obj.power_level])
|
||||||
|
])
|
||||||
|
]),
|
||||||
|
|
||||||
main.appendChild(
|
headline("Statistics"),
|
||||||
genTabRow("nrf24l01" + (obj["isPVariant"] ? "+ " : ""), (obj["isconnected"] ? "is connected " : "is not connected "))
|
ml("table", {class: "table"}, [
|
||||||
);
|
ml("tbody", {}, [
|
||||||
|
tr("TX count", stat.tx_cnt),
|
||||||
if(obj["isconnected"]) {
|
tr("RX success", stat.rx_success),
|
||||||
main.appendChild(genTabRow("Datarate", datarate[obj["DataRate"]]));
|
tr("RX fail", stat.rx_fail),
|
||||||
main.appendChild(genTabRow("Power Level", pa[obj["power_level"]]));
|
tr("RX no answer", stat.rx_fail_answer),
|
||||||
}
|
tr("RX fragments", stat.frame_cnt),
|
||||||
|
tr("TX retransmits", stat.retransmits)
|
||||||
main.append(
|
])
|
||||||
genTabRow("TX count", stat["tx_cnt"]),
|
])
|
||||||
genTabRow("RX success", stat["rx_success"]),
|
|
||||||
genTabRow("RX fail", stat["rx_fail"]),
|
|
||||||
genTabRow("RX no answer", stat["rx_fail_answer"]),
|
|
||||||
genTabRow("RX fragments", stat["frame_cnt"]),
|
|
||||||
genTabRow("TX retransmits", stat["retransmits"])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue