|  | @ -26,8 +26,8 @@ class HistoryData { | 
			
		
	
		
		
			
				
					|  |  |     private: |  |  |     private: | 
			
		
	
		
		
			
				
					|  |  |         struct storage_t { |  |  |         struct storage_t { | 
			
		
	
		
		
			
				
					|  |  |             uint16_t refreshCycle = 0; |  |  |             uint16_t refreshCycle = 0; | 
			
		
	
		
		
			
				
					
					|  |  |             uint16_t loopCnt; |  |  |             uint16_t loopCnt = 0; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |             uint16_t listIdx; // index for next Element to write into WattArr
 |  |  |             uint16_t listIdx = 0; // index for next Element to write into WattArr
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |             // ring buffer for watt history
 |  |  |             // ring buffer for watt history
 | 
			
		
	
		
		
			
				
					|  |  |             std::array<uint16_t, (HISTORY_DATA_ARR_LENGTH + 1)> data; |  |  |             std::array<uint16_t, (HISTORY_DATA_ARR_LENGTH + 1)> data; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  | @ -45,13 +45,12 @@ class HistoryData { | 
			
		
	
		
		
			
				
					|  |  |             mConfig = config; |  |  |             mConfig = config; | 
			
		
	
		
		
			
				
					|  |  |             mTs = ts; |  |  |             mTs = ts; | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             mCurPwr.reset(); |  |  |  | 
			
		
	
		
		
			
				
					|  |  |             mCurPwr.refreshCycle = mConfig->inst.sendInterval; |  |  |             mCurPwr.refreshCycle = mConfig->inst.sendInterval; | 
			
		
	
		
		
			
				
					|  |  |             mCurPwrDay.reset(); |  |  |  | 
			
		
	
		
		
			
				
					|  |  |             mCurPwrDay.refreshCycle = mConfig->inst.sendInterval; |  |  |             mCurPwrDay.refreshCycle = mConfig->inst.sendInterval; | 
			
		
	
		
		
			
				
					
					|  |  |             mYieldDay.reset(); |  |  |             #if defined(ENABLE_HISTORY_YIELD_PER_DAY) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             mYieldDay.refreshCycle = 60; |  |  |             mYieldDay.refreshCycle = 60; | 
			
		
	
		
		
			
				
					
					|  |  | 			mLastValueTs = 0; |  |  |             #endif | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             mLastValueTs = 0; | 
			
		
	
		
		
			
				
					|  |  |             mPgPeriod=0; |  |  |             mPgPeriod=0; | 
			
		
	
		
		
			
				
					|  |  |             mMaximumDay = 0; |  |  |             mMaximumDay = 0; | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
	
		
		
			
				
					|  | @ -60,7 +59,7 @@ class HistoryData { | 
			
		
	
		
		
			
				
					|  |  |             float curPwr = 0; |  |  |             float curPwr = 0; | 
			
		
	
		
		
			
				
					|  |  |             //float maxPwr = 0;
 |  |  |             //float maxPwr = 0;
 | 
			
		
	
		
		
			
				
					|  |  |             float yldDay = -0.1; |  |  |             float yldDay = -0.1; | 
			
		
	
		
		
			
				
					
					|  |  | 			uint32_t ts = 0; |  |  |             uint32_t ts = 0; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             for (uint8_t i = 0; i < mSys->getNumInverters(); i++) { |  |  |             for (uint8_t i = 0; i < mSys->getNumInverters(); i++) { | 
			
		
	
		
		
			
				
					|  |  |                 Inverter<> *iv = mSys->getInverterByPos(i); |  |  |                 Inverter<> *iv = mSys->getInverterByPos(i); | 
			
		
	
	
		
		
			
				
					|  | @ -70,14 +69,14 @@ class HistoryData { | 
			
		
	
		
		
			
				
					|  |  |                 curPwr += iv->getChannelFieldValue(CH0, FLD_PAC, rec); |  |  |                 curPwr += iv->getChannelFieldValue(CH0, FLD_PAC, rec); | 
			
		
	
		
		
			
				
					|  |  |                 //maxPwr += iv->getChannelFieldValue(CH0, FLD_MP, rec);
 |  |  |                 //maxPwr += iv->getChannelFieldValue(CH0, FLD_MP, rec);
 | 
			
		
	
		
		
			
				
					|  |  |                 yldDay += iv->getChannelFieldValue(CH0, FLD_YD, rec); |  |  |                 yldDay += iv->getChannelFieldValue(CH0, FLD_YD, rec); | 
			
		
	
		
		
			
				
					
					|  |  | 				if (rec->ts > ts) |  |  |                 if (rec->ts > ts) | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 					ts = rec->ts; |  |  |                     ts = rec->ts; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |             if ((++mCurPwr.loopCnt % mCurPwr.refreshCycle) == 0) { |  |  |             if ((++mCurPwr.loopCnt % mCurPwr.refreshCycle) == 0) { | 
			
		
	
		
		
			
				
					|  |  |                 mCurPwr.loopCnt = 0; |  |  |                 mCurPwr.loopCnt = 0; | 
			
		
	
		
		
			
				
					|  |  |                 if (curPwr > 0) { |  |  |                 if (curPwr > 0) { | 
			
		
	
		
		
			
				
					
					|  |  | 					mLastValueTs = ts; |  |  |                     mLastValueTs = ts; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |                     addValue(&mCurPwr, roundf(curPwr)); |  |  |                     addValue(&mCurPwr, roundf(curPwr)); | 
			
		
	
		
		
			
				
					|  |  |                     if (curPwr > mMaximumDay) |  |  |                     if (curPwr > mMaximumDay) | 
			
		
	
		
		
			
				
					|  |  |                         mMaximumDay = roundf(curPwr); |  |  |                         mMaximumDay = roundf(curPwr); | 
			
		
	
	
		
		
			
				
					|  | @ -94,18 +93,18 @@ class HistoryData { | 
			
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             #if defined(ENABLE_HISTORY_YIELD_PER_DAY) | 
			
		
	
		
		
			
				
					|  |  |             if((++mYieldDay.loopCnt % mYieldDay.refreshCycle) == 0) { |  |  |             if((++mYieldDay.loopCnt % mYieldDay.refreshCycle) == 0) { | 
			
		
	
		
		
			
				
					
					|  |  | 				mYieldDay.loopCnt = 0; |  |  |                 mYieldDay.loopCnt = 0; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 				if (*mTs > mApp->getSunset()) |  |  |                 if (*mTs > mApp->getSunset()) { | 
			
				
				
			
		
	
		
		
			
				
					|  |  | 				{ |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |                     if ((!mDayStored) && (yldDay > 0)) { |  |  |                     if ((!mDayStored) && (yldDay > 0)) { | 
			
		
	
		
		
			
				
					|  |  |                         addValue(&mYieldDay, roundf(yldDay)); |  |  |                         addValue(&mYieldDay, roundf(yldDay)); | 
			
		
	
		
		
			
				
					|  |  |                         mDayStored = true; |  |  |                         mDayStored = true; | 
			
		
	
		
		
			
				
					|  |  |                     } |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  | 				} |  |  |                 } else if (*mTs > mApp->getSunrise()) | 
			
				
				
			
		
	
		
		
			
				
					|  |  | 				else if (*mTs > mApp->getSunrise()) |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					|  |  |                     mDayStored = false; |  |  |                     mDayStored = false; | 
			
		
	
		
		
			
				
					
					|  |  | 			} |  |  |             } | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |  |  |  |             #endif | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         uint16_t valueAt(HistoryStorageType type, uint16_t i) { |  |  |         uint16_t valueAt(HistoryStorageType type, uint16_t i) { | 
			
		
	
	
		
		
			
				
					|  | @ -113,10 +112,12 @@ class HistoryData { | 
			
		
	
		
		
			
				
					|  |  |             uint16_t idx=i; |  |  |             uint16_t idx=i; | 
			
		
	
		
		
			
				
					|  |  |             DPRINTLN(DBG_VERBOSE, F("valueAt ") + String((uint8_t)type) + " i=" + String(i)); |  |  |             DPRINTLN(DBG_VERBOSE, F("valueAt ") + String((uint8_t)type) + " i=" + String(i)); | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             idx = (s->listIdx + i) % HISTORY_DATA_ARR_LENGTH; | 
			
		
	
		
		
			
				
					|  |  |             switch (type) { |  |  |             switch (type) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                 default: | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     [[fallthrough]]; | 
			
		
	
		
		
			
				
					|  |  |                 case HistoryStorageType::POWER: |  |  |                 case HistoryStorageType::POWER: | 
			
		
	
		
		
			
				
					|  |  |                     s = &mCurPwr; |  |  |                     s = &mCurPwr; | 
			
		
	
		
		
			
				
					|  |  |                     idx = (s->listIdx + i) % HISTORY_DATA_ARR_LENGTH; |  |  |  | 
			
		
	
		
		
			
				
					|  |  |                     break; |  |  |                     break; | 
			
		
	
		
		
			
				
					|  |  |                 case HistoryStorageType::POWER_DAY: |  |  |                 case HistoryStorageType::POWER_DAY: | 
			
		
	
		
		
			
				
					|  |  |                     s = &mCurPwrDay; |  |  |                     s = &mCurPwrDay; | 
			
		
	
	
		
		
			
				
					|  | @ -124,12 +125,10 @@ class HistoryData { | 
			
		
	
		
		
			
				
					|  |  |                     break; |  |  |                     break; | 
			
		
	
		
		
			
				
					|  |  |                 case HistoryStorageType::YIELD: |  |  |                 case HistoryStorageType::YIELD: | 
			
		
	
		
		
			
				
					|  |  |                     s = &mYieldDay; |  |  |                     s = &mYieldDay; | 
			
		
	
		
		
			
				
					|  |  |                     idx = (s->listIdx + i) % HISTORY_DATA_ARR_LENGTH; |  |  |  | 
			
		
	
		
		
			
				
					|  |  |                     break; |  |  |                     break; | 
			
		
	
		
		
			
				
					|  |  |             } |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |             if (s) |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |             return s->data[idx]; |  |  |             return s->data[idx]; | 
			
		
	
		
		
			
				
					|  |  |             return 0; |  |  |  | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         uint16_t getMaximumDay() { |  |  |         uint16_t getMaximumDay() { | 
			
		
	
	
		
		
			
				
					|  | @ -150,8 +149,8 @@ class HistoryData { | 
			
		
	
		
		
			
				
					|  |  |                     return mCurPwr.refreshCycle; |  |  |                     return mCurPwr.refreshCycle; | 
			
		
	
		
		
			
				
					|  |  |                     break; |  |  |                     break; | 
			
		
	
		
		
			
				
					|  |  |                 case HistoryStorageType::POWER_DAY: |  |  |                 case HistoryStorageType::POWER_DAY: | 
			
		
	
		
		
			
				
					
					|  |  | 					return mPgPeriod / HISTORY_DATA_ARR_LENGTH; |  |  |                     return mPgPeriod / HISTORY_DATA_ARR_LENGTH; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  | 					break; |  |  |                     break; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					|  |  |                 case HistoryStorageType::YIELD: |  |  |                 case HistoryStorageType::YIELD: | 
			
		
	
		
		
			
				
					|  |  |                     return (60 * 60 * 24);  // 1 day
 |  |  |                     return (60 * 60 * 24);  // 1 day
 | 
			
		
	
		
		
			
				
					|  |  |                     break; |  |  |                     break; | 
			
		
	
	
		
		
			
				
					|  | @ -159,21 +158,29 @@ class HistoryData { | 
			
		
	
		
		
			
				
					|  |  |             return 0; |  |  |             return 0; | 
			
		
	
		
		
			
				
					|  |  |         } |  |  |         } | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         bool isDataValid(void) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |             return ((0 != mPgStartTime) && (0 != mPgEndTime)); | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					|  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         #if defined(ENABLE_HISTORY_LOAD_DATA) |  |  |         #if defined(ENABLE_HISTORY_LOAD_DATA) | 
			
		
	
		
		
			
				
					|  |  |         /* For filling data from outside */ |  |  |         /* For filling data from outside */ | 
			
		
	
		
		
			
				
					|  |  |         void addValue(HistoryStorageType historyType, uint8_t valueType, uint32_t value) { |  |  |         void addValue(HistoryStorageType historyType, uint8_t valueType, uint32_t value) { | 
			
		
	
		
		
			
				
					|  |  |             if (valueType<2) { |  |  |             if (valueType<2) { | 
			
		
	
		
		
			
				
					|  |  |                 storage_t *s=NULL; |  |  |                 storage_t *s=NULL; | 
			
		
	
		
		
			
				
					|  |  |                 switch (historyType) { |  |  |                 switch (historyType) { | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     default: | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                         [[fallthrough]]; | 
			
		
	
		
		
			
				
					|  |  |                     case HistoryStorageType::POWER: |  |  |                     case HistoryStorageType::POWER: | 
			
		
	
		
		
			
				
					|  |  |                         s = &mCurPwr; |  |  |                         s = &mCurPwr; | 
			
		
	
		
		
			
				
					|  |  |                         break; |  |  |                         break; | 
			
		
	
		
		
			
				
					|  |  |                     case HistoryStorageType::POWER_DAY: |  |  |                     case HistoryStorageType::POWER_DAY: | 
			
		
	
		
		
			
				
					|  |  |                         s = &mCurPwrDay; |  |  |                         s = &mCurPwrDay; | 
			
		
	
		
		
			
				
					|  |  |                         break; |  |  |                         break; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     #if defined(ENABLE_HISTORY_YIELD_PER_DAY) | 
			
		
	
		
		
			
				
					|  |  |                     case HistoryStorageType::YIELD: |  |  |                     case HistoryStorageType::YIELD: | 
			
		
	
		
		
			
				
					|  |  |                         s = &mYieldDay; |  |  |                         s = &mYieldDay; | 
			
		
	
		
		
			
				
					|  |  |                         break; |  |  |                         break; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |                     #endif | 
			
		
	
		
		
			
				
					|  |  |                 } |  |  |                 } | 
			
		
	
		
		
			
				
					|  |  |                 if (s) |  |  |                 if (s) | 
			
		
	
		
		
			
				
					|  |  |                 { |  |  |                 { | 
			
		
	
	
		
		
			
				
					|  | @ -275,10 +282,12 @@ class HistoryData { | 
			
		
	
		
		
			
				
					|  |  | 
 |  |  | 
 | 
			
		
	
		
		
			
				
					|  |  |         storage_t mCurPwr; |  |  |         storage_t mCurPwr; | 
			
		
	
		
		
			
				
					|  |  |         storage_t mCurPwrDay; |  |  |         storage_t mCurPwrDay; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         #if defined(ENABLE_HISTORY_YIELD_PER_DAY) | 
			
		
	
		
		
			
				
					|  |  |         storage_t mYieldDay; |  |  |         storage_t mYieldDay; | 
			
		
	
		
		
			
				
					|  |  |  |  |  |         #endif | 
			
		
	
		
		
			
				
					|  |  |         bool mDayStored = false; |  |  |         bool mDayStored = false; | 
			
		
	
		
		
			
				
					|  |  |         uint16_t mMaximumDay = 0; |  |  |         uint16_t mMaximumDay = 0; | 
			
		
	
		
		
			
				
					
					|  |  | 		uint32_t mLastValueTs = 0; |  |  |         uint32_t mLastValueTs = 0; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					|  |  |         enum class PowerGraphState { |  |  |         enum class PowerGraphState { | 
			
		
	
		
		
			
				
					|  |  |             NO_TIME_SYNC, |  |  |             NO_TIME_SYNC, | 
			
		
	
		
		
			
				
					|  |  |             IN_PERIOD, |  |  |             IN_PERIOD, | 
			
		
	
	
		
		
			
				
					|  | 
 |