Skip to content

Commit 0587870

Browse files
Save values of diagram while rebooting
Prevent loosing diagram values when performing a reboot or firmware update.
1 parent 1f1227f commit 0587870

5 files changed

+91
-3
lines changed

include/Display_Graphic.h

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class DisplayGraphicClass {
4343
void setLanguage(const uint8_t language);
4444
void setDiagramMode(DiagramMode_t mode);
4545
void setStartupDisplay();
46+
void prepareDtuRestart();
4647

4748
DisplayGraphicDiagramClass& Diagram();
4849

include/Display_Graphic_Diagram.h

+5
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@ class DisplayGraphicDiagramClass {
1616

1717
void updatePeriod();
1818

19+
void prepareDtuRestart();
20+
1921
private:
2022
void averageLoop();
2123
void dataPointLoop();
2224

25+
void backupGraphValuesBeforeRestart();
26+
void restoreGraphValuesAfterRestart(bool& delayUpdateTasks);
27+
2328
uint32_t getSecondsPerDot();
2429

2530
Task _averageTask;

src/Display_Graphic.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -297,4 +297,11 @@ void DisplayGraphicClass::setStatus(const bool turnOn)
297297
_displayTurnedOn = turnOn;
298298
}
299299

300+
void DisplayGraphicClass::prepareDtuRestart() {
301+
if (isValidDisplay()) {
302+
setStatus(false);
303+
_diagram.prepareDtuRestart();
304+
}
305+
}
306+
300307
DisplayGraphicClass Display;

src/Display_Graphic_Diagram.cpp

+77-2
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,42 @@
66
#include "Configuration.h"
77
#include "Datastore.h"
88
#include <algorithm>
9+
#include <Preferences.h>
10+
11+
12+
// Expected time after a restart all inverters are ready
13+
#define EXPECTED_SECS_INVERTERS_AVAILABLE_AFTER_RESTART 60
14+
915

1016
DisplayGraphicDiagramClass::DisplayGraphicDiagramClass()
1117
: _averageTask(1 * TASK_SECOND, TASK_FOREVER, std::bind(&DisplayGraphicDiagramClass::averageLoop, this))
1218
, _dataPointTask(TASK_IMMEDIATE, TASK_FOREVER, std::bind(&DisplayGraphicDiagramClass::dataPointLoop, this))
1319
{
1420
}
1521

22+
1623
void DisplayGraphicDiagramClass::init(Scheduler& scheduler, U8G2* display)
1724
{
25+
bool delayUpdateTasks;
26+
1827
_display = display;
1928

29+
restoreGraphValuesAfterRestart(delayUpdateTasks);
30+
2031
scheduler.addTask(_averageTask);
21-
_averageTask.enable();
32+
if (delayUpdateTasks) {
33+
_averageTask.restartDelayed(EXPECTED_SECS_INVERTERS_AVAILABLE_AFTER_RESTART * TASK_SECOND);
34+
} else {
35+
_averageTask.enable();
36+
}
2237

2338
scheduler.addTask(_dataPointTask);
2439
updatePeriod();
25-
_dataPointTask.enable();
40+
if (delayUpdateTasks) {
41+
_dataPointTask.restartDelayed(EXPECTED_SECS_INVERTERS_AVAILABLE_AFTER_RESTART * TASK_SECOND);
42+
} else {
43+
_dataPointTask.enable();
44+
}
2645
}
2746

2847
void DisplayGraphicDiagramClass::averageLoop()
@@ -134,3 +153,59 @@ void DisplayGraphicDiagramClass::redraw(uint8_t screenSaverOffsetX, uint8_t xPos
134153
graphPosX + i / scaleFactorX, horizontal_line_y - std::max<int16_t>(0, _graphValues[i] / scaleFactorY - 0.5));
135154
}
136155
}
156+
157+
void DisplayGraphicDiagramClass::backupGraphValuesBeforeRestart()
158+
{
159+
auto prefs = Preferences();
160+
161+
if (!prefs.begin("OPENDtuGraphVal")) {
162+
return;
163+
}
164+
_dataPointTask.disable();
165+
166+
// Find an easy way to wait till a possible current execution of _dataPointTask has ended
167+
// Or: Use a mutex here and in dataPointLoop()
168+
// For now: I assume restarting is very rare and we validate everything in restoreGraphValuesAfterRestart()
169+
prefs.putUChar("count", _graphValuesCount);
170+
prefs.putBytes("vars", &_graphValues[0], sizeof(_graphValues));
171+
prefs.end();
172+
}
173+
174+
void DisplayGraphicDiagramClass::restoreGraphValuesAfterRestart(bool& delayUpdateTasks)
175+
{
176+
auto prefs = Preferences();
177+
178+
delayUpdateTasks = false;
179+
180+
if (!prefs.begin("OPENDtuGraphVal")) {
181+
return;
182+
}
183+
_graphValuesCount = prefs.getUChar("count", _graphValuesCount);
184+
if (_graphValuesCount >= std::size(_graphValues)) {
185+
_graphValuesCount = std::size(_graphValues) - 1;
186+
}
187+
prefs.getBytes("vars", &_graphValues[0], sizeof(_graphValues));
188+
prefs.clear(); // clear - so only after a Utils::restartDtu() the variables are available
189+
prefs.end();
190+
191+
// Check if it was a restart due software reset
192+
if (esp_reset_reason() != ESP_RST_SW) {
193+
_graphValuesCount = 0;
194+
return;
195+
}
196+
197+
// Delaying the data collection makes no sense if a dot is less than the time we need
198+
// to query all the inverters after a reboot.
199+
// At 60secs this equals a diagram period of ~7680sec (2h8m) on a 128 dot display
200+
_chartWidth = _display->getDisplayWidth(); // assume diagram use the whole display
201+
if (getSecondsPerDot() <= EXPECTED_SECS_INVERTERS_AVAILABLE_AFTER_RESTART) {
202+
return;
203+
}
204+
205+
delayUpdateTasks = (_graphValuesCount != 0);
206+
}
207+
208+
void DisplayGraphicDiagramClass::prepareDtuRestart()
209+
{
210+
backupGraphValuesBeforeRestart();
211+
}

src/Utils.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ int Utils::getTimezoneOffset()
6262
void Utils::restartDtu()
6363
{
6464
LedSingle.turnAllOff();
65-
Display.setStatus(false);
65+
Display.prepareDtuRestart();
6666
yield();
6767
delay(1000);
6868
yield();

0 commit comments

Comments
 (0)