From 20713c9ffbf378a968bb77222616d40d77509dc1 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Wed, 23 Aug 2023 10:45:58 +0200 Subject: [PATCH 01/20] MI - first update on HW detection see https://github.com/lumapu/ahoy/issues/1111 --- src/hm/hmDefines.h | 6 +++++- src/hm/miPayload.h | 37 ++++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/hm/hmDefines.h b/src/hm/hmDefines.h index 3c63aa9e..edf1fc99 100644 --- a/src/hm/hmDefines.h +++ b/src/hm/hmDefines.h @@ -25,7 +25,7 @@ enum {FLD_UDC = 0, FLD_IDC, FLD_PDC, FLD_YD, FLD_YW, FLD_YT, FLD_FW_BUILD_MONTH_DAY, FLD_FW_BUILD_HOUR_MINUTE, FLD_BOOTLOADER_VER, FLD_ACT_ACTIVE_PWR_LIMIT, FLD_PART_NUM, FLD_HW_VERSION, FLD_GRID_PROFILE_CODE, FLD_GRID_PROFILE_VERSION, /*FLD_ACT_REACTIVE_PWR_LIMIT, FLD_ACT_PF,*/ FLD_LAST_ALARM_CODE, FLD_MP}; - + const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", "YieldTotal", "U_AC", "U_AC_1N", "U_AC_2N", "U_AC_3N", "UAC_12", "UAC_23", "UAC_31", "I_AC", "IAC_1", "I_AC_2", "I_AC_3", "P_AC", "F_AC", "Temp", "PF_AC", "Efficiency", "Irradiation","Q_AC", @@ -260,6 +260,10 @@ typedef struct { } devInfo_t; const devInfo_t devInfo[] = { + // MI 2nd gen + { 0x13118f, 600 }, + + // MI 3rd gen { 0x100230, 1500 }, diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index fb909663..efb6102b 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -219,12 +219,13 @@ case InverterDevInform_All: rec->assign = (byteAssign_t *)InfoAssignment; rec->pyldLen = HMINFO_PAYLOAD_LEN; break; + const byteAssign_t InfoAssignment[] = { { FLD_FW_VERSION, UNIT_NONE, CH0, 0, 2, 1 }, { FLD_FW_BUILD_YEAR, UNIT_NONE, CH0, 2, 2, 1 }, { FLD_FW_BUILD_MONTH_DAY, UNIT_NONE, CH0, 4, 2, 1 }, { FLD_FW_BUILD_HOUR_MINUTE, UNIT_NONE, CH0, 6, 2, 1 }, - { FLD_HW_ID, UNIT_NONE, CH0, 8, 2, 1 } + { FLD_BOOTLOADER_VER, UNIT_NONE, CH0, 8, 2, 1 } }; */ @@ -237,27 +238,37 @@ const byteAssign_t InfoAssignment[] = { mPayload[iv->id].gotFragment = true; if(mSerialDebug) { DPRINT_IVID(DBG_INFO, iv->id); - DPRINT(DBG_INFO,F("HW_VER is ")); - DBGPRINTLN(String((p->packet[24] << 8) + p->packet[25])); + DPRINT(DBG_INFO,F("HW_VER is ")); + DBGPRINTLN(String((p->packet[24] << 8) + p->packet[25])); } + record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure + rec->ts = mPayload[iv->id].ts; + iv->setValue(1, rec, (uint16_t) ((p->packet[24] << 8) + p->packet[25])/1); + //28737 } else if ( p->packet[9] == 0x01 || p->packet[9] == 0x10 ) {//second frame for MI, 3rd gen. answers in 0x10 DPRINT_IVID(DBG_INFO, iv->id); if ( p->packet[9] == 0x01 ) { DBGPRINTLN(F("got 2nd frame (hw info)")); - DPRINT(DBG_INFO,F("HW_PartNo ")); - DBGPRINTLN(String((uint32_t) (((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])); + DPRINT(DBG_INFO,F("HW_PartNo ")); + DBGPRINTLN(String((uint32_t) (((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])); mPayload[iv->id].gotFragment = true; - iv->setValue(iv->getPosByChFld(0, FLD_YT, rec), rec, (float) ((p->packet[20] << 8) + p->packet[21])/1); + record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure + rec->ts = mPayload[iv->id].ts; + /*for (uint8_t i = 0; i < 5; i++) { + iv->setValue(i, rec, (float) ((p->packet[(10+2*i)] << 8) + p->packet[(11+2*i)])/1); + }*/ + iv->setValue(0, rec, (uint32_t) ((((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])/1); + if(mSerialDebug) { - DPRINT(DBG_INFO,F("HW_FB_TLmValue ")); - DBGPRINTLN(String((p->packet[14] << 8) + p->packet[15])); - DPRINT(DBG_INFO,F("HW_FB_ReSPRT ")); - DBGPRINTLN(String((p->packet[16] << 8) + p->packet[17])); - DPRINT(DBG_INFO,F("HW_GridSamp_ResValule ")); - DBGPRINTLN(String((p->packet[18] << 8) + p->packet[19])); + DPRINT(DBG_INFO,F("HW_FB_TLmValue ")); + DBGPRINTLN(String((p->packet[14] << 8) + p->packet[15])); + DPRINT(DBG_INFO,F("HW_FB_ReSPRT ")); + DBGPRINTLN(String((p->packet[16] << 8) + p->packet[17])); + DPRINT(DBG_INFO,F("HW_GridSamp_ResValule ")); + DBGPRINTLN(String((p->packet[18] << 8) + p->packet[19])); DPRINT(DBG_INFO,F("HW_ECapValue ")); DBGPRINTLN(String((p->packet[20] << 8) + p->packet[21])); - } + } } else { DBGPRINTLN(F("3rd gen. inverter!")); // see table in OpenDTU code, DevInfoParser.cpp devInfo[] } From 5fc80f660a64f249d25d7dc8e4efd395ae5f2500 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Wed, 23 Aug 2023 18:28:44 +0200 Subject: [PATCH 02/20] Add files via upload --- src/hm/hmInverter.h | 2 +- src/hm/miPayload.h | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index 75ab9ec4..dc6c9779 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -210,7 +210,7 @@ class Inverter { enqueCommand(InverterDevInform_Simple); // hardware version enqueCommand(RealTimeRunData_Debug); // live data } else if (ivGen == IV_MI){ - if (getFwVersion() == 0) + if (getFwVersion() == 0 || getHwVersion() == 0) enqueCommand(InverterDevInform_All); // firmware version; might not work, esp. for 1/2 ch hardware if (type == INV_TYPE_4CH) { enqueCommand(0x36); diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index efb6102b..a16cbe21 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -243,20 +243,26 @@ const byteAssign_t InfoAssignment[] = { } record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure rec->ts = mPayload[iv->id].ts; - iv->setValue(1, rec, (uint16_t) ((p->packet[24] << 8) + p->packet[25])/1); + iv->setValue(1, rec, (uint32_t) ((p->packet[24] << 8) + p->packet[25])); //28737 } else if ( p->packet[9] == 0x01 || p->packet[9] == 0x10 ) {//second frame for MI, 3rd gen. answers in 0x10 DPRINT_IVID(DBG_INFO, iv->id); if ( p->packet[9] == 0x01 ) { DBGPRINTLN(F("got 2nd frame (hw info)")); + /* according to xlsx (different start byte -1!) + byte[11] to byte[14] HW_PN + byte[15] byte[16] HW_FB_TLmValue + byte[17] byte[18] HW_FB_ReSPRT + byte[19] byte[20] HW_GridSamp_ResValule + byte[21] byte[22] HW_ECapValue + byte[23] to byte[26] Matching_APPFW_PN + */ + DPRINT(DBG_INFO,F("HW_PartNo ")); DBGPRINTLN(String((uint32_t) (((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])); mPayload[iv->id].gotFragment = true; record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure rec->ts = mPayload[iv->id].ts; - /*for (uint8_t i = 0; i < 5; i++) { - iv->setValue(i, rec, (float) ((p->packet[(10+2*i)] << 8) + p->packet[(11+2*i)])/1); - }*/ iv->setValue(0, rec, (uint32_t) ((((p->packet[10] << 8) | p->packet[11]) << 8 | p->packet[12]) << 8 | p->packet[13])/1); if(mSerialDebug) { @@ -268,6 +274,8 @@ const byteAssign_t InfoAssignment[] = { DBGPRINTLN(String((p->packet[18] << 8) + p->packet[19])); DPRINT(DBG_INFO,F("HW_ECapValue ")); DBGPRINTLN(String((p->packet[20] << 8) + p->packet[21])); + DPRINT(DBG_INFO,F("Matching_APPFW_PN ")); + DBGPRINTLN(String((uint32_t) (((p->packet[22] << 8) | p->packet[23]) << 8 | p->packet[24]) << 8 | p->packet[25])); } } else { DBGPRINTLN(F("3rd gen. inverter!")); // see table in OpenDTU code, DevInfoParser.cpp devInfo[] @@ -276,6 +284,22 @@ const byteAssign_t InfoAssignment[] = { } else if ( p->packet[9] == 0x12 ) {//3rd frame DPRINT_IVID(DBG_INFO, iv->id); DBGPRINTLN(F("got 3rd frame (hw info)")); + /* according to xlsx (different start byte -1!) + byte[11] byte[12] APPFW_MINVER + byte[13] byte[14] HWInfoAddr + byte[15] byte[16] PNInfoCRC_gusv + byte[15] byte[16] PNInfoCRC_gusv + */ + if(mSerialDebug) { + DPRINT(DBG_INFO,F("APPFW_MINVER ")); + DBGPRINTLN(String((p->packet[10] << 8) + p->packet[11])); + DPRINT(DBG_INFO,F("HWInfoAddr ")); + DBGPRINTLN(String((p->packet[12] << 8) + p->packet[13])); + DPRINT(DBG_INFO,F("PNInfoCRC_gusv ")); + DBGPRINTLN(String((p->packet[14] << 8) + p->packet[15])); + DPRINT(DBG_INFO,F("PNInfoCRC_gusv (pt. 2?) ")); + DBGPRINTLN(String((p->packet[16] << 8) + p->packet[17])); + } iv->setQueuedCmdFinished(); mPayload[iv->id].complete = true; mStat->rxSuccess++; From f9857b52ab41f47c4418eac4519685f53f81fed1 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Thu, 24 Aug 2023 10:10:47 +0200 Subject: [PATCH 03/20] MI - assure HW part no is there --- src/hm/hmInverter.h | 9 +++++++-- src/hm/miPayload.h | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index dc6c9779..d00e9e5d 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -210,8 +210,13 @@ class Inverter { enqueCommand(InverterDevInform_Simple); // hardware version enqueCommand(RealTimeRunData_Debug); // live data } else if (ivGen == IV_MI){ - if (getFwVersion() == 0 || getHwVersion() == 0) - enqueCommand(InverterDevInform_All); // firmware version; might not work, esp. for 1/2 ch hardware + if (getFwVersion() == 0) { + enqueCommand(InverterDevInform_All); // hard- and firmware version + } else { + record_t<> *rec = getRecordStruct(InverterDevInform_Simple); + if (getChannelFieldValue(CH0, FLD_PART_NUM, rec) == 0) + enqueCommand(InverterDevInform_All); // hard- and firmware version for missing HW part nr, delivered by frame 1 + } if (type == INV_TYPE_4CH) { enqueCommand(0x36); } else { diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index a16cbe21..c96e9896 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -243,7 +243,8 @@ const byteAssign_t InfoAssignment[] = { } record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure rec->ts = mPayload[iv->id].ts; - iv->setValue(1, rec, (uint32_t) ((p->packet[24] << 8) + p->packet[25])); + iv->setValue(1, rec, (uint32_t) ((p->packet[24] << 8) + p->packet[25])/1); + notify(InverterDevInform_All, iv); //28737 } else if ( p->packet[9] == 0x01 || p->packet[9] == 0x10 ) {//second frame for MI, 3rd gen. answers in 0x10 DPRINT_IVID(DBG_INFO, iv->id); @@ -277,6 +278,7 @@ const byteAssign_t InfoAssignment[] = { DPRINT(DBG_INFO,F("Matching_APPFW_PN ")); DBGPRINTLN(String((uint32_t) (((p->packet[22] << 8) | p->packet[23]) << 8 | p->packet[24]) << 8 | p->packet[25])); } + notify(InverterDevInform_Simple, iv); } else { DBGPRINTLN(F("3rd gen. inverter!")); // see table in OpenDTU code, DevInfoParser.cpp devInfo[] } From 3105cd43808c824ba6f7481d9d30bf3eb87447e0 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Fri, 25 Aug 2023 08:45:43 +0200 Subject: [PATCH 04/20] HW info triggers next request immediate request prod. data if HW info was received --- src/hm/hmInverter.h | 3 +++ src/hm/hmPayload.h | 3 +++ src/hm/miPayload.h | 7 +++++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index d00e9e5d..8ce964e9 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -339,6 +339,9 @@ class Inverter { DPRINT(DBG_INFO, "alarm ID incremented to "); DBGPRINTLN(String(alarmMesIndex)); enqueCommand(AlarmData); +// ivSendHighPrio(id); +// if(mHighPrioIv == NULL) // process the request immediately if possible +// mHighPrioIv = iv; } } } diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index 441981cf..3d8692e4 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -338,6 +338,9 @@ class HmPayload { yield(); } } + if( (InverterDevInform_All == mPayload[iv->id].txCmd) && (mHighPrioIv == NULL) ) // process next request immediately if possible + mHighPrioIv = iv; + } else { DPRINT(DBG_ERROR, F("plausibility check failed, expected ")); DBGPRINT(String(rec->pyldLen)); diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index c96e9896..ecef1330 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -193,6 +193,8 @@ class MiPayload { record_t<> *rec = iv->getRecordStruct(InverterDevInform_All); // choose the record structure rec->ts = mPayload[iv->id].ts; mPayload[iv->id].gotFragment = true; + if(mHighPrioIv == NULL) // process next request immediately if possible + mHighPrioIv = iv; /* Polling the device software and hardware version number command @@ -244,7 +246,7 @@ const byteAssign_t InfoAssignment[] = { record_t<> *rec = iv->getRecordStruct(InverterDevInform_Simple); // choose the record structure rec->ts = mPayload[iv->id].ts; iv->setValue(1, rec, (uint32_t) ((p->packet[24] << 8) + p->packet[25])/1); - notify(InverterDevInform_All, iv); + //notify(InverterDevInform_All, iv); //28737 } else if ( p->packet[9] == 0x01 || p->packet[9] == 0x10 ) {//second frame for MI, 3rd gen. answers in 0x10 DPRINT_IVID(DBG_INFO, iv->id); @@ -278,7 +280,8 @@ const byteAssign_t InfoAssignment[] = { DPRINT(DBG_INFO,F("Matching_APPFW_PN ")); DBGPRINTLN(String((uint32_t) (((p->packet[22] << 8) | p->packet[23]) << 8 | p->packet[24]) << 8 | p->packet[25])); } - notify(InverterDevInform_Simple, iv); + //notify(InverterDevInform_Simple, iv); + notify(InverterDevInform_All, iv); } else { DBGPRINTLN(F("3rd gen. inverter!")); // see table in OpenDTU code, DevInfoParser.cpp devInfo[] } From e2f8fcab408049ec1ab641bce687545cd8094d87 Mon Sep 17 00:00:00 2001 From: dAjaY85 Date: Tue, 29 Aug 2023 14:56:10 +0200 Subject: [PATCH 05/20] Symbols instead of Text --- src/plugins/Display/Display_ePaper.cpp | 107 ++++++++++++++++--------- src/plugins/Display/imagedata.h | 41 ++++++++++ 2 files changed, 111 insertions(+), 37 deletions(-) diff --git a/src/plugins/Display/Display_ePaper.cpp b/src/plugins/Display/Display_ePaper.cpp index 8a72a485..2ac0238a 100644 --- a/src/plugins/Display/Display_ePaper.cpp +++ b/src/plugins/Display/Display_ePaper.cpp @@ -1,9 +1,9 @@ #include "Display_ePaper.h" #ifdef ESP8266 - #include +#include #elif defined(ESP32) - #include +#include #endif #include "../../utils/helper.h" #include "imagedata.h" @@ -21,7 +21,6 @@ DisplayEPaper::DisplayEPaper() { mHeadFootPadding = 16; } - //*************************************************************************** void DisplayEPaper::init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, uint8_t _BUSY, uint8_t _SCK, uint8_t _MOSI, uint32_t *utcTs, const char *version) { mUtcTs = utcTs; @@ -154,9 +153,11 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa _display->setPartialWindow(0, mHeadFootPadding, _display->width(), _display->height() - (mHeadFootPadding * 2)); _display->fillScreen(GxEPD_WHITE); + do { + // actual Production if (totalPower > 9999) { - snprintf(_fmtText, sizeof(_fmtText), "%.1f kW", (totalPower / 10000)); + snprintf(_fmtText, sizeof(_fmtText), "%.1f kW", (totalPower / 1000)); _changed = true; } else if ((totalPower > 0) && (totalPower <= 9999)) { snprintf(_fmtText, sizeof(_fmtText), "%.0f W", totalPower); @@ -164,43 +165,75 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa } else { snprintf(_fmtText, sizeof(_fmtText), "offline"); } - if (totalPower == 0){ - _display->fillRect(0, mHeadFootPadding, 200,200, GxEPD_BLACK); - _display->drawBitmap(0, 0, logo, 200, 200, GxEPD_WHITE); - } else { - _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->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); + if ((totalYieldDay > 0) && (totalYieldTotal > 0)) { + // Today Production + _display->setFont(&FreeSans18pt7b); y = _display->height() / 2; _display->setCursor(5, 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() - 38, y); - _display->println("Wh"); - y = y + tbh + 7; + if (totalYieldDay > 9999) { + snprintf(_fmtText, _display->width(), "%.1f", (totalYieldDay / 1000)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - ((tbh + 30) / 2), myToday, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 50, y); + _display->setFont(&FreeSans12pt7b); + _display->println("kWh"); + } else if (totalYieldDay <= 9999) { + snprintf(_fmtText, _display->width(), "%.0f", (totalYieldDay)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - tbh, myToday, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 38, y); + _display->setFont(&FreeSans12pt7b); + _display->println("Wh"); + } + y = y + tbh + 15; + + // Total Production + _display->setFont(&FreeSans18pt7b); _display->setCursor(5, y); - _display->print("total:"); - snprintf(_fmtText, _display->width(), "%.1f", totalYieldTotal); - _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - x = ((_display->width() - tbw) / 2) - tbx; - _display->setCursor(x, y); - _display->print(_fmtText); - _display->setCursor(_display->width() - 50, y); - _display->println("kWh"); - - _display->setCursor(10, _display->height() - (mHeadFootPadding + 10)); - snprintf(_fmtText, sizeof(_fmtText), "%d Inverter online", isprod); - _display->println(_fmtText); - + if (totalYieldTotal > 9999) { + snprintf(_fmtText, _display->width(), "%.1f", (totalYieldTotal / 1000)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 59, y); + _display->setFont(&FreeSans12pt7b); + _display->println("MWh"); + } else if (totalYieldTotal <= 9999) { + snprintf(_fmtText, _display->width(), "%.0f", (totalYieldTotal)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 50, y); + _display->setFont(&FreeSans12pt7b); + _display->println("kWh"); + } } + + // Inverter online + _display->setFont(&FreeSans12pt7b); + y = _display->height() - (mHeadFootPadding + 10); + snprintf(_fmtText, sizeof(_fmtText), " %d online", isprod); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(10, y - tbh, myWR, 20, 20, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->println(_fmtText); } while (_display->nextPage()); } //*************************************************************************** @@ -219,10 +252,10 @@ void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYield if ((isprod > 0) && (_changed)) { _changed = false; lastUpdatePaged(); - } else if((0 == totalPower) && (mEnPowerSafe)) + } else if ((0 == totalPower) && (mEnPowerSafe)) offlineFooter(); _display->powerOff(); } //*************************************************************************** -#endif // ESP32 +#endif // ESP32 diff --git a/src/plugins/Display/imagedata.h b/src/plugins/Display/imagedata.h index baaddec8..b136193b 100644 --- a/src/plugins/Display/imagedata.h +++ b/src/plugins/Display/imagedata.h @@ -9,6 +9,47 @@ #include #endif +// 'Sigma', 30x30px +const unsigned char mySigma[] PROGMEM = { + 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x3f, 0x80, 0x07, 0xf0, 0x3f, 0x80, 0x07, 0xf0, 0x3f, 0x9f, 0xe7, 0xf0, 0x3f, 0xcf, 0xe7, 0xf0, + 0x3f, 0xcf, 0xff, 0xf0, 0x3f, 0xe7, 0xff, 0xf0, 0x3f, 0xe7, 0xff, 0xf0, 0x3f, 0xf3, 0xff, 0xf0, + 0x3f, 0xf3, 0xff, 0xf0, 0x3f, 0xf9, 0xff, 0xf0, 0x3f, 0xf8, 0xff, 0xf0, 0x3f, 0xf8, 0xff, 0xf0, + 0x3f, 0xf9, 0xff, 0xf0, 0x3f, 0xf3, 0xff, 0xf0, 0x3f, 0xf3, 0xff, 0xf0, 0x3f, 0xe7, 0xff, 0xf0, + 0x3f, 0xe7, 0xff, 0xf0, 0x3f, 0xcf, 0xff, 0xf0, 0x3f, 0xcf, 0xe7, 0xf0, 0x3f, 0x9f, 0xe7, 0xf0, + 0x3f, 0x80, 0x07, 0xf0, 0x3f, 0x80, 0x07, 0xf0, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04 +}; +// 'Sun', 30x30px +const unsigned char mySun[] PROGMEM = { + 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xfb, 0xf0, + 0x3f, 0xfc, 0xfb, 0xf0, 0x3f, 0xfc, 0xfb, 0xf0, 0x3e, 0xfc, 0xf3, 0xf0, 0x3c, 0x7c, 0xf3, 0xf0, + 0x3e, 0x30, 0x33, 0xf0, 0x3f, 0x0f, 0xcb, 0xf0, 0x3f, 0x9f, 0xeb, 0xf0, 0x3f, 0xbf, 0xeb, 0xf0, + 0x3f, 0x7f, 0xd8, 0x30, 0x3f, 0x7f, 0xdf, 0xb0, 0x30, 0x7f, 0xdf, 0xb0, 0x30, 0x7f, 0xbf, 0x70, + 0x3f, 0x7f, 0xbf, 0x70, 0x3f, 0x7f, 0x83, 0x70, 0x3f, 0xbf, 0xf2, 0xf0, 0x3f, 0x9f, 0xe2, 0xf0, + 0x3f, 0x0f, 0xca, 0xf0, 0x3e, 0x30, 0x39, 0xf0, 0x3c, 0x7c, 0xf9, 0xf0, 0x3e, 0xfc, 0xf9, 0xf0, + 0x3f, 0xfc, 0xfb, 0xf0, 0x3f, 0xfc, 0xfb, 0xf0, 0x3f, 0xff, 0xfb, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04 +}; +// 'Today', 30x30px +const unsigned char myToday[] PROGMEM = { + 0xf3, 0xff, 0xff, 0x3c, 0xf3, 0xff, 0xff, 0x3c, 0x80, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x33, 0xff, 0xff, 0x30, 0x33, 0xff, 0xff, 0x30, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x3f, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xfc, 0xf0, 0x3f, 0xff, 0xf8, 0xf0, 0x3f, 0xff, 0xf1, 0xf0, + 0x3f, 0xff, 0xe3, 0xf0, 0x3f, 0xff, 0xc7, 0xf0, 0x3f, 0xff, 0x8f, 0xf0, 0x3f, 0xff, 0x1f, 0xf0, + 0x3f, 0xfe, 0x3f, 0xf0, 0x3e, 0x7c, 0x7f, 0xf0, 0x3e, 0x38, 0xff, 0xf0, 0x3f, 0x11, 0xff, 0xf0, + 0x3f, 0x83, 0xff, 0xf0, 0x3f, 0xc7, 0xff, 0xf0, 0x3f, 0xef, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x04 +}; +// 'WR', 20x20px +const unsigned char myWR[] PROGMEM = { + 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x80, 0x3f, 0xff, 0x40, 0x30, 0x7e, 0xc0, 0x3f, + 0xfd, 0xc0, 0x30, 0x7b, 0xc0, 0x3f, 0xf7, 0xc0, 0x3f, 0xef, 0xc0, 0x3f, 0xdf, 0xc0, 0x3f, 0xbf, + 0xc0, 0x3f, 0x7f, 0xc0, 0x3e, 0xff, 0xc0, 0x3d, 0xf7, 0xc0, 0x3b, 0xea, 0xc0, 0x37, 0xfd, 0xc0, + 0x2f, 0xff, 0xc0, 0x1f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10 +}; + // 'Logo', 200x200px const unsigned char logo[] PROGMEM = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, From b12effd59ed30c0dee46d40585d0c3fe519f8db7 Mon Sep 17 00:00:00 2001 From: dAjaY85 Date: Tue, 29 Aug 2023 15:28:28 +0200 Subject: [PATCH 06/20] bug fixes --- src/plugins/Display/Display_ePaper.cpp | 140 +++++++++++++------------ 1 file changed, 73 insertions(+), 67 deletions(-) diff --git a/src/plugins/Display/Display_ePaper.cpp b/src/plugins/Display/Display_ePaper.cpp index 2ac0238a..b24bbd07 100644 --- a/src/plugins/Display/Display_ePaper.cpp +++ b/src/plugins/Display/Display_ePaper.cpp @@ -165,75 +165,81 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa } 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); - - if ((totalYieldDay > 0) && (totalYieldTotal > 0)) { - // Today Production - _display->setFont(&FreeSans18pt7b); - y = _display->height() / 2; - _display->setCursor(5, y); - - if (totalYieldDay > 9999) { - snprintf(_fmtText, _display->width(), "%.1f", (totalYieldDay / 1000)); - _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - _display->drawInvertedBitmap(5, y - ((tbh + 30) / 2), myToday, 30, 30, GxEPD_BLACK); - x = ((_display->width() - tbw - 20) / 2) - tbx; - _display->setCursor(x, y); - _display->print(_fmtText); - _display->setCursor(_display->width() - 50, y); - _display->setFont(&FreeSans12pt7b); - _display->println("kWh"); - } else if (totalYieldDay <= 9999) { - snprintf(_fmtText, _display->width(), "%.0f", (totalYieldDay)); - _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - _display->drawInvertedBitmap(5, y - tbh, myToday, 30, 30, GxEPD_BLACK); - x = ((_display->width() - tbw - 20) / 2) - tbx; - _display->setCursor(x, y); - _display->print(_fmtText); - _display->setCursor(_display->width() - 38, y); - _display->setFont(&FreeSans12pt7b); - _display->println("Wh"); - } - y = y + tbh + 15; - - // Total Production - _display->setFont(&FreeSans18pt7b); - _display->setCursor(5, y); - if (totalYieldTotal > 9999) { - snprintf(_fmtText, _display->width(), "%.1f", (totalYieldTotal / 1000)); - _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - _display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK); - x = ((_display->width() - tbw - 20) / 2) - tbx; - _display->setCursor(x, y); - _display->print(_fmtText); - _display->setCursor(_display->width() - 59, y); - _display->setFont(&FreeSans12pt7b); - _display->println("MWh"); - } else if (totalYieldTotal <= 9999) { - snprintf(_fmtText, _display->width(), "%.0f", (totalYieldTotal)); - _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - _display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK); - x = ((_display->width() - tbw - 20) / 2) - tbx; - _display->setCursor(x, y); - _display->print(_fmtText); - _display->setCursor(_display->width() - 50, y); - _display->setFont(&FreeSans12pt7b); - _display->println("kWh"); + + if ((totalPower == 0) && (mEnPowerSafe)) { + _display->fillRect(0, mHeadFootPadding, 200, 200, GxEPD_BLACK); + _display->drawBitmap(0, 0, logo, 200, 200, GxEPD_WHITE); + } else { + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + x = ((_display->width() - tbw) / 2) - tbx; + _display->setCursor(x, mHeadFootPadding + tbh + 10); + _display->print(_fmtText); + + if ((totalYieldDay > 0) && (totalYieldTotal > 0)) { + // Today Production + _display->setFont(&FreeSans18pt7b); + y = _display->height() / 2; + _display->setCursor(5, y); + + if (totalYieldDay > 9999) { + snprintf(_fmtText, _display->width(), "%.1f", (totalYieldDay / 1000)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - ((tbh + 30) / 2), myToday, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 50, y); + _display->setFont(&FreeSans12pt7b); + _display->println("kWh"); + } else if (totalYieldDay <= 9999) { + snprintf(_fmtText, _display->width(), "%.0f", (totalYieldDay)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - tbh, myToday, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 38, y); + _display->setFont(&FreeSans12pt7b); + _display->println("Wh"); + } + y = y + tbh + 15; + + // Total Production + _display->setFont(&FreeSans18pt7b); + _display->setCursor(5, y); + if (totalYieldTotal > 9999) { + snprintf(_fmtText, _display->width(), "%.1f", (totalYieldTotal / 1000)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 59, y); + _display->setFont(&FreeSans12pt7b); + _display->println("MWh"); + } else if (totalYieldTotal <= 9999) { + snprintf(_fmtText, _display->width(), "%.0f", (totalYieldTotal)); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->print(_fmtText); + _display->setCursor(_display->width() - 50, y); + _display->setFont(&FreeSans12pt7b); + _display->println("kWh"); + } } - } - // Inverter online - _display->setFont(&FreeSans12pt7b); - y = _display->height() - (mHeadFootPadding + 10); - snprintf(_fmtText, sizeof(_fmtText), " %d online", isprod); - _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - _display->drawInvertedBitmap(10, y - tbh, myWR, 20, 20, GxEPD_BLACK); - x = ((_display->width() - tbw - 20) / 2) - tbx; - _display->setCursor(x, y); - _display->println(_fmtText); + // Inverter online + _display->setFont(&FreeSans12pt7b); + y = _display->height() - (mHeadFootPadding + 10); + snprintf(_fmtText, sizeof(_fmtText), " %d online", isprod); + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(10, y - tbh, myWR, 20, 20, GxEPD_BLACK); + x = ((_display->width() - tbw - 20) / 2) - tbx; + _display->setCursor(x, y); + _display->println(_fmtText); + } } while (_display->nextPage()); } //*************************************************************************** From 4ef38f126618f75a02e278d51dc36a46f39dcf45 Mon Sep 17 00:00:00 2001 From: dAjaY85 Date: Tue, 29 Aug 2023 22:01:56 +0200 Subject: [PATCH 07/20] Integration VersionNr durring startup --- src/plugins/Display/Display_ePaper.cpp | 23 +++++++++++++++ src/plugins/Display/Display_ePaper.h | 41 +++++++++++++------------- 2 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/plugins/Display/Display_ePaper.cpp b/src/plugins/Display/Display_ePaper.cpp index b24bbd07..c2f93938 100644 --- a/src/plugins/Display/Display_ePaper.cpp +++ b/src/plugins/Display/Display_ePaper.cpp @@ -53,6 +53,9 @@ void DisplayEPaper::init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, u headlineIP(); + _version = version; + versionFooter(); + // call the PowerPage to change the PV Power Values actualPowerPaged(0, 0, 0, 0); } @@ -122,6 +125,26 @@ void DisplayEPaper::lastUpdatePaged() { } while (_display->nextPage()); } //*************************************************************************** +void DisplayEPaper::versionFooter() { + int16_t tbx, tby; + uint16_t tbw, tbh; + + _display->setFont(&FreeSans9pt7b); + _display->setTextColor(GxEPD_WHITE); + + _display->setPartialWindow(0, _display->height() - mHeadFootPadding, _display->width(), mHeadFootPadding); + _display->fillScreen(GxEPD_BLACK); + do { + snprintf(_fmtText, sizeof(_fmtText), "Version: %s", _version); + + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + uint16_t x = ((_display->width() - tbw) / 2) - tbx; + + _display->setCursor(x, (_display->height() - 3)); + _display->println(_fmtText); + } while (_display->nextPage()); +} +//*************************************************************************** void DisplayEPaper::offlineFooter() { int16_t tbx, tby; uint16_t tbw, tbh; diff --git a/src/plugins/Display/Display_ePaper.h b/src/plugins/Display/Display_ePaper.h index d9b24e34..65c5b91a 100644 --- a/src/plugins/Display/Display_ePaper.h +++ b/src/plugins/Display/Display_ePaper.h @@ -25,27 +25,28 @@ class DisplayEPaper { public: - DisplayEPaper(); - void fullRefresh(); - void init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, uint8_t _BUSY, uint8_t _SCK, uint8_t _MOSI, uint32_t *utcTs, const char* version); - void config(uint8_t rotation, bool enPowerSafe); - void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod); - + DisplayEPaper(); + void fullRefresh(); + void init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, uint8_t _BUSY, uint8_t _SCK, uint8_t _MOSI, uint32_t* utcTs, const char* version); + void config(uint8_t rotation, bool enPowerSafe); + void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod); private: - void headlineIP(); - void actualPowerPaged(float _totalPower, float _totalYieldDay, float _totalYieldTotal, uint8_t _isprod); - void lastUpdatePaged(); - void offlineFooter(); - - uint8_t mDisplayRotation; - bool _changed = false; - char _fmtText[35]; - const char* _settedIP; - uint8_t mHeadFootPadding; - GxEPD2_GFX* _display; - uint32_t *mUtcTs; - bool mEnPowerSafe; + void headlineIP(); + void actualPowerPaged(float _totalPower, float _totalYieldDay, float _totalYieldTotal, uint8_t _isprod); + void lastUpdatePaged(); + void offlineFooter(); + void versionFooter(); + + uint8_t mDisplayRotation; + bool _changed = false; + char _fmtText[35]; + const char* _settedIP; + uint8_t mHeadFootPadding; + GxEPD2_GFX* _display; + uint32_t* mUtcTs; + bool mEnPowerSafe; + const char* _version; }; -#endif // ESP32 +#endif // ESP32 From 201098ae0bc1874c5b4a81a1187d0a1b840aca12 Mon Sep 17 00:00:00 2001 From: lumapu Date: Wed, 30 Aug 2023 00:06:32 +0200 Subject: [PATCH 08/20] 0.7.45 * change ePaper text to symbols PR #1131 * added some invertes to dev info list #1111 --- src/CHANGES.md | 4 +++ src/defines.h | 2 +- src/hm/hmDefines.h | 47 +++++++++++++++++++++++----- src/plugins/Display/Display_ePaper.h | 46 +++++++++++++-------------- 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index a16a638e..974c7282 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,9 @@ # Development Changes +## 0.7.45 - 2023-08-29 +* change ePaper text to symbols PR #1131 +* added some invertes to dev info list #1111 + ## 0.7.44 - 2023-08-28 * fix `last_success` transmitted to often #1124 diff --git a/src/defines.h b/src/defines.h index ca67f8fb..8a125bfa 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 7 -#define VERSION_PATCH 44 +#define VERSION_PATCH 45 //------------------------------------- typedef struct { diff --git a/src/hm/hmDefines.h b/src/hm/hmDefines.h index 7b1549ab..87d47699 100644 --- a/src/hm/hmDefines.h +++ b/src/hm/hmDefines.h @@ -25,7 +25,7 @@ enum {FLD_UDC = 0, FLD_IDC, FLD_PDC, FLD_YD, FLD_YW, FLD_YT, FLD_FW_BUILD_MONTH_DAY, FLD_FW_BUILD_HOUR_MINUTE, FLD_BOOTLOADER_VER, FLD_ACT_ACTIVE_PWR_LIMIT, FLD_PART_NUM, FLD_HW_VERSION, FLD_GRID_PROFILE_CODE, FLD_GRID_PROFILE_VERSION, /*FLD_ACT_REACTIVE_PWR_LIMIT, FLD_ACT_PF,*/ FLD_LAST_ALARM_CODE, FLD_MP}; - + const char* const fields[] = {"U_DC", "I_DC", "P_DC", "YieldDay", "YieldWeek", "YieldTotal", "U_AC", "U_AC_1N", "U_AC_2N", "U_AC_3N", "UAC_12", "UAC_23", "UAC_31", "I_AC", "IAC_1", "I_AC_2", "I_AC_3", "P_AC", "F_AC", "Temp", "PF_AC", "Efficiency", "Irradiation","Q_AC", @@ -259,20 +259,52 @@ typedef struct { uint16_t maxPower; } devInfo_t; +// https://github.com/lumapu/ahoy/issues/1111 +// Hardware number: +// 0xAABBCCDD +// ^^ ------- always 10 (for MI, HM, HMS, HMT) +// ^ ------ 0 = MI +// 1 = HM +// 1, 2 = HMS (version) +// 3 = HMT +// ^ ----- 0 = 1 Input +// 1 = 2 Inputs +// 2 = 4 Inputs +// 3 = 6 Inputs +// ^ ---- 0 = smallest with x inputs +// 7 = biggest with x inputs + const devInfo_t devInfo[] = { // MI 3rd gen + { 0x001311, 600 }, + { 0x001411, 700 }, + { 0x002111, 1000 }, + { 0x002311, 1200 }, + { 0x002411, 1500 }, + { 0x002511, 1500 }, + + { 0x100000, 250 }, + { 0x100010, 300 }, + { 0x100020, 350 }, + { 0x100030, 400 }, + { 0x100100, 500 }, + { 0x100110, 600 }, + { 0x100120, 700 }, + { 0x100130, 800 }, + { 0x100200, 1000 }, + { 0x100210, 1200 }, { 0x100230, 1500 }, // HM { 0x101010, 300 }, { 0x101020, 350 }, { 0x101030, 400 }, - { 0x101040, 400 }, - { 0x101110, 600 }, // [TSOL800(DE) ..20, HWv=??], [HM-600 ..20, HWv=2.66] + { 0x101110, 600 }, // [TSOL800(DE) ..20, HWv=2.66], [HM-600 ..20, HWv=2.66] { 0x101120, 700 }, { 0x101130, 800 }, { 0x101140, 800 }, - { 0x101210, 1200 }, // ..00 + { 0x101200, 1000 }, + { 0x101210, 1200 }, { 0x101230, 1500 }, // HMS @@ -281,18 +313,19 @@ const devInfo_t devInfo[] = { { 0x101051, 450 }, { 0x101071, 500 }, { 0x102111, 600 }, + { 0x101120, 700 }, { 0x102141, 800 }, { 0x101151, 900 }, { 0x102171, 1000 }, { 0x102241, 1600 }, { 0x101251, 1800 }, { 0x102251, 1800 }, - { 0x101271, 2000 }, // ..00 - { 0x102271, 2000 }, + { 0x101271, 2000 }, // v1 grey backplane, 14A + { 0x102271, 2000 }, // v2 black backplane, 16A // HMT { 0x103311, 1800 }, - { 0x103331, 2250 } // ..00 + { 0x103331, 2250 } }; #endif /*__HM_DEFINES_H__*/ diff --git a/src/plugins/Display/Display_ePaper.h b/src/plugins/Display/Display_ePaper.h index 65c5b91a..e89c191b 100644 --- a/src/plugins/Display/Display_ePaper.h +++ b/src/plugins/Display/Display_ePaper.h @@ -24,29 +24,29 @@ // 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, bool enPowerSafe); - void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod); - - private: - void headlineIP(); - void actualPowerPaged(float _totalPower, float _totalYieldDay, float _totalYieldTotal, uint8_t _isprod); - void lastUpdatePaged(); - void offlineFooter(); - void versionFooter(); - - uint8_t mDisplayRotation; - bool _changed = false; - char _fmtText[35]; - const char* _settedIP; - uint8_t mHeadFootPadding; - GxEPD2_GFX* _display; - uint32_t* mUtcTs; - bool mEnPowerSafe; - const char* _version; + public: + DisplayEPaper(); + void fullRefresh(); + void init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, uint8_t _BUSY, uint8_t _SCK, uint8_t _MOSI, uint32_t* utcTs, const char* version); + void config(uint8_t rotation, bool enPowerSafe); + void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod); + + private: + void headlineIP(); + void actualPowerPaged(float _totalPower, float _totalYieldDay, float _totalYieldTotal, uint8_t _isprod); + void lastUpdatePaged(); + void offlineFooter(); + void versionFooter(); + + uint8_t mDisplayRotation; + bool _changed = false; + char _fmtText[35]; + const char* _settedIP; + uint8_t mHeadFootPadding; + GxEPD2_GFX* _display; + uint32_t* mUtcTs; + bool mEnPowerSafe; + const char* _version; }; #endif // ESP32 From c0bb7403f365d58a28230f3d6423138e7ce67590 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Wed, 30 Aug 2023 14:48:40 +0200 Subject: [PATCH 09/20] MI - add model codes thx to beegee3 in https://github.com/lumapu/ahoy/issues/1111#issuecomment-1698100571 Only MI-600 (0x001311) is tested! --- src/hm/hmDefines.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/hm/hmDefines.h b/src/hm/hmDefines.h index edf1fc99..cef64fc1 100644 --- a/src/hm/hmDefines.h +++ b/src/hm/hmDefines.h @@ -260,9 +260,20 @@ typedef struct { } devInfo_t; const devInfo_t devInfo[] = { - // MI 2nd gen - { 0x13118f, 600 }, - + // MI 2nd gen; only 0x001311 is tested, + // others (starting with MI-250) according to https://github.com/lumapu/ahoy/issues/1111#issuecomment-1698100571 + { 0x000111, 250 }, + { 0x000311, 300 }, + { 0x000411, 350 }, + { 0x001111, 500 }, + { 0x001311, 600 }, + { 0x001321, 600 }, + { 0x001421, 700 }, + { 0x001411, 700 }, + { 0x002111, 1000 }, + { 0x002311, 1200 }, + { 0x002511, 1500 }, + { 0x002411, 1500 }, // MI 3rd gen { 0x100230, 1500 }, From 63a74eb02b30b9f9bacd751fc92bc07afcc566ea Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Wed, 30 Aug 2023 15:04:19 +0200 Subject: [PATCH 10/20] Typo in miPayload.h --- src/hm/miPayload.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index a438c346..7909f016 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -737,7 +737,7 @@ const byteAssign_t InfoAssignment[] = { uint8_t txCmd = mPayload[id].txCmd; if(!*complete) { - DPRINTLN(DBG_VERBOSE, F("incomlete, txCmd is 0x") + String(txCmd, HEX)); + DPRINTLN(DBG_VERBOSE, F("incomplete, txCmd is 0x") + String(txCmd, HEX)); //DBGHEXLN(txCmd); if (txCmd == 0x09 || txCmd == 0x11 || (txCmd >= 0x36 && txCmd <= 0x39)) return false; From b0590b6ea73c097c418467227fc174aafdc3e846 Mon Sep 17 00:00:00 2001 From: rejoe2 Date: Wed, 30 Aug 2023 20:02:07 +0200 Subject: [PATCH 11/20] MI models - cleanup delete unintented duplicates --- src/hm/hmDefines.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/hm/hmDefines.h b/src/hm/hmDefines.h index a04d7d68..71a61db5 100644 --- a/src/hm/hmDefines.h +++ b/src/hm/hmDefines.h @@ -291,13 +291,6 @@ const devInfo_t devInfo[] = { { 0x002411, 1500 }, // MI 3rd gen - { 0x001311, 600 }, - { 0x001411, 700 }, - { 0x002111, 1000 }, - { 0x002311, 1200 }, - { 0x002411, 1500 }, - { 0x002511, 1500 }, - { 0x100000, 250 }, { 0x100010, 300 }, { 0x100020, 350 }, From f3192b49ab82e3b9863749c3805d85e33c27234d Mon Sep 17 00:00:00 2001 From: lumapu Date: Fri, 1 Sep 2023 07:58:33 +0200 Subject: [PATCH 12/20] 0.7.46 * removed `delay` from ePaper * started improvements of `/system` * fix LEDs to check all configured inverters --- src/CHANGES.md | 5 + src/app.cpp | 26 ++-- src/app.h | 1 + src/hm/miPayload.h | 4 +- src/hms/hmsRadio.h | 16 ++- src/platformio.ini | 6 +- src/plugins/Display/Display.h | 8 +- src/plugins/Display/Display_Mono_64X48.h | 2 +- src/plugins/Display/Display_Mono_84X48.h | 2 +- src/plugins/Display/Display_ePaper.cpp | 166 +++++++++++++---------- src/plugins/Display/Display_ePaper.h | 15 +- src/web/RestApi.h | 2 +- src/web/html/colorBright.css | 1 + src/web/html/colorDark.css | 1 + src/web/html/style.css | 29 +++- src/web/html/system.html | 58 +++++--- 16 files changed, 218 insertions(+), 124 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index 974c7282..c81162ad 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,5 +1,10 @@ # 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 * change ePaper text to symbols PR #1131 * added some invertes to dev info list #1111 diff --git a/src/app.cpp b/src/app.cpp index 25a849ee..15fc432c 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -567,11 +567,11 @@ void app::mqttSubRxCb(JsonObject obj) { void app::setupLed(void) { 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); digitalWrite(mConfig->led.led0, led_off); } - if (mConfig->led.led1 != 0xff) { + if (mConfig->led.led1 != DEF_PIN_OFF) { pinMode(mConfig->led.led1, OUTPUT); 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_on = (mConfig->led.led_high_active) ? HIGH : LOW; - if (mConfig->led.led0 != 0xff) { - Inverter<> *iv = mSys.getInverterByPos(0); - if (NULL != iv) { - if (iv->isProducing()) - digitalWrite(mConfig->led.led0, led_on); - else - digitalWrite(mConfig->led.led0, led_off); + if (mConfig->led.led0 != DEF_PIN_OFF) { + Inverter<> *iv; + for (uint8_t id = 0; id < mSys.getNumInverters(); id++) { + iv = mSys.getInverterByPos(id); + if (NULL != iv) { + if (iv->isProducing()) { + // turn on when at least one inverter is producing + digitalWrite(mConfig->led.led0, led_on); + break; + } + else if(iv->config->enabled) + digitalWrite(mConfig->led.led0, led_off); + } } } - if (mConfig->led.led1 != 0xff) { + if (mConfig->led.led1 != DEF_PIN_OFF) { if (getMqttIsConnected()) { digitalWrite(mConfig->led.led1, led_on); } else { diff --git a/src/app.h b/src/app.h index fb3da7f6..5a7831c1 100644 --- a/src/app.h +++ b/src/app.h @@ -273,6 +273,7 @@ class app : public IApp, public ah::Scheduler { #endif if(mConfig->plugin.display.type != 0) mDisplay.payloadEventListener(cmd); + updateLed(); } void mqttSubRxCb(JsonObject obj); diff --git a/src/hm/miPayload.h b/src/hm/miPayload.h index e461a8dc..5619b1d6 100644 --- a/src/hm/miPayload.h +++ b/src/hm/miPayload.h @@ -728,8 +728,8 @@ const byteAssign_t InfoAssignment[] = { */ void reset(uint8_t id, bool clrSts = false) { - DPRINT_IVID(DBG_INFO, id); - DBGPRINTLN(F("resetPayload")); + //DPRINT_IVID(DBG_INFO, id); + //DBGPRINTLN(F("resetPayload")); memset(mPayload[id].len, 0, MAX_PAYLOAD_ENTRIES); mPayload[id].gotFragment = false; /*mPayload[id].maxPackId = MAX_PAYLOAD_ENTRIES; diff --git a/src/hms/hmsRadio.h b/src/hms/hmsRadio.h index dc79afcb..c515ae0e 100644 --- a/src/hms/hmsRadio.h +++ b/src/hms/hmsRadio.h @@ -25,7 +25,8 @@ class CmtRadio { typedef Cmt2300a CmtType; public: CmtRadio() { - mDtuSn = DTU_SN; + mDtuSn = DTU_SN; + mCmtAvail = false; } void setup(uint8_t pinCsb, uint8_t pinFcsb, bool genDtuSn = true) { @@ -63,6 +64,10 @@ class CmtRadio { mSerialDebug = true; } + bool cmtIsAvail() { + return mCmtAvail; + } + void sendControlPacket(const uint64_t *ivId, uint8_t cmd, uint16_t *data, bool isRetransmit) { DPRINT(DBG_INFO, F("sendControlPacket cmd: 0x")); DBGHEXLN(cmd); @@ -143,10 +148,14 @@ class CmtRadio { inline void reset(bool genDtuSn) { if(genDtuSn) generateDtuSn(); - if(!mCmt.reset()) + if(!mCmt.reset()) { + mCmtAvail = false; DPRINTLN(DBG_WARN, F("Initializing CMT2300A failed!")); - else + } + else { + mCmtAvail = true; mCmt.goRx(); + } mSendCnt = 0; mRetransmits = 0; @@ -208,6 +217,7 @@ class CmtRadio { bool mSerialDebug; bool mIrqRcvd; bool mRqstGetRx; + bool mCmtAvail; }; #endif /*__HMS_RADIO_H__*/ diff --git a/src/platformio.ini b/src/platformio.ini index 1e61dda1..42c1557a 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -127,8 +127,6 @@ monitor_filters = platform = espressif32@6.3.2 board = esp32-s3-devkitc-1 upload_protocol = esp-builtin -debug_tool = esp-builtin -debug_speed = 12000 build_flags = ${env.build_flags} -DDEF_NRF_CS_PIN=37 -DDEF_NRF_CE_PIN=38 @@ -142,5 +140,7 @@ build_flags = ${env.build_flags} -DDEF_LED0=18 -DDEF_LED1=17 -DLED_ACTIVE_HIGH + -DARDUINO_USB_MODE=1 + -DARDUINO_USB_CDC_ON_BOOT=1 monitor_filters = - esp32_exception_decoder + esp32_exception_decoder, colorize diff --git a/src/plugins/Display/Display.h b/src/plugins/Display/Display.h index 2340fd42..584d1c84 100644 --- a/src/plugins/Display/Display.h +++ b/src/plugins/Display/Display.h @@ -61,11 +61,14 @@ class Display { if (mMono != NULL) mMono->loop(); - if (mNewPayload || ((++mLoopCnt % 10) == 0)) { + if (mNewPayload || (((++mLoopCnt) % 30) == 0)) { mNewPayload = false; mLoopCnt = 0; DataScreen(); } + #if defined(ESP32) + mEpaper.tickerSecond(); + #endif } private: @@ -102,13 +105,10 @@ class Display { } #if defined(ESP32) else if (mCfg->type == 10) { - mEpaper.loop(totalPower, totalYieldDay, totalYieldTotal, isprod); mRefreshCycle++; } -#endif -#if defined(ESP32) if (mRefreshCycle > 480) { mEpaper.fullRefresh(); mRefreshCycle = 0; diff --git a/src/plugins/Display/Display_Mono_64X48.h b/src/plugins/Display/Display_Mono_64X48.h index 8c355322..67b38e44 100644 --- a/src/plugins/Display/Display_Mono_64X48.h +++ b/src/plugins/Display/Display_Mono_64X48.h @@ -50,7 +50,7 @@ class DisplayMono64X48 : public DisplayMono { void loop(void) { if (mEnPowerSafe) { if (mTimeout != 0) - mTimeout--; + mTimeout--; } } diff --git a/src/plugins/Display/Display_Mono_84X48.h b/src/plugins/Display/Display_Mono_84X48.h index aefe1372..9f7761dc 100644 --- a/src/plugins/Display/Display_Mono_84X48.h +++ b/src/plugins/Display/Display_Mono_84X48.h @@ -50,7 +50,7 @@ class DisplayMono84X48 : public DisplayMono { void loop(void) { if (mEnPowerSafe) { if (mTimeout != 0) - mTimeout--; + mTimeout--; } } diff --git a/src/plugins/Display/Display_ePaper.cpp b/src/plugins/Display/Display_ePaper.cpp index c2f93938..9a4b594c 100644 --- a/src/plugins/Display/Display_ePaper.cpp +++ b/src/plugins/Display/Display_ePaper.cpp @@ -21,10 +21,14 @@ DisplayEPaper::DisplayEPaper() { mHeadFootPadding = 16; } + //*************************************************************************** void DisplayEPaper::init(uint8_t type, uint8_t _CS, uint8_t _DC, uint8_t _RST, uint8_t _BUSY, uint8_t _SCK, uint8_t _MOSI, uint32_t *utcTs, const char *version) { mUtcTs = utcTs; + mRefreshState = RefreshStatus::LOGO; + mSecondCnt = 0; + if (type == 10) { Serial.begin(115200); _display = new GxEPD2_BW(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->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(); - _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() { - // screen complete black - _display->fillScreen(GxEPD_BLACK); - while (_display->nextPage()) - ; - delay(2000); - // screen complete white - _display->fillScreen(GxEPD_WHITE); - while (_display->nextPage()) - ; + if(RefreshStatus::DONE != mRefreshState) + return; + mSecondCnt = 2; + mRefreshState = RefreshStatus::BLACK; +} + +//*************************************************************************** +void DisplayEPaper::refreshLoop() { + switch(mRefreshState) { + case RefreshStatus::LOGO: + _display->fillScreen(GxEPD_BLACK); + _display->drawBitmap(0, 0, logo, 200, 200, GxEPD_WHITE); + mNextRefreshState = RefreshStatus::PARTITIALS; + mRefreshState = RefreshStatus::WAIT; + 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); + 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() { @@ -185,9 +206,8 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa } else if ((totalPower > 0) && (totalPower <= 9999)) { snprintf(_fmtText, sizeof(_fmtText), "%.0f W", totalPower); _changed = true; - } else { + } else snprintf(_fmtText, sizeof(_fmtText), "offline"); - } if ((totalPower == 0) && (mEnPowerSafe)) { _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)) { // 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); y = _display->height() / 2; _display->setCursor(5, y); - - if (totalYieldDay > 9999) { - snprintf(_fmtText, _display->width(), "%.1f", (totalYieldDay / 1000)); - _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - _display->drawInvertedBitmap(5, y - ((tbh + 30) / 2), myToday, 30, 30, GxEPD_BLACK); - x = ((_display->width() - tbw - 20) / 2) - tbx; - _display->setCursor(x, y); - _display->print(_fmtText); - _display->setCursor(_display->width() - 50, y); - _display->setFont(&FreeSans12pt7b); - _display->println("kWh"); - } else if (totalYieldDay <= 9999) { - snprintf(_fmtText, _display->width(), "%.0f", (totalYieldDay)); - _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - _display->drawInvertedBitmap(5, y - tbh, myToday, 30, 30, GxEPD_BLACK); - x = ((_display->width() - tbw - 20) / 2) - tbx; - _display->setCursor(x, y); - _display->print(_fmtText); - _display->setCursor(_display->width() - 38, y); - _display->setFont(&FreeSans12pt7b); - _display->println("Wh"); - } + _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); + _display->drawInvertedBitmap(5, ((kwh) ? (y - ((tbh + 30) / 2)) : (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() - ((kwh) ? 50 : 38), y); + _display->setFont(&FreeSans12pt7b); + _display->println((kwh) ? "kWh" : "Wh"); y = y + tbh + 15; + // Total Production - _display->setFont(&FreeSans18pt7b); - _display->setCursor(5, y); - if (totalYieldTotal > 9999) { + bool mwh = (totalYieldTotal > 9999); + if(mwh) snprintf(_fmtText, _display->width(), "%.1f", (totalYieldTotal / 1000)); - _display->getTextBounds(_fmtText, 0, 0, &tbx, &tby, &tbw, &tbh); - _display->drawInvertedBitmap(5, y - tbh, mySigma, 30, 30, GxEPD_BLACK); - x = ((_display->width() - tbw - 20) / 2) - tbx; - _display->setCursor(x, y); - _display->print(_fmtText); - _display->setCursor(_display->width() - 59, y); - _display->setFont(&FreeSans12pt7b); - _display->println("MWh"); - } else if (totalYieldTotal <= 9999) { + else 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"); - } + + _display->setFont(&FreeSans18pt7b); + _display->setCursor(5, y); + _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() - ((mwh) ? 59 : 50), y); + _display->setFont(&FreeSans12pt7b); + _display->println((mwh) ? "MWh" : "kWh"); } // Inverter online @@ -263,14 +269,18 @@ void DisplayEPaper::actualPowerPaged(float totalPower, float totalYieldDay, floa _display->setCursor(x, y); _display->println(_fmtText); } + yield(); } while (_display->nextPage()); } //*************************************************************************** void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { + if(RefreshStatus::DONE != mRefreshState) + return; + // 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 - _settedIP = WiFi.localIP().toString().c_str(); + _settedIP = WiFi.localIP().toString(); headlineIP(); } @@ -286,5 +296,11 @@ void DisplayEPaper::loop(float totalPower, float totalYieldDay, float totalYield _display->powerOff(); } + //*************************************************************************** +void DisplayEPaper::tickerSecond() { + if(mSecondCnt != 0) + mSecondCnt--; + refreshLoop(); +} #endif // ESP32 diff --git a/src/plugins/Display/Display_ePaper.h b/src/plugins/Display/Display_ePaper.h index e89c191b..2ff7e58d 100644 --- a/src/plugins/Display/Display_ePaper.h +++ b/src/plugins/Display/Display_ePaper.h @@ -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 config(uint8_t rotation, bool enPowerSafe); void loop(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod); + void refreshLoop(); + void tickerSecond(); private: void headlineIP(); @@ -38,15 +40,26 @@ class DisplayEPaper { void offlineFooter(); void versionFooter(); + enum class RefreshStatus : uint8_t { + DONE, + BLACK, + WHITE, + WAIT, + PARTITIALS, + LOGO + }; + uint8_t mDisplayRotation; bool _changed = false; char _fmtText[35]; - const char* _settedIP; + String _settedIP; uint8_t mHeadFootPadding; GxEPD2_GFX* _display; uint32_t* mUtcTs; bool mEnPowerSafe; const char* _version; + RefreshStatus mRefreshState, mNextRefreshState; + uint8_t mSecondCnt; }; #endif // ESP32 diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 095b065e..7f722d89 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -224,7 +224,7 @@ class RestApi { #endif /* !defined(ETHERNET) */ obj[F("device_name")] = mConfig->sys.deviceName; obj[F("dark_mode")] = (bool)mConfig->sys.darkMode; - obj[F("sched_reboot")] = (bool)mConfig->sys.schedReboot; + obj[F("sched_reboot")] = (bool)mConfig->sys.schedReboot; obj[F("mac")] = WiFi.macAddress(); obj[F("hostname")] = mConfig->sys.deviceName; diff --git a/src/web/html/colorBright.css b/src/web/html/colorBright.css index 255b5130..47382daa 100644 --- a/src/web/html/colorBright.css +++ b/src/web/html/colorBright.css @@ -8,6 +8,7 @@ --success: #009900; --input-bg: #eee; + --table-border: #ccc; --nav-bg: #333; --primary: #006ec0; diff --git a/src/web/html/colorDark.css b/src/web/html/colorDark.css index d143f8be..3d9d167a 100644 --- a/src/web/html/colorDark.css +++ b/src/web/html/colorDark.css @@ -8,6 +8,7 @@ --success: #00bb00; --input-bg: #333; + --table-border: #333; --nav-bg: #333; --primary: #004d87; diff --git a/src/web/html/style.css b/src/web/html/style.css index 4d4dc6f8..6d19bd21 100644 --- a/src/web/html/style.css +++ b/src/web/html/style.css @@ -329,7 +329,7 @@ th { .table td, .table th { padding: .75rem; - border-bottom: 1px solid var(--nav-bg); + border-bottom: 1px solid var(--table-border); } #wrapper { @@ -737,3 +737,30 @@ h5 { .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; +} diff --git a/src/web/html/system.html b/src/web/html/system.html index d51c01cc..c504057f 100644 --- a/src/web/html/system.html +++ b/src/web/html/system.html @@ -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) { const pa = ["MIN (recommended)", "LOW", "HIGH", "MAX"]; const datarate = ["1 MBps", "2 MBps", "250 kbps"]; - var main = document.getElementById("radio"); - var h = div(["head", "p-2"]); - var r = div(["row"]); - r.appendChild(div(["col", "a-c"], "Radio")); - h.appendChild(r); - main.appendChild(h); - - main.appendChild( - genTabRow("nrf24l01" + (obj["isPVariant"] ? "+ " : ""), (obj["isconnected"] ? "is connected " : "is not connected ")) - ); - - if(obj["isconnected"]) { - main.appendChild(genTabRow("Datarate", datarate[obj["DataRate"]])); - main.appendChild(genTabRow("Power Level", pa[obj["power_level"]])); - } + document.getElementById("radio").append( + headline("NRF Radio"), + ml("table", {class: "table"}, [ + ml("tbody", {}, [ + tr("NRF24L01", badge(obj.isconnected, ((obj.isconnected) ? "" : "not ") + "connected")), + tr("Power Level", pa[obj.power_level]) + ]) + ]), - 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"]) + headline("Statistics"), + ml("table", {class: "table"}, [ + ml("tbody", {}, [ + tr("TX count", stat.tx_cnt), + tr("RX success", stat.rx_success), + tr("RX fail", stat.rx_fail), + tr("RX no answer", stat.rx_fail_answer), + tr("RX fragments", stat.frame_cnt), + tr("TX retransmits", stat.retransmits) + ]) + ]) ); } From 69e2a63eab755313938a88a7be66c2211c0e132d Mon Sep 17 00:00:00 2001 From: lumapu Date: Fri, 1 Sep 2023 23:35:51 +0200 Subject: [PATCH 13/20] 0.7.46 * send loop skip disabled inverters fix * print generated DTU SN to console --- src/CHANGES.md | 2 ++ src/app.cpp | 30 ++++++++++++++++-------------- src/hm/hmRadio.h | 7 ++++--- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index c81162ad..e55fc198 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -4,6 +4,8 @@ * removed `delay` from ePaper * started improvements of `/system` * fix LEDs to check all configured inverters +* send loop skip disabled inverters fix +* print generated DTU SN to console ## 0.7.45 - 2023-08-29 * change ePaper text to symbols PR #1131 diff --git a/src/app.cpp b/src/app.cpp index 15fc432c..ca33a895 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -454,24 +454,26 @@ void app::tickSend(void) { int8_t maxLoop = MAX_NUM_INVERTERS; Inverter<> *iv = mSys.getInverterByPos(mSendLastIvId); do { - mSendLastIvId = ((MAX_NUM_INVERTERS - 1) == mSendLastIvId) ? 0 : mSendLastIvId + 1; - iv = mSys.getInverterByPos(mSendLastIvId); - } while ((NULL == iv) && ((maxLoop--) > 0)); + do { + mSendLastIvId = ((MAX_NUM_INVERTERS - 1) == mSendLastIvId) ? 0 : mSendLastIvId + 1; + iv = mSys.getInverterByPos(mSendLastIvId); + } while ((NULL == iv) && ((maxLoop--) > 0)); + } while((!iv->config->enabled) && (maxLoop > 0)); if (NULL != iv) { if (iv->config->enabled) { if(mConfig->nrf.enabled) { - if (iv->ivGen == IV_HM) - mPayload.ivSend(iv); - else if(iv->ivGen == IV_MI) - mMiPayload.ivSend(iv); - } - #if defined(ESP32) - if(mConfig->cmt.enabled) { - if((iv->ivGen == IV_HMS) || (iv->ivGen == IV_HMT)) - mHmsPayload.ivSend(iv); - } - #endif + if (iv->ivGen == IV_HM) + mPayload.ivSend(iv); + else if(iv->ivGen == IV_MI) + mMiPayload.ivSend(iv); + } + #if defined(ESP32) + if(mConfig->cmt.enabled) { + if((iv->ivGen == IV_HMS) || (iv->ivGen == IV_HMT)) + mHmsPayload.ivSend(iv); + } + #endif } } } else { diff --git a/src/hm/hmRadio.h b/src/hm/hmRadio.h index 0b5feea5..ee037adb 100644 --- a/src/hm/hmRadio.h +++ b/src/hm/hmRadio.h @@ -32,7 +32,7 @@ class HmRadio { public: HmRadio() : mNrf24(CE_PIN, CS_PIN, SPI_SPEED) { if(mSerialDebug) { - DPRINT(DBG_VERBOSE, F("hmRadio.h : HmRadio():mNrf24(CE_PIN: ")); + DPRINT(DBG_VERBOSE, F("hmRadio.h : HmRadio():mNrf24(CE_PIN: ")); DBGPRINT(String(CE_PIN)); DBGPRINT(F(", CS_PIN: ")); DBGPRINT(String(CS_PIN)); @@ -117,8 +117,9 @@ class HmRadio { if(mNrf24.isChipConnected()) { DPRINTLN(DBG_INFO, F("Radio Config:")); mNrf24.printPrettyDetails(); - } - else + DPRINT(DBG_INFO, F("DTU_SN: 0x")); + DBGPRINTLN(String(DTU_RADIO_ID, HEX)); + } else DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring")); } From 7c6cb35c8ed78de7c91263b99b8f79217beb4d46 Mon Sep 17 00:00:00 2001 From: dAjaY85 Date: Mon, 4 Sep 2023 11:02:25 +0200 Subject: [PATCH 14/20] Integration 2.42" Display als Typ 6 --- src/plugins/Display/Display.h | 2 +- src/plugins/Display/Display_Mono_128X64.h | 4 +++- src/web/html/setup.html | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/Display/Display.h b/src/plugins/Display/Display.h index 2340fd42..76b41c77 100644 --- a/src/plugins/Display/Display.h +++ b/src/plugins/Display/Display.h @@ -35,7 +35,7 @@ class Display { case 3: mMono = new DisplayMono84X48(); break; case 4: mMono = new DisplayMono128X32(); break; case 5: mMono = new DisplayMono64X48(); break; - + case 6: mMono = new DisplayMono128X64(); break; #if defined(ESP32) case 10: mMono = NULL; // ePaper does not use this diff --git a/src/plugins/Display/Display_Mono_128X64.h b/src/plugins/Display/Display_Mono_128X64.h index a828816c..b7d52868 100644 --- a/src/plugins/Display/Display_Mono_128X64.h +++ b/src/plugins/Display/Display_Mono_128X64.h @@ -27,10 +27,12 @@ class DisplayMono128X64 : public DisplayMono { case 1: mDisplay = new U8G2_SSD1306_128X64_NONAME_F_HW_I2C(rot, reset, clock, data); break; - default: case 2: mDisplay = new U8G2_SH1106_128X64_NONAME_F_HW_I2C(rot, reset, clock, data); break; + case 6: + mDisplay = new U8G2_SSD1309_128X64_NONAME0_F_HW_I2C(rot, reset, clock, data); + break; } mUtcTs = utcTs; diff --git a/src/web/html/setup.html b/src/web/html/setup.html index 9df891c8..dbc82a75 100644 --- a/src/web/html/setup.html +++ b/src/web/html/setup.html @@ -839,7 +839,7 @@ } // keep display types grouped - var opts = [[0, "None"], [2, "SH1106 1.3\" 128X64"], [5, "SSD1306 0.66\" 64X48 (Wemos OLED Shield)"], [4, "SSD1306 0.91\" 128X32"], [1, "SSD1306 0.96\" 128X64"], [3, "Nokia5110"]]; + var opts = [[0, "None"], [2, "SH1106 1.3\" 128X64"], [5, "SSD1306 0.66\" 64X48 (Wemos OLED Shield)"], [4, "SSD1306 0.91\" 128X32"], [1, "SSD1306 0.96\" 128X64"], [6, "SSD1309 2.42\" 128X64"], [3, "Nokia5110"]]; if("ESP32" == type) opts.push([10, "ePaper"]); var dispType = sel("disp_typ", opts, obj["disp_typ"]); From 67d3e824afce8ed705e8eb81f9086d00a4e6e178 Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 4 Sep 2023 20:27:06 +0200 Subject: [PATCH 15/20] 0.7.46 * HW Versions for MI series PR #1133 --- src/CHANGES.md | 3 ++- src/hm/hmInverter.h | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index e55fc198..71b15400 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -1,11 +1,12 @@ # Development Changes -## 0.7.46 - 2023-09-01 +## 0.7.46 - 2023-09-04 * removed `delay` from ePaper * started improvements of `/system` * fix LEDs to check all configured inverters * send loop skip disabled inverters fix * print generated DTU SN to console +* HW Versions for MI series PR #1133 ## 0.7.45 - 2023-08-29 * change ePaper text to symbols PR #1131 diff --git a/src/hm/hmInverter.h b/src/hm/hmInverter.h index c491f754..c8088087 100644 --- a/src/hm/hmInverter.h +++ b/src/hm/hmInverter.h @@ -339,9 +339,6 @@ class Inverter { DPRINT(DBG_INFO, "alarm ID incremented to "); DBGPRINTLN(String(alarmMesIndex)); enqueCommand(AlarmData); -// ivSendHighPrio(id); -// if(mHighPrioIv == NULL) // process the request immediately if possible -// mHighPrioIv = iv; } } } From 7dfe7d425f3872477e45a8dbe7507e8fc6cd7dd6 Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 4 Sep 2023 20:30:05 +0200 Subject: [PATCH 16/20] 0.7.46 * 2.42" display (SSD1309) integration PR #1139 --- src/CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/CHANGES.md b/src/CHANGES.md index 71b15400..402ec595 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -7,6 +7,7 @@ * send loop skip disabled inverters fix * print generated DTU SN to console * HW Versions for MI series PR #1133 +* 2.42" display (SSD1309) integration PR #1139 ## 0.7.45 - 2023-08-29 * change ePaper text to symbols PR #1131 From a1a9a1f9cbf4f4cc16f6f170e8170926096fc67a Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 4 Sep 2023 20:45:31 +0200 Subject: [PATCH 17/20] 0.7.46 * add / rename alarm codes PR #1118 --- src/CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CHANGES.md b/src/CHANGES.md index 402ec595..f142a012 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -8,6 +8,8 @@ * print generated DTU SN to console * HW Versions for MI series PR #1133 * 2.42" display (SSD1309) integration PR #1139 +* update user manual PR #1121 +* add / rename alarm codes PR #1118 ## 0.7.45 - 2023-08-29 * change ePaper text to symbols PR #1131 From 4b34aadc1690566cb37bc37b4b5f8e20b40ec94d Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 4 Sep 2023 21:32:23 +0200 Subject: [PATCH 18/20] 0.7.46 * luminance of display can be changed during runtime #1106 --- src/CHANGES.md | 2 ++ src/config/config.h | 2 +- src/plugins/Display/Display.h | 2 +- src/plugins/Display/Display_Mono_128X32.h | 7 ++++++- src/plugins/Display/Display_Mono_128X64.h | 7 ++++++- src/plugins/Display/Display_Mono_64X48.h | 7 ++++++- src/plugins/Display/Display_Mono_84X48.h | 7 ++++++- 7 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/CHANGES.md b/src/CHANGES.md index f142a012..6c59822e 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -10,6 +10,8 @@ * 2.42" display (SSD1309) integration PR #1139 * update user manual PR #1121 * add / rename alarm codes PR #1118 +* revert default pin ESP32 for NRF23-CE #1132 +* luminance of display can be changed during runtime #1106 ## 0.7.45 - 2023-08-29 * change ePaper text to symbols PR #1131 diff --git a/src/config/config.h b/src/config/config.h index 397ad15a..54686ab8 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -68,7 +68,7 @@ #define DEF_NRF_CS_PIN 5 #endif #ifndef DEF_NRF_CE_PIN - #define DEF_NRF_CE_PIN 17 + #define DEF_NRF_CE_PIN 4 #endif #ifndef DEF_NRF_IRQ_PIN #define DEF_NRF_IRQ_PIN 16 diff --git a/src/plugins/Display/Display.h b/src/plugins/Display/Display.h index 915a7475..36a7df46 100644 --- a/src/plugins/Display/Display.h +++ b/src/plugins/Display/Display.h @@ -59,7 +59,7 @@ class Display { void tickerSecond() { if (mMono != NULL) - mMono->loop(); + mMono->loop(mCfg->contrast); if (mNewPayload || (((++mLoopCnt) % 30) == 0)) { mNewPayload = false; diff --git a/src/plugins/Display/Display_Mono_128X32.h b/src/plugins/Display/Display_Mono_128X32.h index e9e09d28..5a6d6c7e 100644 --- a/src/plugins/Display/Display_Mono_128X32.h +++ b/src/plugins/Display/Display_Mono_128X32.h @@ -46,11 +46,16 @@ class DisplayMono128X32 : public DisplayMono { mLuminance = lum; } - void loop(void) { + void loop(uint8_t lum) { if (mEnPowerSafe) { if (mTimeout != 0) mTimeout--; } + + if(mLuminance != lum) { + mLuminance = lum; + mDisplay->setContrast(mLuminance); + } } void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { diff --git a/src/plugins/Display/Display_Mono_128X64.h b/src/plugins/Display/Display_Mono_128X64.h index b7d52868..438cb79e 100644 --- a/src/plugins/Display/Display_Mono_128X64.h +++ b/src/plugins/Display/Display_Mono_128X64.h @@ -54,11 +54,16 @@ class DisplayMono128X64 : public DisplayMono { mLuminance = lum; } - void loop(void) { + void loop(uint8_t lum) { if (mEnPowerSafe) { if (mTimeout != 0) mTimeout--; } + + if(mLuminance != lum) { + mLuminance = lum; + mDisplay->setContrast(mLuminance); + } } void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { diff --git a/src/plugins/Display/Display_Mono_64X48.h b/src/plugins/Display/Display_Mono_64X48.h index 67b38e44..ae074c33 100644 --- a/src/plugins/Display/Display_Mono_64X48.h +++ b/src/plugins/Display/Display_Mono_64X48.h @@ -47,11 +47,16 @@ class DisplayMono64X48 : public DisplayMono { mLuminance = lum; } - void loop(void) { + void loop(uint8_t lum) { if (mEnPowerSafe) { if (mTimeout != 0) mTimeout--; } + + if(mLuminance != lum) { + mLuminance = lum; + mDisplay->setContrast(mLuminance); + } } void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { diff --git a/src/plugins/Display/Display_Mono_84X48.h b/src/plugins/Display/Display_Mono_84X48.h index 9f7761dc..fff983bc 100644 --- a/src/plugins/Display/Display_Mono_84X48.h +++ b/src/plugins/Display/Display_Mono_84X48.h @@ -47,11 +47,16 @@ class DisplayMono84X48 : public DisplayMono { mLuminance = lum; } - void loop(void) { + void loop(uint8_t lum) { if (mEnPowerSafe) { if (mTimeout != 0) mTimeout--; } + + if(mLuminance != lum) { + mLuminance = lum; + mDisplay->setContrast(mLuminance); + } } void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) { From 81dfff15ca52f680fa3e70163b5abb7bee309064 Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 4 Sep 2023 21:36:02 +0200 Subject: [PATCH 19/20] 0.7.46 * fix compile --- src/plugins/Display/Display_Mono.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/Display/Display_Mono.h b/src/plugins/Display/Display_Mono.h index 42eea5f3..4739f83f 100644 --- a/src/plugins/Display/Display_Mono.h +++ b/src/plugins/Display/Display_Mono.h @@ -23,7 +23,7 @@ class 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 config(bool enPowerSafe, bool enScreenSaver, uint8_t lum) = 0; - virtual void loop(void) = 0; + virtual void loop(uint8_t lum) = 0; virtual void disp(float totalPower, float totalYieldDay, float totalYieldTotal, uint8_t isprod) = 0; protected: From 6b721cbe0cf736afbe93479288417fa60db50988 Mon Sep 17 00:00:00 2001 From: lumapu Date: Mon, 4 Sep 2023 21:37:02 +0200 Subject: [PATCH 20/20] 0.7.46 * version number increase --- src/defines.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/defines.h b/src/defines.h index 8a125bfa..465bf201 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 7 -#define VERSION_PATCH 45 +#define VERSION_PATCH 46 //------------------------------------- typedef struct {