mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-22 13:26:10 +02:00
fix immediate clearing of display after sunset
This commit is contained in:
parent
f4a82242df
commit
ac2f772b74
2 changed files with 79 additions and 45 deletions
|
@ -81,7 +81,7 @@ class DisplayMono {
|
||||||
mDispWidth = mDisplay->getDisplayWidth();
|
mDispWidth = mDisplay->getDisplayWidth();
|
||||||
mDispHeight = mDisplay->getDisplayHeight();
|
mDispHeight = mDisplay->getDisplayHeight();
|
||||||
mDispSwitchTime.stopTimeMonitor();
|
mDispSwitchTime.stopTimeMonitor();
|
||||||
if (mCfg->graph_ratio == 100) // if graph ratio is 100% start in graph mode
|
if (100 == mCfg->graph_ratio) // if graph ratio is 100% start in graph mode
|
||||||
mDispSwitchState = DispSwitchState::GRAPH;
|
mDispSwitchState = DispSwitchState::GRAPH;
|
||||||
else if (mCfg->graph_ratio != 0)
|
else if (mCfg->graph_ratio != 0)
|
||||||
mDispSwitchTime.startTimeMonitor(150 * (100 - mCfg->graph_ratio)); // start display mode change only if ratio is neither 0 nor 100
|
mDispSwitchTime.startTimeMonitor(150 * (100 - mCfg->graph_ratio)); // start display mode change only if ratio is neither 0 nor 100
|
||||||
|
@ -90,39 +90,70 @@ class DisplayMono {
|
||||||
// pixelshift screensaver with wipe effect
|
// pixelshift screensaver with wipe effect
|
||||||
void calcPixelShift(int range) {
|
void calcPixelShift(int range) {
|
||||||
int8_t mod = (millis() / 10000) % ((range >> 1) << 2);
|
int8_t mod = (millis() / 10000) % ((range >> 1) << 2);
|
||||||
mPixelshift = mCfg->screenSaver == 1 ? ((mod < range) ? mod - (range >> 1) : -(mod - range - (range >> 1) + 1)) : 0;
|
mPixelshift = (1 == mCfg->screenSaver) ? ((mod < range) ? mod - (range >> 1) : -(mod - range - (range >> 1) + 1)) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enum class PowerGraphState {
|
||||||
|
NO_TIME_SYNC,
|
||||||
|
IN_PERIOD,
|
||||||
|
WAIT_4_NEW_PERIOD,
|
||||||
|
WAIT_4_RESTART
|
||||||
|
};
|
||||||
|
|
||||||
|
// initialize power graph and allocate data buffer based on pixel width
|
||||||
void initPowerGraph(uint8_t width, uint8_t height) {
|
void initPowerGraph(uint8_t width, uint8_t height) {
|
||||||
DBGPRINTLN(F("---- Init Power Graph ----"));
|
DBGPRINTLN(F("---- Init Power Graph ----"));
|
||||||
mPgWidth = width;
|
mPgWidth = width;
|
||||||
mPgHeight = height;
|
mPgHeight = height;
|
||||||
mPgData = new float[mPgWidth];
|
mPgData = new float[mPgWidth];
|
||||||
|
mPgState = PowerGraphState::NO_TIME_SYNC;
|
||||||
resetPowerGraph();
|
resetPowerGraph();
|
||||||
/*
|
|
||||||
Inverter<> *iv;
|
|
||||||
mPgMaxAvailPower = 0;
|
|
||||||
uint8_t nInv = mSys->getNumInverters();
|
|
||||||
for (uint8_t i = 0; i < nInv; i++) {
|
|
||||||
iv = mSys->getInverterByPos(i);
|
|
||||||
if (iv == NULL)
|
|
||||||
continue;
|
|
||||||
for (uint8_t ch = 0; ch < 6; ch++) {
|
|
||||||
mPgMaxAvailPower += iv->config->chMaxPwr[ch];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DBGPRINTLN("max. Power = " + String(mPgMaxAvailPower));*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add new value to power graph and maintain state engine for period times
|
||||||
void addPowerGraphEntry(float val) {
|
void addPowerGraphEntry(float val) {
|
||||||
if ((nullptr != mPgData) && (mDisplayData->utcTs > 0)) { // precondition: power graph initialized and utc time available
|
if (nullptr == mPgData) // power graph not initialized
|
||||||
calcPowerGraphValues();
|
return;
|
||||||
//mPgData[mPgLastPos] = std::max(mPgData[mPgLastPos], (uint8_t) (val * 255.0 / mPgMaxAvailPower)); // normalizing of data to 0-255
|
|
||||||
mPgData[mPgLastPos] = std::max(mPgData[mPgLastPos], val);
|
bool store_entry = false;
|
||||||
mPgMaxPwr = std::max(mPgMaxPwr, val); // max value of stored data for scaling of y-axis
|
switch(mPgState) {
|
||||||
|
case PowerGraphState::NO_TIME_SYNC:
|
||||||
|
if ((mDisplayData->pGraphStartTime > 0) && (mDisplayData->pGraphEndTime > 0) && // wait until period data is available ...
|
||||||
|
(mDisplayData->utcTs >= mDisplayData->pGraphStartTime) && (mDisplayData->utcTs < mDisplayData->pGraphEndTime)) { // and current time is in period
|
||||||
|
storeStartEndTimes(); // period was received -> store
|
||||||
|
store_entry = true;
|
||||||
|
mPgState = PowerGraphState::IN_PERIOD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PowerGraphState::IN_PERIOD:
|
||||||
|
if (mDisplayData->utcTs > mPgEndTime) // check if end of day is reached ...
|
||||||
|
mPgState = PowerGraphState::WAIT_4_NEW_PERIOD; // then wait for new period setting
|
||||||
|
else
|
||||||
|
store_entry = true;
|
||||||
|
break;
|
||||||
|
case PowerGraphState::WAIT_4_NEW_PERIOD:
|
||||||
|
if ((mPgStartTime != mDisplayData->pGraphStartTime) || (mPgEndTime != mDisplayData->pGraphEndTime)) { // wait until new time period was received ...
|
||||||
|
storeStartEndTimes(); // and store it for next period
|
||||||
|
mPgState = PowerGraphState::WAIT_4_RESTART;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PowerGraphState::WAIT_4_RESTART:
|
||||||
|
if ((mDisplayData->utcTs >= mPgStartTime) && (mDisplayData->utcTs < mPgEndTime)) { // wait until current time is in period again ...
|
||||||
|
resetPowerGraph(); // then reset power graph data
|
||||||
|
store_entry = true;
|
||||||
|
mPgState = PowerGraphState::IN_PERIOD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (store_entry) {
|
||||||
|
mPgLastPos = std::min((uint8_t) sss2PgPos(mDisplayData->utcTs - mPgStartTime), (uint8_t) (mPgWidth - 1)); // current datapoint based on seconds since start
|
||||||
|
mPgData[mPgLastPos] = std::max(mPgData[mPgLastPos], val); // update current datapoint to maximum of all seen values
|
||||||
|
mPgMaxPwr = std::max(mPgMaxPwr, val); // update max value of stored data for scaling of y-axis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// plot power graph to given display offset
|
||||||
void plotPowerGraph(uint8_t xoff, uint8_t yoff) {
|
void plotPowerGraph(uint8_t xoff, uint8_t yoff) {
|
||||||
if (nullptr == mPgData) // power graph not initialized
|
if (nullptr == mPgData) // power graph not initialized
|
||||||
return;
|
return;
|
||||||
|
@ -146,7 +177,7 @@ class DisplayMono {
|
||||||
tm.Minute = 0;
|
tm.Minute = 0;
|
||||||
tm.Second = 0;
|
tm.Second = 0;
|
||||||
for (; tm.Hour <= endHour; tm.Hour++) {
|
for (; tm.Hour <= endHour; tm.Hour++) {
|
||||||
uint8_t x_pos_screen = getPowerGraphXpos(sss2pgpos((uint32_t) makeTime(tm) - mDisplayData->pGraphStartTime)); // scale horizontal axis
|
uint8_t x_pos_screen = getPowerGraphXpos(sss2PgPos((uint32_t) makeTime(tm) - mDisplayData->pGraphStartTime)); // scale horizontal axis
|
||||||
mDisplay->drawPixel(xoff + x_pos_screen, yoff - 1);
|
mDisplay->drawPixel(xoff + x_pos_screen, yoff - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +194,8 @@ class DisplayMono {
|
||||||
|
|
||||||
// draw curve
|
// draw curve
|
||||||
for (uint8_t i = 1; i <= mPgLastPos; i++) {
|
for (uint8_t i = 1; i <= mPgLastPos; i++) {
|
||||||
mDisplay->drawLine(xoff + getPowerGraphXpos(i - 1), yoff - getPowerGraphYpos(i - 1),
|
mDisplay->drawLine(xoff + getPowerGraphXpos(i - 1), yoff - getPowerGraphValueYpos(i - 1),
|
||||||
xoff + getPowerGraphXpos(i), yoff - getPowerGraphYpos(i));
|
xoff + getPowerGraphXpos(i), yoff - getPowerGraphValueYpos(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// print max power value
|
// print max power value
|
||||||
|
@ -195,6 +226,7 @@ class DisplayMono {
|
||||||
return change;
|
return change;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset power graph
|
||||||
void resetPowerGraph() {
|
void resetPowerGraph() {
|
||||||
if (mPgData != nullptr) {
|
if (mPgData != nullptr) {
|
||||||
mPgMaxPwr = 0.0;
|
mPgMaxPwr = 0.0;
|
||||||
|
@ -205,34 +237,35 @@ class DisplayMono {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t sss2pgpos(uint seconds_since_start) {
|
// store start and end times of current time period and calculate period length
|
||||||
uint32_t diff = (mDisplayData->pGraphEndTime - mDisplayData->pGraphStartTime);
|
void storeStartEndTimes() {
|
||||||
if(diff)
|
mPgStartTime = mDisplayData->pGraphStartTime;
|
||||||
return (seconds_since_start * (mPgWidth - 1) / diff);
|
mPgEndTime = mDisplayData->pGraphEndTime;
|
||||||
return 0;
|
mPgPeriod = mDisplayData->pGraphEndTime - mDisplayData->pGraphStartTime; // time period of power graph in sec for scaling of x-axis
|
||||||
}
|
}
|
||||||
|
|
||||||
void calcPowerGraphValues() {
|
// get power graph datapoint index, scaled to current time period, by seconds since start
|
||||||
mPgPeriod = mDisplayData->pGraphEndTime - mDisplayData->pGraphStartTime; // length of power graph for scaling of x-axis
|
uint8_t sss2PgPos(uint seconds_since_start) {
|
||||||
uint32_t oldTimeOfDay = mPgTimeOfDay;
|
if(mPgPeriod)
|
||||||
mPgTimeOfDay = (mDisplayData->utcTs > mDisplayData->pGraphStartTime) ? mDisplayData->utcTs - mDisplayData->pGraphStartTime : 0; // current time of day with respect to current sunrise time
|
return (seconds_since_start * (mPgWidth - 1) / mPgPeriod);
|
||||||
if (oldTimeOfDay > mPgTimeOfDay) // new day -> reset old data
|
else
|
||||||
resetPowerGraph();
|
return 0;
|
||||||
if(0 == mPgPeriod)
|
|
||||||
mPgPeriod = 1;
|
|
||||||
mPgLastPos = std::min((uint8_t) (mPgTimeOfDay * (mPgWidth - 1) / mPgPeriod), (uint8_t) (mPgWidth - 1)); // current datapoint based on currenct time of day
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get X-position of power graph, scaled to lastpos, by according data point index
|
||||||
uint8_t getPowerGraphXpos(uint8_t p) {
|
uint8_t getPowerGraphXpos(uint8_t p) {
|
||||||
if ((p <= mPgLastPos) && (mPgLastPos > 0))
|
if ((p <= mPgLastPos) && (mPgLastPos > 0))
|
||||||
return((p * (mPgWidth - 1)) / mPgLastPos); // scaling of x-axis
|
return((p * (mPgWidth - 1)) / mPgLastPos); // scaling of x-axis
|
||||||
return 0;
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getPowerGraphYpos(uint8_t p) {
|
// get Y-position of power graph, scaled to maximum value, by according datapoint index
|
||||||
|
uint8_t getPowerGraphValueYpos(uint8_t p) {
|
||||||
if ((p < mPgWidth) && (mPgMaxPwr > 0))
|
if ((p < mPgWidth) && (mPgMaxPwr > 0))
|
||||||
return((mPgData[p] * (uint32_t) mPgHeight / mPgMaxPwr)); // scaling of data to graph height
|
return((mPgData[p] * (uint32_t) mPgHeight / mPgMaxPwr)); // scaling of data to graph height
|
||||||
return 0;
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -254,9 +287,11 @@ class DisplayMono {
|
||||||
float *mPgData = nullptr;
|
float *mPgData = nullptr;
|
||||||
uint8_t mPgHeight = 0;
|
uint8_t mPgHeight = 0;
|
||||||
float mPgMaxPwr = 0.0;
|
float mPgMaxPwr = 0.0;
|
||||||
uint32_t mPgPeriod = 0; // seconds
|
uint32_t mPgStartTime = 0;
|
||||||
uint32_t mPgTimeOfDay = 0;
|
uint32_t mPgEndTime = 0;
|
||||||
|
uint32_t mPgPeriod = 0; // seconds
|
||||||
uint8_t mPgLastPos = 0;
|
uint8_t mPgLastPos = 0;
|
||||||
|
PowerGraphState mPgState = PowerGraphState::NO_TIME_SYNC;
|
||||||
|
|
||||||
uint16_t mDispHeight;
|
uint16_t mDispHeight;
|
||||||
uint8_t mLuminance;
|
uint8_t mLuminance;
|
||||||
|
|
|
@ -89,9 +89,8 @@ class DisplayMono128X64 : public DisplayMono {
|
||||||
calcPixelShift(pixelShiftRange);
|
calcPixelShift(pixelShiftRange);
|
||||||
|
|
||||||
// add new power data to power graph
|
// add new power data to power graph
|
||||||
if (mDisplayData->nrProducing > 0) {
|
if (mDisplayData->nrProducing > 0)
|
||||||
addPowerGraphEntry(mDisplayData->totalPower);
|
addPowerGraphEntry(mDisplayData->totalPower);
|
||||||
}
|
|
||||||
|
|
||||||
// print Date and time
|
// print Date and time
|
||||||
if (0 != mDisplayData->utcTs)
|
if (0 != mDisplayData->utcTs)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue