tweak diagram
This commit is contained in:
parent
891cc26583
commit
efb38cc423
61
.vscode/settings.json
vendored
61
.vscode/settings.json
vendored
@ -1,3 +1,60 @@
|
||||
{
|
||||
"C_Cpp.clang_format_style": "WebKit"
|
||||
}
|
||||
"C_Cpp.clang_format_style": "WebKit",
|
||||
"files.associations": {
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"chrono": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"map": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp"
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ public:
|
||||
private:
|
||||
void averageLoop();
|
||||
void dataPointLoop();
|
||||
void resetDataPoints();
|
||||
|
||||
uint32_t getSecondsPerDot();
|
||||
|
||||
@ -33,4 +34,5 @@ private:
|
||||
|
||||
float _iRunningAverage = 0;
|
||||
uint16_t _iRunningAverageCnt = 0;
|
||||
uint32_t _daySeconds = 0;
|
||||
};
|
||||
|
||||
@ -11,6 +11,7 @@ public:
|
||||
void init(Scheduler& scheduler);
|
||||
|
||||
bool isDayPeriod() const;
|
||||
uint32_t dayPeriodLength() const;
|
||||
bool isSunsetAvailable() const;
|
||||
bool sunsetTime(struct tm* info) const;
|
||||
bool sunriseTime(struct tm* info) const;
|
||||
|
||||
@ -31,8 +31,8 @@ const uint8_t languages[] = {
|
||||
|
||||
static const char* const i18n_offline[] = { "Offline", "OFFLINE", "Offline" };
|
||||
|
||||
static const char* const i18n_current_power_w[] = { "☀ %.1f W ☀", "☀ %.1f W ☀", "%.1f W ☀" };
|
||||
static const char* const i18n_current_power_kw[] = { "☀ %.1f kW ☀", "☀ %.1f kW ☀", "☀ %.1f kW ☀" };
|
||||
static const char* const i18n_current_power_w[] = { "%.1f W", "%.1f W", "%.1f W" };
|
||||
static const char* const i18n_current_power_kw[] = { "%.1f kW", "%.1f kW", "%.1f kW" };
|
||||
|
||||
static const char* const i18n_yield_today_wh[] = { "today: %.0f Wh", "Heute: %.0f Wh", "auj.: %.0f Wh" };
|
||||
static const char* const i18n_yield_today_kwh[] = { "today: %.1f kWh", "Heute: %.1f kWh", "auj.: %.1f kWh" };
|
||||
@ -189,7 +189,7 @@ void DisplayGraphicClass::loop()
|
||||
case DiagramMode_t::Fullscreen:
|
||||
// Every 10 seconds
|
||||
if (_mExtra % (10 * 2) < 10) {
|
||||
_diagram.redraw(screenSaverOffsetX, 10, 0, _display->getDisplayWidth() - 12, _display->getDisplayHeight() - 3, true);
|
||||
_diagram.redraw(screenSaverOffsetX, 0, 0, _display->getDisplayWidth(), _display->getDisplayHeight(), true);
|
||||
showText = false;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "Display_Graphic_Diagram.h"
|
||||
#include "Configuration.h"
|
||||
#include "Datastore.h"
|
||||
#include "SunPosition.h"
|
||||
#include <algorithm>
|
||||
|
||||
DisplayGraphicDiagramClass::DisplayGraphicDiagramClass()
|
||||
@ -30,6 +31,14 @@ void DisplayGraphicDiagramClass::averageLoop()
|
||||
const float currentWatts = Datastore.getTotalAcPowerEnabled(); // get the current AC production
|
||||
_iRunningAverage += currentWatts;
|
||||
_iRunningAverageCnt++;
|
||||
if(SunPosition.dayPeriodLength() == 0) { // noch keine Uhrzeit oder ein neuer tag
|
||||
_graphValuesCount = 0;
|
||||
} else {
|
||||
if(SunPosition.dayPeriodLength() != _daySeconds) { // neue Tageslänge
|
||||
updatePeriod();
|
||||
_daySeconds = SunPosition.dayPeriodLength();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayGraphicDiagramClass::dataPointLoop()
|
||||
@ -47,20 +56,26 @@ void DisplayGraphicDiagramClass::dataPointLoop()
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayGraphicDiagramClass::resetDataPoints()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint32_t DisplayGraphicDiagramClass::getSecondsPerDot()
|
||||
{
|
||||
return Configuration.get().Display.Diagram.Duration / _chartWidth;
|
||||
return SunPosition.dayPeriodLength() / _chartWidth;
|
||||
}
|
||||
|
||||
void DisplayGraphicDiagramClass::updatePeriod()
|
||||
{
|
||||
// Calculate seconds per datapoint
|
||||
_dataPointTask.setInterval(Configuration.get().Display.Diagram.Duration * TASK_SECOND / MAX_DATAPOINTS);
|
||||
_dataPointTask.setInterval(SunPosition.dayPeriodLength() * TASK_SECOND / MAX_DATAPOINTS);
|
||||
}
|
||||
|
||||
void DisplayGraphicDiagramClass::redraw(uint8_t screenSaverOffsetX, uint8_t xPos, uint8_t yPos, uint8_t width, uint8_t height, bool isFullscreen)
|
||||
{
|
||||
_chartWidth = width;
|
||||
Serial.println(SunPosition.dayPeriodLength());
|
||||
|
||||
// screenSaverOffsetX expected to be in range 0..6
|
||||
const uint8_t graphPosX = xPos + ((screenSaverOffsetX > 3) ? 1 : 0);
|
||||
@ -69,58 +84,52 @@ void DisplayGraphicDiagramClass::redraw(uint8_t screenSaverOffsetX, uint8_t xPos
|
||||
const uint8_t horizontal_line_y = graphPosY + height - 1;
|
||||
const uint8_t arrow_size = 2;
|
||||
|
||||
const float maxWatts = Datastore.getTotalDcIrradiationInstalled();//*std::max_element(_graphValues.begin(), _graphValues.end());
|
||||
|
||||
// draw diagram axis
|
||||
_display->drawVLine(graphPosX, graphPosY, height);
|
||||
_display->drawHLine(graphPosX, horizontal_line_y, width);
|
||||
//_display->drawHLine(graphPosX, horizontal_line_y, width);
|
||||
if (!isFullscreen) {
|
||||
_display->drawVLine(graphPosX, graphPosY, height);
|
||||
|
||||
// UP-arrow
|
||||
_display->drawLine(graphPosX, graphPosY, graphPosX + arrow_size, graphPosY + arrow_size);
|
||||
_display->drawLine(graphPosX, graphPosY, graphPosX - arrow_size, graphPosY + arrow_size);
|
||||
// UP-arrow
|
||||
_display->drawLine(graphPosX, graphPosY, graphPosX + arrow_size, graphPosY + arrow_size);
|
||||
_display->drawLine(graphPosX, graphPosY, graphPosX - arrow_size, graphPosY + arrow_size);
|
||||
|
||||
// LEFT-arrow
|
||||
_display->drawLine(graphPosX + width - 1, horizontal_line_y, graphPosX + width - 1 - arrow_size, horizontal_line_y - arrow_size);
|
||||
_display->drawLine(graphPosX + width - 1, horizontal_line_y, graphPosX + width - 1 - arrow_size, horizontal_line_y + arrow_size);
|
||||
// LEFT-arrow
|
||||
_display->drawLine(graphPosX + width - 1, horizontal_line_y, graphPosX + width - 1 - arrow_size, horizontal_line_y - arrow_size);
|
||||
_display->drawLine(graphPosX + width - 1, horizontal_line_y, graphPosX + width - 1 - arrow_size, horizontal_line_y + arrow_size);
|
||||
|
||||
// draw AC value
|
||||
char fmtText[7];
|
||||
const float maxWatts = *std::max_element(_graphValues.begin(), _graphValues.end());
|
||||
if (maxWatts > 999) {
|
||||
snprintf(fmtText, sizeof(fmtText), "%2.1fkW", maxWatts / 1000);
|
||||
} else {
|
||||
snprintf(fmtText, sizeof(fmtText), "%dW", static_cast<uint16_t>(maxWatts));
|
||||
}
|
||||
|
||||
if (isFullscreen) {
|
||||
_display->setFont(u8g2_font_5x8_tr);
|
||||
_display->setFontDirection(3);
|
||||
_display->drawStr(graphPosX - arrow_size, graphPosY + _display->getStrWidth(fmtText), fmtText);
|
||||
_display->setFontDirection(0);
|
||||
} else {
|
||||
// 4 pixels per char
|
||||
// draw AC value
|
||||
char fmtText[7];
|
||||
if (maxWatts > 999) {
|
||||
snprintf(fmtText, sizeof(fmtText), "%2.1fkW", maxWatts / 1000);
|
||||
} else {
|
||||
snprintf(fmtText, sizeof(fmtText), "%dW", static_cast<uint16_t>(maxWatts));
|
||||
}
|
||||
_display->setFont(u8g2_font_tom_thumb_4x6_mr);
|
||||
_display->drawStr(graphPosX - arrow_size - _display->getStrWidth(fmtText), graphPosY + 5, fmtText);
|
||||
}
|
||||
else {
|
||||
float wattsToday = Datastore.getTotalAcYieldDayEnabled();
|
||||
char * text = new char[10]();
|
||||
if (wattsToday > 999) {
|
||||
snprintf(text, 10, "%.0fkWh" , wattsToday / 1000);
|
||||
} else {
|
||||
snprintf(text, 10, "%.0fWh", wattsToday);
|
||||
}
|
||||
_display->setFont(u8g2_font_unifont_t_0_76);
|
||||
_display->drawUTF8(0, 16, text);
|
||||
}
|
||||
|
||||
// draw chart
|
||||
const float scaleFactorY = maxWatts / static_cast<float>(height);
|
||||
const float scaleFactorX = static_cast<float>(MAX_DATAPOINTS) / static_cast<float>(_chartWidth);
|
||||
|
||||
if (maxWatts > 0 && isFullscreen) {
|
||||
// draw y axis ticks
|
||||
const uint16_t yAxisWattPerTick = maxWatts <= 100 ? 10 : maxWatts <= 1000 ? 100
|
||||
: maxWatts < 5000 ? 500
|
||||
: 1000;
|
||||
const uint8_t yAxisTickSizePixel = height / (maxWatts / yAxisWattPerTick);
|
||||
|
||||
for (int16_t tickYPos = graphPosY + height; tickYPos > graphPosY - arrow_size; tickYPos -= yAxisTickSizePixel) {
|
||||
_display->drawPixel(graphPosX - 1, tickYPos);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t xAxisTicks = 1;
|
||||
for (uint8_t i = 1; i < _graphValuesCount; i++) {
|
||||
Serial.println(_graphValuesCount);
|
||||
for (uint8_t i = 0; i < _graphValuesCount; i++) {
|
||||
// draw one tick per hour to the x-axis
|
||||
if (i * getSecondsPerDot() > (3600u * xAxisTicks)) {
|
||||
if (!isFullscreen && i * getSecondsPerDot() > (3600u * xAxisTicks)) {
|
||||
_display->drawPixel((graphPosX + 1 + i) * scaleFactorX, graphPosY + height);
|
||||
xAxisTicks++;
|
||||
}
|
||||
@ -130,7 +139,7 @@ void DisplayGraphicDiagramClass::redraw(uint8_t screenSaverOffsetX, uint8_t xPos
|
||||
}
|
||||
|
||||
_display->drawLine(
|
||||
graphPosX + (i - 1) / scaleFactorX, horizontal_line_y - std::max<int16_t>(0, _graphValues[i - 1] / scaleFactorY - 0.5),
|
||||
graphPosX + i / scaleFactorX, horizontal_line_y - std::max<int16_t>(0, _graphValues[i] / scaleFactorY - 0.5));
|
||||
graphPosX + i / scaleFactorX, horizontal_line_y - std::max<int16_t>(0, _graphValues[i] / scaleFactorY - 0.5),
|
||||
graphPosX + i / scaleFactorX, horizontal_line_y);
|
||||
}
|
||||
}
|
||||
|
||||
12
src/NerdMiner_v2.code-workspace
Normal file
12
src/NerdMiner_v2.code-workspace
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "../../NerdMiner_v2"
|
||||
},
|
||||
{
|
||||
"name": "OpenDTU",
|
||||
"path": ".."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
||||
@ -39,6 +39,14 @@ bool SunPositionClass::isDayPeriod() const
|
||||
return (minutesPastMidnight >= _sunriseMinutes) && (minutesPastMidnight < _sunsetMinutes);
|
||||
}
|
||||
|
||||
uint32_t SunPositionClass::dayPeriodLength() const
|
||||
{
|
||||
if (!_isValidInfo) {
|
||||
return 0;
|
||||
}
|
||||
return (60 * (_sunsetMinutes - _sunriseMinutes));
|
||||
}
|
||||
|
||||
bool SunPositionClass::isSunsetAvailable() const
|
||||
{
|
||||
return _isSunsetAvailable;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user