Skip to content

Commit

Permalink
Feature: show power grid usage on display (#658)
Browse files Browse the repository at this point in the history
* make efficient use of available display area

fix calculation of the text baselines, using getAscent() in favor of
getMaxCharHeight(), which includes ascent and descent. this moves the
first text up and allows to insert margin between the lines until the
display area is fully utilized.

on large displays, if the small diagram is selected, keep the first line
rather low to avoid collision with the diagram y-axis label. in this mode,
there is still more space between the text lines as before, allowing for
improved readability.

* Feature: show power grid usage on display

if the power meter is enabled, the display will use two of three out
of every three-second time slot to show the grid consumption.

closes #620.
  • Loading branch information
schlimmchen committed Feb 19, 2024
1 parent b794f46 commit 9240663
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 4 deletions.
42 changes: 40 additions & 2 deletions src/Display_Graphic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
*/
#include "Display_Graphic.h"
#include "Datastore.h"
#include "PowerMeter.h"
#include "Configuration.h"
#include <NetworkSettings.h>
#include <map>
#include <time.h>
Expand Down Expand Up @@ -31,6 +33,8 @@ const uint8_t languages[] = {
static const char* const i18n_offline[] = { "Offline", "Offline", "Offline" };
static const char* const i18n_current_power_w[] = { "%.0f W", "%.0f W", "%.0f W" };
static const char* const i18n_current_power_kw[] = { "%.1f kW", "%.1f kW", "%.1f kW" };
static const char* const i18n_meter_power_w[] = { "grid: %.0f W", "Netz: %.0f W", "reseau: %.0f W" };
static const char* const i18n_meter_power_kw[] = { "grid: %.1f kW", "Netz: %.1f kW", "reseau: %.1f kW" };
static const char* const i18n_yield_today_wh[] = { "today: %4.0f Wh", "Heute: %4.0f Wh", "auj.: %4.0f Wh" };
static const char* const i18n_yield_total_kwh[] = { "total: %.1f kWh", "Ges.: %.1f kWh", "total: %.1f kWh" };
static const char* const i18n_date_format[] = { "%m/%d/%Y %H:%M", "%d.%m.%Y %H:%M", "%d/%m/%Y %H:%M" };
Expand Down Expand Up @@ -67,11 +71,19 @@ void DisplayGraphicClass::init(Scheduler& scheduler, const DisplayType_t type, c

void DisplayGraphicClass::calcLineHeights()
{
uint8_t yOff = 0;
bool diagram = (_isLarge && _diagram_mode == DiagramMode_t::Small);
// the diagram needs space. we need to keep
// away from the y-axis label in particular.
uint8_t yOff = (diagram?7:0);
for (uint8_t i = 0; i < 4; i++) {
setFont(i);
yOff += (_display->getMaxCharHeight());
yOff += _display->getAscent();
_lineOffsets[i] = yOff;
yOff += ((!_isLarge || diagram)?2:3);
// the descent is a negative value and moves the *next* line's
// baseline. the first line never uses a letter with descent and
// we need that space when showing the small diagram.
yOff -= ((i == 0 && diagram)?0:_display->getDescent());
}
}

Expand Down Expand Up @@ -252,6 +264,32 @@ void DisplayGraphicClass::loop()
}
}

// the IP and time info in the third line use three-second slots. the
// timing for the power meter is chosen such that every third of those
// three-second slots is used to NOT overwrite the total inverter energy.
bool timing = (_mExtra % 9) >= 3;

if (showText && Configuration.get().PowerMeter.Enabled && timing && !displayPowerSave) {
// erase the third line and print the power meter value instead.
// we do it this way to touch as least upstream code as possible
// to make maintenance easier.
setFont(2);
auto lineHeight = _display->getAscent() - _display->getDescent();
auto y = _lineOffsets[2] - _display->getAscent();
_display->setDrawColor(0);
_display->drawBox(0, y, _display->getDisplayWidth(), lineHeight);
_display->setDrawColor(1);

auto acPower = PowerMeter.getPowerTotal(false);
if (acPower > 999) {
snprintf(_fmtText, sizeof(_fmtText), i18n_meter_power_kw[_display_language], (acPower / 1000));
} else {
snprintf(_fmtText, sizeof(_fmtText), i18n_meter_power_w[_display_language], acPower);
}

printText(_fmtText, 2);
}

_display->sendBuffer();

_mExtra++;
Expand Down
2 changes: 1 addition & 1 deletion src/WebApi_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,12 @@ void WebApiDeviceClass::onDeviceAdminPost(AsyncWebServerRequest* request)
config.Led_Single[i].Brightness = min<uint8_t>(100, config.Led_Single[i].Brightness);
}

Display.setDiagramMode(static_cast<DiagramMode_t>(config.Display.Diagram.Mode));
Display.setOrientation(config.Display.Rotation);
Display.enablePowerSafe = config.Display.PowerSafe;
Display.enableScreensaver = config.Display.ScreenSaver;
Display.setContrast(config.Display.Contrast);
Display.setLanguage(config.Display.Language);
Display.setDiagramMode(static_cast<DiagramMode_t>(config.Display.Diagram.Mode));
Display.Diagram().updatePeriod();

WebApi.writeConfig(retMsg);
Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,12 @@ void setup()
pin.display_clk,
pin.display_cs,
pin.display_reset);
Display.setDiagramMode(static_cast<DiagramMode_t>(config.Display.Diagram.Mode));
Display.setOrientation(config.Display.Rotation);
Display.enablePowerSafe = config.Display.PowerSafe;
Display.enableScreensaver = config.Display.ScreenSaver;
Display.setContrast(config.Display.Contrast);
Display.setLanguage(config.Display.Language);
Display.setDiagramMode(static_cast<DiagramMode_t>(config.Display.Diagram.Mode));
Display.setStartupDisplay();
MessageOutput.println("done");

Expand Down

0 comments on commit 9240663

Please sign in to comment.