You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

228 lines
8.9 KiB

//-----------------------------------------------------------------------------
// 2024 Ahoy, https://ahoydtu.de
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
//-----------------------------------------------------------------------------
#pragma once
#include "Display_Mono.h"
class DisplayMono84X48 : public DisplayMono {
public:
DisplayMono84X48() : DisplayMono() {
mExtra = 0;
}
void config(display_t *cfg) override {
mCfg = cfg;
}
void init(DisplayData *displayData) override {
u8g2_cb_t *rot = (u8g2_cb_t *)((mCfg->rot != 0x00) ? U8G2_R2 : U8G2_R0);
monoInit(new U8G2_PCD8544_84X48_F_4W_SW_SPI(rot, mCfg->disp_clk, mCfg->disp_data, mCfg->disp_cs, mCfg->disp_dc, 0xff), displayData);
calcLinePositions();
switch(mCfg->graph_size) { // var opts2 = [[0, "Line 1 - 2"], [1, "Line 2 - 3"], [2, "Line 1 - 3"], [3, "Line 2 - 4"], [4, "Line 1 - 4"]];
case 0:
graph_first_line = 1;
graph_last_line = 2;
break;
case 1:
graph_first_line = 2;
graph_last_line = 3;
break;
case 2:
graph_first_line = 1;
graph_last_line = 3;
break;
case 3:
graph_first_line = 2;
graph_last_line = 4;
break;
case 4:
default:
graph_first_line = 1;
graph_last_line = 4;
break;
}
if (mCfg->graph_ratio > 0)
initPowerGraph(mDispWidth - 16, mLineYOffsets[graph_last_line] - mLineYOffsets[graph_first_line - 1] - 2);
printText("Ahoy!", l_Ahoy, 0xff);
printText("ahoydtu.de", l_Website, 0xff);
printText(mDisplayData->version, l_Version, 0xff);
mDisplay->sendBuffer();
}
void disp(void) override {
mDisplay->clearBuffer();
// Layout-Test
/*
mDisplayData->nrSleeping = 10;
mDisplayData->nrProducing = 10;
mDisplayData->totalPower = 19897.6; // W
mDisplayData->totalYieldDay = 15521.9; // Wh
mDisplayData->totalYieldTotal = 654321.9; // kWh
mDisplay->drawPixel(0, 0);
mDisplay->drawPixel(mDispWidth-1, 0);
mDisplay->drawPixel(0, mDispHeight-1);
mDisplay->drawPixel(mDispWidth-1, mDispHeight-1);
*/
// add new power data to power graph
if (mDisplayData->nrProducing > 0) {
addPowerGraphEntry(mDisplayData->totalPower);
}
// print Date and time
if (0 != mDisplayData->utcTs)
printText(ah::getDateTimeStrShort_i18n(mDisplayData->utcTs).c_str(), l_Time, 0xff);
if (showLine(l_Status)) {
// alternatively:
// print ip address
if (!(mExtra % 5) && (mDisplayData->ipAddress)) {
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%s", (mDisplayData->ipAddress).toString().c_str());
printText(mFmtText, l_Status, 0xff);
}
// print status of inverters
else {
if (0 == mDisplayData->nrSleeping + mDisplayData->nrProducing)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, STR_NO_INVERTER);
else if (0 == mDisplayData->nrSleeping)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "\x86"); // sun symbol
else if (0 == mDisplayData->nrProducing)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "\x87"); // moon symbol
else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%d\x86 %d\x87", mDisplayData->nrProducing, mDisplayData->nrSleeping);
printText(mFmtText, l_Status, 0xff);
}
}
if (showLine(l_TotalPower)) {
// print total power
if (mDisplayData->nrProducing > 0) {
if (mDisplayData->totalPower > 9999.0)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f kW", (mDisplayData->totalPower / 1000.0));
else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f W", mDisplayData->totalPower);
printText(mFmtText, l_TotalPower, 0xff);
} else
printText(STR_OFFLINE, l_TotalPower, 0xff);
}
if (showLine(l_YieldDay)) {
// print day yield
printText("\x88", l_YieldDay, 10); // day symbol
if (mDisplayData->totalYieldDay > 9999.0)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f kWh", mDisplayData->totalYieldDay / 1000.0);
else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f Wh", mDisplayData->totalYieldDay);
printText(mFmtText, l_YieldDay, 0xff);
}
if (showLine(l_YieldTotal)) {
// print total yield
printText("\x83", l_YieldTotal, 10); // total symbol
if (mDisplayData->totalYieldTotal > 9999.0)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.2f MWh", mDisplayData->totalYieldTotal / 1000.0);
else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%.0f kWh", mDisplayData->totalYieldTotal);
printText(mFmtText, l_YieldTotal, 0xff);
}
if ((mCfg->graph_ratio > 0) && (mDispSwitchState == DispSwitchState::GRAPH)) {
// plot power graph
plotPowerGraph(8, mLineYOffsets[graph_last_line] - 1);
}
// draw dynamic RSSI bars
int rssi_bar_height = 7;
for (int i = 0; i < 4; i++) {
int rssi_threshold = -60 - i * 10;
uint8_t barwidth = std::min(4 - i, 3);
if (mDisplayData->RadioRSSI > rssi_threshold)
mDisplay->drawBox(0, 8 + (rssi_bar_height + 1) * i, barwidth, rssi_bar_height);
if (mDisplayData->WifiRSSI > rssi_threshold)
mDisplay->drawBox(mDispWidth - barwidth, 8 + (rssi_bar_height + 1) * i, barwidth, rssi_bar_height);
}
// draw dynamic antenna and WiFi symbols
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%c", mDisplayData->RadioSymbol?'\x80':'\x84'); // NRF
printText(mFmtText, l_RSSI);
if (mDisplayData->MQTTSymbol)
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "\x89"); // MQTT
else
snprintf(mFmtText, DISP_FMT_TEXT_LEN, "%c", mDisplayData->WifiSymbol?'\x81':'\x85'); // Wifi connected
printText(mFmtText, l_RSSI, mDispWidth - 6);
mDisplay->sendBuffer();
mExtra++;
}
private:
enum _dispLine {
// start page
l_Website = 0,
l_Ahoy = 2,
l_Version = 4,
// run page
l_Time = 0,
l_Status = 1,
l_TotalPower = 2,
l_YieldDay = 3,
l_YieldTotal = 4,
// run page - rssi bar symbols
l_RSSI = 4,
// End
l_MAX_LINES = 5,
};
uint8_t graph_first_line = 0;
uint8_t graph_last_line = 0;
void calcLinePositions() {
uint8_t yOff = 0;
uint8_t i = 0;
do {
setLineFont(i);
uint8_t asc = mDisplay->getAscent();
yOff += asc;
mLineYOffsets[i] = yOff;
uint8_t dsc = mDisplay->getDescent();
if (l_TotalPower != i) // power line needs no descent spacing
yOff -= dsc;
yOff++; // instead lets spend one pixel space between all lines
i++;
} while(l_MAX_LINES > i);
}
inline void setLineFont(uint8_t line) {
if (line == l_TotalPower) // || (line == l_Ahoy) -> l_TotalPower == l_Ahoy == 2
mDisplay->setFont(u8g2_font_logisoso16_tr);
else
mDisplay->setFont(u8g2_font_5x8_symbols_ahoy);
}
void printText(const char *text, uint8_t line, uint8_t col=0) {
uint8_t dispX;
setLineFont(line);
if (0xff == col)
dispX = (mDispWidth - mDisplay->getStrWidth(text)) / 2; // center text
else
dispX = col;
mDisplay->drawStr(dispX, mLineYOffsets[line], text);
}
bool showLine(uint8_t line) {
return ((mDispSwitchState == DispSwitchState::TEXT) || ((line < graph_first_line) || (line > graph_last_line)));
}
};